From ef43883fb55c1da8708c88537d614a67ae5e6881 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 25 Mar 2019 11:53:13 +0100 Subject: [PATCH 001/158] dynarec: WinCE support WIP Only for the x64 dynarec atm Bugs remaining --- core/hw/sh4/dyna/blockmanager.cpp | 79 +++- core/hw/sh4/dyna/blockmanager.h | 6 +- core/hw/sh4/dyna/decoder.cpp | 62 ++-- core/hw/sh4/dyna/driver.cpp | 86 +++-- core/hw/sh4/dyna/ngen.h | 2 +- core/hw/sh4/dyna/regalloc.h | 33 +- core/hw/sh4/dyna/shil.h | 1 + core/hw/sh4/interpr/sh4_interpreter.cpp | 6 +- core/hw/sh4/modules/ccn.cpp | 8 +- core/hw/sh4/modules/mmu.cpp | 272 +++++--------- core/hw/sh4/modules/mmu_impl.h | 11 +- core/hw/sh4/modules/wince.h | 73 +++- core/hw/sh4/sh4_core.h | 9 + core/rec-x64/rec_x64.cpp | 474 ++++++++++++++++++++---- core/rec-x64/x64_regalloc.h | 10 + 15 files changed, 791 insertions(+), 341 deletions(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index dd0a3b818..2392a8a99 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -18,6 +18,7 @@ //#include "../intc.h" //#include "../tmu.h" #include "hw/sh4/sh4_mem.h" +#include "hw/sh4/sh4_sched.h" #if HOST_OS==OS_LINUX && defined(DYNA_OPROF) @@ -86,6 +87,7 @@ u32 bm_gc_luc,bm_gcf_luc; #define FPCA(x) ((DynarecCodeEntryPtr&)sh4rcb.fpcb[(x>>1)&FPCB_MASK]) +// addr must be a physical address DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr) { //rdv_FailedToFindBlock_pc=addr; @@ -94,11 +96,51 @@ DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr) return (DynarecCodeEntryPtr)rv; } +// addr must be a virtual address DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr) { - return (DynarecCodeEntryPtr)bm_GetCode(addr); +#ifndef NO_MMU + if (!mmu_enabled()) +#endif + return (DynarecCodeEntryPtr)bm_GetCode(addr); +#ifndef NO_MMU + else + { + if (addr & 1) + { + switch (addr) + { + case 0xfffffde7: // GetTickCount + // This should make this syscall faster + r[0] = sh4_sched_now64() * 1000 / SH4_MAIN_CLOCK; + next_pc = pr; + addr = next_pc; + break; + default: + Do_Exception(addr, 0xE0, 0x100); + addr = next_pc; + break; + } + } + + try { + u32 paddr; + bool shared; + mmu_instruction_translation(addr, paddr, shared); + + return (DynarecCodeEntryPtr)bm_GetCode(paddr); + } catch (SH4ThrownException& ex) { + Do_Exception(addr, ex.expEvn, ex.callVect); + u32 paddr; + bool shared; + mmu_instruction_translation(next_pc, paddr, shared); + return (DynarecCodeEntryPtr)bm_GetCode(paddr); + } + } +#endif } +// addr must be a physical address RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr) { DynarecCodeEntryPtr cde=bm_GetCode(addr); @@ -165,6 +207,22 @@ void bm_AddBlock(RuntimeBlockInfo* blk) } +void bm_RemoveBlock(RuntimeBlockInfo* block) +{ + verify((void*)bm_GetCode(block->addr) != (void*)ngen_FailedToFindBlock); + FPCA(block->addr) = ngen_FailedToFindBlock; + auto it = blkmap.find(block); + if (it != blkmap.end()) + blkmap.erase(it); + for (auto it = all_blocks.begin(); it != all_blocks.end(); it++) + if (*it == block) + { + all_blocks.erase(it); + break; + } + delete block; +} + bool UDgreaterX ( RuntimeBlockInfo* elem1, RuntimeBlockInfo* elem2 ) { return elem1->runs > elem2->runs; @@ -594,7 +652,8 @@ void print_blocks() if (f) { fprintf(f,"block: %p\n",blk); - fprintf(f,"addr: %08X\n",blk->addr); + fprintf(f,"vaddr: %08X\n",blk->vaddr); + fprintf(f,"paddr: %08X\n",blk->addr); fprintf(f,"hash: %s\n",blk->hash()); fprintf(f,"hash_rloc: %s\n",blk->hash(false,true)); fprintf(f,"code: %p\n",blk->code); @@ -624,17 +683,21 @@ void print_blocks() if (gcode!=op->guest_offs) { gcode=op->guest_offs; - u32 rpc=blk->addr+gcode; - u16 op=ReadMem16(rpc); + u32 rpc=blk->vaddr+gcode; + try { + u16 op=IReadMem16(rpc); - char temp[128]; - OpDesc[op]->Disassemble(temp,rpc,op); + char temp[128]; + OpDesc[op]->Disassemble(temp,rpc,op); - fprintf(f,"//g:%s\n",temp); + fprintf(f,"//g: %04X %s\n", op, temp); + } catch (SH4ThrownException& ex) { + fprintf(f,"//g: ???? (page fault)\n"); + } } string s=op->dissasm(); - fprintf(f,"//il:%d:%d:%s\n",op->guest_offs,op->host_offs,s.c_str()); + fprintf(f,"//il:%d:%d: %s\n",op->guest_offs,op->host_offs,s.c_str()); } fprint_hex(f,"//h:",pucode,hcode,blk->host_code_size); diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index f676500c3..b750449e4 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -20,6 +20,8 @@ struct RuntimeBlockInfo: RuntimeBlockInfo_Core void Setup(u32 pc,fpscr_t fpu_cfg); const char* hash(bool full=true, bool reloc=false); + u32 vaddr; + u32 host_code_size; //in bytes u32 sh4_code_size; //in bytes @@ -33,7 +35,8 @@ struct RuntimeBlockInfo: RuntimeBlockInfo_Core u32 guest_cycles; u32 guest_opcodes; u32 host_opcodes; - + bool has_fpu_op; + u32 asid; // if not 0xFFFFFFFF then private page belonging to this id u32 BranchBlock; //if not 0xFFFFFFFF then jump target u32 NextBlock; //if not 0xFFFFFFFF then next block (by position) @@ -94,6 +97,7 @@ RuntimeBlockInfo* bm_GetStaleBlock(void* dynarec_code); RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr); void bm_AddBlock(RuntimeBlockInfo* blk); +void bm_RemoveBlock(RuntimeBlockInfo* block); void bm_Reset(); void bm_Periodical_1s(); void bm_Periodical_14k(); diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 3b6705ef7..cda15f6c4 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -82,7 +82,8 @@ void Emit(shilop op,shil_param rd=shil_param(),shil_param rs1=shil_param(),shil_ sp.rs1=(rs1); sp.rs2=(rs2); sp.rs3=(rs3); - sp.guest_offs=state.cpu.rpc-blk->addr; + sp.guest_offs = state.cpu.rpc - blk->vaddr; + sp.delay_slot = state.cpu.is_delayslot; blk->oplist.push_back(sp); } @@ -96,22 +97,14 @@ void dec_fallback(u32 op) opcd.rs2=shil_param(FMT_IMM,state.cpu.rpc+2); opcd.rs3=shil_param(FMT_IMM,op); + + opcd.guest_offs = state.cpu.rpc - blk->vaddr; + opcd.delay_slot = state.cpu.is_delayslot; blk->oplist.push_back(opcd); } #if 1 -#define FMT_I32 ERROR!WRONG++!! -#define FMT_F32 ERROR!WRONG++!! -#define FMT_F32 ERROR!WRONG++!! -#define FMT_TYPE ERROR!WRONG++!! - -#define FMT_REG ERROR!WRONG++!! -#define FMT_IMM ERROR!WRONG++!! - -#define FMT_PARAM ERROR!WRONG++!! -#define FMT_MASK ERROR!WRONG++!! - void dec_DynamicSet(u32 regbase,u32 offs=0) { if (offs==0) @@ -277,6 +270,7 @@ sh4dec(i0000_0000_0001_1011) } //ldc.l @+,SR +/* sh4dec(i0100_nnnn_0000_0111) { /* @@ -290,9 +284,10 @@ sh4dec(i0100_nnnn_0000_0111) { //FIXME only if interrupts got on .. :P UpdateINTC(); - }*/ + }* / dec_End(0xFFFFFFFF,BET_StaticIntr,false); } +*/ //ldc ,SR sh4dec(i0100_nnnn_0000_1110) @@ -309,6 +304,7 @@ sh4dec(i0000_0000_0000_1001) { } +//fschg sh4dec(i1111_0011_1111_1101) { //fpscr.SZ is bit 20 @@ -594,7 +590,7 @@ u32 MatchDiv32(u32 pc , Sh4RegType ®1,Sh4RegType ®2 , Sh4RegType ®3) u32 match=1; for (int i=0;i<32;i++) { - u16 opcode=ReadMem16(v_pc); + u16 opcode=IReadMem16(v_pc); v_pc+=2; if ((opcode&MASK_N)==ROTCL_KEY) { @@ -610,7 +606,7 @@ u32 MatchDiv32(u32 pc , Sh4RegType ®1,Sh4RegType ®2 , Sh4RegType ®3) break; } - opcode=ReadMem16(v_pc); + opcode=IReadMem16(v_pc); v_pc+=2; if ((opcode&MASK_N_M)==DIV1_KEY) { @@ -684,11 +680,11 @@ bool MatchDiv32s(u32 op,u32 pc) else //no match ... { /* - printf("%04X\n",ReadMem16(pc-2)); - printf("%04X\n",ReadMem16(pc-0)); - printf("%04X\n",ReadMem16(pc+2)); - printf("%04X\n",ReadMem16(pc+4)); - printf("%04X\n",ReadMem16(pc+6));*/ + printf("%04X\n",IReadMem16(pc-2)); + printf("%04X\n",IReadMem16(pc-0)); + printf("%04X\n",IReadMem16(pc+2)); + printf("%04X\n",IReadMem16(pc+4)); + printf("%04X\n",IReadMem16(pc+6));*/ return false; } } @@ -697,11 +693,11 @@ bool MatchDiv32s(u32 op,u32 pc) //This ended up too rare (and too hard to match) bool MatchDiv0S_0(u32 pc) { - if (ReadMem16(pc+0)==0x233A && //XOR r3,r3 - ReadMem16(pc+2)==0x2137 && //DIV0S r3,r1 - ReadMem16(pc+4)==0x322A && //SUBC r2,r2 - ReadMem16(pc+6)==0x313A && //SUBC r3,r1 - (ReadMem16(pc+8)&0xF00F)==0x2007) //DIV0S x,x + if (IReadMem16(pc+0)==0x233A && //XOR r3,r3 + IReadMem16(pc+2)==0x2137 && //DIV0S r3,r1 + IReadMem16(pc+4)==0x322A && //SUBC r2,r2 + IReadMem16(pc+6)==0x313A && //SUBC r3,r1 + (IReadMem16(pc+8)&0xF00F)==0x2007) //DIV0S x,x return true; else return false; @@ -829,7 +825,7 @@ bool dec_generic(u32 op) bool update_after=false; if ((s32)e<0) { - if (rs1._reg!=rs2._reg) //reg shouldn't be updated if its written + if (rs1._reg!=rs2._reg && !mmu_enabled()) //reg shouldn't be updated if its written { Emit(shop_sub,rs1,rs1,mk_imm(-e)); } @@ -998,7 +994,7 @@ void state_Setup(u32 rpc,fpscr_t fpu_cfg) state.cpu.FPR64=fpu_cfg.PR; state.cpu.FSZ64=fpu_cfg.SZ; state.cpu.RoundToZero=fpu_cfg.RM==1; - verify(fpu_cfg.RM<2); + //verify(fpu_cfg.RM<2); // Happens with many wince games (set to 3) //what about fp/fs ? state.NextOp=NDO_NextOp; @@ -1014,7 +1010,7 @@ void state_Setup(u32 rpc,fpscr_t fpu_cfg) void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) { blk=rbi; - state_Setup(blk->addr,blk->fpu_cfg); + state_Setup(blk->vaddr, blk->fpu_cfg); ngen_GetFeatures(&state.ngen); blk->guest_opcodes=0; @@ -1057,7 +1053,7 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) } */ - u32 op=ReadMem16(state.cpu.rpc); + u32 op=IReadMem16(state.cpu.rpc); if (op==0 && state.cpu.is_delayslot) { printf("Delayslot 0 hack!\n"); @@ -1069,6 +1065,8 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) blk->guest_cycles+=0; else blk->guest_cycles+=CPU_RATIO; + if (OpDesc[op]->IsFloatingPoint()) + blk->has_fpu_op = true; verify(!(state.cpu.is_delayslot && OpDesc[op]->SetPC())); if (state.ngen.OnlyDynamicEnds || !OpDesc[op]->rec_oph) @@ -1116,7 +1114,7 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) } _end: - blk->sh4_code_size=state.cpu.rpc-blk->addr; + blk->sh4_code_size=state.cpu.rpc-blk->vaddr; blk->NextBlock=state.NextAddr; blk->BranchBlock=state.JumpAddr; blk->BlockType=state.BlockType; @@ -1150,12 +1148,12 @@ _end: //Small-n-simple idle loop detector :p if (state.info.has_readm && !state.info.has_writem && !state.info.has_fpu && blk->guest_opcodes<6) { - if (blk->BlockType==BET_Cond_0 || (blk->BlockType==BET_Cond_1 && blk->BranchBlock<=blk->addr)) + if (blk->BlockType==BET_Cond_0 || (blk->BlockType==BET_Cond_1 && blk->BranchBlock<=blk->vaddr)) { blk->guest_cycles*=3; } - if (blk->BranchBlock==blk->addr) + if (blk->BranchBlock==blk->vaddr) { blk->guest_cycles*=10; } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index d398a6f70..d410b8546 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -14,6 +14,7 @@ #include "hw/sh4/sh4_interrupts.h" #include "hw/sh4/sh4_mem.h" +#include "hw/sh4/modules/mmu.h" #include "hw/pvr/pvr_mem.h" #include "hw/aica/aica_if.h" #include "hw/gdrom/gdrom_if.h" @@ -118,7 +119,7 @@ u32 emit_FreeSpace() return CODE_SIZE-LastAddr; } - +// pc must be a physical address bool DoCheck(u32 pc) { if (IsOnRam(pc)) @@ -202,8 +203,19 @@ void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) has_jcond=false; BranchBlock=NextBlock=csc_RetCache=0xFFFFFFFF; BlockType=BET_SCL_Intr; + has_fpu_op = false; + asid = 0xFFFFFFFF; - addr=rpc; + vaddr = rpc; + if (mmu_enabled()) + { + bool shared; + mmu_instruction_translation(vaddr, addr, shared); + if (addr != vaddr && !shared) + asid = CCN_PTEH.ASID; + } + else + addr = vaddr; fpu_cfg=rfpu_cfg; oplist.clear(); @@ -219,37 +231,44 @@ DynarecCodeEntryPtr rdv_CompilePC() if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300) recSh4_ClearCache(); - RuntimeBlockInfo* rv=0; - do - { - RuntimeBlockInfo* rbi = ngen_AllocateBlock(); - if (rv==0) rv=rbi; - + RuntimeBlockInfo* rbi = ngen_AllocateBlock(); +#ifndef NO_MMU + try { +#endif rbi->Setup(pc,fpscr); - + bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100); rbi->staging_runs=do_opts?100:-100; ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); verify(rbi->code!=0); bm_AddBlock(rbi); +#ifndef NO_MMU + } catch (SH4ThrownException& ex) { + delete rbi; + throw ex; + } +#endif - if (rbi->BlockType==BET_Cond_0 || rbi->BlockType==BET_Cond_1) - pc=rbi->NextBlock; - else - pc=0; - } while(false && pc); - - return rv->code; + return rbi->code; } DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc) { //printf("rdv_FailedToFindBlock ~ %08X\n",pc); - next_pc=pc; +#ifndef NO_MMU + try { +#endif + next_pc=pc; - return rdv_CompilePC(); + return rdv_CompilePC(); +#ifndef NO_MMU + } catch (SH4ThrownException& ex) { + Do_Exception(pc, ex.expEvn, ex.callVect); + return bm_GetCode2(next_pc); + } +#endif } static void ngen_FailedToFindBlock_internal() { @@ -258,9 +277,6 @@ static void ngen_FailedToFindBlock_internal() { void (*ngen_FailedToFindBlock)() = &ngen_FailedToFindBlock_internal; -extern u32 rebuild_counter; - - u32 DYNACALL rdv_DoInterrupts_pc(u32 pc) { next_pc = pc; UpdateINTC(); @@ -268,37 +284,39 @@ u32 DYNACALL rdv_DoInterrupts_pc(u32 pc) { //We can only safely relocate/etc stuff here, as in other generic update cases //There's a RET, meaning the code can't move around //Interrupts happen at least 50 times/second, so its not a problem .. + /* if (rebuild_counter == 0) { // TODO: Why is this commented, etc. //bm_Rebuild(); } + */ return next_pc; } -void bm_Rebuild(); u32 DYNACALL rdv_DoInterrupts(void* block_cpde) { RuntimeBlockInfo* rbi = bm_GetBlock(block_cpde); - return rdv_DoInterrupts_pc(rbi->addr); + return rdv_DoInterrupts_pc(rbi->vaddr); } -DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc) +// addr must be the physical address of the start of the block +DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) { - next_pc=pc; - recSh4_ClearCache(); + RuntimeBlockInfo *block = bm_GetBlock(addr); + bm_RemoveBlock(block); return rdv_CompilePC(); } -DynarecCodeEntryPtr rdv_FindCode() -{ - DynarecCodeEntryPtr rv=bm_GetCode(next_pc); - if (rv==ngen_FailedToFindBlock) - return 0; - - return rv; -} +//DynarecCodeEntryPtr rdv_FindCode() +//{ +// DynarecCodeEntryPtr rv=bm_GetCode(next_pc); +// if (rv==ngen_FailedToFindBlock) +// return 0; +// +// return rv; +//} DynarecCodeEntryPtr rdv_FindOrCompile() { diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index 0e7d9cd3b..f2b07aef2 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -70,7 +70,7 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc); //Called to compile code @pc DynarecCodeEntryPtr rdv_CompilePC(); //Returns 0 if there is no code @pc, code ptr otherwise -DynarecCodeEntryPtr rdv_FindCode(); +//DynarecCodeEntryPtr rdv_FindCode(); //Finds or compiles code @pc DynarecCodeEntryPtr rdv_FindOrCompile(); diff --git a/core/hw/sh4/dyna/regalloc.h b/core/hw/sh4/dyna/regalloc.h index eee756571..774d3d4a6 100644 --- a/core/hw/sh4/dyna/regalloc.h +++ b/core/hw/sh4/dyna/regalloc.h @@ -368,7 +368,8 @@ struct RegAlloc verify(opid>=0 && opidoplist.size()); shil_opcode* op=&block->oplist[opid]; - return op->op == shop_sync_fpscr || op->op == shop_sync_sr || op->op == shop_ifb; + return op->op == shop_sync_fpscr || op->op == shop_sync_sr || op->op == shop_ifb + || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref)); } bool IsRegWallOp(RuntimeBlockInfo* block, int opid, bool is_fpr) @@ -496,6 +497,12 @@ struct RegAlloc { fp=true; } + else + { + all = true; + fp = true; + gpr_b = true; + } if (all) { @@ -1119,6 +1126,30 @@ struct RegAlloc } } + void BailOut(u32 opid) + { + for (u32 sid = 0; sid < all_spans.size(); sid++) + { + RegSpan* spn = all_spans[sid]; + + if (spn->end >= opid && spn->start < opid && spn->writeback) + { + if (spn->fpr) + { + //printf("Op %d: Writing back f%d from %d\n",current_opid,spn->regstart,spn->nregf); + writeback_fpu++; + Writeback_FPU(spn->regstart,spn->nregf); + } + else + { + //printf("Op %d: Writing back r%d from %d\n",current_opid,spn->regstart,spn->nreg); + writeback_gpr++; + Writeback(spn->regstart,spn->nreg); + } + } + } + } + void Cleanup() { writeback_gpr=writeback_fpu=0; diff --git a/core/hw/sh4/dyna/shil.h b/core/hw/sh4/dyna/shil.h index c85b6ce87..315ab806a 100644 --- a/core/hw/sh4/dyna/shil.h +++ b/core/hw/sh4/dyna/shil.h @@ -151,6 +151,7 @@ struct shil_opcode u16 host_offs; u16 guest_offs; + bool delay_slot; string dissasm(); }; diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index ddc7d509c..fc358ee05 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -173,11 +173,7 @@ void ExecuteDelayslot() #if !defined(NO_MMU) } catch (SH4ThrownException& ex) { - ex.epc -= 2; - if (ex.expEvn == 0x800) // FPU disable exception - ex.expEvn = 0x820; // Slot FPU disable exception - else if (ex.expEvn == 0x180) // Illegal instruction exception - ex.expEvn = 0x1A0; // Slot illegal instruction exception + AdjustDelaySlotException(ex); //printf("Delay slot exception\n"); throw ex; } diff --git a/core/hw/sh4/modules/ccn.cpp b/core/hw/sh4/modules/ccn.cpp index 49b7c574f..d084f58fc 100644 --- a/core/hw/sh4/modules/ccn.cpp +++ b/core/hw/sh4/modules/ccn.cpp @@ -50,11 +50,8 @@ void CCN_MMUCR_write(u32 addr, u32 value) if (temp.TI != 0) { - for (u32 i = 0; i < 4; i++) - ITLB[i].Data.V = 0; - - for (u32 i = 0; i < 64; i++) - UTLB[i].Data.V = 0; + //sh4_cpu.ResetCache(); + mmu_flush_table(); temp.TI = 0; } @@ -63,6 +60,7 @@ void CCN_MMUCR_write(u32 addr, u32 value) if (mmu_changed_state) { //printf("<*******>MMU Enabled , ONLY SQ remaps work<*******>\n"); + sh4_cpu.ResetCache(); mmu_set_state(); } } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 1b0189cbc..07b20f923 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -201,7 +201,7 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) return; break; - //TLB Multyhit + //TLB Multihit case MMU_ERROR_TLB_MHIT: printf("MMU_ERROR_TLB_MHIT @ 0x%X\n", address); break; @@ -239,19 +239,10 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) else //IADDERR - Instruction Address Error { #ifdef TRACE_WINCE_SYSCALLS - bool skip_exception = false; - if (!print_wince_syscall(address, skip_exception)) - printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); - //if (!skip_exception) - RaiseException(0xE0, 0x100); - //else { - // SH4ThrownException ex = { 0, 0, 0 }; - // throw ex; - //} -#else - printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); - RaiseException(0xE0, 0x100); + if (!print_wince_syscall(address)) #endif + printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); + RaiseException(0xE0, 0x100); return; } printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address); @@ -291,9 +282,10 @@ bool mmu_match(u32 va, CCN_PTEH_type Address, CCN_PTEL_type Data) return false; } + //Do a full lookup on the UTLB entry's template -u32 mmu_full_lookup(u32 va, u32& idx, u32& rv) +u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) { if (!internal) { @@ -302,21 +294,21 @@ u32 mmu_full_lookup(u32 va, u32& idx, u32& rv) CCN_MMUCR.URC = 0; } - u32 entry = 0; + u32 entry = -1; u32 nom = 0; - for (u32 i = 0; i<64; i++) { //verify(sz!=0); - if (mmu_match(va, UTLB[i].Address, UTLB[i].Data)) + TLB_Entry *tlb_entry = &UTLB[i]; + if (mmu_match(va, tlb_entry->Address, tlb_entry->Data)) { entry = i; nom++; - u32 sz = UTLB[i].Data.SZ1 * 2 + UTLB[i].Data.SZ0; + u32 sz = tlb_entry->Data.SZ1 * 2 + tlb_entry->Data.SZ0; u32 mask = mmu_mask[sz]; //VPN->PPN | low bits - rv = ((UTLB[i].Data.PPN << 10)&mask) | (va&(~mask)); + rv = ((tlb_entry->Data.PPN << 10) & mask) | (va & (~mask)); } } @@ -332,7 +324,7 @@ u32 mmu_full_lookup(u32 va, u32& idx, u32& rv) } } - idx = entry; + *tlb_entry_ret = &UTLB[entry]; return MMU_ERROR_NONE; } @@ -364,15 +356,15 @@ u32 mmu_full_SQ(u32 va, u32& rv) { //Address=Dest&0xFFFFFFE0; - u32 entry; - u32 lookup = mmu_full_lookup(va, entry, rv); + const TLB_Entry *entry; + u32 lookup = mmu_full_lookup(va, &entry, rv); rv &= ~31;//lower 5 bits are forced to 0 if (lookup != MMU_ERROR_NONE) return lookup; - u32 md = UTLB[entry].Data.PR >> 1; + u32 md = entry->Data.PR >> 1; //Priv mode protection if ((md == 0) && sr.MD == 0) @@ -383,9 +375,9 @@ u32 mmu_full_SQ(u32 va, u32& rv) //Write Protection (Lock or FW) if (translation_type == MMU_TT_DWRITE) { - if ((UTLB[entry].Data.PR & 1) == 0) + if ((entry->Data.PR & 1) == 0) return MMU_ERROR_PROTECTED; - else if (UTLB[entry].Data.D == 0) + else if (entry->Data.D == 0) return MMU_ERROR_FIRSTWRITE; } } @@ -395,48 +387,50 @@ u32 mmu_full_SQ(u32 va, u32& rv) } return MMU_ERROR_NONE; } -template -u32 mmu_data_translation(u32 va, u32& rv) +template +void mmu_data_translation(u32 va, u32& rv) { - //*opt notice* this could be only checked for writes, as reads are invalid - if ((va & 0xFC000000) == 0xE0000000) + if (va & (sizeof(T) - 1)) + mmu_raise_exception(MMU_ERROR_BADADDR, va, translation_type); + + if (translation_type == MMU_TT_DWRITE) { - u32 lookup = mmu_full_SQ(va, rv); - if (lookup != MMU_ERROR_NONE) - return lookup; - rv = va; //SQ writes are not translated, only write backs are. - return MMU_ERROR_NONE; + if ((va & 0xFC000000) == 0xE0000000) + { + u32 lookup = mmu_full_SQ(va, rv); + if (lookup != MMU_ERROR_NONE) + mmu_raise_exception(lookup, va, translation_type); + + rv = va; //SQ writes are not translated, only write backs are. + return; + } } if ((sr.MD == 0) && (va & 0x80000000) != 0) { //if on kernel, and not SQ addr -> error - return MMU_ERROR_BADADDR; + mmu_raise_exception(MMU_ERROR_BADADDR, va, translation_type); } if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000)) { rv = va; - return MMU_ERROR_NONE; + return; } - if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) + // Not called if CCN_MMUCR.AT == 0 + //if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) + if (fast_reg_lut[va >> 29] != 0) { rv = va; - return MMU_ERROR_NONE; + return; } - /* - if ( CCN_CCR.ORA && ((va&0xFC000000)==0x7C000000)) - { - verify(false); - return va; - } - */ - u32 entry; - u32 lookup = mmu_full_lookup(va, entry, rv); + + const TLB_Entry *entry; + u32 lookup = mmu_full_lookup(va, &entry, rv); if (lookup != MMU_ERROR_NONE) - return lookup; + mmu_raise_exception(lookup, va, translation_type); #ifdef TRACE_WINCE_SYSCALLS if (unresolved_unicode_string != 0) @@ -449,13 +443,13 @@ u32 mmu_data_translation(u32 va, u32& rv) } #endif - u32 md = UTLB[entry].Data.PR >> 1; + u32 md = entry->Data.PR >> 1; //0X & User mode-> protection violation //Priv mode protection if ((md == 0) && sr.MD == 0) { - return MMU_ERROR_PROTECTED; + mmu_raise_exception(MMU_ERROR_PROTECTED, va, translation_type); } //X0 -> read olny @@ -464,27 +458,33 @@ u32 mmu_data_translation(u32 va, u32& rv) //Write Protection (Lock or FW) if (translation_type == MMU_TT_DWRITE) { - if ((UTLB[entry].Data.PR & 1) == 0) - return MMU_ERROR_PROTECTED; - else if (UTLB[entry].Data.D == 0) - return MMU_ERROR_FIRSTWRITE; + if ((entry->Data.PR & 1) == 0) + mmu_raise_exception(MMU_ERROR_PROTECTED, va, translation_type); + else if (entry->Data.D == 0) + mmu_raise_exception(MMU_ERROR_FIRSTWRITE, va, translation_type); } - return MMU_ERROR_NONE; } -u32 mmu_instruction_translation(u32 va, u32& rv) +template void mmu_data_translation(u32 va, u32& rv); +template void mmu_data_translation(u32 va, u32& rv); + +void mmu_instruction_translation(u32 va, u32& rv, bool& shared) { + if (va & 1) + { + mmu_raise_exception(MMU_ERROR_BADADDR, va, MMU_TT_IREAD); + } if ((sr.MD == 0) && (va & 0x80000000) != 0) { //if SQ disabled , or if if SQ on but out of SQ mem then BAD ADDR ;) if (va >= 0xE0000000) - return MMU_ERROR_BADADDR; + mmu_raise_exception(MMU_ERROR_BADADDR, va, MMU_TT_IREAD); } if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) { rv = va; - return MMU_ERROR_NONE; + return; } bool mmach = false; @@ -509,6 +509,7 @@ retry_ITLB_Match: nom++; //VPN->PPN | low bits rv = ((ITLB[i].Data.PPN << 10)&mask) | (va&(~mask)); + shared = ITLB[i].Data.SH == 1; } } } @@ -516,13 +517,15 @@ retry_ITLB_Match: if (entry == 4) { verify(mmach == false); - u32 lookup = mmu_full_lookup(va, entry, rv); + const TLB_Entry *tlb_entry; + u32 lookup = mmu_full_lookup(va, &tlb_entry, rv); if (lookup != MMU_ERROR_NONE) - return lookup; + mmu_raise_exception(lookup, va, MMU_TT_IREAD); + u32 replace_index = ITLB_LRU_USE[CCN_MMUCR.LRUI]; verify(replace_index != 0xFFFFFFFF); - ITLB[replace_index] = UTLB[entry]; + ITLB[replace_index] = *tlb_entry; entry = replace_index; ITLB_Sync(entry); mmach = true; @@ -532,11 +535,11 @@ retry_ITLB_Match: { if (nom) { - return MMU_ERROR_TLB_MHIT; + mmu_raise_exception(MMU_ERROR_TLB_MHIT, va, MMU_TT_IREAD); } else { - return MMU_ERROR_TLB_MISS; + mmu_raise_exception(MMU_ERROR_TLB_MISS, va, MMU_TT_IREAD); } } @@ -549,10 +552,8 @@ retry_ITLB_Match: //Priv mode protection if ((md == 0) && sr.MD == 0) { - return MMU_ERROR_PROTECTED; + mmu_raise_exception(MMU_ERROR_PROTECTED, va, MMU_TT_IREAD); } - - return MMU_ERROR_NONE; } void mmu_set_state() @@ -570,6 +571,7 @@ void mmu_set_state() WriteMem16 = &mmu_WriteMem16; WriteMem32 = &mmu_WriteMem32; WriteMem64 = &mmu_WriteMem64; + mmu_flush_table(); } else { @@ -617,149 +619,77 @@ void MMU_term() { } +void mmu_flush_table() +{ + //printf("MMU tables flushed\n"); + + ITLB[0].Data.V = 0; + ITLB[1].Data.V = 0; + ITLB[2].Data.V = 0; + ITLB[3].Data.V = 0; + + for (u32 i = 0; i < 64; i++) + UTLB[i].Data.V = 0; +} + u8 DYNACALL mmu_ReadMem8(u32 adr) { u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - return _vmem_ReadMem8(addr); - else - mmu_raise_exception(tv, adr, MMU_TT_DREAD); - - return 0; + mmu_data_translation(adr, addr); + return _vmem_ReadMem8(addr); } u16 DYNACALL mmu_ReadMem16(u32 adr) { - if (adr & 1) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DREAD); - return 0; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - return _vmem_ReadMem16(addr); - else - mmu_raise_exception(tv, adr, MMU_TT_DREAD); - - return 0; + mmu_data_translation(adr, addr); + return _vmem_ReadMem16(addr); } -u16 DYNACALL mmu_IReadMem16(u32 adr) +u16 DYNACALL mmu_IReadMem16(u32 vaddr) { - if (adr & 1) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_IREAD); - return 0; - } u32 addr; - u32 tv = mmu_instruction_translation(adr, addr); - if (tv == 0) - return _vmem_ReadMem16(addr); - else - mmu_raise_exception(tv, adr, MMU_TT_IREAD); - - return 0; + bool shared; + mmu_instruction_translation(vaddr, addr, shared); + return _vmem_ReadMem16(addr); } u32 DYNACALL mmu_ReadMem32(u32 adr) { - if (adr & 3) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DREAD); - return 0; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - return _vmem_ReadMem32(addr); - else - mmu_raise_exception(tv, adr, MMU_TT_DREAD); - - return 0; + mmu_data_translation(adr, addr); + return _vmem_ReadMem32(addr); } u64 DYNACALL mmu_ReadMem64(u32 adr) { - if (adr & 7) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DREAD); - return 0; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - { - return _vmem_ReadMem64(addr); - } - else - mmu_raise_exception(tv, adr, MMU_TT_DREAD); - - return 0; + mmu_data_translation(adr, addr); + return _vmem_ReadMem64(addr); } void DYNACALL mmu_WriteMem8(u32 adr, u8 data) { u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - { - _vmem_WriteMem8(addr, data); - return; - } - else - mmu_raise_exception(tv, adr, MMU_TT_DWRITE); + mmu_data_translation(adr, addr); + _vmem_WriteMem8(addr, data); } void DYNACALL mmu_WriteMem16(u32 adr, u16 data) { - if (adr & 1) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DWRITE); - return; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - { - _vmem_WriteMem16(addr, data); - return; - } - else - mmu_raise_exception(tv, adr, MMU_TT_DWRITE); + mmu_data_translation(adr, addr); + _vmem_WriteMem16(addr, data); } void DYNACALL mmu_WriteMem32(u32 adr, u32 data) { - if (adr & 3) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DWRITE); - return; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - { - _vmem_WriteMem32(addr, data); - return; - } - else - mmu_raise_exception(tv, adr, MMU_TT_DWRITE); + mmu_data_translation(adr, addr); + _vmem_WriteMem32(addr, data); } void DYNACALL mmu_WriteMem64(u32 adr, u64 data) { - if (adr & 7) - { - mmu_raise_exception(MMU_ERROR_BADADDR, adr, MMU_TT_DWRITE); - return; - } u32 addr; - u32 tv = mmu_data_translation(adr, addr); - if (tv == 0) - { - _vmem_WriteMem64(addr, data); - return; - } - else - mmu_raise_exception(tv, adr, MMU_TT_DWRITE); + mmu_data_translation(adr, addr); + _vmem_WriteMem64(addr, data); } bool mmu_TranslateSQW(u32 adr, u32* out) diff --git a/core/hw/sh4/modules/mmu_impl.h b/core/hw/sh4/modules/mmu_impl.h index 4564a8e4e..c0eaba84d 100644 --- a/core/hw/sh4/modules/mmu_impl.h +++ b/core/hw/sh4/modules/mmu_impl.h @@ -10,7 +10,7 @@ #define MMU_ERROR_NONE 0 //TLB miss #define MMU_ERROR_TLB_MISS 1 -//TLB Multyhit +//TLB Multihit #define MMU_ERROR_TLB_MHIT 2 //Mem is read/write protected (depends on translation type) #define MMU_ERROR_PROTECTED 3 @@ -21,15 +21,6 @@ //Can't Execute #define MMU_ERROR_EXECPROT 6 -//Translation Types -//Opcode read -#define MMU_TT_IREAD 0 -//Data write -#define MMU_TT_DWRITE 1 -//Data write -#define MMU_TT_DREAD 2 -//Do an mmu lookup for va , returns translation status , if MMU_ERROR_NONE , rv is set to translated index - extern u32 mmu_error_TT; void MMU_Init(); diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index 570b7d701..b4fab717a 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -7,11 +7,13 @@ #define SH_CURTHREAD 1 #define SH_CURPROC 2 +extern const u32 mmu_mask[4]; + static bool read_mem32(u32 addr, u32& data) { u32 pa; - u32 idx; - if (mmu_full_lookup(addr, idx, pa) != MMU_ERROR_NONE) + const TLB_Entry *entry; + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem32_nommu(pa); return true; @@ -20,8 +22,8 @@ static bool read_mem32(u32 addr, u32& data) static bool read_mem16(u32 addr, u16& data) { u32 pa; - u32 idx; - if (mmu_full_lookup(addr, idx, pa) != MMU_ERROR_NONE) + const TLB_Entry *entry; + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem16_nommu(pa); return true; @@ -30,8 +32,8 @@ static bool read_mem16(u32 addr, u16& data) static bool read_mem8(u32 addr, u8& data) { u32 pa; - u32 idx; - if (mmu_full_lookup(addr, idx, pa) != MMU_ERROR_NONE) + const TLB_Entry *entry; + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem8_nommu(pa); return true; @@ -246,9 +248,8 @@ std::string get_ascii_string(u32 addr) return str; } -static bool print_wince_syscall(u32 address, bool &skip_exception) +static bool print_wince_syscall(u32 address) { - skip_exception = false; if (address & 1) { if (address == 0xfffffd5d || address == 0xfffffd05) // Sleep, QueryPerformanceCounter @@ -329,3 +330,59 @@ static bool print_wince_syscall(u32 address, bool &skip_exception) return false; } + +static bool wince_resolve_address(u32 va, TLB_Entry &entry) +{ + // WinCE hack + if ((va & 0x80000000) == 0) + { + u32 page_group = ReadMem32_nommu(CCN_TTB + ((va >> 25) << 2)); + u32 page = ((va >> 16) & 0x1ff) << 2; + u32 paddr = ReadMem32_nommu(page_group + page); + if (paddr & 0x80000000) + { + u32 whatever = ReadMem32_nommu(r_bank[4] + 0x14); + if (whatever != ReadMem32_nommu(paddr)) + { + paddr += 12; + u32 ptel = ReadMem32_nommu(paddr + ((va >> 10) & 0x3c)); + //FIXME CCN_PTEA = paddr >> 29; + if (ptel != 0) + { + entry.Data.reg_data = ptel - 1; + entry.Address.ASID = CCN_PTEH.ASID; + entry.Assistance.reg_data = 0; + u32 sz = entry.Data.SZ1 * 2 + entry.Data.SZ0; + entry.Address.VPN = (va & mmu_mask[sz]) >> 10; + + true; + } + } + } + } + else + { + // SQ + if (((va >> 26) & 0x3F) == 0x38) + { + u32 r1 = (va - 0xe0000000) & 0xfff00000; + //r1 &= 0xfff00000; + //u32 r0 = ReadMem32_nommu(0x8C01258C); // FIXME + //u32 r0 = 0x8c138b14; + //r0 = ReadMem32_nommu(r0); // 0xE0001F5 + u32 r0 = 0xe0001f5; + r0 += r1; + entry.Data.reg_data = r0 - 1; + entry.Assistance.reg_data = r0 >> 29; + entry.Address.ASID = CCN_PTEH.ASID; + u32 sz = entry.Data.SZ1 * 2 + entry.Data.SZ0; + entry.Address.VPN = (va & mmu_mask[sz]) >> 10; + + return true; + } + } + + return false; +} + + diff --git a/core/hw/sh4/sh4_core.h b/core/hw/sh4/sh4_core.h index a975b0cd6..15ec9fb02 100644 --- a/core/hw/sh4/sh4_core.h +++ b/core/hw/sh4/sh4_core.h @@ -122,6 +122,15 @@ static INLINE void RaiseFPUDisableException() #endif } +static INLINE void AdjustDelaySlotException(SH4ThrownException& ex) +{ + ex.epc -= 2; + if (ex.expEvn == 0x800) // FPU disable exception + ex.expEvn = 0x820; // Slot FPU disable exception + else if (ex.expEvn == 0x180) // Illegal instruction exception + ex.expEvn = 0x1A0; // Slot illegal instruction exception +} + // The SH4 sets the signaling bit to 0 for qNaN (unlike all recent CPUs). Some games relies on this. static INLINE f32 fixNaN(f32 f) { diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 19e9ba835..e70a9b60e 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -11,6 +11,7 @@ #include "hw/sh4/sh4_opcode_list.h" #include "hw/sh4/dyna/ngen.h" #include "hw/sh4/modules/ccn.h" +#include "hw/sh4/modules/mmu.h" #include "hw/sh4/sh4_interrupts.h" #include "hw/sh4/sh4_core.h" @@ -206,6 +207,99 @@ static void ngen_blockcheckfail(u32 pc) { rdv_BlockCheckFail(pc); } +static u32 exception_raised; + +template +static T ReadMemNoEx(u32 addr, u32 pc) +{ + try { + exception_raised = 0; + if (sizeof(T) == 1) + return ReadMem8(addr); + else if (sizeof(T) == 2) + return ReadMem16(addr); + else if (sizeof(T) == 4) + return ReadMem32(addr); + else if (sizeof(T) == 8) + return ReadMem64(addr); + } catch (SH4ThrownException& ex) { + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + exception_raised = 1; + return 0; + } +} + +template +static void WriteMemNoEx(u32 addr, T data, u32 pc) +{ + try { + if (sizeof(T) == 1) + WriteMem8(addr, data); + else if (sizeof(T) == 2) + WriteMem16(addr, data); + else if (sizeof(T) == 4) + WriteMem32(addr, data); + else if (sizeof(T) == 8) + WriteMem64(addr, data); + exception_raised = 0; + } catch (SH4ThrownException& ex) { + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + exception_raised = 1; + } +} + +static void interpreter_fallback(u16 op, u32 pc) +{ + try { + OpDesc[op]->oph(op); + exception_raised = 0; + } catch (SH4ThrownException& ex) { + printf("HOLY SHIT! interpreter_fallback exception pc %08x evn %x vect %x\n", pc, ex.expEvn, ex.callVect); + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + exception_raised = 1; + } +} + +static void do_sqw_mmu_no_ex(u32 addr, u32 pc) +{ + try { + do_sqw_mmu(addr); + exception_raised = 0; + } catch (SH4ThrownException& ex) { + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + exception_raised = 1; + } +} + +static void do_sqw_nommu_local(u32 addr, u8* sqb) +{ + do_sqw_nommu(addr, sqb); +} + class BlockCompiler : public Xbyak::CodeGenerator { public: @@ -258,25 +352,55 @@ public: #else sub(rsp, 0x8); // align stack #endif + Xbyak::Label exit_block; - for (size_t i = 0; i < block->oplist.size(); i++) + if (mmu_enabled() && block->has_fpu_op) { - shil_opcode& op = block->oplist[i]; + Xbyak::Label fpu_enabled; + mov(rax, (uintptr_t)&sr); + mov(eax, dword[rax]); + and_(eax, 0x8000); // test SR.FD bit + jz(fpu_enabled); + mov(call_regs[0], block->vaddr); // pc + mov(call_regs[1], 0x800); // event + mov(call_regs[2], 0x100); // vector + GenCall(Do_Exception); + jmp(exit_block, T_NEAR); + L(fpu_enabled); + } - regalloc.OpBegin(&op, i); + for (current_opid = 0; current_opid < block->oplist.size(); current_opid++) + { + shil_opcode& op = block->oplist[current_opid]; + + regalloc.OpBegin(&op, current_opid); switch (op.op) { case shop_ifb: - if (op.rs1._imm) { - mov(rax, (size_t)&next_pc); - mov(dword[rax], op.rs2._imm); + if (op.rs1._imm) + { + mov(rax, (size_t)&next_pc); + mov(dword[rax], op.rs2._imm); + } + + mov(call_regs[0], op.rs3._imm); + + if (!mmu_enabled()) + { + GenCall(OpDesc[op.rs3._imm]->oph); + } + else + { + mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + GenCall(interpreter_fallback); + + test(dword[(void *)&exception_raised], 1); + jnz(exit_block, T_NEAR); + } } - - mov(call_regs[0], op.rs3._imm); - - GenCall(OpDesc[op.rs3._imm]->oph); break; case shop_jcond: @@ -325,11 +449,28 @@ public: case shop_readm: { u32 size = op.flags & 0x7f; - - if (op.rs1.is_imm()) + bool immediate_address = op.rs1.is_imm(); + if (immediate_address && mmu_enabled() && (op.rs1._imm >> 12) != (block->vaddr >> 12)) { + // When full mmu is on, only consider addresses in the same 4k page + immediate_address = false; + } + if (immediate_address) + { + u32 addr = op.rs1._imm; + if (mmu_enabled()) + { + u32 paddr; + if (size == 2) + mmu_data_translation(addr, paddr); + else if (size == 4) + mmu_data_translation(addr, paddr); + else + die("Invalid immediate size"); + addr = paddr; + } bool isram = false; - void* ptr = _vmem_read_const(op.rs1._imm, isram, size); + void* ptr = _vmem_read_const(addr, isram, size); if (isram) { @@ -338,14 +479,27 @@ public: switch (size) { case 2: - movsx(regalloc.MapRegister(op.rd), word[rax]); + if (regalloc.IsAllocg(op.rd)) + movsx(regalloc.MapRegister(op.rd), word[rax]); + else + { + movsx(eax, word[rax]); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); + } break; case 4: if (regalloc.IsAllocg(op.rd)) mov(regalloc.MapRegister(op.rd), dword[rax]); - else + else if (regalloc.IsAllocf(op.rd)) movd(regalloc.MapXRegister(op.rd), dword[rax]); + else + { + mov(eax, dword[rax]); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); + } break; default: @@ -356,7 +510,7 @@ public: else { // Not RAM: the returned pointer is a memory handler - mov(call_regs[0], op.rs1._imm); + mov(call_regs[0], addr); switch(size) { @@ -385,42 +539,71 @@ public: { if (op.rs3.is_imm()) add(call_regs[0], op.rs3._imm); - else + else if (regalloc.IsAllocg(op.rs3)) add(call_regs[0], regalloc.MapRegister(op.rs3)); + else + { + mov(rax, (uintptr_t)op.rs3.reg_ptr()); + add(call_regs[0], dword[rax]); + } } + if (mmu_enabled()) + mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc if (size == 1) { - GenCall(ReadMem8); + if (!mmu_enabled()) + GenCall(ReadMem8); + else + GenCall(ReadMemNoEx); movsx(ecx, al); } else if (size == 2) { - GenCall(ReadMem16); + if (!mmu_enabled()) + GenCall(ReadMem16); + else + GenCall(ReadMemNoEx); movsx(ecx, ax); } else if (size == 4) { - GenCall(ReadMem32); + if (!mmu_enabled()) + GenCall(ReadMem32); + else + GenCall(ReadMemNoEx); mov(ecx, eax); } else if (size == 8) { - GenCall(ReadMem64); + if (!mmu_enabled()) + GenCall(ReadMem64); + else + GenCall(ReadMemNoEx); mov(rcx, rax); } else { die("1..8 bytes"); } + if (mmu_enabled()) + { + test(dword[(void *)&exception_raised], 1); + jnz(exit_block, T_NEAR); + } + if (size != 8) host_reg_to_shil_param(op.rd, ecx); else { #ifdef EXPLODE_SPANS - verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); - movd(regalloc.MapXRegister(op.rd, 0), ecx); - shr(rcx, 32); - movd(regalloc.MapXRegister(op.rd, 1), ecx); -#else - mov(rax, (uintptr_t)op.rd.reg_ptr()); - mov(qword[rax], rcx); + if (op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)) + { + movd(regalloc.MapXRegister(op.rd, 0), ecx); + shr(rcx, 32); + movd(regalloc.MapXRegister(op.rd, 1), ecx); + } + else #endif + { + mov(rax, (uintptr_t)op.rd.reg_ptr()); + mov(qword[rax], rcx); + } } } } @@ -434,36 +617,69 @@ public: { if (op.rs3.is_imm()) add(call_regs[0], op.rs3._imm); - else + else if (regalloc.IsAllocg(op.rs3)) add(call_regs[0], regalloc.MapRegister(op.rs3)); + else + { + mov(rax, (uintptr_t)op.rs3.reg_ptr()); + add(call_regs[0], dword[rax]); + } } if (size != 8) shil_param_to_host_reg(op.rs2, call_regs[1]); else { #ifdef EXPLODE_SPANS - verify(op.rs2.count() == 2 && regalloc.IsAllocf(op.rs2, 0) && regalloc.IsAllocf(op.rs2, 1)); - movd(call_regs[1], regalloc.MapXRegister(op.rs2, 1)); - shl(call_regs64[1], 32); - movd(eax, regalloc.MapXRegister(op.rs2, 0)); - or_(call_regs64[1], rax); -#else - mov(rax, (uintptr_t)op.rs2.reg_ptr()); - mov(call_regs64[1], qword[rax]); + if (op.rs2.count() == 2 && regalloc.IsAllocf(op.rs2, 0) && regalloc.IsAllocf(op.rs2, 1)) + { + movd(call_regs[1], regalloc.MapXRegister(op.rs2, 1)); + shl(call_regs64[1], 32); + movd(eax, regalloc.MapXRegister(op.rs2, 0)); + or_(call_regs64[1], rax); + } + else #endif + { + mov(rax, (uintptr_t)op.rs2.reg_ptr()); + mov(call_regs64[1], qword[rax]); + } } + if (mmu_enabled()) + mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - if (size == 1) - GenCall(WriteMem8); - else if (size == 2) - GenCall(WriteMem16); - else if (size == 4) - GenCall(WriteMem32); - else if (size == 8) - GenCall(WriteMem64); + if (size == 1) { + if (!mmu_enabled()) + GenCall(WriteMem8); + else + GenCall(WriteMemNoEx); + } + else if (size == 2) { + if (!mmu_enabled()) + GenCall(WriteMem16); + else + GenCall(WriteMemNoEx); + } + else if (size == 4) { + if (!mmu_enabled()) + GenCall(WriteMem32); + else + GenCall(WriteMemNoEx); + } + else if (size == 8) { + if (!mmu_enabled()) + GenCall(WriteMem64); + else + GenCall(WriteMemNoEx); + } else { die("1..8 bytes"); } + + if (mmu_enabled()) + { + test(dword[(void *)&exception_raised], 1); + jnz(exit_block, T_NEAR); + } } break; @@ -683,11 +899,52 @@ public: shr(rax, 32); mov(regalloc.MapRegister(op.rd2), eax); break; -/* + case shop_pref: - // TODO + { + Xbyak::Reg32 rn; + if (regalloc.IsAllocg(op.rs1)) + { + rn = regalloc.MapRegister(op.rs1); + } + else + { + mov(rax, (uintptr_t)op.rs1.reg_ptr()); + mov(eax, dword[rax]); + rn = eax; + } + mov(ecx, rn); + shr(ecx, 26); + cmp(ecx, 0x38); + Xbyak::Label no_sqw; + jne(no_sqw); + + mov(call_regs[0], rn); + if (mmu_enabled()) + { + mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + GenCall(do_sqw_mmu_no_ex); + + test(dword[(void *)&exception_raised], 1); + jnz(exit_block, T_NEAR); + } + else + { + if (CCN_MMUCR.AT == 1) + { + GenCall(do_sqw_mmu); + } + else + { + mov(call_regs64[1], (uintptr_t)sq_both); + GenCall(&do_sqw_nommu_local); + } + } + L(no_sqw); + } break; -*/ + case shop_ext_s8: mov(eax, regalloc.MapRegister(op.rs1)); movsx(regalloc.MapRegister(op.rd), al); @@ -968,6 +1225,7 @@ public: die("Invalid block end type"); } + L(exit_block); #ifdef _WIN32 add(rsp, 0x28); #else @@ -978,6 +1236,7 @@ public: ready(); block->code = (DynarecCodeEntryPtr)getCode(); + block->host_code_size = getSize(); emit_Skip(getSize()); } @@ -1089,6 +1348,19 @@ private: void CheckBlock(RuntimeBlockInfo* block) { mov(call_regs[0], block->addr); +// if (mmu_enabled() && block->asid != 0xFFFFFFFF) +// { +// mov(rax, (uintptr_t)&CCN_PTEH.reg_data); +// cmp(byte[rax], block->asid); +// jne(reinterpret_cast(&ngen_blockcheckfail)); +// } + if (mmu_enabled()) + { + mov(rax, (uintptr_t)&next_pc); + cmp(dword[rax], block->vaddr); + jne(reinterpret_cast(&ngen_blockcheckfail)); + } + s32 sz=block->sh4_code_size; u32 sa=block->addr; @@ -1147,22 +1419,66 @@ private: void GenCall(Ret(*function)(Params...)) { #ifndef _WIN32 + bool xmm8_mapped = regalloc.IsMapped(xmm8, current_opid); + bool xmm9_mapped = regalloc.IsMapped(xmm9, current_opid); + bool xmm10_mapped = regalloc.IsMapped(xmm10, current_opid); + bool xmm11_mapped = regalloc.IsMapped(xmm11, current_opid); + // Need to save xmm registers as they are not preserved in linux/mach - sub(rsp, 16); - movd(ptr[rsp + 0], xmm8); - movd(ptr[rsp + 4], xmm9); - movd(ptr[rsp + 8], xmm10); - movd(ptr[rsp + 12], xmm11); + int offset = 0; + if (xmm8_mapped || xmm9_mapped || xmm10_mapped || xmm11_mapped) + { + sub(rsp, 4 * (xmm8_mapped + xmm9_mapped + xmm10_mapped + xmm11_mapped)); + if (xmm8_mapped) + { + movd(ptr[rsp + offset], xmm8); + offset += 4; + } + if (xmm9_mapped) + { + movd(ptr[rsp + offset], xmm9); + offset += 4; + } + if (xmm10_mapped) + { + movd(ptr[rsp + offset], xmm10); + offset += 4; + } + if (xmm11_mapped) + { + movd(ptr[rsp + offset], xmm11); + offset += 4; + } + } #endif call(function); #ifndef _WIN32 - movd(xmm8, ptr[rsp + 0]); - movd(xmm9, ptr[rsp + 4]); - movd(xmm10, ptr[rsp + 8]); - movd(xmm11, ptr[rsp + 12]); - add(rsp, 16); + if (xmm8_mapped || xmm9_mapped || xmm10_mapped || xmm11_mapped) + { + if (xmm11_mapped) + { + offset -= 4; + movd(xmm11, ptr[rsp + offset]); + } + if (xmm10_mapped) + { + offset -= 4; + movd(xmm10, ptr[rsp + offset]); + } + if (xmm9_mapped) + { + offset -= 4; + movd(xmm9, ptr[rsp + offset]); + } + if (xmm8_mapped) + { + offset -= 4; + movd(xmm8, ptr[rsp + offset]); + } + add(rsp, 4 * (xmm8_mapped + xmm9_mapped + xmm10_mapped + xmm11_mapped)); + } #endif } @@ -1183,17 +1499,36 @@ private: { if (param.is_r32f()) { - if (!reg.isXMM()) - movd((const Xbyak::Reg32 &)reg, regalloc.MapXRegister(param)); + if (regalloc.IsAllocf(param)) + { + if (!reg.isXMM()) + movd((const Xbyak::Reg32 &)reg, regalloc.MapXRegister(param)); + else + movss((const Xbyak::Xmm &)reg, regalloc.MapXRegister(param)); + } else - movss((const Xbyak::Xmm &)reg, regalloc.MapXRegister(param)); + { + mov(rax, (size_t)param.reg_ptr()); + mov((const Xbyak::Reg32 &)reg, dword[rax]); + } } else { - if (!reg.isXMM()) - mov((const Xbyak::Reg32 &)reg, regalloc.MapRegister(param)); + if (regalloc.IsAllocg(param)) + { + if (!reg.isXMM()) + mov((const Xbyak::Reg32 &)reg, regalloc.MapRegister(param)); + else + movd((const Xbyak::Xmm &)reg, regalloc.MapRegister(param)); + } else - movd((const Xbyak::Xmm &)reg, regalloc.MapRegister(param)); + { + mov(rax, (size_t)param.reg_ptr()); + if (!reg.isXMM()) + mov((const Xbyak::Reg32 &)reg, dword[rax]); + else + movss((const Xbyak::Xmm &)reg, dword[rax]); + } } } else @@ -1212,13 +1547,21 @@ private: else movd(regalloc.MapRegister(param), (const Xbyak::Xmm &)reg); } - else + else if (regalloc.IsAllocf(param)) { if (!reg.isXMM()) movd(regalloc.MapXRegister(param), (const Xbyak::Reg32 &)reg); else movss(regalloc.MapXRegister(param), (const Xbyak::Xmm &)reg); } + else + { + mov(rax, (size_t)param.reg_ptr()); + if (!reg.isXMM()) + mov(dword[rax], (const Xbyak::Reg32 &)reg); + else + movss(dword[rax], (const Xbyak::Xmm &)reg); + } } vector call_regs; @@ -1234,6 +1577,7 @@ private: X64RegAlloc regalloc; Xbyak::util::Cpu cpu; + size_t current_opid; static const u32 float_sign_mask; static const u32 float_abs_mask; static const f32 cvtf2i_pos_saturation; diff --git a/core/rec-x64/x64_regalloc.h b/core/rec-x64/x64_regalloc.h index 4e87c3489..7614ba1f6 100644 --- a/core/rec-x64/x64_regalloc.h +++ b/core/rec-x64/x64_regalloc.h @@ -71,6 +71,16 @@ struct X64RegAlloc : RegAllocnregf == xmm.getIdx() && all_spans[sid]->contains(opid)) + return true; + } + return false; + } + BlockCompiler *compiler; }; From cb6acab40fe138be72cab2a7bc66c57f74cdbe36 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 25 Mar 2019 11:56:41 +0100 Subject: [PATCH 002/158] missing file from previous commit --- core/hw/sh4/modules/mmu.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index 1c87af8f3..4219e0f69 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -2,6 +2,14 @@ #include "types.h" #include "hw/sh4/sh4_mmr.h" +//Translation Types +//Opcode read +#define MMU_TT_IREAD 0 +//Data write +#define MMU_TT_DWRITE 1 +//Data write +#define MMU_TT_DREAD 2 + struct TLB_Entry { CCN_PTEH_type Address; @@ -19,12 +27,29 @@ void ITLB_Sync(u32 entry); bool mmu_match(u32 va, CCN_PTEH_type Address, CCN_PTEL_type Data); void mmu_set_state(); +void mmu_flush_table(); + +static INLINE bool mmu_enabled() +{ +#ifndef NO_MMU + return settings.dreamcast.FullMMU && CCN_MMUCR.AT == 1; +#else + return false; +#endif +} + +template +u32 mmu_full_lookup(u32 va, const TLB_Entry **entry, u32& rv); +void mmu_instruction_translation(u32 va, u32& rv, bool& shared); +template +extern void mmu_data_translation(u32 va, u32& rv); #if defined(NO_MMU) bool inline mmu_TranslateSQW(u32 addr, u32* mapped) { *mapped = sq_remap[(addr>>20)&0x3F] | (addr & 0xFFFE0); return true; } + void inline mmu_flush_table() {} #else u8 DYNACALL mmu_ReadMem8(u32 addr); u16 DYNACALL mmu_ReadMem16(u32 addr); From ba00da2420083d75c4ab4a4895a9aace84e693ad Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 25 Mar 2019 13:53:49 +0100 Subject: [PATCH 003/158] dynarec: don't throw exceptions if NO_MMU --- core/hw/sh4/dyna/blockmanager.cpp | 4 ++++ core/rec-x64/rec_x64.cpp | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 2392a8a99..679f0a77d 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -684,16 +684,20 @@ void print_blocks() { gcode=op->guest_offs; u32 rpc=blk->vaddr+gcode; +#ifndef NO_MMU try { +#endif u16 op=IReadMem16(rpc); char temp[128]; OpDesc[op]->Disassemble(temp,rpc,op); fprintf(f,"//g: %04X %s\n", op, temp); +#ifndef NO_MMU } catch (SH4ThrownException& ex) { fprintf(f,"//g: ???? (page fault)\n"); } +#endif } string s=op->dissasm(); diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index e70a9b60e..c1fabc1d8 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -266,7 +266,6 @@ static void interpreter_fallback(u16 op, u32 pc) OpDesc[op]->oph(op); exception_raised = 0; } catch (SH4ThrownException& ex) { - printf("HOLY SHIT! interpreter_fallback exception pc %08x evn %x vect %x\n", pc, ex.expEvn, ex.callVect); if (pc & 1) { // Delay slot From dece3fc13ef63d30caea235417c6cc71b8b08c1f Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 15 Apr 2019 18:02:34 +0200 Subject: [PATCH 004/158] wince: use setjmp/longjmp instead of try/catch for dynarecs WinCE fast mmu implementation WIP arm64 dynarec --- core/build.h | 4 +- core/hw/mem/_vmem.cpp | 37 +- core/hw/mem/_vmem.h | 4 +- core/hw/sh4/dyna/blockmanager.cpp | 44 +- core/hw/sh4/dyna/blockmanager.h | 4 +- core/hw/sh4/dyna/decoder.cpp | 27 +- core/hw/sh4/dyna/decoder.h | 2 +- core/hw/sh4/dyna/driver.cpp | 79 +-- core/hw/sh4/dyna/ngen.h | 1 + core/hw/sh4/modules/fastmmu.cpp | 406 ++++++++++++++ core/hw/sh4/modules/mmu.cpp | 270 +++++++--- core/hw/sh4/modules/mmu.h | 35 +- core/hw/sh4/modules/mmu_impl.h | 22 +- core/hw/sh4/sh4_mem.h | 16 +- core/nullDC.cpp | 9 +- core/rec-ARM64/rec_arm64.cpp | 495 ++++++++++++++---- core/rec-cpp/rec_cpp.cpp | 2 +- core/rec-x64/rec_x64.cpp | 129 ++--- core/rec-x86/rec_lin86_asm.S | 4 +- core/rec-x86/rec_x86_asm.cpp | 2 +- core/serialize.cpp | 6 +- .../reicast/src/main/jni/Android.mk | 4 +- 22 files changed, 1246 insertions(+), 356 deletions(-) create mode 100644 core/hw/sh4/modules/fastmmu.cpp diff --git a/core/build.h b/core/build.h index c3dc80b9a..5add9b580 100755 --- a/core/build.h +++ b/core/build.h @@ -115,7 +115,9 @@ */ -#define NO_MMU +//#define NO_MMU +#define FAST_MMU +#define USE_WINCE_HACK #define DC_PLATFORM_MASK 7 #define DC_PLATFORM_DREAMCAST 0 /* Works, for the most part */ diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 2c02197c5..4950a3e45 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -183,6 +183,11 @@ INLINE Trv DYNACALL _vmem_readt(u32 addr) } } } +template u8 DYNACALL _vmem_readt(u32 addr); +template u16 DYNACALL _vmem_readt(u32 addr); +template u32 DYNACALL _vmem_readt(u32 addr); +template u64 DYNACALL _vmem_readt(u32 addr); + template INLINE void DYNACALL _vmem_writet(u32 addr,T data) { @@ -225,6 +230,10 @@ INLINE void DYNACALL _vmem_writet(u32 addr,T data) } } } +template void DYNACALL _vmem_writet(u32 addr, u8 data); +template void DYNACALL _vmem_writet(u32 addr, u16 data); +template void DYNACALL _vmem_writet(u32 addr, u32 data); +template void DYNACALL _vmem_writet(u32 addr, u64 data); //ReadMem/WriteMem functions //ReadMem @@ -552,7 +561,7 @@ error: } #endif - int fd; + int vmem_fd; void* _nvmem_unused_buffer(u32 start,u32 end) { void* ptr=mmap(&virt_ram_base[start], end-start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); @@ -572,7 +581,7 @@ error: verify((addrsz%size)==0); verify(map_times>=1); u32 prot=PROT_READ|(w?PROT_WRITE:0); - rv= mmap(&virt_ram_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, fd, offset); + rv= mmap(&virt_ram_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); if (MAP_FAILED==rv || rv!=(void*)&virt_ram_base[dst] || (mprotect(rv,size,prot)!=0)) { printf("MAP1 failed %d\n",errno); @@ -582,7 +591,7 @@ error: for (u32 i=1;i slow and stuttery { - fd = open("/data/data/com.reicast.emulator/files/dcnzorz_mem",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU|S_IRWXG|S_IRWXO); - unlink("/data/data/com.reicast.emulator/files/dcnzorz_mem"); + vmem_fd = open("/data/data/com.reicast.emulator/files/dcnzorz_mem",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU|S_IRWXG|S_IRWXO); + unlink("/data/data/com.reicast.emulator/files/dcnzorz_mem"); } #endif @@ -730,7 +739,7 @@ bool _vmem_reserve() //I really should check teh docs before codin ;p //[0x00800000,0x00A00000); map_buffer(0x00800000,0x01000000,MAP_ARAM_START_OFFSET,ARAM_SIZE,false); - map_buffer(0x20000000,0x20000000+ARAM_SIZE,MAP_ARAM_START_OFFSET,ARAM_SIZE,true); + map_buffer(0x02800000,0x02800000+ARAM_SIZE,MAP_ARAM_START_OFFSET,ARAM_SIZE,true); aica_ram.size=ARAM_SIZE; aica_ram.data=(u8*)ptr; @@ -804,7 +813,7 @@ void _vmem_release() virt_ram_base = NULL; } #if HOST_OS != OS_WINDOWS - close(fd); + close(vmem_fd); #endif } } diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index 8509fe3ac..528cf2a90 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -49,11 +49,13 @@ u8 DYNACALL _vmem_ReadMem8(u32 Address); u16 DYNACALL _vmem_ReadMem16(u32 Address); u32 DYNACALL _vmem_ReadMem32(u32 Address); u64 DYNACALL _vmem_ReadMem64(u32 Address); +template Trv DYNACALL _vmem_readt(u32 addr); //WriteMem(s) void DYNACALL _vmem_WriteMem8(u32 Address,u8 data); void DYNACALL _vmem_WriteMem16(u32 Address,u16 data); void DYNACALL _vmem_WriteMem32(u32 Address,u32 data); void DYNACALL _vmem_WriteMem64(u32 Address,u64 data); +template void DYNACALL _vmem_writet(u32 addr, T data); //should be called at start up to ensure it will succeed :) bool _vmem_reserve(); @@ -70,4 +72,4 @@ static inline bool _nvmem_enabled() { return virt_ram_base != 0; } -void _vmem_bm_reset(); \ No newline at end of file +void _vmem_bm_reset(); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 679f0a77d..fe109d63a 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -97,7 +97,7 @@ DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr) } // addr must be a virtual address -DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr) +DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) { #ifndef NO_MMU if (!mmu_enabled()) @@ -110,32 +110,47 @@ DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr) { switch (addr) { +#ifdef USE_WINCE_HACK case 0xfffffde7: // GetTickCount // This should make this syscall faster r[0] = sh4_sched_now64() * 1000 / SH4_MAIN_CLOCK; next_pc = pr; - addr = next_pc; break; + + case 0xfffffd05: // QueryPerformanceCounter(u64 *) + { + u32 paddr; + if (mmu_data_translation(r[4], paddr) == MMU_ERROR_NONE) + { + _vmem_WriteMem64(paddr, sh4_sched_now64() >> 4); + r[0] = 1; + next_pc = pr; + } + else + { + Do_Exception(addr, 0xE0, 0x100); + } + } + break; +#endif + default: Do_Exception(addr, 0xE0, 0x100); - addr = next_pc; break; } + addr = next_pc; } - try { - u32 paddr; - bool shared; - mmu_instruction_translation(addr, paddr, shared); - - return (DynarecCodeEntryPtr)bm_GetCode(paddr); - } catch (SH4ThrownException& ex) { - Do_Exception(addr, ex.expEvn, ex.callVect); - u32 paddr; - bool shared; + u32 paddr; + bool shared; + u32 rv = mmu_instruction_translation(addr, paddr, shared); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(addr, rv, MMU_TT_IREAD); mmu_instruction_translation(next_pc, paddr, shared); - return (DynarecCodeEntryPtr)bm_GetCode(paddr); } + + return (DynarecCodeEntryPtr)bm_GetCode(paddr); } #endif } @@ -220,6 +235,7 @@ void bm_RemoveBlock(RuntimeBlockInfo* block) all_blocks.erase(it); break; } + // FIXME need to remove refs delete block; } diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index b750449e4..6dd89e481 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -17,7 +17,7 @@ struct RuntimeBlockInfo_Core struct RuntimeBlockInfo: RuntimeBlockInfo_Core { - void Setup(u32 pc,fpscr_t fpu_cfg); + bool Setup(u32 pc,fpscr_t fpu_cfg); const char* hash(bool full=true, bool reloc=false); u32 vaddr; @@ -89,7 +89,7 @@ void bm_WriteBlockMap(const string& file); DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr); extern "C" { -__attribute__((used)) DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr); +__attribute__((used)) DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr); } RuntimeBlockInfo* bm_GetBlock(void* dynarec_code); diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index cda15f6c4..8e9050441 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1007,13 +1007,15 @@ void state_Setup(u32 rpc,fpscr_t fpu_cfg) state.info.has_fpu=false; } -void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) +bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) { blk=rbi; state_Setup(blk->vaddr, blk->fpu_cfg); ngen_GetFeatures(&state.ngen); blk->guest_opcodes=0; + // If full MMU, don't allow the block to extend past the end of the current 4K page + u32 max_pc = mmu_enabled() ? ((state.cpu.rpc >> 12) + 1) << 12 : 0xFFFFFFFF; for(;;) { @@ -1025,10 +1027,8 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) //there is no break here by design case NDO_NextOp: { - if ( - ( (blk->oplist.size() >= BLOCK_MAX_SH_OPS_SOFT) || (blk->guest_cycles >= max_cycles) ) - && !state.cpu.is_delayslot - ) + if ((blk->oplist.size() >= BLOCK_MAX_SH_OPS_SOFT || blk->guest_cycles >= max_cycles || state.cpu.rpc >= max_pc) + && !state.cpu.is_delayslot) { dec_End(state.cpu.rpc,BET_StaticJump,false); } @@ -1053,7 +1053,16 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) } */ - u32 op=IReadMem16(state.cpu.rpc); + u32 op; + if (!mmu_enabled()) + op = IReadMem16(state.cpu.rpc); + else + { + u32 exception_occurred; + op = mmu_IReadMem16NoEx(state.cpu.rpc, &exception_occurred); + if (exception_occurred) + return false; + } if (op==0 && state.cpu.is_delayslot) { printf("Delayslot 0 hack!\n"); @@ -1104,8 +1113,8 @@ void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) case NDO_Jump: die("Too old"); - state.NextOp=state.JumpOp; - state.cpu.rpc=state.JumpAddr; + //state.NextOp=state.JumpOp; + //state.cpu.rpc=state.JumpAddr; break; case NDO_End: @@ -1187,6 +1196,8 @@ _end: //make sure we don't use wayy-too-few cycles blk->guest_cycles=max(1U,blk->guest_cycles); blk=0; + + return true; } #endif diff --git a/core/hw/sh4/dyna/decoder.h b/core/hw/sh4/dyna/decoder.h index efe0e470e..4fb843f47 100644 --- a/core/hw/sh4/dyna/decoder.h +++ b/core/hw/sh4/dyna/decoder.h @@ -45,7 +45,7 @@ struct ngen_features }; struct RuntimeBlockInfo; -void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles); +bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles); struct state_t { diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index d410b8546..9c803d492 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -194,7 +194,7 @@ const char* RuntimeBlockInfo::hash(bool full, bool relocable) return block_hash; } -void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) +bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) { staging_runs=addr=lookups=runs=host_code_size=0; guest_cycles=guest_opcodes=host_opcodes=0; @@ -210,7 +210,12 @@ void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) if (mmu_enabled()) { bool shared; - mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr, shared); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(vaddr, rv, MMU_TT_IREAD); + return false; + } if (addr != vaddr && !shared) asid = CCN_PTEH.ASID; } @@ -220,8 +225,12 @@ void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) oplist.clear(); - dec_DecodeBlock(this,SH4_TIMESLICE/2); + if (!dec_DecodeBlock(this,SH4_TIMESLICE/2)) + return false; + AnalyseBlock(this); + + return true; } DynarecCodeEntryPtr rdv_CompilePC() @@ -232,43 +241,36 @@ DynarecCodeEntryPtr rdv_CompilePC() recSh4_ClearCache(); RuntimeBlockInfo* rbi = ngen_AllocateBlock(); -#ifndef NO_MMU - try { -#endif - rbi->Setup(pc,fpscr); - - bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100); - rbi->staging_runs=do_opts?100:-100; - ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); - verify(rbi->code!=0); - - bm_AddBlock(rbi); -#ifndef NO_MMU - } catch (SH4ThrownException& ex) { + if (!rbi->Setup(pc,fpscr)) + { delete rbi; - throw ex; + return NULL; } -#endif + + bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100); + rbi->staging_runs=do_opts?100:-100; + ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); + verify(rbi->code!=0); + + bm_AddBlock(rbi); return rbi->code; } +DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock_pc() +{ + return rdv_FailedToFindBlock(next_pc); +} + DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc) { //printf("rdv_FailedToFindBlock ~ %08X\n",pc); -#ifndef NO_MMU - try { -#endif - next_pc=pc; - - return rdv_CompilePC(); -#ifndef NO_MMU - } catch (SH4ThrownException& ex) { - Do_Exception(pc, ex.expEvn, ex.callVect); - return bm_GetCode2(next_pc); - } -#endif + next_pc=pc; + DynarecCodeEntryPtr code = rdv_CompilePC(); + if (code == NULL) + code = bm_GetCodeByVAddr(next_pc); + return code; } static void ngen_FailedToFindBlock_internal() { @@ -304,8 +306,17 @@ u32 DYNACALL rdv_DoInterrupts(void* block_cpde) // addr must be the physical address of the start of the block DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) { - RuntimeBlockInfo *block = bm_GetBlock(addr); - bm_RemoveBlock(block); + if (mmu_enabled()) + { + RuntimeBlockInfo *block = bm_GetBlock(addr); + //printf("rdv_BlockCheckFail addr %08x vaddr %08x pc %08x\n", addr, block->vaddr, next_pc); + bm_RemoveBlock(block); + } + else + { + next_pc = addr; + recSh4_ClearCache(); + } return rdv_CompilePC(); } @@ -320,7 +331,7 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) DynarecCodeEntryPtr rdv_FindOrCompile() { - DynarecCodeEntryPtr rv=bm_GetCode(next_pc); + DynarecCodeEntryPtr rv=bm_GetCodeByVAddr(next_pc); if (rv==ngen_FailedToFindBlock) rv=rdv_CompilePC(); @@ -359,7 +370,7 @@ void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc) DynarecCodeEntryPtr rv=rdv_FindOrCompile(); - bool do_link=bm_GetBlock(code)==rbi; + bool do_link = !mmu_enabled() && bm_GetBlock(code) == rbi; if (do_link) { diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index f2b07aef2..d9c4209b3 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -65,6 +65,7 @@ void emit_SetBaseAddr(); //Called from ngen_FailedToFindBlock DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc); +DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock_pc(); //Called when a block check failed, and the block needs to be invalidated DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc); //Called to compile code @pc diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp new file mode 100644 index 000000000..2211e3e04 --- /dev/null +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -0,0 +1,406 @@ +#include "mmu.h" +#include "hw/sh4/sh4_if.h" +#include "hw/sh4/sh4_interrupts.h" +#include "hw/sh4/sh4_core.h" +#include "types.h" + +#ifdef FAST_MMU + +#include "hw/mem/_vmem.h" + +#include "mmu_impl.h" +#include "ccn.h" +#include "hw/sh4/sh4_mem.h" +#include "oslib/oslib.h" + +extern TLB_Entry UTLB[64]; +// Used when FullMMU is off +extern u32 sq_remap[64]; + +//#define TRACE_WINCE_SYSCALLS + +#include "wince.h" + +#define printf_mmu(...) +//#define printf_mmu printf +#define printf_win32(...) + +extern const u32 mmu_mask[4]; +extern const u32 fast_reg_lut[8]; + +const TLB_Entry *lru_entry = NULL; +static u32 lru_mask; +static u32 lru_address; + +struct TLB_LinkedEntry { + TLB_Entry entry; + TLB_LinkedEntry *next_entry; +}; +#define NBUCKETS 65536 +TLB_LinkedEntry full_table[65536]; +u32 full_table_size; +TLB_LinkedEntry *entry_buckets[NBUCKETS]; + +static u16 bucket_index(u32 address, int size) +{ + return ((address >> 16) ^ ((address & 0xFC00) | size)) & (NBUCKETS - 1); +} + +static void cache_entry(const TLB_Entry &entry) +{ + verify(full_table_size < ARRAY_SIZE(full_table)); + u16 bucket = bucket_index(entry.Address.VPN << 10, entry.Data.SZ1 * 2 + entry.Data.SZ0); + + full_table[full_table_size].entry = entry; + full_table[full_table_size].next_entry = entry_buckets[bucket]; + entry_buckets[bucket] = &full_table[full_table_size]; + full_table_size++; +} + +static void flush_cache() +{ + full_table_size = 0; + memset(entry_buckets, 0, sizeof(entry_buckets)); +} + +template +bool find_entry_by_page_size(u32 address, const TLB_Entry **ret_entry) +{ + u32 shift = size == 1 ? 2 : + size == 2 ? 6 : + size == 3 ? 10 : 0; + u32 vpn = (address >> (10 + shift)) << shift; + u16 bucket = bucket_index(vpn << 10, size); + TLB_LinkedEntry *pEntry = entry_buckets[bucket]; + u32 length = 0; + while (pEntry != NULL) + { + if (pEntry->entry.Address.VPN == vpn && (size >> 1) == pEntry->entry.Data.SZ1 && (size & 1) == pEntry->entry.Data.SZ0) + { + if (pEntry->entry.Data.SH == 1 || pEntry->entry.Address.ASID == CCN_PTEH.ASID) + { + *ret_entry = &pEntry->entry; + return true; + } + } + pEntry = pEntry->next_entry; + } + + return false; +} + +static bool find_entry(u32 address, const TLB_Entry **ret_entry) +{ + // 4k + if (find_entry_by_page_size<1>(address, ret_entry)) + return true; + // 64k + if (find_entry_by_page_size<2>(address, ret_entry)) + return true; + // 1m + if (find_entry_by_page_size<3>(address, ret_entry)) + return true; + // 1k + if (find_entry_by_page_size<0>(address, ret_entry)) + return true; + return false; +} + +#if 0 +static void dump_table() +{ + static int iter = 1; + char filename[128]; + sprintf(filename, "mmutable%03d", iter++); + FILE *f = fopen(filename, "wb"); + if (f == NULL) + return; + fwrite(full_table, sizeof(full_table[0]), full_table_size, f); + fclose(f); +} + +int main(int argc, char *argv[]) +{ + FILE *f = fopen(argv[1], "rb"); + if (f == NULL) + { + perror(argv[1]); + return 1; + } + full_table_size = fread(full_table, sizeof(full_table[0]), ARRAY_SIZE(full_table), f); + fclose(f); + printf("Loaded %d entries\n", full_table_size); + std::vector addrs; + std::vector asids; + for (int i = 0; i < full_table_size; i++) + { + u32 sz = full_table[i].entry.Data.SZ1 * 2 + full_table[i].entry.Data.SZ0; + u32 mask = sz == 3 ? 1*1024*1024 : sz == 2 ? 64*1024 : sz == 1 ? 4*1024 : 1024; + mask--; + addrs.push_back(((full_table[i].entry.Address.VPN << 10) & mmu_mask[sz]) | (random() * mask / RAND_MAX)); + asids.push_back(full_table[i].entry.Address.ASID); +// printf("%08x -> %08x sz %d ASID %d SH %d\n", full_table[i].entry.Address.VPN << 10, full_table[i].entry.Data.PPN << 10, +// full_table[i].entry.Data.SZ1 * 2 + full_table[i].entry.Data.SZ0, +// full_table[i].entry.Address.ASID, full_table[i].entry.Data.SH); + u16 bucket = bucket_index(full_table[i].entry.Address.VPN << 10, full_table[i].entry.Data.SZ1 * 2 + full_table[i].entry.Data.SZ0); + full_table[i].next_entry = entry_buckets[bucket]; + entry_buckets[bucket] = &full_table[i]; + } + for (int i = 0; i < full_table_size / 10; i++) + { + addrs.push_back(random()); + asids.push_back(666); + } + double start = os_GetSeconds(); + int success = 0; + const int loops = 100000; + for (int i = 0; i < loops; i++) + { + for (int j = 0; j < addrs.size(); j++) + { + u32 addr = addrs[j]; + CCN_PTEH.ASID = asids[j]; + const TLB_Entry *p; + if (find_entry(addr, &p)) + success++; + } + } + double end = os_GetSeconds(); + printf("Lookup time: %f ms. Success rate %f max_len %d\n", (end - start) * 1000.0 / addrs.size(), (double)success / addrs.size() / loops, 0/*max_length*/); +} +#endif + +bool UTLB_Sync(u32 entry) +{ + TLB_Entry& tlb_entry = UTLB[entry]; + u32 sz = tlb_entry.Data.SZ1 * 2 + tlb_entry.Data.SZ0; + + lru_entry = &tlb_entry; + lru_mask = mmu_mask[sz]; + lru_address = (tlb_entry.Address.VPN << 10) & lru_mask; + + tlb_entry.Address.VPN = lru_address >> 10; + cache_entry(tlb_entry); + + if (!mmu_enabled() && (tlb_entry.Address.VPN & (0xFC000000 >> 10)) == (0xE0000000 >> 10)) + { + // Used when FullMMU is off + u32 vpn_sq = ((tlb_entry.Address.VPN & 0x7FFFF) >> 10) & 0x3F;//upper bits are always known [0xE0/E1/E2/E3] + sq_remap[vpn_sq] = tlb_entry.Data.PPN << 10; + } + return true; +} + +void ITLB_Sync(u32 entry) +{ +} + +//Do a full lookup on the UTLB entry's +template +u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) +{ + if (lru_entry != NULL) + { + if (/*lru_entry->Data.V == 1 && */ + lru_address == (va & lru_mask) + && (lru_entry->Address.ASID == CCN_PTEH.ASID + || lru_entry->Data.SH == 1 + /*|| (sr.MD == 1 && CCN_MMUCR.SV == 1)*/)) // SV=1 not handled + { + //VPN->PPN | low bits + // TODO mask off PPN when updating TLB to avoid doing it at look up time + rv = ((lru_entry->Data.PPN << 10) & lru_mask) | (va & (~lru_mask)); + *tlb_entry_ret = lru_entry; + + return MMU_ERROR_NONE; + } + } + + if (find_entry(va, tlb_entry_ret)) + { + u32 mask = mmu_mask[(*tlb_entry_ret)->Data.SZ1 * 2 + (*tlb_entry_ret)->Data.SZ0]; + rv = (((*tlb_entry_ret)->Data.PPN << 10) & mask) | (va & (~mask)); + lru_entry = *tlb_entry_ret; + lru_mask = mask; + lru_address = ((*tlb_entry_ret)->Address.VPN << 10); + return MMU_ERROR_NONE; + } + +#ifdef USE_WINCE_HACK + // WinCE hack + TLB_Entry entry; + if (wince_resolve_address(va, entry)) + { + CCN_PTEL.reg_data = entry.Data.reg_data; + CCN_PTEA.reg_data = entry.Assistance.reg_data; + CCN_PTEH.reg_data = entry.Address.reg_data; + UTLB[CCN_MMUCR.URC] = entry; + + *tlb_entry_ret = &UTLB[CCN_MMUCR.URC]; + lru_entry = *tlb_entry_ret; + + u32 sz = lru_entry->Data.SZ1 * 2 + lru_entry->Data.SZ0; + lru_mask = mmu_mask[sz]; + lru_address = va & lru_mask; + + rv = ((lru_entry->Data.PPN << 10) & lru_mask) | (va & (~lru_mask)); + + cache_entry(*lru_entry); + + return MMU_ERROR_NONE; + } +#endif + + return MMU_ERROR_TLB_MISS; +} +template u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv); + +template +u32 mmu_data_translation(u32 va, u32& rv) +{ + if (va & (sizeof(T) - 1)) + { + return MMU_ERROR_BADADDR; + } + + if (translation_type == MMU_TT_DWRITE) + { + if ((va & 0xFC000000) == 0xE0000000) + { + u32 lookup = mmu_full_SQ(va, rv); + if (lookup != MMU_ERROR_NONE) + return lookup; + + rv = va; //SQ writes are not translated, only write backs are. + return MMU_ERROR_NONE; + } + } + +// if ((sr.MD == 0) && (va & 0x80000000) != 0) +// { +// //if on kernel, and not SQ addr -> error +// return MMU_ERROR_BADADDR; +// } + + if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000)) + { + rv = va; + return MMU_ERROR_NONE; + } + + // Not called if CCN_MMUCR.AT == 0 + //if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) + if (fast_reg_lut[va >> 29] != 0) + { + rv = va; + return MMU_ERROR_NONE; + } + + const TLB_Entry *entry; + u32 lookup = mmu_full_lookup(va, &entry, rv); + +// if (lookup != MMU_ERROR_NONE) +// return lookup; + +#ifdef TRACE_WINCE_SYSCALLS + if (unresolved_unicode_string != 0 && lookup == MMU_ERROR_NONE) + { + if (va == unresolved_unicode_string) + { + unresolved_unicode_string = 0; + printf("RESOLVED %s\n", get_unicode_string(va).c_str()); + } + } +#endif + +// u32 md = entry->Data.PR >> 1; +// +// //0X & User mode-> protection violation +// //Priv mode protection +// if ((md == 0) && sr.MD == 0) +// { +// die("MMU_ERROR_PROTECTED"); +// return MMU_ERROR_PROTECTED; +// } +// +// //X0 -> read olny +// //X1 -> read/write , can be FW +// +// //Write Protection (Lock or FW) +// if (translation_type == MMU_TT_DWRITE) +// { +// if ((entry->Data.PR & 1) == 0) +// { +// die("MMU_ERROR_PROTECTED"); +// return MMU_ERROR_PROTECTED; +// } +// else if (entry->Data.D == 0) +// { +// die("MMU_ERROR_FIRSTWRITE"); +// return MMU_ERROR_FIRSTWRITE; +// } +// } + + return lookup; +} +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); + +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); + +u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) +{ + if (va & 1) + { + return MMU_ERROR_BADADDR; + } +// if ((sr.MD == 0) && (va & 0x80000000) != 0) +// { +// //if SQ disabled , or if if SQ on but out of SQ mem then BAD ADDR ;) +// if (va >= 0xE0000000) +// return MMU_ERROR_BADADDR; +// } + + if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) + { + rv = va; + return MMU_ERROR_NONE; + } + + // Hack fast implementation + const TLB_Entry *tlb_entry; + u32 lookup = mmu_full_lookup(va, &tlb_entry, rv); + if (lookup != MMU_ERROR_NONE) + return lookup; + u32 md = tlb_entry->Data.PR >> 1; + //0X & User mode-> protection violation + //Priv mode protection +// if ((md == 0) && sr.MD == 0) +// { +// return MMU_ERROR_PROTECTED; +// } + shared = tlb_entry->Data.SH == 1; + return MMU_ERROR_NONE; +} + +void mmu_flush_table() +{ +// printf("MMU tables flushed\n"); + +// ITLB[0].Data.V = 0; +// ITLB[1].Data.V = 0; +// ITLB[2].Data.V = 0; +// ITLB[3].Data.V = 0; +// +// for (u32 i = 0; i < 64; i++) +// UTLB[i].Data.V = 0; + + lru_entry = NULL; + flush_cache(); +} +#endif // FAST_MMU diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 07b20f923..4799cb0fb 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -101,7 +101,7 @@ WriteMem16Func WriteMem16; WriteMem32Func WriteMem32; WriteMem64Func WriteMem64; -const u32 mmu_mask[4] = +extern const u32 mmu_mask[4] = { ((0xFFFFFFFF) >> 10) << 10, //1 kb page ((0xFFFFFFFF) >> 12) << 12, //4 kb page @@ -109,7 +109,7 @@ const u32 mmu_mask[4] = ((0xFFFFFFFF) >> 20) << 20 //1 MB page }; -const u32 fast_reg_lut[8] = +extern const u32 fast_reg_lut[8] = { 0, 0, 0, 0 //P0-U0 , 1 //P1 @@ -134,6 +134,7 @@ const u32 ITLB_LRU_AND[4] = }; u32 ITLB_LRU_USE[64]; +#ifndef FAST_MMU //sync mem mapping to mmu , suspend compiled blocks if needed.entry is a UTLB entry # , -1 is for full sync bool UTLB_Sync(u32 entry) { @@ -160,6 +161,7 @@ void ITLB_Sync(u32 entry) { printf_mmu("ITLB MEM remap %d : 0x%X to 0x%X : %d\n", entry, ITLB[entry].Address.VPN << 10, ITLB[entry].Data.PPN << 10, ITLB[entry].Data.V); } +#endif void RaiseException(u32 expEvnt, u32 callVect) { #if !defined(NO_MMU) @@ -170,16 +172,12 @@ void RaiseException(u32 expEvnt, u32 callVect) { #endif } -u32 mmu_error_TT; void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) { printf_mmu("mmu_raise_exception -> pc = 0x%X : ", next_pc); CCN_TEA = address; CCN_PTEH.VPN = address >> 10; - //save translation type error :) - mmu_error_TT = am; - switch (mmu_error) { //No error @@ -262,6 +260,94 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) die("Unknown mmu_error"); } + +void DoMMUException(u32 address, u32 mmu_error, u32 access_type) +{ + printf_mmu("DoMMUException -> pc = 0x%X : ", next_pc); + CCN_TEA = address; + CCN_PTEH.VPN = address >> 10; + + switch (mmu_error) + { + //No error + case MMU_ERROR_NONE: + printf("Error : mmu_raise_exception(MMU_ERROR_NONE)\n"); + break; + + //TLB miss + case MMU_ERROR_TLB_MISS: + printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled\n", address); + if (access_type == MMU_TT_DWRITE) //WTLBMISS - Write Data TLB Miss Exception + Do_Exception(next_pc, 0x60, 0x400); + else if (access_type == MMU_TT_DREAD) //RTLBMISS - Read Data TLB Miss Exception + Do_Exception(next_pc, 0x40, 0x400); + else //ITLBMISS - Instruction TLB Miss Exception + Do_Exception(next_pc, 0x40, 0x400); + + return; + break; + + //TLB Multihit + case MMU_ERROR_TLB_MHIT: + printf("MMU_ERROR_TLB_MHIT @ 0x%X\n", address); + break; + + //Mem is read/write protected (depends on translation type) + case MMU_ERROR_PROTECTED: + printf_mmu("MMU_ERROR_PROTECTED 0x%X, handled\n", address); + if (access_type == MMU_TT_DWRITE) //WRITEPROT - Write Data TLB Protection Violation Exception + Do_Exception(next_pc, 0xC0, 0x100); + else if (access_type == MMU_TT_DREAD) //READPROT - Data TLB Protection Violation Exception + Do_Exception(next_pc, 0xA0, 0x100); + else + { + verify(false); + } + return; + break; + + //Mem is write protected , firstwrite + case MMU_ERROR_FIRSTWRITE: + printf_mmu("MMU_ERROR_FIRSTWRITE\n"); + verify(access_type == MMU_TT_DWRITE); + //FIRSTWRITE - Initial Page Write Exception + Do_Exception(next_pc, 0x80, 0x100); + + return; + break; + + //data read/write missasligned + case MMU_ERROR_BADADDR: + if (access_type == MMU_TT_DWRITE) //WADDERR - Write Data Address Error + Do_Exception(next_pc, 0x100, 0x100); + else if (access_type == MMU_TT_DREAD) //RADDERR - Read Data Address Error + Do_Exception(next_pc, 0xE0, 0x100); + else //IADDERR - Instruction Address Error + { +#ifdef TRACE_WINCE_SYSCALLS + if (!print_wince_syscall(address)) +#endif + printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); + Do_Exception(next_pc, 0xE0, 0x100); + return; + } + printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address); + return; + break; + + //Can't Execute + case MMU_ERROR_EXECPROT: + printf("MMU_ERROR_EXECPROT 0x%X\n", address); + + //EXECPROT - Instruction TLB Protection Violation Exception + Do_Exception(next_pc, 0xA0, 0x100); + return; + break; + } + + die("Unknown mmu_error"); +} + bool mmu_match(u32 va, CCN_PTEH_type Address, CCN_PTEL_type Data) { if (Data.V == 0) @@ -283,6 +369,7 @@ bool mmu_match(u32 va, CCN_PTEH_type Address, CCN_PTEL_type Data) return false; } +#ifndef FAST_MMU //Do a full lookup on the UTLB entry's template u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) @@ -328,6 +415,7 @@ u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) return MMU_ERROR_NONE; } +#endif //Simple QACR translation for mmu (when AT is off) u32 mmu_QACR_SQ(u32 va) @@ -342,6 +430,7 @@ u32 mmu_QACR_SQ(u32 va) va &= ~0x1f; return QACR + va; } + template u32 mmu_full_SQ(u32 va, u32& rv) { @@ -387,11 +476,14 @@ u32 mmu_full_SQ(u32 va, u32& rv) } return MMU_ERROR_NONE; } +template u32 mmu_full_SQ(u32 va, u32& rv); + +#ifndef FAST_MMU template -void mmu_data_translation(u32 va, u32& rv) +u32 mmu_data_translation(u32 va, u32& rv) { if (va & (sizeof(T) - 1)) - mmu_raise_exception(MMU_ERROR_BADADDR, va, translation_type); + return MMU_ERROR_BADADDR; if (translation_type == MMU_TT_DWRITE) { @@ -399,23 +491,23 @@ void mmu_data_translation(u32 va, u32& rv) { u32 lookup = mmu_full_SQ(va, rv); if (lookup != MMU_ERROR_NONE) - mmu_raise_exception(lookup, va, translation_type); + return lookup; rv = va; //SQ writes are not translated, only write backs are. - return; + return MMU_ERROR_NONE; } } if ((sr.MD == 0) && (va & 0x80000000) != 0) { //if on kernel, and not SQ addr -> error - mmu_raise_exception(MMU_ERROR_BADADDR, va, translation_type); + return MMU_ERROR_BADADDR; } if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000)) { rv = va; - return; + return MMU_ERROR_NONE; } // Not called if CCN_MMUCR.AT == 0 @@ -423,14 +515,14 @@ void mmu_data_translation(u32 va, u32& rv) if (fast_reg_lut[va >> 29] != 0) { rv = va; - return; + return MMU_ERROR_NONE; } const TLB_Entry *entry; u32 lookup = mmu_full_lookup(va, &entry, rv); if (lookup != MMU_ERROR_NONE) - mmu_raise_exception(lookup, va, translation_type); + return lookup; #ifdef TRACE_WINCE_SYSCALLS if (unresolved_unicode_string != 0) @@ -449,7 +541,7 @@ void mmu_data_translation(u32 va, u32& rv) //Priv mode protection if ((md == 0) && sr.MD == 0) { - mmu_raise_exception(MMU_ERROR_PROTECTED, va, translation_type); + return MMU_ERROR_PROTECTED; } //X0 -> read olny @@ -459,32 +551,34 @@ void mmu_data_translation(u32 va, u32& rv) if (translation_type == MMU_TT_DWRITE) { if ((entry->Data.PR & 1) == 0) - mmu_raise_exception(MMU_ERROR_PROTECTED, va, translation_type); + return MMU_ERROR_PROTECTED; else if (entry->Data.D == 0) - mmu_raise_exception(MMU_ERROR_FIRSTWRITE, va, translation_type); + return MMU_ERROR_FIRSTWRITE; } + return MMU_ERROR_NONE; } -template void mmu_data_translation(u32 va, u32& rv); -template void mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); +template u32 mmu_data_translation(u32 va, u32& rv); -void mmu_instruction_translation(u32 va, u32& rv, bool& shared) +u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) { if (va & 1) { - mmu_raise_exception(MMU_ERROR_BADADDR, va, MMU_TT_IREAD); + return MMU_ERROR_BADADDR; } if ((sr.MD == 0) && (va & 0x80000000) != 0) { //if SQ disabled , or if if SQ on but out of SQ mem then BAD ADDR ;) if (va >= 0xE0000000) - mmu_raise_exception(MMU_ERROR_BADADDR, va, MMU_TT_IREAD); + return MMU_ERROR_BADADDR; } if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) { rv = va; - return; + return MMU_ERROR_NONE; } bool mmach = false; @@ -521,7 +615,7 @@ retry_ITLB_Match: u32 lookup = mmu_full_lookup(va, &tlb_entry, rv); if (lookup != MMU_ERROR_NONE) - mmu_raise_exception(lookup, va, MMU_TT_IREAD); + return lookup; u32 replace_index = ITLB_LRU_USE[CCN_MMUCR.LRUI]; verify(replace_index != 0xFFFFFFFF); @@ -535,11 +629,11 @@ retry_ITLB_Match: { if (nom) { - mmu_raise_exception(MMU_ERROR_TLB_MHIT, va, MMU_TT_IREAD); + return MMU_ERROR_TLB_MHIT; } else { - mmu_raise_exception(MMU_ERROR_TLB_MISS, va, MMU_TT_IREAD); + return MMU_ERROR_TLB_MISS; } } @@ -552,25 +646,27 @@ retry_ITLB_Match: //Priv mode protection if ((md == 0) && sr.MD == 0) { - mmu_raise_exception(MMU_ERROR_PROTECTED, va, MMU_TT_IREAD); + return MMU_ERROR_PROTECTED; } + return MMU_ERROR_NONE; } +#endif void mmu_set_state() { if (CCN_MMUCR.AT == 1 && settings.dreamcast.FullMMU) { printf("Enabling Full MMU support\n"); - ReadMem8 = &mmu_ReadMem8; - ReadMem16 = &mmu_ReadMem16; IReadMem16 = &mmu_IReadMem16; - ReadMem32 = &mmu_ReadMem32; - ReadMem64 = &mmu_ReadMem64; + ReadMem8 = &mmu_ReadMem; + ReadMem16 = &mmu_ReadMem; + ReadMem32 = &mmu_ReadMem; + ReadMem64 = &mmu_ReadMem; - WriteMem8 = &mmu_WriteMem8; - WriteMem16 = &mmu_WriteMem16; - WriteMem32 = &mmu_WriteMem32; - WriteMem64 = &mmu_WriteMem64; + WriteMem8 = &mmu_WriteMem; + WriteMem16 = &mmu_WriteMem; + WriteMem32 = &mmu_WriteMem; + WriteMem64 = &mmu_WriteMem; mmu_flush_table(); } else @@ -619,6 +715,7 @@ void MMU_term() { } +#ifndef FAST_MMU void mmu_flush_table() { //printf("MMU tables flushed\n"); @@ -631,66 +728,95 @@ void mmu_flush_table() for (u32 i = 0; i < 64; i++) UTLB[i].Data.V = 0; } +#endif -u8 DYNACALL mmu_ReadMem8(u32 adr) +template +T DYNACALL mmu_ReadMem(u32 adr) { u32 addr; - mmu_data_translation(adr, addr); - return _vmem_ReadMem8(addr); + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + mmu_raise_exception(rv, adr, MMU_TT_DREAD); + return _vmem_readt(addr); } -u16 DYNACALL mmu_ReadMem16(u32 adr) -{ - u32 addr; - mmu_data_translation(adr, addr); - return _vmem_ReadMem16(addr); -} u16 DYNACALL mmu_IReadMem16(u32 vaddr) { u32 addr; bool shared; - mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr, shared); + if (rv != MMU_ERROR_NONE) + mmu_raise_exception(rv, vaddr, MMU_TT_IREAD); return _vmem_ReadMem16(addr); } -u32 DYNACALL mmu_ReadMem32(u32 adr) +template +void DYNACALL mmu_WriteMem(u32 adr, T data) { u32 addr; - mmu_data_translation(adr, addr); - return _vmem_ReadMem32(addr); -} -u64 DYNACALL mmu_ReadMem64(u32 adr) -{ - u32 addr; - mmu_data_translation(adr, addr); - return _vmem_ReadMem64(addr); + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + mmu_raise_exception(rv, adr, MMU_TT_DWRITE); + _vmem_writet(addr, data); } -void DYNACALL mmu_WriteMem8(u32 adr, u8 data) +template +T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred) { u32 addr; - mmu_data_translation(adr, addr); - _vmem_WriteMem8(addr, data); + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(adr, rv, MMU_TT_DREAD); + *exception_occurred = 1; + return 0; + } + else + { + *exception_occurred = 0; + return _vmem_readt(addr); + } +} +template u8 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); +template u16 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); +template u32 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); +template u64 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); + +u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) +{ + u32 addr; + bool shared; + u32 rv = mmu_instruction_translation(vaddr, addr, shared); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(vaddr, rv, MMU_TT_IREAD); + *exception_occurred = 1; + return 0; + } + else + { + *exception_occurred = 0; + return _vmem_ReadMem16(addr); + } } -void DYNACALL mmu_WriteMem16(u32 adr, u16 data) +template +u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data) { u32 addr; - mmu_data_translation(adr, addr); - _vmem_WriteMem16(addr, data); -} -void DYNACALL mmu_WriteMem32(u32 adr, u32 data) -{ - u32 addr; - mmu_data_translation(adr, addr); - _vmem_WriteMem32(addr, data); -} -void DYNACALL mmu_WriteMem64(u32 adr, u64 data) -{ - u32 addr; - mmu_data_translation(adr, addr); - _vmem_WriteMem64(addr, data); + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(adr, rv, MMU_TT_DWRITE); + return 1; + } + _vmem_writet(addr, data); + return 0; } +template u32 mmu_WriteMemNoEx(u32 adr, u8 data); +template u32 mmu_WriteMemNoEx(u32 adr, u16 data); +template u32 mmu_WriteMemNoEx(u32 adr, u32 data); +template u32 mmu_WriteMemNoEx(u32 adr, u64 data); bool mmu_TranslateSQW(u32 adr, u32* out) { diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index 4219e0f69..98f81a1ca 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -10,6 +10,22 @@ //Data write #define MMU_TT_DREAD 2 +//Return Values +//Translation was successful +#define MMU_ERROR_NONE 0 +//TLB miss +#define MMU_ERROR_TLB_MISS 1 +//TLB Multihit +#define MMU_ERROR_TLB_MHIT 2 +//Mem is read/write protected (depends on translation type) +#define MMU_ERROR_PROTECTED 3 +//Mem is write protected , firstwrite +#define MMU_ERROR_FIRSTWRITE 4 +//data-Opcode read/write missasligned +#define MMU_ERROR_BADADDR 5 +//Can't Execute +#define MMU_ERROR_EXECPROT 6 + struct TLB_Entry { CCN_PTEH_type Address; @@ -40,9 +56,10 @@ static INLINE bool mmu_enabled() template u32 mmu_full_lookup(u32 va, const TLB_Entry **entry, u32& rv); -void mmu_instruction_translation(u32 va, u32& rv, bool& shared); +u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared); template -extern void mmu_data_translation(u32 va, u32& rv); +extern u32 mmu_data_translation(u32 va, u32& rv); +void DoMMUException(u32 addr, u32 error_code, u32 access_type); #if defined(NO_MMU) bool inline mmu_TranslateSQW(u32 addr, u32* mapped) { @@ -51,16 +68,14 @@ extern void mmu_data_translation(u32 va, u32& rv); } void inline mmu_flush_table() {} #else - u8 DYNACALL mmu_ReadMem8(u32 addr); - u16 DYNACALL mmu_ReadMem16(u32 addr); + template T DYNACALL mmu_ReadMem(u32 adr); u16 DYNACALL mmu_IReadMem16(u32 addr); - u32 DYNACALL mmu_ReadMem32(u32 addr); - u64 DYNACALL mmu_ReadMem64(u32 addr); - void DYNACALL mmu_WriteMem8(u32 addr, u8 data); - void DYNACALL mmu_WriteMem16(u32 addr, u16 data); - void DYNACALL mmu_WriteMem32(u32 addr, u32 data); - void DYNACALL mmu_WriteMem64(u32 addr, u64 data); + template void DYNACALL mmu_WriteMem(u32 adr, T data); bool mmu_TranslateSQW(u32 addr, u32* mapped); + + u16 DYNACALL mmu_IReadMem16NoEx(u32 adr, u32 *exception_occurred); + template T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); + template u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data); #endif diff --git a/core/hw/sh4/modules/mmu_impl.h b/core/hw/sh4/modules/mmu_impl.h index c0eaba84d..a154c9abe 100644 --- a/core/hw/sh4/modules/mmu_impl.h +++ b/core/hw/sh4/modules/mmu_impl.h @@ -3,26 +3,8 @@ #include "ccn.h" #include "mmu.h" - -//Do a full lookup on the UTLB entry's -//Return Values -//Translation was sucessfull , rv contains return -#define MMU_ERROR_NONE 0 -//TLB miss -#define MMU_ERROR_TLB_MISS 1 -//TLB Multihit -#define MMU_ERROR_TLB_MHIT 2 -//Mem is read/write protected (depends on translation type) -#define MMU_ERROR_PROTECTED 3 -//Mem is write protected , firstwrite -#define MMU_ERROR_FIRSTWRITE 4 -//data-Opcode read/write missasligned -#define MMU_ERROR_BADADDR 5 -//Can't Execute -#define MMU_ERROR_EXECPROT 6 - -extern u32 mmu_error_TT; - void MMU_Init(); void MMU_Reset(bool Manual); void MMU_Term(); + +template u32 mmu_full_SQ(u32 va, u32& rv); diff --git a/core/hw/sh4/sh4_mem.h b/core/hw/sh4/sh4_mem.h index e9a03af47..153d3a527 100644 --- a/core/hw/sh4/sh4_mem.h +++ b/core/hw/sh4/sh4_mem.h @@ -22,15 +22,15 @@ extern VArray2 mem_b; //#define WriteMem64(addr,reg) { _vmem_WriteMem32(addr,((u32*)reg)[0]);_vmem_WriteMem32((addr)+4, ((u32*)reg)[1]); } #else -typedef u8 (*ReadMem8Func)(u32 addr); -typedef u16 (*ReadMem16Func)(u32 addr); -typedef u32 (*ReadMem32Func)(u32 addr); -typedef u64 (*ReadMem64Func)(u32 addr); +typedef u8 DYNACALL (*ReadMem8Func)(u32 addr); +typedef u16 DYNACALL (*ReadMem16Func)(u32 addr); +typedef u32 DYNACALL (*ReadMem32Func)(u32 addr); +typedef u64 DYNACALL (*ReadMem64Func)(u32 addr); -typedef void (*WriteMem8Func)(u32 addr, u8 data); -typedef void (*WriteMem16Func)(u32 addr, u16 data); -typedef void (*WriteMem32Func)(u32 addr, u32 data); -typedef void (*WriteMem64Func)(u32 addr, u64 data); +typedef void DYNACALL (*WriteMem8Func)(u32 addr, u8 data); +typedef void DYNACALL (*WriteMem16Func)(u32 addr, u16 data); +typedef void DYNACALL (*WriteMem32Func)(u32 addr, u32 data); +typedef void DYNACALL (*WriteMem64Func)(u32 addr, u64 data); extern ReadMem8Func ReadMem8; extern ReadMem16Func ReadMem16; diff --git a/core/nullDC.cpp b/core/nullDC.cpp index e43a6117b..7ca8bc480 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -34,6 +34,7 @@ static bool rtt_to_buffer_game; static bool safemode_game; static bool tr_poly_depth_mask_game; static bool extra_depth_game; +static bool full_mmu_game; cThread emu_thread(&dc_run, NULL); @@ -137,12 +138,15 @@ void LoadSpecialSettings() safemode_game = false; tr_poly_depth_mask_game = false; extra_depth_game = false; + full_mmu_game = false; if (reios_windows_ce) { - printf("Enabling Extra depth scaling for Windows CE games\n"); + printf("Enabling Full MMU and Extra depth scaling for Windows CE game\n"); settings.rend.ExtraDepthScale = 0.1; extra_depth_game = true; + settings.dreamcast.FullMMU = true; + full_mmu_game = true; } // Tony Hawk's Pro Skater 2 @@ -660,7 +664,8 @@ void SaveSettings() cfgSaveInt("config", "Dreamcast.Cable", settings.dreamcast.cable); cfgSaveInt("config", "Dreamcast.Region", settings.dreamcast.region); cfgSaveInt("config", "Dreamcast.Broadcast", settings.dreamcast.broadcast); - cfgSaveBool("config", "Dreamcast.FullMMU", settings.dreamcast.FullMMU); + if (!full_mmu_game || !settings.dreamcast.FullMMU) + cfgSaveBool("config", "Dreamcast.FullMMU", settings.dreamcast.FullMMU); cfgSaveBool("config", "Dynarec.idleskip", settings.dynarec.idleskip); cfgSaveBool("config", "Dynarec.unstable-opt", settings.dynarec.unstable_opt); if (!safemode_game || !settings.dynarec.safemode) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index ca5d96b4c..d0a829c5d 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "deps/vixl/aarch64/macro-assembler-aarch64.h" using namespace vixl::aarch64; @@ -104,6 +105,8 @@ void Arm64CacheFlush(void* start, void* end) double host_cpu_time; u64 guest_cpu_cycles; +static jmp_buf jmp_env; +static u32 cycle_counter; #ifdef PROFILING #include @@ -153,8 +156,8 @@ __asm__ ".hidden ngen_FailedToFindBlock_ \n\t" ".globl ngen_FailedToFindBlock_ \n\t" "ngen_FailedToFindBlock_: \n\t" - "mov w0, w29 \n\t" - "bl rdv_FailedToFindBlock \n\t" +// "mov w0, w29 \n\t" // FIXME w29 might not be up to date anymore (exception in bm_GetCodeByVAddr) + "bl rdv_FailedToFindBlock_pc \n\t" "br x0 \n" ".hidden ngen_blockcheckfail \n\t" @@ -180,10 +183,16 @@ void ngen_mainloop(void* v_cntx) "stp s10, s11, [sp, #112] \n\t" "stp s12, s13, [sp, #128] \n\t" "stp x29, x30, [sp, #144] \n\t" - // Use x28 as sh4 context pointer - "mov x28, %[cntx] \n\t" - // Use x27 as cycle_counter + + "stp %[cntx], %[cycle_counter], [sp, #-16]! \n\t" // Push context, cycle_counter address "mov w27, %[_SH4_TIMESLICE] \n\t" + "str w27, [%[cycle_counter]] \n\t" + + "mov x0, %[jmp_env] \n\t" // SETJMP + "bl setjmp \n\t" + + // Use x28 as sh4 context pointer + "ldr x28, [sp] \n\t" // Set context // w29 is next_pc "ldr w29, [x28, %[pc]] \n\t" "b no_update \n" @@ -191,8 +200,11 @@ void ngen_mainloop(void* v_cntx) ".hidden intc_sched \n\t" ".globl intc_sched \n\t" "intc_sched: \n\t" - "add w27, w27, %[_SH4_TIMESLICE] \n\t" - "mov x29, lr \n\r" // Trashing pc here but it will be reset at the end of the block or in DoInterrupts + "ldr x27, [sp, #8] \n\t" // &cycle_counter + "ldr w0, [x27] \n\t" // cycle_counter + "add w0, w0, %[_SH4_TIMESLICE] \n\t" + "str w0, [x27] \n\t" + "mov x29, lr \n\t" // Trashing pc here but it will be reset at the end of the block or in DoInterrupts "bl UpdateSystem \n\t" "mov lr, x29 \n\t" "cbnz w0, .do_interrupts \n\t" @@ -208,7 +220,9 @@ void ngen_mainloop(void* v_cntx) "no_update: \n\t" // next_pc _MUST_ be on w29 "ldr w0, [x28, %[CpuRunning]] \n\t" "cbz w0, .end_mainloop \n\t" + "ldr w29, [x28, %[pc]] \n\t" // shouldn't be necessary +#ifdef NO_MMU "movz x2, %[RCB_SIZE], lsl #16 \n\t" "sub x2, x28, x2 \n\t" "add x2, x2, %[SH4CTX_SIZE] \n\t" @@ -221,8 +235,14 @@ void ngen_mainloop(void* v_cntx) #endif "ldr x0, [x2, x1, lsl #3] \n\t" "br x0 \n" +#else + "mov w0, w29 \n\t" + "bl bm_GetCodeByVAddr \n\t" + "br x0 \n" +#endif ".end_mainloop: \n\t" + "add sp, sp, #16 \n\t" // Pop context "ldp x29, x30, [sp, #144] \n\t" "ldp s12, s13, [sp, #128] \n\t" "ldp s10, s11, [sp, #112] \n\t" @@ -239,7 +259,9 @@ void ngen_mainloop(void* v_cntx) [_SH4_TIMESLICE] "i"(SH4_TIMESLICE), [CpuRunning] "i"(offsetof(Sh4Context, CpuRunning)), [RCB_SIZE] "i" (sizeof(Sh4RCB) >> 16), - [SH4CTX_SIZE] "i" (sizeof(Sh4Context)) + [SH4CTX_SIZE] "i" (sizeof(Sh4Context)), + [jmp_env] "r"(reinterpret_cast(jmp_env)), + [cycle_counter] "r"(reinterpret_cast(&cycle_counter)) : "memory" ); } @@ -265,6 +287,75 @@ RuntimeBlockInfo* ngen_AllocateBlock() return new DynaRBI(); } +template +static T ReadMemNoEx(u32 addr, u32 pc) +{ + u32 ex; + T rv = mmu_ReadMemNoEx(addr, &ex); + if (ex) + { + if (pc & 1) + spc = pc - 1; + else + spc = pc; + longjmp(jmp_env, 1); + } + return rv; +} + +template +static void WriteMemNoEx(u32 addr, T data, u32 pc) +{ + u32 ex = mmu_WriteMemNoEx(addr, data); + if (ex) + { + if (pc & 1) + spc = pc - 1; + else + spc = pc; + longjmp(jmp_env, 1); + } +} + +static u32 interpreter_fallback(u16 op, u32 pc) +{ + try { + OpDesc[op]->oph(op); + return 0; + } catch (SH4ThrownException& ex) { + die("IFB exception"); + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + return 1; + } +} + +static u32 exception_raised; + +static void do_sqw_mmu_no_ex(u32 addr, u32 pc) +{ + try { + do_sqw_mmu(addr); + exception_raised = 0; + } catch (SH4ThrownException& ex) { + die("do_sqw_mmu exception"); + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + exception_raised = 1; + printf("SQW MMU EXCEPTION\n"); + } +} + class Arm64Assembler : public MacroAssembler { typedef void (MacroAssembler::*Arm64Op_RRO)(const Register&, const Register&, const Operand&); @@ -327,22 +418,47 @@ public: if (op.rs3.is_imm()) { - Add(*ret_reg, regalloc.MapRegister(op.rs1), op.rs3._imm); + if (regalloc.IsAllocg(op.rs1)) + Add(*ret_reg, regalloc.MapRegister(op.rs1), op.rs3._imm); + else + { + Ldr(*ret_reg, sh4_context_mem_operand(op.rs1.reg_ptr())); + Add(*ret_reg, *ret_reg, op.rs3._imm); + } } else if (op.rs3.is_r32i()) { - Add(*ret_reg, regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs3)); + if (regalloc.IsAllocg(op.rs1) && regalloc.IsAllocg(op.rs3)) + Add(*ret_reg, regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs3)); + else + { + Ldr(*ret_reg, sh4_context_mem_operand(op.rs1.reg_ptr())); + Ldr(w8, sh4_context_mem_operand(op.rs3.reg_ptr())); + Add(*ret_reg, *ret_reg, w8); + } } else if (!op.rs3.is_null()) { die("invalid rs3"); } + else if (op.rs1.is_reg()) + { + if (regalloc.IsAllocg(op.rs1)) + { + if (raddr == NULL) + ret_reg = ®alloc.MapRegister(op.rs1); + else + Mov(*ret_reg, regalloc.MapRegister(op.rs1)); + } + else + { + Ldr(*ret_reg, sh4_context_mem_operand(op.rs1.reg_ptr())); + } + } else { - if (raddr == NULL) - ret_reg = ®alloc.MapRegister(op.rs1); - else - Mov(*ret_reg, regalloc.MapRegister(op.rs1)); + verify(op.rs1.is_imm()); + Mov(*ret_reg, op.rs1._imm); } return *ret_reg; @@ -362,7 +478,10 @@ public: regalloc.DoAlloc(block); // scheduler - Subs(w27, w27, block->guest_cycles); + Mov(x27, reinterpret_cast(&cycle_counter)); + Ldr(w0, MemOperand(x27)); + Subs(w0, w0, block->guest_cycles); + Str(w0, MemOperand(x27)); Label cycles_remaining; B(&cycles_remaining, pl); GenCallRuntime(intc_sched); @@ -389,7 +508,21 @@ public: } Mov(*call_regs[0], op.rs3._imm); - GenCallRuntime(OpDesc[op.rs3._imm]->oph); + if (!mmu_enabled()) + { + GenCallRuntime(OpDesc[op.rs3._imm]->oph); + } + else + { + Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + GenCallRuntime(interpreter_fallback); + + Cmp(w0, 0); + Ldr(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update, ne); + } + break; case shop_jcond: @@ -532,20 +665,33 @@ public: case shop_shld: case shop_shad: - // TODO optimize - Cmp(regalloc.MapRegister(op.rs2), 0); - Csel(w1, regalloc.MapRegister(op.rs2), wzr, ge); // if shift >= 0 then w1 = shift else w1 = 0 - Mov(w0, wzr); // wzr not supported by csneg - Csneg(w2, w0, regalloc.MapRegister(op.rs2), ge); // if shift < 0 then w2 = -shift else w2 = 0 - Cmp(w2, 32); - Csel(w2, 31, w2, eq); // if shift == -32 then w2 = 31 - Lsl(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), w1); // Left shift by w1 - if (op.op == shop_shld) // Right shift by w2 - // Logical shift - Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2); - else - // Arithmetic shift - Asr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2); + { + Label positive_shift, negative_shift, end; + Tbz(regalloc.MapRegister(op.rs2), 31, &positive_shift); + Cmn(regalloc.MapRegister(op.rs2), 32); + B(&negative_shift, ne); + if (op.op == shop_shld) + // Logical shift + Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), 31); + else + // Arithmetic shift + Asr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), 31); + B(&end); + + Bind(&positive_shift); + Lsl(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + B(&end); + + Bind(&negative_shift); + Neg(w1, regalloc.MapRegister(op.rs2)); + if (op.op == shop_shld) + // Logical shift + Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w1); + else + // Arithmetic shift + Asr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), w1); + Bind(&end); + } break; case shop_test: @@ -617,31 +763,45 @@ public: break; case shop_pref: - Mov(w0, regalloc.MapRegister(op.rs1)); - if (op.flags != 0x1337) { - Lsr(w1, regalloc.MapRegister(op.rs1), 26); + if (regalloc.IsAllocg(op.rs1)) + Lsr(w1, regalloc.MapRegister(op.rs1), 26); + else + { + Ldr(w0, sh4_context_mem_operand(op.rs1.reg_ptr())); + Lsr(w1, w0, 26); + } Cmp(w1, 0x38); - } + Label not_sqw; + B(¬_sqw, ne); + if (regalloc.IsAllocg(op.rs1)) + Mov(w0, regalloc.MapRegister(op.rs1)); - if (CCN_MMUCR.AT) - { - Ldr(x9, reinterpret_cast(&do_sqw_mmu)); - } - else - { - Sub(x9, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, do_sqw_nommu)); - Ldr(x9, MemOperand(x9)); - Sub(x1, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, sq_buffer)); - } - if (op.flags == 0x1337) - Blr(x9); - else - { - Label no_branch; - B(&no_branch, ne); - Blr(x9); - Bind(&no_branch); + if (mmu_enabled()) + { + Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + GenCallRuntime(do_sqw_mmu_no_ex); + + Cmp(w0, 0); + Ldr(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update, ne); + } + else + { + if (CCN_MMUCR.AT) + { + Ldr(x9, reinterpret_cast(&do_sqw_mmu)); + } + else + { + Sub(x9, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, do_sqw_nommu)); + Ldr(x9, MemOperand(x9)); + Sub(x1, x28, offsetof(Sh4RCB, cntx) - offsetof(Sh4RCB, sq_buffer)); + } + Blr(x9); + } + Bind(¬_sqw); } break; @@ -863,24 +1023,39 @@ public: Instruction *start_instruction = GetCursorAddress(); u32 size = op.flags & 0x7f; + if (mmu_enabled()) + Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + switch (size) { case 1: - GenCallRuntime(ReadMem8); + if (!mmu_enabled()) + GenCallRuntime(ReadMem8); + else + GenCallRuntime(ReadMemNoEx); Sxtb(w0, w0); break; case 2: - GenCallRuntime(ReadMem16); + if (!mmu_enabled()) + GenCallRuntime(ReadMem16); + else + GenCallRuntime(ReadMemNoEx); Sxth(w0, w0); break; case 4: - GenCallRuntime(ReadMem32); + if (!mmu_enabled()) + GenCallRuntime(ReadMem32); + else + GenCallRuntime(ReadMemNoEx); break; case 8: - GenCallRuntime(ReadMem64); + if (!mmu_enabled()) + GenCallRuntime(ReadMem64); + else + GenCallRuntime(ReadMemNoEx); break; default: @@ -906,24 +1081,39 @@ public: void GenWriteMemorySlow(const shil_opcode& op) { + if (mmu_enabled()) + Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + Instruction *start_instruction = GetCursorAddress(); u32 size = op.flags & 0x7f; switch (size) { case 1: - GenCallRuntime(WriteMem8); + if (!mmu_enabled()) + GenCallRuntime(WriteMem8); + else + GenCallRuntime(WriteMemNoEx); break; case 2: - GenCallRuntime(WriteMem16); + if (!mmu_enabled()) + GenCallRuntime(WriteMem16); + else + GenCallRuntime(WriteMemNoEx); break; case 4: - GenCallRuntime(WriteMem32); + if (!mmu_enabled()) + GenCallRuntime(WriteMem32); + else + GenCallRuntime(WriteMemNoEx); break; case 8: - GenCallRuntime(WriteMem64); + if (!mmu_enabled()) + GenCallRuntime(WriteMem64); + else + GenCallRuntime(WriteMemNoEx); break; default: @@ -950,7 +1140,16 @@ public: case BET_StaticCall: // next_pc = block->BranchBlock; if (block->pBranchBlock == NULL) - GenCallRuntime(ngen_LinkBlock_Generic_stub); + { + if (!mmu_enabled()) + GenCallRuntime(ngen_LinkBlock_Generic_stub); + else + { + Mov(w29, block->BranchBlock); + Str(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update); + } + } else GenBranch(block->pBranchBlock->code); break; @@ -975,14 +1174,32 @@ public: if (block->pBranchBlock != NULL) GenBranch(block->pBranchBlock->code); else - GenCallRuntime(ngen_LinkBlock_cond_Branch_stub); + { + if (!mmu_enabled()) + GenCallRuntime(ngen_LinkBlock_cond_Branch_stub); + else + { + Mov(w29, block->BranchBlock); + Str(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update); + } + } Bind(&branch_not_taken); if (block->pNextBlock != NULL) GenBranch(block->pNextBlock->code); else - GenCallRuntime(ngen_LinkBlock_cond_Next_stub); + { + if (!mmu_enabled()) + GenCallRuntime(ngen_LinkBlock_cond_Next_stub); + else + { + Mov(w29, block->NextBlock); + Str(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update); + } + } } break; @@ -991,18 +1208,26 @@ public: case BET_DynamicRet: // next_pc = *jdyn; - Str(w29, sh4_context_mem_operand(&next_pc)); - // TODO Call no_update instead (and check CpuRunning less frequently?) - Mov(x2, sizeof(Sh4RCB)); - Sub(x2, x28, x2); - Add(x2, x2, sizeof(Sh4Context)); // x2 now points to FPCB + if (!mmu_enabled()) + { + Str(w29, sh4_context_mem_operand(&next_pc)); + // TODO Call no_update instead (and check CpuRunning less frequently?) + Mov(x2, sizeof(Sh4RCB)); + Sub(x2, x28, x2); + Add(x2, x2, sizeof(Sh4Context)); // x2 now points to FPCB #if RAM_SIZE_MAX == 33554432 - Ubfx(w1, w29, 1, 24); + Ubfx(w1, w29, 1, 24); #else - Ubfx(w1, w29, 1, 23); + Ubfx(w1, w29, 1, 23); #endif - Ldr(x15, MemOperand(x2, x1, LSL, 3)); // Get block entry point - Br(x15); + Ldr(x15, MemOperand(x2, x1, LSL, 3)); // Get block entry point + Br(x15); + } + else + { + Str(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update); + } break; @@ -1093,8 +1318,6 @@ private: void GenReadMemory(const shil_opcode& op, size_t opid) { - u32 size = op.flags & 0x7f; - if (GenReadMemoryImmediate(op)) return; @@ -1112,34 +1335,73 @@ private: return false; u32 size = op.flags & 0x7f; + u32 addr = op.rs1._imm; + if (mmu_enabled()) + { + if ((addr >> 12) != (block->vaddr >> 12)) + // When full mmu is on, only consider addresses in the same 4k page + return false; + u32 paddr; + u32 rv; + if (size == 2) + rv = mmu_data_translation(addr, paddr); + else if (size == 4) + rv = mmu_data_translation(addr, paddr); + else + die("Invalid immediate size"); + if (rv != MMU_ERROR_NONE) + return false; + addr = paddr; + } bool isram = false; - void* ptr = _vmem_read_const(op.rs1._imm, isram, size); + void* ptr = _vmem_read_const(addr, isram, size); if (isram) { Ldr(x1, reinterpret_cast(ptr)); - switch (size) + if (regalloc.IsAllocAny(op.rd)) { - case 2: - Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x1, xzr, SXTW)); - break; + switch (size) + { + case 2: + Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x1, xzr, SXTW)); + break; - case 4: - if (op.rd.is_r32f()) - Ldr(regalloc.MapVRegister(op.rd), MemOperand(x1)); - else - Ldr(regalloc.MapRegister(op.rd), MemOperand(x1)); - break; + case 4: + if (op.rd.is_r32f()) + Ldr(regalloc.MapVRegister(op.rd), MemOperand(x1)); + else + Ldr(regalloc.MapRegister(op.rd), MemOperand(x1)); + break; - default: - die("Invalid size"); - break; + default: + die("Invalid size"); + break; + } + } + else + { + switch (size) + { + case 2: + Ldrsh(w1, MemOperand(x1, xzr, SXTW)); + break; + + case 4: + Ldr(w1, MemOperand(x1)); + break; + + default: + die("Invalid size"); + break; + } + Str(w1, sh4_context_mem_operand(op.rd.reg_ptr())); } } else { // Not RAM - Mov(w0, op.rs1._imm); + Mov(w0, addr); switch(size) { @@ -1165,7 +1427,10 @@ private: if (regalloc.IsAllocg(op.rd)) Mov(regalloc.MapRegister(op.rd), w0); else + { + verify(regalloc.IsAllocf(op.rd)); Fmov(regalloc.MapVRegister(op.rd), w0); + } } return true; @@ -1174,7 +1439,7 @@ private: bool GenReadMemoryFast(const shil_opcode& op, size_t opid) { // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() - if (!_nvmem_enabled()) + if (!_nvmem_enabled() || mmu_enabled()) return false; Instruction *start_instruction = GetCursorAddress(); @@ -1254,7 +1519,7 @@ private: bool GenWriteMemoryFast(const shil_opcode& op, size_t opid) { // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() - if (!_nvmem_enabled()) + if (!_nvmem_enabled() || mmu_enabled()) return false; Instruction *start_instruction = GetCursorAddress(); @@ -1307,9 +1572,16 @@ private: u8* ptr = GetMemPtr(block->addr, sz); if (ptr == NULL) - // FIXME Can a block cross a RAM / non-RAM boundary?? return; + if (mmu_enabled()) + { + Ldr(w10, sh4_context_mem_operand(&next_pc)); + Ldr(w11, block->vaddr); + Cmp(w10, w11); + B(ne, &blockcheck_fail); + } + Ldr(x9, reinterpret_cast(ptr)); while (sz > 0) @@ -1347,6 +1619,23 @@ private: TailCallRuntime(ngen_blockcheckfail); Bind(&blockcheck_success); +/* + if (mmu_enabled() && block->has_fpu_op) + { + Label fpu_enabled; + Ldr(w10, sh4_context_mem_operand(&sr)); + Tbz(w10, 15, &fpu_enabled); // test SR.FD bit + + Mov(*call_regs[0], block->vaddr); // pc + Mov(*call_regs[1], 0x800); // event + Mov(*call_regs[2], 0x100); // vector + CallRuntime(Do_Exception); + Ldr(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(no_update); + + Bind(&fpu_enabled); + } +*/ } void shil_param_to_host_reg(const shil_param& param, const Register& reg) @@ -1360,9 +1649,19 @@ private: if (param.is_r64f()) Ldr(reg, sh4_context_mem_operand(param.reg_ptr())); else if (param.is_r32f()) - Fmov(reg, regalloc.MapVRegister(param)); + { + if (regalloc.IsAllocf(param)) + Fmov(reg, regalloc.MapVRegister(param)); + else + Ldr(reg, sh4_context_mem_operand(param.reg_ptr())); + } else - Mov(reg, regalloc.MapRegister(param)); + { + if (regalloc.IsAllocg(param)) + Mov(reg, regalloc.MapRegister(param)); + else + Ldr(reg, sh4_context_mem_operand(param.reg_ptr())); + } } else { @@ -1383,13 +1682,17 @@ private: else Fmov(regalloc.MapRegister(param), (const VRegister&)reg); } - else + else if (regalloc.IsAllocf(param)) { if (reg.IsVRegister()) Fmov(regalloc.MapVRegister(param), (const VRegister&)reg); else Fmov(regalloc.MapVRegister(param), (const Register&)reg); } + else + { + Str(reg, sh4_context_mem_operand(param.reg_ptr())); + } } struct CC_PS @@ -1476,6 +1779,8 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) u32 DynaRBI::Relink() { + if (mmu_enabled()) + return 0; //printf("DynaRBI::Relink %08x\n", this->addr); Arm64Assembler *compiler = new Arm64Assembler((u8 *)this->code + this->relink_offset); diff --git a/core/rec-cpp/rec_cpp.cpp b/core/rec-cpp/rec_cpp.cpp index c2232fbba..6dbf5ac0f 100644 --- a/core/rec-cpp/rec_cpp.cpp +++ b/core/rec-cpp/rec_cpp.cpp @@ -50,7 +50,7 @@ void ngen_mainloop(void* v_cntx) #endif cycle_counter = SH4_TIMESLICE; do { - DynarecCodeEntryPtr rcb = bm_GetCode(ctx->cntx.pc); + DynarecCodeEntryPtr rcb = bm_GetCodeByVAddr(ctx->cntx.pc); rcb(); } while (cycle_counter > 0); diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index c1fabc1d8..02e2e64cb 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1,6 +1,8 @@ #include "build.h" #if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64 +#include + #define EXPLODE_SPANS //#define PROFILING @@ -77,6 +79,8 @@ static __attribute((used)) void end_slice() #error RAM_SIZE_MAX unknown #endif +jmp_buf jmp_env; + #ifdef _WIN32 // Fully naked function in win32 for proper SEH prologue __asm__ ( @@ -120,6 +124,14 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") #endif "movl $" _S(SH4_TIMESLICE) "," _U "cycle_counter(%rip) \n" +#ifdef _WIN32 + "movq $" _U "jmp_env, %rcx \n\t" // SETJMP +#else + "movq $" _U "jmp_env, %rdi \n\t" +#endif + "call " _U "setjmp \n\t" +// "testl %rax, %rax \n\t" + "1: \n\t" // run_loop "movq " _U "p_sh4rcb(%rip), %rax \n\t" "movl " _S(CPU_RUNNING) "(%rax), %edx \n\t" @@ -136,7 +148,7 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") #else "movl " _S(PC)"(%rax), %edi \n\t" #endif - "call " _U "bm_GetCode2 \n\t" + "call " _U "bm_GetCodeByVAddr \n\t" "call *%rax \n\t" "movl " _U "cycle_counter(%rip), %ecx \n\t" "testl %ecx, %ecx \n\t" @@ -212,51 +224,31 @@ static u32 exception_raised; template static T ReadMemNoEx(u32 addr, u32 pc) { - try { - exception_raised = 0; - if (sizeof(T) == 1) - return ReadMem8(addr); - else if (sizeof(T) == 2) - return ReadMem16(addr); - else if (sizeof(T) == 4) - return ReadMem32(addr); - else if (sizeof(T) == 8) - return ReadMem64(addr); - } catch (SH4ThrownException& ex) { + T rv = mmu_ReadMemNoEx(addr, &exception_raised); + if (exception_raised) + { if (pc & 1) - { // Delay slot - AdjustDelaySlotException(ex); - pc--; - } - Do_Exception(pc, ex.expEvn, ex.callVect); - exception_raised = 1; - return 0; + spc = pc - 1; + else + spc = pc; + longjmp(jmp_env, 1); } + return rv; } template static void WriteMemNoEx(u32 addr, T data, u32 pc) { - try { - if (sizeof(T) == 1) - WriteMem8(addr, data); - else if (sizeof(T) == 2) - WriteMem16(addr, data); - else if (sizeof(T) == 4) - WriteMem32(addr, data); - else if (sizeof(T) == 8) - WriteMem64(addr, data); - exception_raised = 0; - } catch (SH4ThrownException& ex) { + exception_raised = mmu_WriteMemNoEx(addr, data); + if (exception_raised) + { if (pc & 1) - { // Delay slot - AdjustDelaySlotException(ex); - pc--; - } - Do_Exception(pc, ex.expEvn, ex.callVect); - exception_raised = 1; + spc = pc - 1; + else + spc = pc; + longjmp(jmp_env, 1); } } @@ -352,7 +344,7 @@ public: sub(rsp, 0x8); // align stack #endif Xbyak::Label exit_block; - +/* if (mmu_enabled() && block->has_fpu_op) { Xbyak::Label fpu_enabled; @@ -367,7 +359,7 @@ public: jmp(exit_block, T_NEAR); L(fpu_enabled); } - +*/ for (current_opid = 0; current_opid < block->oplist.size(); current_opid++) { shil_opcode& op = block->oplist[current_opid]; @@ -449,25 +441,32 @@ public: { u32 size = op.flags & 0x7f; bool immediate_address = op.rs1.is_imm(); - if (immediate_address && mmu_enabled() && (op.rs1._imm >> 12) != (block->vaddr >> 12)) + u32 addr = op.rs1._imm; + if (immediate_address && mmu_enabled()) { - // When full mmu is on, only consider addresses in the same 4k page - immediate_address = false; + if ((op.rs1._imm >> 12) != (block->vaddr >> 12)) + { + // When full mmu is on, only consider addresses in the same 4k page + immediate_address = false; + } + else + { + u32 paddr; + u32 rv; + if (size == 2) + rv = mmu_data_translation(addr, paddr); + else if (size == 4) + rv = mmu_data_translation(addr, paddr); + else + die("Invalid immediate size"); + if (rv != MMU_ERROR_NONE) + immediate_address = false; + else + addr = paddr; + } } if (immediate_address) { - u32 addr = op.rs1._imm; - if (mmu_enabled()) - { - u32 paddr; - if (size == 2) - mmu_data_translation(addr, paddr); - else if (size == 4) - mmu_data_translation(addr, paddr); - else - die("Invalid immediate size"); - addr = paddr; - } bool isram = false; void* ptr = _vmem_read_const(addr, isram, size); @@ -581,11 +580,11 @@ public: die("1..8 bytes"); } - if (mmu_enabled()) - { - test(dword[(void *)&exception_raised], 1); - jnz(exit_block, T_NEAR); - } +// if (mmu_enabled()) +// { +// test(dword[(void *)&exception_raised], 1); +// jnz(exit_block, T_NEAR); +// } if (size != 8) host_reg_to_shil_param(op.rd, ecx); @@ -674,11 +673,11 @@ public: die("1..8 bytes"); } - if (mmu_enabled()) - { - test(dword[(void *)&exception_raised], 1); - jnz(exit_block, T_NEAR); - } +// if (mmu_enabled()) +// { +// test(dword[(void *)&exception_raised], 1); +// jnz(exit_block, T_NEAR); +// } } break; @@ -1353,6 +1352,10 @@ private: // cmp(byte[rax], block->asid); // jne(reinterpret_cast(&ngen_blockcheckfail)); // } + // FIXME Neither of these tests should be necessary + // However the decoder makes various assumptions about the current PC value, which are simply not + // true in a virtualized memory model. So this can only work if virtual and phy addresses are the + // same at compile and run times. if (mmu_enabled()) { mov(rax, (uintptr_t)&next_pc); diff --git a/core/rec-x86/rec_lin86_asm.S b/core/rec-x86/rec_lin86_asm.S index a8d8d42a6..9dee7fc9c 100644 --- a/core/rec-x86/rec_lin86_asm.S +++ b/core/rec-x86/rec_lin86_asm.S @@ -9,7 +9,7 @@ .globl cycle_counter .globl loop_no_update .globl intc_sched -.globl bm_GetCode +.globl bm_GetCodeByVAddr .globl cycle_counter .globl UpdateSystem .globl rdv_DoInterrupts @@ -109,7 +109,7 @@ ngen_mainloop: # next_pc _MUST_ be on ecx no_update: mov esi,ecx - call _Z10bm_GetCodej #bm_GetCode + call bm_GetCodeByVAddr jmp eax intc_sched_offs: diff --git a/core/rec-x86/rec_x86_asm.cpp b/core/rec-x86/rec_x86_asm.cpp index 74ba494f5..0d7161980 100644 --- a/core/rec-x86/rec_x86_asm.cpp +++ b/core/rec-x86/rec_x86_asm.cpp @@ -84,7 +84,7 @@ naked void ngen_mainloop(void* cntx) //next_pc _MUST_ be on ecx no_update: mov esi,ecx; - call bm_GetCode + call bm_GetCodeByVAddr jmp eax; intc_sched_offs: diff --git a/core/serialize.cpp b/core/serialize.cpp index 04cb136a1..913d6bbe5 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -492,8 +492,7 @@ extern TLB_Entry ITLB[4]; #if defined(NO_MMU) extern u32 sq_remap[64]; #else -extern u32 ITLB_LRU_USE[64]; -extern u32 mmu_error_TT; +static u32 ITLB_LRU_USE[64]; #endif @@ -1085,7 +1084,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_SA(sq_remap,64); #else REICAST_SA(ITLB_LRU_USE,64); - REICAST_S(mmu_error_TT); #endif @@ -1487,7 +1485,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(sq_remap,64); #else REICAST_USA(ITLB_LRU_USE,64); - REICAST_US(mmu_error_TT); #endif @@ -1877,7 +1874,6 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(sq_remap,64); #else REICAST_USA(ITLB_LRU_USE,64); - REICAST_US(mmu_error_TT); #endif diff --git a/shell/android-studio/reicast/src/main/jni/Android.mk b/shell/android-studio/reicast/src/main/jni/Android.mk index fb12326e1..09719e421 100644 --- a/shell/android-studio/reicast/src/main/jni/Android.mk +++ b/shell/android-studio/reicast/src/main/jni/Android.mk @@ -63,8 +63,8 @@ LOCAL_SRC_FILES := $(RZDCY_FILES) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/jni/src/Android.cpp) LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/jni/src/utils.cpp) LOCAL_CFLAGS := $(RZDCY_CFLAGS) -fPIC -fvisibility=hidden -ffunction-sections -fdata-sections -LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -LOCAL_CPPFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections +LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -fexceptions +LOCAL_CPPFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -fexceptions # 7-Zip/LZMA settings (CHDv5) ifdef CHD5_LZMA From 5d6e96463c0c81a0707719747e2f6e63ac6a1521 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 15 Apr 2019 18:31:15 +0200 Subject: [PATCH 005/158] x64 and win32 build fixes --- core/hw/sh4/modules/wince.h | 6 +++--- core/rec-x64/rec_x64.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index b4fab717a..50a662e68 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -39,7 +39,7 @@ static bool read_mem8(u32 addr, u8& data) return true; } -static inline u32 GetCurrentThreadId() +static inline u32 getCurrentThreadId() { u32 addr = PUserKData + SYSHANDLE_OFFSET + SH_CURTHREAD * 4; u32 tid; @@ -49,7 +49,7 @@ static inline u32 GetCurrentThreadId() return 0; } -static inline u32 GetCurrentProcessId() +static inline u32 getCurrentProcessId() { u32 addr = PUserKData + SYSHANDLE_OFFSET + SH_CURPROC * 4; u32 pid; @@ -294,7 +294,7 @@ static bool print_wince_syscall(u32 address) sprintf(method_buf, "[%d]", meth_id); method = method_buf; } - printf("WinCE %08x %04x.%04x %s: %s", address, GetCurrentProcessId() & 0xffff, GetCurrentThreadId() & 0xffff, api, method); + printf("WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); if (address == 0xfffffd51) // SetLastError printf(" dwErrCode = %x\n", r[4]); else if (address == 0xffffd5ef) // CreateFile diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 02e2e64cb..9d5acd6b1 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -125,9 +125,9 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") "movl $" _S(SH4_TIMESLICE) "," _U "cycle_counter(%rip) \n" #ifdef _WIN32 - "movq $" _U "jmp_env, %rcx \n\t" // SETJMP + "lea " _U "jmp_env(%rip), %rcx \n\t" // SETJMP #else - "movq $" _U "jmp_env, %rdi \n\t" + "lea " _U "jmp_env(%rip), %rdi \n\t" #endif "call " _U "setjmp \n\t" // "testl %rax, %rax \n\t" From a25918839bf986516260de7dcb462d3ffb2c0cfe Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 15 Apr 2019 19:02:10 +0200 Subject: [PATCH 006/158] save fpu regs when sr.FD is set, and restore them when unset --- core/hw/sh4/sh4_core_regs.cpp | 26 ++++++++++++++++++++++++++ core/nullDC.cpp | 3 +++ core/serialize.cpp | 24 ++++++++++++++++-------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/core/hw/sh4/sh4_core_regs.cpp b/core/hw/sh4/sh4_core_regs.cpp index 5bbfff5c7..edb7f7238 100644 --- a/core/hw/sh4/sh4_core_regs.cpp +++ b/core/hw/sh4/sh4_core_regs.cpp @@ -33,6 +33,10 @@ INLINE void ChangeFP() } } +f32 saved_xffr[32]; +u32 saved_fpul; +fpscr_t saved_fpscr; + //called when sr is changed and we must check for reg banks etc.. , returns true if interrupts got bool UpdateSR() { @@ -51,6 +55,28 @@ bool UpdateSR() if (old_sr.RB) ChangeGPR();//switch } + // Hack: save fp registers when disabling fp ops, restore them when re-enabled + // We assume that fp ops are disabled to avoid saving/restoring fp registers as + // long as they're not used by the kernel + if (sr.FD != old_sr.FD) + { + if (sr.FD) + { + // Disable floating-point + memcpy(saved_xffr, Sh4cntx.xffr, sizeof(saved_xffr)); + saved_fpul = fpul; + saved_fpscr = fpscr; + } + else + { + // Enable floating-point + memcpy(Sh4cntx.xffr, saved_xffr, sizeof(saved_xffr)); + fpul = saved_fpul; + fpscr = saved_fpscr; + old_fpscr.FR = fpscr.FR; // Make sure we don't switch bank + UpdateFPSCR(); + } + } old_sr.status=sr.status; diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 7ca8bc480..388d8418d 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -844,6 +844,9 @@ void dc_loadstate() #if FEAT_AREC == DYNAREC_JIT FlushCache(); #endif +#ifndef NO_MMU + mmu_flush_table(); +#endif if ( ! dc_unserialize(&data_ptr, &total_size) ) { diff --git a/core/serialize.cpp b/core/serialize.cpp index 913d6bbe5..67a099f83 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -35,7 +35,8 @@ enum serialize_version_enum { V2, V3, V4, - V5_LIBRETRO + V5_LIBRETRO, + V5 = 100 } ; //./core/hw/arm7/arm_mem.cpp @@ -434,6 +435,9 @@ extern Sh4RCB* p_sh4rcb; //extern u8* sh4_dyna_rcb; extern u32 old_rm; extern u32 old_dn; +extern f32 saved_xffr[32]; +extern u32 saved_fpul; +extern fpscr_t saved_fpscr; @@ -791,7 +795,7 @@ bool dc_serialize(void **data, unsigned int *total_size) { int i = 0; int j = 0; - serialize_version_enum version = V4 ; + serialize_version_enum version = V5 ; *total_size = 0 ; @@ -999,8 +1003,9 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(old_rm); REICAST_S(old_dn); - - + REICAST_S(saved_xffr); + REICAST_S(saved_fpul); + REICAST_S(saved_fpscr); REICAST_S(sh4_sched_ffb); @@ -1581,7 +1586,7 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(version) ; if (version == V5_LIBRETRO) return dc_unserialize_libretro(data, total_size); - if (version != V4) + if (version != V4 && version < V5) { fprintf(stderr, "Save State version not supported: %d\n", version); return false; @@ -1789,9 +1794,12 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(old_rm); REICAST_US(old_dn); - - - + if (version >= V5) + { + REICAST_US(saved_xffr); + REICAST_US(saved_fpul); + REICAST_US(saved_fpscr); + } REICAST_US(sh4_sched_ffb); REICAST_US(sh4_sched_intr); From d68da6bdd4a548474b1cccf25177116425e39f6f Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 18 Apr 2019 13:55:10 +0200 Subject: [PATCH 007/158] wince: let fp disable exception run before compiling a block --- core/hw/sh4/dyna/decoder.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 8e9050441..52944bc66 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -825,15 +825,16 @@ bool dec_generic(u32 op) bool update_after=false; if ((s32)e<0) { - if (rs1._reg!=rs2._reg && !mmu_enabled()) //reg shouldn't be updated if its written + if (rs1._reg!=rs2._reg) //reg shouldn't be updated if its written { - Emit(shop_sub,rs1,rs1,mk_imm(-e)); - } - else - { - verify(rs3.is_null()); - rs3=mk_imm(e); - update_after=true; + if (!mmu_enabled()) + Emit(shop_sub,rs1,rs1,mk_imm(-e)); + else + { + verify(rs3.is_null()); + rs3=mk_imm(e); + update_after=true; + } } } @@ -1075,7 +1076,16 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) else blk->guest_cycles+=CPU_RATIO; if (OpDesc[op]->IsFloatingPoint()) + { + if (sr.FD == 1) + { + // We need to know FPSCR to compile the block, so let the exception handler run first + // as it may change the fp registers + Do_Exception(next_pc, 0x800, 0x100); + return false; + } blk->has_fpu_op = true; + } verify(!(state.cpu.is_delayslot && OpDesc[op]->SetPC())); if (state.ngen.OnlyDynamicEnds || !OpDesc[op]->rec_oph) From 0f34d776f66cdbb6058517b63fcdf0aa47b354cb Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 18 Apr 2019 14:15:01 +0200 Subject: [PATCH 008/158] wince: delete sr.FD hack, restore FD block check in x64 rec use longjmp for interpreter fallback exceptions --- core/hw/sh4/sh4_core_regs.cpp | 23 +---------------------- core/rec-x64/rec_x64.cpp | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 40 deletions(-) diff --git a/core/hw/sh4/sh4_core_regs.cpp b/core/hw/sh4/sh4_core_regs.cpp index edb7f7238..622cc1b54 100644 --- a/core/hw/sh4/sh4_core_regs.cpp +++ b/core/hw/sh4/sh4_core_regs.cpp @@ -55,28 +55,6 @@ bool UpdateSR() if (old_sr.RB) ChangeGPR();//switch } - // Hack: save fp registers when disabling fp ops, restore them when re-enabled - // We assume that fp ops are disabled to avoid saving/restoring fp registers as - // long as they're not used by the kernel - if (sr.FD != old_sr.FD) - { - if (sr.FD) - { - // Disable floating-point - memcpy(saved_xffr, Sh4cntx.xffr, sizeof(saved_xffr)); - saved_fpul = fpul; - saved_fpscr = fpscr; - } - else - { - // Enable floating-point - memcpy(Sh4cntx.xffr, saved_xffr, sizeof(saved_xffr)); - fpul = saved_fpul; - fpscr = saved_fpscr; - old_fpscr.FR = fpscr.FR; // Make sure we don't switch bank - UpdateFPSCR(); - } - } old_sr.status=sr.status; @@ -168,6 +146,7 @@ void SetFloatStatusReg() //called when fpscr is changed and we must check for reg banks etc.. void UpdateFPSCR() { + verify(fpscr.PR == 0 || fpscr.SZ == 0); if (fpscr.FR !=old_fpscr.FR) ChangeFP(); // FPU bank change diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 9d5acd6b1..e8cffd6a4 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -252,11 +252,10 @@ static void WriteMemNoEx(u32 addr, T data, u32 pc) } } -static void interpreter_fallback(u16 op, u32 pc) +static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) { try { - OpDesc[op]->oph(op); - exception_raised = 0; + oph(op); } catch (SH4ThrownException& ex) { if (pc & 1) { @@ -265,7 +264,7 @@ static void interpreter_fallback(u16 op, u32 pc) pc--; } Do_Exception(pc, ex.expEvn, ex.callVect); - exception_raised = 1; + longjmp(jmp_env, 1); } } @@ -294,7 +293,7 @@ static void do_sqw_nommu_local(u32 addr, u8* sqb) class BlockCompiler : public Xbyak::CodeGenerator { public: - BlockCompiler() : Xbyak::CodeGenerator(64 * 1024, emit_GetCCPtr()), regalloc(this) + BlockCompiler() : Xbyak::CodeGenerator(emit_FreeSpace(), emit_GetCCPtr()), regalloc(this) { #if HOST_OS == OS_WINDOWS call_regs.push_back(ecx); @@ -344,13 +343,12 @@ public: sub(rsp, 0x8); // align stack #endif Xbyak::Label exit_block; -/* + if (mmu_enabled() && block->has_fpu_op) { Xbyak::Label fpu_enabled; mov(rax, (uintptr_t)&sr); - mov(eax, dword[rax]); - and_(eax, 0x8000); // test SR.FD bit + test(dword[rax], 0x8000); // test SR.FD bit jz(fpu_enabled); mov(call_regs[0], block->vaddr); // pc mov(call_regs[1], 0x800); // event @@ -359,7 +357,7 @@ public: jmp(exit_block, T_NEAR); L(fpu_enabled); } -*/ + for (current_opid = 0; current_opid < block->oplist.size(); current_opid++) { shil_opcode& op = block->oplist[current_opid]; @@ -370,6 +368,12 @@ public: case shop_ifb: { + if (mmu_enabled()) + { + mov(call_regs64[1], reinterpret_cast(*OpDesc[op.rs3._imm]->oph)); // op handler + mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + } + if (op.rs1._imm) { mov(rax, (size_t)&next_pc); @@ -379,18 +383,9 @@ public: mov(call_regs[0], op.rs3._imm); if (!mmu_enabled()) - { GenCall(OpDesc[op.rs3._imm]->oph); - } else - { - mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - GenCall(interpreter_fallback); - - test(dword[(void *)&exception_raised], 1); - jnz(exit_block, T_NEAR); - } } break; @@ -1160,6 +1155,7 @@ public: } regalloc.OpEnd(&op); } + regalloc.Cleanup(); mov(rax, (size_t)&next_pc); @@ -1511,6 +1507,7 @@ private: else { mov(rax, (size_t)param.reg_ptr()); + verify(!reg.isXMM()); mov((const Xbyak::Reg32 &)reg, dword[rax]); } } From d82e5e2017df56e98c7a2d967d3f191618de1c2b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 18 Apr 2019 22:48:37 +0200 Subject: [PATCH 009/158] don't use mmu for dma --- core/hw/sh4/modules/dmac.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/hw/sh4/modules/dmac.cpp b/core/hw/sh4/modules/dmac.cpp index 6f862a228..887aeb4df 100644 --- a/core/hw/sh4/modules/dmac.cpp +++ b/core/hw/sh4/modules/dmac.cpp @@ -46,7 +46,7 @@ void DMAC_Ch2St() return; } -// printf(">>\tDMAC: Ch2 DMA SRC=%X DST=%X LEN=%X\n", src, dst, len ); + //printf(">>\tDMAC: Ch2 DMA SRC=%X DST=%X LEN=%X\n", src, dst, len ); // Direct DList DMA (Ch2) @@ -80,7 +80,6 @@ void DMAC_Ch2St() else if((dst >= 0x11000000) && (dst <= 0x11FFFFE0)) { //printf(">>\tDMAC: TEX LNMODE0 Ch2 DMA SRC=%X DST=%X LEN=%X SB_LMMODE0 %d\n", src, dst, len, SB_LMMODE0); - SB_C2DSTAT += len; if (SB_LMMODE0 == 0) { @@ -111,13 +110,14 @@ void DMAC_Ch2St() dst = (dst & 0xFFFFFF) | 0xa5000000; while (len > 0) { - u32 v = ReadMem32(src); + u32 v = ReadMem32_nommu(src); pvr_write_area1_32(dst, v); len -= 4; src += 4; dst += 4; } } + SB_C2DSTAT = dst; } // If SB_C2DSTAT reg is in range from 0x13000000 to 0x13FFFFE0, set 1 in SB_LMMODE1 reg. else if((dst >= 0x13000000) && (dst <= 0x13FFFFE0)) @@ -135,11 +135,11 @@ void DMAC_Ch2St() // Setup some of the regs so it thinks we've finished DMA DMAC_SAR(2) = (src); - DMAC_CHCR(2).full &= 0xFFFFFFFE; - DMAC_DMATCR(2) = 0x00000000; + DMAC_CHCR(2).TE = 1; + DMAC_DMATCR(2) = 0; - SB_C2DST = 0x00000000; - SB_C2DLEN = 0x00000000; + SB_C2DST = 0; + SB_C2DLEN = 0; // The DMA end interrupt flag (SB_ISTNRM - bit 19: DTDE2INT) is set to "1." //-> fixed , holly_PVR_DMA is for different use now (fixed the interrupts enum too) From 76348b13ce075dae12e94f50b88514afec18fb8e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 19 Apr 2019 09:58:25 +0200 Subject: [PATCH 010/158] wince: use cpu ratio of 2 in dynarec --- core/hw/sh4/dyna/decoder.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 52944bc66..e0e4e401e 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1200,6 +1200,9 @@ _end: { blk->guest_cycles*=1.5; } + // Win CE boost + if (mmu_enabled()) + blk->guest_cycles *= 2; //make sure we don't use wayy-too-many cycles blk->guest_cycles=min(blk->guest_cycles,max_cycles); From 992088098734b3ec79cae4ac4e5c19492eba5613 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 19 Apr 2019 11:45:05 +0200 Subject: [PATCH 011/158] dynarec: reserve code cache space for frequently changing blocks detect frequent SMC check failures and use a specific code cache area for these blocks. flush the temp area when full but keep the main code cache area --- core/hw/sh4/dyna/blockmanager.cpp | 55 ++++++++++++++++----- core/hw/sh4/dyna/blockmanager.h | 3 ++ core/hw/sh4/dyna/driver.cpp | 82 ++++++++++++++++++++++++------- core/hw/sh4/dyna/ngen.h | 9 ++-- core/rec-x64/rec_x64.cpp | 2 +- 5 files changed, 117 insertions(+), 34 deletions(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index fe109d63a..2d21f3971 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -32,6 +32,7 @@ op_agent_t oprofHandle; typedef vector bm_List; bm_List all_blocks; +bm_List all_temp_blocks; bm_List del_blocks; #include @@ -39,7 +40,7 @@ struct BlockMapCMP { static bool is_code(RuntimeBlockInfo* blk) { - if ((unat)((u8*)blk-CodeCache)temp_block) + all_blocks.push_back(blk); + else + all_temp_blocks.push_back(blk); if (blkmap.find(blk)!=blkmap.end()) { printf("DUP: %08X %p %08X %p\n", (*blkmap.find(blk))->addr,(*blkmap.find(blk))->code,blk->addr,blk->code); @@ -229,14 +233,26 @@ void bm_RemoveBlock(RuntimeBlockInfo* block) auto it = blkmap.find(block); if (it != blkmap.end()) blkmap.erase(it); - for (auto it = all_blocks.begin(); it != all_blocks.end(); it++) - if (*it == block) - { - all_blocks.erase(it); - break; - } + if (!block->temp_block) + { + for (auto it = all_blocks.begin(); it != all_blocks.end(); it++) + if (*it == block) + { + all_blocks.erase(it); + break; + } + } + else + { + for (auto it = all_temp_blocks.begin(); it != all_temp_blocks.end(); it++) + if (*it == block) + { + all_temp_blocks.erase(it); + break; + } + } // FIXME need to remove refs - delete block; + del_blocks.push_back(block); } bool UDgreaterX ( RuntimeBlockInfo* elem1, RuntimeBlockInfo* elem2 ) @@ -451,6 +467,21 @@ void bm_Reset() #endif } +void bm_ResetTempCache(bool full) +{ + if (!full) + { + for (auto block : all_temp_blocks) + { + FPCA(block->addr) = ngen_FailedToFindBlock; + auto it = blkmap.find(block); + if (it != blkmap.end()) + blkmap.erase(it); + } + } + del_blocks.insert(del_blocks.begin(),all_temp_blocks.begin(),all_temp_blocks.end()); + all_temp_blocks.clear(); +} void bm_Init() { diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index 6dd89e481..719234f5e 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -37,6 +37,8 @@ struct RuntimeBlockInfo: RuntimeBlockInfo_Core u32 host_opcodes; bool has_fpu_op; u32 asid; // if not 0xFFFFFFFF then private page belonging to this id + u32 blockcheck_failures; + bool temp_block; u32 BranchBlock; //if not 0xFFFFFFFF then jump target u32 NextBlock; //if not 0xFFFFFFFF then next block (by position) @@ -99,6 +101,7 @@ RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr); void bm_AddBlock(RuntimeBlockInfo* blk); void bm_RemoveBlock(RuntimeBlockInfo* block); void bm_Reset(); +void bm_ResetTempCache(bool full); void bm_Periodical_1s(); void bm_Periodical_14k(); void bm_Sort(); diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 9c803d492..f27750cc6 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -1,4 +1,5 @@ #include "types.h" +#include #if HOST_OS==OS_WINDOWS #include @@ -30,7 +31,7 @@ //uh uh #if !defined(_WIN64) -u8 SH4_TCB[CODE_SIZE+4096] +u8 SH4_TCB[CODE_SIZE + TEMP_CODE_SIZE + 4096] #if HOST_OS == OS_WINDOWS || FEAT_SHREC != DYNAREC_JIT ; #elif HOST_OS == OS_LINUX @@ -43,11 +44,15 @@ u8 SH4_TCB[CODE_SIZE+4096] #endif u8* CodeCache; - +u8* TempCodeCache; u32 LastAddr; u32 LastAddr_min; +u32 TempLastAddr; u32* emit_ptr=0; +u32* emit_ptr_limit; + +std::unordered_set smc_hotspots; void* emit_GetCCPtr() { return emit_ptr==0?(void*)&CodeCache[LastAddr]:(void*)emit_ptr; } void emit_SetBaseAddr() { LastAddr_min = LastAddr; } @@ -73,10 +78,20 @@ void RASDASD() LastAddr=LastAddr_min; memset(emit_GetCCPtr(),0xCC,emit_FreeSpace()); } + +void clear_temp_cache(bool full) +{ + //printf("recSh4:Temp Code Cache clear at %08X\n", curr_pc); + TempLastAddr = 0; + bm_ResetTempCache(full); +} + void recSh4_ClearCache() { LastAddr=LastAddr_min; bm_Reset(); + smc_hotspots.clear(); + clear_temp_cache(true); printf("recSh4:Dynarec Cache clear at %08X\n",curr_pc); } @@ -112,11 +127,18 @@ void emit_Write32(u32 data) void emit_Skip(u32 sz) { - LastAddr+=sz; + if (emit_ptr) + emit_ptr = (u32*)((u8*)emit_ptr + sz); + else + LastAddr+=sz; + } u32 emit_FreeSpace() { - return CODE_SIZE-LastAddr; + if (emit_ptr) + return (emit_ptr_limit - emit_ptr) * sizeof(u32); + else + return CODE_SIZE-LastAddr; } // pc must be a physical address @@ -205,6 +227,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) BlockType=BET_SCL_Intr; has_fpu_op = false; asid = 0xFFFFFFFF; + temp_block = false; vaddr = rpc; if (mmu_enabled()) @@ -233,7 +256,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) return true; } -DynarecCodeEntryPtr rdv_CompilePC() +DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) { u32 pc=next_pc; @@ -247,7 +270,15 @@ DynarecCodeEntryPtr rdv_CompilePC() delete rbi; return NULL; } - + rbi->blockcheck_failures = blockcheck_failures; + if (smc_hotspots.find(rbi->addr) != smc_hotspots.end()) + { + if (TEMP_CODE_SIZE - TempLastAddr < 16 * 1024) + clear_temp_cache(false); + emit_ptr = (u32 *)(TempCodeCache + TempLastAddr); + emit_ptr_limit = (u32 *)(TempCodeCache + TEMP_CODE_SIZE); + rbi->temp_block = true; + } bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100); rbi->staging_runs=do_opts?100:-100; ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); @@ -255,6 +286,13 @@ DynarecCodeEntryPtr rdv_CompilePC() bm_AddBlock(rbi); + if (emit_ptr != NULL) + { + TempLastAddr = (u8*)emit_ptr - TempCodeCache; + emit_ptr = NULL; + emit_ptr_limit = NULL; + } + return rbi->code; } @@ -267,7 +305,7 @@ DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc) { //printf("rdv_FailedToFindBlock ~ %08X\n",pc); next_pc=pc; - DynarecCodeEntryPtr code = rdv_CompilePC(); + DynarecCodeEntryPtr code = rdv_CompilePC(0); if (code == NULL) code = bm_GetCodeByVAddr(next_pc); return code; @@ -306,10 +344,17 @@ u32 DYNACALL rdv_DoInterrupts(void* block_cpde) // addr must be the physical address of the start of the block DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) { + u32 blockcheck_failures = 0; if (mmu_enabled()) { RuntimeBlockInfo *block = bm_GetBlock(addr); - //printf("rdv_BlockCheckFail addr %08x vaddr %08x pc %08x\n", addr, block->vaddr, next_pc); + blockcheck_failures = block->blockcheck_failures + 1; + if (blockcheck_failures > 5) + { + bool inserted = smc_hotspots.insert(addr).second; + //if (inserted) + // printf("rdv_BlockCheckFail SMC hotspot @ %08x fails %d\n", addr, blockcheck_failures); + } bm_RemoveBlock(block); } else @@ -317,7 +362,7 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) next_pc = addr; recSh4_ClearCache(); } - return rdv_CompilePC(); + return rdv_CompilePC(blockcheck_failures); } //DynarecCodeEntryPtr rdv_FindCode() @@ -333,7 +378,7 @@ DynarecCodeEntryPtr rdv_FindOrCompile() { DynarecCodeEntryPtr rv=bm_GetCodeByVAddr(next_pc); if (rv==ngen_FailedToFindBlock) - rv=rdv_CompilePC(); + rv=rdv_CompilePC(0); return rv; } @@ -467,13 +512,13 @@ void recSh4_Init() //align to next page .. u8* ptr = (u8*)recSh4_Init - i * 1024 * 1024; - CodeCache = (u8*)VirtualAlloc(ptr, CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);//; (u8*)(((unat)SH4_TCB+4095)& ~4095); + CodeCache = (u8*)VirtualAlloc(ptr, CODE_SIZE + TEMP_CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);//; (u8*)(((unat)SH4_TCB+4095)& ~4095); if (CodeCache) break; } #else - CodeCache = (u8*)VirtualAlloc(NULL, CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + CodeCache = (u8*)VirtualAlloc(NULL, CODE_SIZE + TEMP_CODE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); #endif verify(CodeCache != NULL); #else @@ -481,19 +526,19 @@ void recSh4_Init() #endif #if HOST_OS == OS_DARWIN - munmap(CodeCache, CODE_SIZE); - CodeCache = (u8*)mmap(CodeCache, CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); + munmap(CodeCache, CODE_SIZE + TEMP_CODE_SIZE); + CodeCache = (u8*)mmap(CodeCache, CODE_SIZE + TEMP_CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); #endif #if HOST_OS == OS_WINDOWS DWORD old; - VirtualProtect(CodeCache,CODE_SIZE,PAGE_EXECUTE_READWRITE,&old); + VirtualProtect(CodeCache,CODE_SIZE + TEMP_CODE_SIZE,PAGE_EXECUTE_READWRITE,&old); #elif HOST_OS == OS_LINUX || HOST_OS == OS_DARWIN printf("\n\t CodeCache addr: %p | from: %p | addr here: %p\n", CodeCache, CodeCache, recSh4_Init); #if FEAT_SHREC == DYNAREC_JIT - if (mprotect(CodeCache, CODE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC)) + if (mprotect(CodeCache, CODE_SIZE + TEMP_CODE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC)) { perror("\n\tError,Couldn’t mprotect CodeCache!"); die("Couldn’t mprotect CodeCache"); @@ -501,12 +546,13 @@ void recSh4_Init() #endif #if TARGET_IPHONE - memset((u8*)mmap(CodeCache, CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0),0xFF,CODE_SIZE); + memset((u8*)mmap(CodeCache, CODE_SIZE + TEMP_CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0),0xFF,CODE_SIZE + TEMP_CODE_SIZE); #else - memset(CodeCache,0xFF,CODE_SIZE); + memset(CodeCache,0xFF,CODE_SIZE + TEMP_CODE_SIZE); #endif #endif + TempCodeCache = CodeCache + CODE_SIZE; ngen_init(); } diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index d9c4209b3..f6a256510 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -45,9 +45,12 @@ #include "decoder.h" #include "blockmanager.h" - #define CODE_SIZE (10*1024*1024) - +#ifdef NO_MMU +#define TEMP_CODE_SIZE (0) +#else +#define TEMP_CODE_SIZE (1024*1024) +#endif //alternative emit ptr, set to 0 to use the main buffer extern u32* emit_ptr; @@ -69,7 +72,7 @@ DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock_pc(); //Called when a block check failed, and the block needs to be invalidated DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc); //Called to compile code @pc -DynarecCodeEntryPtr rdv_CompilePC(); +DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures); //Returns 0 if there is no code @pc, code ptr otherwise //DynarecCodeEntryPtr rdv_FindCode(); //Finds or compiles code @pc diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index e8cffd6a4..9c413ed8a 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -215,7 +215,7 @@ RuntimeBlockInfo* ngen_AllocateBlock() } static void ngen_blockcheckfail(u32 pc) { - printf("X64 JIT: SMC invalidation at %08X\n", pc); + //printf("X64 JIT: SMC invalidation at %08X\n", pc); rdv_BlockCheckFail(pc); } From 553f6054ce097cb0f58590cd98d484a8467feacb Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 19 Apr 2019 11:56:11 +0200 Subject: [PATCH 012/158] NO_MMU build fixes --- core/hw/sh4/dyna/decoder.cpp | 4 +++- core/rec-ARM64/rec_arm64.cpp | 9 +++++++-- core/rec-x64/rec_x64.cpp | 7 +++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index e0e4e401e..742216508 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1057,6 +1057,7 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) u32 op; if (!mmu_enabled()) op = IReadMem16(state.cpu.rpc); +#ifndef NO_MMU else { u32 exception_occurred; @@ -1064,6 +1065,7 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) if (exception_occurred) return false; } +#endif if (op==0 && state.cpu.is_delayslot) { printf("Delayslot 0 hack!\n"); @@ -1157,7 +1159,7 @@ _end: if (settings.dynarec.idleskip) { //Experimental hash-id based idle skip - if (strstr(idle_hash,blk->hash(false,true))) + if (strstr(idle_hash,blk->hash(false,true))) // FIXME don't hash temp blocks. Use xxhash instead of sha1 { //printf("IDLESKIP: %08X reloc match %s\n",blk->addr,blk->hash(false,true)); blk->guest_cycles=max_cycles*100; diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index d0a829c5d..343a80639 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -290,6 +290,7 @@ RuntimeBlockInfo* ngen_AllocateBlock() template static T ReadMemNoEx(u32 addr, u32 pc) { +#ifndef NO_MMU u32 ex; T rv = mmu_ReadMemNoEx(addr, &ex); if (ex) @@ -301,11 +302,15 @@ static T ReadMemNoEx(u32 addr, u32 pc) longjmp(jmp_env, 1); } return rv; +#else + return (T)0; // not used +#endif } template static void WriteMemNoEx(u32 addr, T data, u32 pc) { +#ifndef NO_MMU u32 ex = mmu_WriteMemNoEx(addr, data); if (ex) { @@ -315,6 +320,7 @@ static void WriteMemNoEx(u32 addr, T data, u32 pc) spc = pc; longjmp(jmp_env, 1); } +#endif } static u32 interpreter_fallback(u16 op, u32 pc) @@ -1619,7 +1625,7 @@ private: TailCallRuntime(ngen_blockcheckfail); Bind(&blockcheck_success); -/* + if (mmu_enabled() && block->has_fpu_op) { Label fpu_enabled; @@ -1635,7 +1641,6 @@ private: Bind(&fpu_enabled); } -*/ } void shil_param_to_host_reg(const shil_param& param, const Register& reg) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 9c413ed8a..9723ffc43 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -224,6 +224,7 @@ static u32 exception_raised; template static T ReadMemNoEx(u32 addr, u32 pc) { +#ifndef NO_MMU T rv = mmu_ReadMemNoEx(addr, &exception_raised); if (exception_raised) { @@ -235,11 +236,16 @@ static T ReadMemNoEx(u32 addr, u32 pc) longjmp(jmp_env, 1); } return rv; +#else + // not used + return (T)0; +#endif } template static void WriteMemNoEx(u32 addr, T data, u32 pc) { +#ifndef NO_MMU exception_raised = mmu_WriteMemNoEx(addr, data); if (exception_raised) { @@ -250,6 +256,7 @@ static void WriteMemNoEx(u32 addr, T data, u32 pc) spc = pc; longjmp(jmp_env, 1); } +#endif } static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) From 011849ea74b0dd298d51d5c7e49172a866722fa3 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 19 Apr 2019 17:20:55 +0200 Subject: [PATCH 013/158] wince: arm64 dynarec fixes --- core/rec-ARM64/rec_arm64.cpp | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 343a80639..74bb3bf1a 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -220,7 +220,6 @@ void ngen_mainloop(void* v_cntx) "no_update: \n\t" // next_pc _MUST_ be on w29 "ldr w0, [x28, %[CpuRunning]] \n\t" "cbz w0, .end_mainloop \n\t" - "ldr w29, [x28, %[pc]] \n\t" // shouldn't be necessary #ifdef NO_MMU "movz x2, %[RCB_SIZE], lsl #16 \n\t" @@ -237,7 +236,7 @@ void ngen_mainloop(void* v_cntx) "br x0 \n" #else "mov w0, w29 \n\t" - "bl bm_GetCodeByVAddr \n\t" + "bl bm_GetCodeByVAddr \n\t" "br x0 \n" #endif @@ -323,13 +322,11 @@ static void WriteMemNoEx(u32 addr, T data, u32 pc) #endif } -static u32 interpreter_fallback(u16 op, u32 pc) +static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) { try { - OpDesc[op]->oph(op); - return 0; + oph(op); } catch (SH4ThrownException& ex) { - die("IFB exception"); if (pc & 1) { // Delay slot @@ -337,19 +334,15 @@ static u32 interpreter_fallback(u16 op, u32 pc) pc--; } Do_Exception(pc, ex.expEvn, ex.callVect); - return 1; + longjmp(jmp_env, 1); } } -static u32 exception_raised; - static void do_sqw_mmu_no_ex(u32 addr, u32 pc) { try { do_sqw_mmu(addr); - exception_raised = 0; } catch (SH4ThrownException& ex) { - die("do_sqw_mmu exception"); if (pc & 1) { // Delay slot @@ -357,8 +350,7 @@ static void do_sqw_mmu_no_ex(u32 addr, u32 pc) pc--; } Do_Exception(pc, ex.expEvn, ex.callVect); - exception_raised = 1; - printf("SQW MMU EXCEPTION\n"); + longjmp(jmp_env, 1); } } @@ -371,7 +363,7 @@ public: Arm64Assembler() : Arm64Assembler(emit_GetCCPtr()) { } - Arm64Assembler(void *buffer) : MacroAssembler((u8 *)buffer, 64 * 1024), regalloc(this) + Arm64Assembler(void *buffer) : MacroAssembler((u8 *)buffer, emit_FreeSpace()), regalloc(this) { call_regs.push_back(&w0); call_regs.push_back(&w1); @@ -520,13 +512,10 @@ public: } else { - Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + Mov(*call_regs64[1], reinterpret_cast(*OpDesc[op.rs3._imm]->oph)); // op handler + Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc GenCallRuntime(interpreter_fallback); - - Cmp(w0, 0); - Ldr(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update, ne); } break; @@ -788,10 +777,6 @@ public: Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc GenCallRuntime(do_sqw_mmu_no_ex); - - Cmp(w0, 0); - Ldr(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update, ne); } else { @@ -927,6 +912,7 @@ public: } regalloc.OpEnd(&op); } + regalloc.Cleanup(); block->relink_offset = (u32)GetBuffer()->GetCursorOffset(); block->relink_data = 0; @@ -1710,7 +1696,7 @@ private: std::vector call_regs64; std::vector call_fregs; Arm64RegAlloc regalloc; - RuntimeBlockInfo* block; + RuntimeBlockInfo* block = NULL; const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov // FIXME rewrite size per read/write size? const int write_memory_rewrite_size = 3; From 6b78e1f87910c492924ac811a1aba7db11d8915e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 28 Apr 2019 20:41:39 +0200 Subject: [PATCH 014/158] fix dynarec regression --- core/hw/sh4/dyna/decoder.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 742216508..e50f29953 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -825,16 +825,15 @@ bool dec_generic(u32 op) bool update_after=false; if ((s32)e<0) { - if (rs1._reg!=rs2._reg) //reg shouldn't be updated if its written + if (rs1._reg!=rs2._reg && !mmu_enabled()) //reg shouldn't be updated if its written { - if (!mmu_enabled()) - Emit(shop_sub,rs1,rs1,mk_imm(-e)); - else - { - verify(rs3.is_null()); - rs3=mk_imm(e); - update_after=true; - } + Emit(shop_sub,rs1,rs1,mk_imm(-e)); + } + else + { + verify(rs3.is_null()); + rs3=mk_imm(e); + update_after=true; } } From 693a6c97f3b1ad2701d836fc2a9cc3efbad56e80 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 28 Apr 2019 20:46:18 +0200 Subject: [PATCH 015/158] vmem: revert aica ram mapping change. Fix ptr diff overflow in 64-bit Aica ram mapping conflicts with P4 store queues in arm dynarecs --- core/hw/mem/_vmem.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 4950a3e45..cde6d9a18 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -561,7 +561,7 @@ error: } #endif - int vmem_fd; + int vmem_fd = -1; void* _nvmem_unused_buffer(u32 start,u32 end) { void* ptr=mmap(&virt_ram_base[start], end-start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); @@ -679,7 +679,7 @@ bool BM_LockedWrite(u8* address) return false; #if FEAT_SHREC != DYNAREC_NONE - u32 addr=address-(u8*)p_sh4rcb->fpcb; + size_t addr=address-(u8*)p_sh4rcb->fpcb; address=(u8*)p_sh4rcb->fpcb+ (addr&~PAGE_MASK); @@ -739,7 +739,7 @@ bool _vmem_reserve() //I really should check teh docs before codin ;p //[0x00800000,0x00A00000); map_buffer(0x00800000,0x01000000,MAP_ARAM_START_OFFSET,ARAM_SIZE,false); - map_buffer(0x02800000,0x02800000+ARAM_SIZE,MAP_ARAM_START_OFFSET,ARAM_SIZE,true); + map_buffer(0x20000000,0x20000000+ARAM_SIZE,MAP_ARAM_START_OFFSET,ARAM_SIZE,true); aica_ram.size=ARAM_SIZE; aica_ram.data=(u8*)ptr; @@ -786,7 +786,7 @@ bool _vmem_reserve() //[0x10000000,0x20000000) -> unused unused_buffer(0x10000000,0x20000000); - printf("vmem reserve: base: %08X, aram: %08x, vram: %08X, ram: %08X\n",virt_ram_base,aica_ram.data,vram.data,mem_b.data); + printf("vmem reserve: base: %p, aram: %p, vram: %p, ram: %p\n",virt_ram_base,aica_ram.data,vram.data,mem_b.data); aica_ram.Zero(); vram.Zero(); From 810b8a59da2bb25e992bd10f6dfe55d61098e236 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 29 Apr 2019 18:23:00 +0200 Subject: [PATCH 016/158] wince: 32-bit virtual mem space use fast mem read/write for x64 and arm64 dynarecs --- core/build.h | 4 + core/hw/mem/vmem32.cpp | 396 +++++++++++++++ core/hw/mem/vmem32.h | 11 + core/hw/sh4/dyna/driver.cpp | 5 +- core/hw/sh4/dyna/ngen.h | 1 + core/hw/sh4/interpr/sh4_interpreter.cpp | 4 + core/hw/sh4/interpr/sh4_opcodes.cpp | 2 +- core/hw/sh4/modules/ccn.cpp | 15 +- core/hw/sh4/sh4_if.h | 3 + core/linux/common.cpp | 21 +- core/nullDC.cpp | 15 +- core/rec-ARM64/rec_arm64.cpp | 185 ++++--- core/rec-x64/rec_x64.cpp | 623 +++++++++++++++--------- core/rend/TexCache.cpp | 21 +- core/rend/TexCache.h | 14 - core/types.h | 1 + core/windows/winmain.cpp | 20 +- 17 files changed, 1024 insertions(+), 317 deletions(-) create mode 100644 core/hw/mem/vmem32.cpp create mode 100644 core/hw/mem/vmem32.h diff --git a/core/build.h b/core/build.h index 5add9b580..de8a72034 100755 --- a/core/build.h +++ b/core/build.h @@ -288,6 +288,10 @@ #define FEAT_HAS_SOFTREND BUILD_COMPILER == COMPILER_VC //GCC wants us to enable sse4 globaly to enable intrins #endif +#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64 +#define HOST_64BIT_CPU +#endif + #define RAM_SIZE_MAX (32*1024*1024) #define VRAM_SIZE_MAX (16*1024*1024) #define ARAM_SIZE_MAX (8*1024*1024) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp new file mode 100644 index 000000000..472fc561d --- /dev/null +++ b/core/hw/mem/vmem32.cpp @@ -0,0 +1,396 @@ +/* + * vmem32.cpp + * + * Created on: Apr 11, 2019 + * Author: Flyinghead + */ +#include +#include "build.h" +#include "vmem32.h" +#include "_vmem.h" + +#if HOST_OS == OS_WINDOWS +#include +#else +#include +#include /* For mode constants */ +#include /* For O_* constants */ +#include +#include +#ifdef _ANDROID +#include +#endif +#endif + +#ifndef MAP_NOSYNC +#define MAP_NOSYNC 0 +#endif + +#include "types.h" +#include "hw/sh4/dyna/ngen.h" +#include "hw/sh4/modules/mmu.h" + +extern bool VramLockedWriteOffset(size_t offset); +extern cMutex vramlist_lock; + +#if HOST_OS == OS_WINDOWS +extern HANDLE mem_handle; +#else +extern int vmem_fd; +#endif + +#define VMEM32_ERROR_NOT_MAPPED 0x100 + +// FIXME stolen from _vmem.cpp +#define MAP_RAM_START_OFFSET 0 +#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) +#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) + +static const u64 VMEM32_SIZE = 0x100000000L; +static const u64 KERNEL_SPACE = 0x80000000L; +static const u64 AREA7_ADDRESS = 0x7C000000L; + +#define VRAM_PROT_SEGMENT (1024 * 1024) // vram protection regions are grouped by 1MB segment + +u8* vmem32_base; +unordered_set vram_mapped_pages; +vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; + +// stats +u64 vmem32_page_faults; +u64 vmem32_flush; + +static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool write) +{ + void* ptr; + void* rv; + + //printf("MAP32 %08X w/ %d\n",dst,offset); + u32 map_times = addrsz / size; +#if HOST_OS == OS_WINDOWS + rv = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &vmem32_base[dst]); + if (rv == NULL) + return NULL; + + for (u32 i = 1; i < map_times; i++) + { + dst += size; + ptr = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &vmem32_base[dst]); + if (ptr == NULL) + return NULL; + } +#else + u32 prot = PROT_READ | (write ? PROT_WRITE : 0); + rv = mmap(&vmem32_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); + if (MAP_FAILED == rv) + { + printf("MAP1 failed %d\n", errno); + return NULL; + } + + for (u32 i = 1; i < map_times; i++) + { + dst += size; + ptr = mmap(&vmem32_base[dst], size, prot , MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); + if (MAP_FAILED == ptr) + { + printf("MAP2 failed %d\n", errno); + return NULL; + } + } +#endif + return rv; +} + +static void vmem32_unmap_buffer(u32 start, u64 end) +{ +#if HOST_OS == OS_LINUX + mmap(&vmem32_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#elif HOST_OS == OS_WINDOWS + VirtualAlloc(&vmem32_base[start], end - start, MEM_RESERVE, PAGE_NOACCESS); +#else +#error Unsupported OS +#endif +} + +static void vmem32_protect_buffer(u32 start, u32 size) +{ + verify((start & PAGE_MASK) == 0); +#if HOST_OS == OS_LINUX + mprotect(&vmem32_base[start], size, PROT_READ); +#elif HOST_OS == OS_WINDOWS + DWORD old; + VirtualProtect(vmem32_base + start, end - start, PAGE_READONLY, &old); +#else +#error Unsupported OS +#endif +} + +static void vmem32_unprotect_buffer(u32 start, u32 size) +{ + verify((start & PAGE_MASK) == 0); +#if HOST_OS == OS_LINUX + mprotect(&vmem32_base[start], size, PROT_READ | PROT_WRITE); +#elif HOST_OS == OS_WINDOWS + DWORD old; + VirtualProtect(vmem32_base + start, end - start, PAGE_READWRITE, &old); +#else +#error Unsupported OS +#endif +} + +void vmem32_protect_vram(vram_block *block) +{ + if (vmem32_base == NULL) + return; + for (int i = block->start / VRAM_PROT_SEGMENT; i <= block->end / VRAM_PROT_SEGMENT; i++) + { + vram_blocks[i].push_back(block); + } +} +void vmem32_unprotect_vram(vram_block *block) +{ + if (vmem32_base == NULL) + return; + for (int page = block->start / VRAM_PROT_SEGMENT; page <= block->end / VRAM_PROT_SEGMENT; page++) + { + for (int i = 0; i < vram_blocks[page].size(); i++) + if (vram_blocks[page][i] == block) + { + vram_blocks[page].erase(vram_blocks[page].begin() + i); + break; + } + } +} + +static bool vmem32_map_areas() +{ + // Aica ram + vmem32_map_buffer(0x80800000, 0x00800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); // P1 + vmem32_map_buffer(0x82800000, ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); + vmem32_map_buffer(0xA0800000, 0x00800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); // P2 + vmem32_map_buffer(0xA2800000, ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); + + // Vram + // Note: this should be mapped read/write but doesn't seem to be used + vmem32_map_buffer(0x84000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); // P1 + vmem32_map_buffer(0x86000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); + vmem32_map_buffer(0xA4000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); // P2 + vmem32_map_buffer(0xA6000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); + + // System ram + vmem32_map_buffer(0x8C000000, 0x04000000, MAP_RAM_START_OFFSET, RAM_SIZE, true); // P1 + vmem32_map_buffer(0xAC000000, 0x04000000, MAP_RAM_START_OFFSET, RAM_SIZE, true); // P2 + + return true; +} + +static const u32 page_sizes[] = { 1024, 4 * 1024, 64 * 1024, 1024 * 1024 }; + +static u32 vmem32_paddr_to_offset(u32 address) +{ + u32 low_addr = address & 0x1FFFFFFF; + switch ((address >> 26) & 7) + { + case 0: // area 0 + // Aica ram + if (low_addr >= 0x00800000 && low_addr < 0x00800000 + 0x00800000) + { + return ((low_addr - 0x00800000) & (ARAM_SIZE - 1)) + MAP_ARAM_START_OFFSET; + } + else if (low_addr >= 0x02800000 && low_addr < 0x02800000 + 0x00800000) + { + return low_addr - 0x02800000 + MAP_ARAM_START_OFFSET; + } + break; + case 1: // area 1 + // Vram + if (low_addr >= 0x04000000 && low_addr < 0x04000000 + 0x01000000) + { + return ((low_addr - 0x04000000) & (VRAM_SIZE - 1)) + MAP_VRAM_START_OFFSET; + } + else if (low_addr >= 0x06000000 && low_addr < 0x06000000 + 0x01000000) + { + return ((low_addr - 0x06000000) & (VRAM_SIZE - 1)) + MAP_VRAM_START_OFFSET; + } + break; + case 3: // area 3 + // System ram + if (low_addr >= 0x0C000000 && low_addr < 0x0C000000 + 0x04000000) + { + return ((low_addr - 0x0C000000) & (RAM_SIZE - 1)) + MAP_RAM_START_OFFSET; + } + break; + //case 4: + // TODO vram? + //break; + default: + break; + } + // Unmapped address + return -1; +} + +static u32 vmem32_map_mmu(u32 address, bool write) +{ +#ifndef NO_MMU + u32 pa; + const TLB_Entry *entry; + u32 rc = mmu_full_lookup(address, &entry, pa); + if (rc == MMU_ERROR_NONE) + { + //0X & User mode-> protection violation + //if ((entry->Data.PR >> 1) == 0 && p_sh4rcb->cntx.sr.MD == 0) + // return MMU_ERROR_PROTECTED; + + //if (write) + //{ + // if ((entry->Data.PR & 1) == 0) + // return MMU_ERROR_PROTECTED; + // if (entry->Data.D == 0) + // return MMU_ERROR_FIRSTWRITE; + //} + u32 page_size = page_sizes[entry->Data.SZ1 * 2 + entry->Data.SZ0]; + if (page_size == 1024) + return VMEM32_ERROR_NOT_MAPPED; + + u32 vpn = (entry->Address.VPN << 10) & ~(page_size - 1); + u32 ppn = (entry->Data.PPN << 10) & ~(page_size - 1); + u32 offset = vmem32_paddr_to_offset(ppn); + if (offset == -1) + return VMEM32_ERROR_NOT_MAPPED; + + if (offset >= MAP_VRAM_START_OFFSET && offset < MAP_VRAM_START_OFFSET + VRAM_SIZE) + { + // Check vram protected regions + u32 start = offset - MAP_VRAM_START_OFFSET; + if (!vram_mapped_pages.insert(vpn).second) + { + // page has been mapped already: vram locked write + vmem32_unprotect_buffer(address & ~PAGE_MASK, PAGE_SIZE); + u32 addr_offset = start + (address & (page_size - 1)); + VramLockedWriteOffset(addr_offset); + + return MMU_ERROR_NONE; + } + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); + u32 end = start + page_size; + const vector& blocks = vram_blocks[start / VRAM_PROT_SEGMENT]; + + vramlist_lock.Lock(); + for (int i = blocks.size() - 1; i >= 0; i--) + { + if (blocks[i]->start < end && blocks[i]->end >= start) + { + u32 prot_start = max(start, blocks[i]->start); + u32 prot_size = min(end, blocks[i]->end + 1) - prot_start; + prot_size += prot_start % PAGE_SIZE; + prot_start &= ~PAGE_MASK; + vmem32_protect_buffer(vpn + (prot_start & (page_size - 1)), prot_size); + } + } + vramlist_lock.Unlock(); + } + else + // Not vram + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); + + return MMU_ERROR_NONE; + } +#else + u32 rc = MMU_ERROR_PROTECTED; +#endif + return rc; +} + +static u32 vmem32_map_address(u32 address, bool write) +{ + u32 area = address >> 29; + switch (area) + { + case 3: // P0/U0 + if (address >= AREA7_ADDRESS) + // area 7: unmapped + return VMEM32_ERROR_NOT_MAPPED; + /* no break */ + case 0: + case 1: + case 2: + case 6: // P3 + return vmem32_map_mmu(address, write); + + default: + break; + } + return VMEM32_ERROR_NOT_MAPPED; +} + +#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) +bool vmem32_handle_signal(void *fault_addr, bool write) +{ + if ((u8*)fault_addr < vmem32_base || (u8*)fault_addr >= vmem32_base + VMEM32_SIZE) + return false; + vmem32_page_faults++; + u32 guest_addr = (u8*)fault_addr - vmem32_base; + u32 rv = vmem32_map_address(guest_addr, write); + //printf("vmem32_handle_signal handled signal %s @ %p -> %08x rv=%d\n", write ? "W" : "R", fault_addr, guest_addr, rv); + if (rv == MMU_ERROR_NONE) + return true; + if (rv == VMEM32_ERROR_NOT_MAPPED) + return false; + p_sh4rcb->cntx.pc = p_sh4rcb->cntx.exception_pc; + DoMMUException(guest_addr, rv, write ? MMU_TT_DWRITE : MMU_TT_DREAD); + ngen_HandleException(); + // not reached + return true; +} +#endif + +void vmem32_flush_mmu() +{ + vmem32_flush++; + vram_mapped_pages.clear(); + vmem32_unmap_buffer(0, KERNEL_SPACE); + // TODO flush P3? +} + +bool vmem32_init() +{ + if (!_nvmem_enabled()) + return false; +#ifdef HOST_64BIT_CPU +#if HOST_OS == OS_LINUX + void* rv = mmap(0, VMEM32_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + verify(rv != NULL); + munmap(rv, VMEM32_SIZE); + vmem32_base = (u8*)rv; +#elif HOST_OS == OS_WINDOWS + void* rv = (u8 *)VirtualAlloc(0, VMEM32_SIZE, MEM_RESERVE, PAGE_NOACCESS); + if (rv != NULL) + VirtualFree(rv, 0, MEM_RELEASE); + vmem32_base = (u8*)rv; +#else +#error Unsupported OS +#endif + + vmem32_unmap_buffer(0, VMEM32_SIZE); + printf("vmem32_init: allocated %zx bytes from %p to %p\n", VMEM32_SIZE, vmem32_base, vmem32_base + VMEM32_SIZE); + + if (!vmem32_map_areas()) + { + vmem32_term(); + return false; + } +#endif + return true; +} + +void vmem32_term() +{ + if (vmem32_base != NULL) + { + munmap(vmem32_base, VMEM32_SIZE); + vmem32_base = NULL; + } +} + diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h new file mode 100644 index 000000000..692d25b5e --- /dev/null +++ b/core/hw/mem/vmem32.h @@ -0,0 +1,11 @@ +#include "types.h" + +bool vmem32_init(); +void vmem32_term(); +bool vmem32_handle_signal(void *fault_addr, bool write); +void vmem32_flush_mmu(); +void vmem32_protect_vram(vram_block *block); +void vmem32_unprotect_vram(vram_block *block); +static inline bool vmem32_enabled() { + return !settings.dynarec.disable_vmem32; +} diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index f27750cc6..a659c82bb 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -88,12 +88,11 @@ void clear_temp_cache(bool full) void recSh4_ClearCache() { + printf("recSh4:Dynarec Cache clear at %08X free space %d\n",curr_pc, emit_FreeSpace()); LastAddr=LastAddr_min; bm_Reset(); smc_hotspots.clear(); clear_temp_cache(true); - - printf("recSh4:Dynarec Cache clear at %08X\n",curr_pc); } void recSh4_Run() @@ -279,7 +278,7 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) emit_ptr_limit = (u32 *)(TempCodeCache + TEMP_CODE_SIZE); rbi->temp_block = true; } - bool do_opts=((rbi->addr&0x3FFFFFFF)>0x0C010100); + bool do_opts = !rbi->temp_block; //((rbi->addr&0x3FFFFFFF)>0x0C010100); rbi->staging_runs=do_opts?100:-100; ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); verify(rbi->code!=0); diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index f6a256510..76abe6210 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -100,6 +100,7 @@ extern void (*ngen_FailedToFindBlock)(); void ngen_mainloop(void* cntx); void ngen_GetFeatures(ngen_features* dst); +void ngen_HandleException(); //Canonical callback interface enum CanonicalParamType diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index fc358ee05..b9dc3a765 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -124,6 +124,8 @@ void Sh4_int_Skip() } } +extern u8 *vmem32_base; + void Sh4_int_Reset(bool Manual) { if (sh4_int_bCpuRun) @@ -148,6 +150,8 @@ void Sh4_int_Reset(bool Manual) old_fpscr=fpscr; UpdateFPSCR(); + p_sh4rcb->cntx.vmem32_base = vmem32_base; + //Any more registers have default value ? printf("Sh4 Reset\n"); } diff --git a/core/hw/sh4/interpr/sh4_opcodes.cpp b/core/hw/sh4/interpr/sh4_opcodes.cpp index 3cb3a52f7..7330db791 100644 --- a/core/hw/sh4/interpr/sh4_opcodes.cpp +++ b/core/hw/sh4/interpr/sh4_opcodes.cpp @@ -2066,7 +2066,7 @@ sh4op(i0000_nnnn_0110_1010) { u32 n = GetN(op); r[n] = fpscr.full; - UpdateFPSCR(); + //UpdateFPSCR(); } //sts.l FPSCR,@- diff --git a/core/hw/sh4/modules/ccn.cpp b/core/hw/sh4/modules/ccn.cpp index d084f58fc..efb1375a9 100644 --- a/core/hw/sh4/modules/ccn.cpp +++ b/core/hw/sh4/modules/ccn.cpp @@ -8,6 +8,7 @@ #include "../sh4_core.h" #include "hw/pvr/pvr_mem.h" #include "hw/mem/_vmem.h" +#include "hw/mem/vmem32.h" #include "mmu.h" //Types @@ -41,6 +42,16 @@ void CCN_QACR_write(u32 addr, u32 value) } } +void CCN_PTEH_write(u32 addr, u32 value) +{ + CCN_PTEH_type temp; + temp.reg_data = value; + if (temp.ASID != CCN_PTEH.ASID && vmem32_enabled()) + vmem32_flush_mmu(); + + CCN_PTEH = temp; +} + void CCN_MMUCR_write(u32 addr, u32 value) { CCN_MMUCR_type temp; @@ -52,6 +63,8 @@ void CCN_MMUCR_write(u32 addr, u32 value) { //sh4_cpu.ResetCache(); mmu_flush_table(); + if (vmem32_enabled()) + vmem32_flush_mmu(); temp.TI = 0; } @@ -99,7 +112,7 @@ static u32 CCN_PRR_read(u32 addr) void ccn_init() { //CCN PTEH 0xFF000000 0x1F000000 32 Undefined Undefined Held Held Iclk - sh4_rio_reg(CCN,CCN_PTEH_addr,RIO_DATA,32); + sh4_rio_reg(CCN,CCN_PTEH_addr,RIO_WF,32,0,&CCN_PTEH_write); //CCN PTEL 0xFF000004 0x1F000004 32 Undefined Undefined Held Held Iclk sh4_rio_reg(CCN,CCN_PTEL_addr,RIO_DATA,32); diff --git a/core/hw/sh4/sh4_if.h b/core/hw/sh4/sh4_if.h index c9505700b..c6999df96 100644 --- a/core/hw/sh4/sh4_if.h +++ b/core/hw/sh4/sh4_if.h @@ -282,6 +282,9 @@ struct Sh4Context int sh4_sched_next; u32 interrupt_pend; + + u32 exception_pc; + u8 *vmem32_base; }; u64 raw[64-8]; }; diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 43c367b09..347b80235 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -29,6 +29,7 @@ #endif #include #include "hw/sh4/dyna/blockmanager.h" +#include "hw/mem/vmem32.h" #include "linux/context.h" @@ -48,7 +49,7 @@ void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) { context_from_segfault(&ctx, segfault_ctx); unat pc = (unat)ctx.pc; - bool dyna_cde = (pc>(unat)CodeCache) && (pc<(unat)(CodeCache + CODE_SIZE)); + bool dyna_cde = (pc>(unat)CodeCache) && (pc<(unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); printf("SIGILL @ %lx -> %p was not in vram, dynacode:%d\n", pc, si->si_addr, dyna_cde); @@ -64,12 +65,21 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) context_from_segfault(&ctx, segfault_ctx); - bool dyna_cde = ((unat)ctx.pc>(unat)CodeCache) && ((unat)ctx.pc<(unat)(CodeCache + CODE_SIZE)); + bool dyna_cde = ((unat)ctx.pc>(unat)CodeCache) && ((unat)ctx.pc<(unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); //ucontext_t* ctx=(ucontext_t*)ctxr; //printf("mprot hit @ ptr 0x%08X @@ code: %08X, %d\n",si->si_addr,ctx->uc_mcontext.arm_pc,dyna_cde); - +#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) +#if HOST_CPU == CPU_ARM64 + u32 op = *(u32*)ctx.pc; + bool write = (op & 0x00400000) == 0; +#elif HOST_CPU == CPU_X64 + bool write = false; // TODO? +#endif + if (vmem32_handle_signal(si->si_addr, write)) + return; +#endif if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) return; #if FEAT_SHREC == DYNAREC_JIT @@ -91,7 +101,10 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) context_to_segfault(&ctx, segfault_ctx); } #elif HOST_CPU == CPU_X64 - //x64 has no rewrite support + else if (dyna_cde && ngen_Rewrite((unat&)ctx.pc, 0, 0)) + { + context_to_segfault(&ctx, segfault_ctx); + } #elif HOST_CPU == CPU_ARM64 else if (dyna_cde && ngen_Rewrite(ctx.pc, 0, 0)) { diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 388d8418d..d46cee630 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -6,6 +6,7 @@ #include "oslib/oslib.h" #include "oslib/audiostream.h" #include "hw/mem/_vmem.h" +#include "hw/mem/vmem32.h" #include "stdclass.h" #include "cfg/cfg.h" @@ -140,7 +141,9 @@ void LoadSpecialSettings() extra_depth_game = false; full_mmu_game = false; - if (reios_windows_ce) + if (reios_windows_ce + // Half-life + || !strncmp("MK-51035", reios_product_number, 8)) { printf("Enabling Full MMU and Extra depth scaling for Windows CE game\n"); settings.rend.ExtraDepthScale = 0.1; @@ -275,6 +278,13 @@ int reicast_init(int argc, char* argv[]) printf("Failed to alloc mem\n"); return -1; } +#ifdef HOST_64BIT_CPU + if (!vmem32_init()) + { + printf("Failed to alloc 32-bit mem space\n"); + return -1; + } +#endif if (ParseCommandLine(argc, argv)) { return 69; @@ -461,6 +471,7 @@ void InitSettings() settings.dynarec.idleskip = true; settings.dynarec.unstable_opt = false; settings.dynarec.safemode = true; + settings.dynarec.disable_vmem32 = false; settings.dreamcast.cable = 3; // TV composite settings.dreamcast.region = 3; // default settings.dreamcast.broadcast = 4; // default @@ -534,6 +545,7 @@ void LoadSettings(bool game_specific) settings.dynarec.idleskip = cfgLoadBool(config_section, "Dynarec.idleskip", settings.dynarec.idleskip); settings.dynarec.unstable_opt = cfgLoadBool(config_section, "Dynarec.unstable-opt", settings.dynarec.unstable_opt); settings.dynarec.safemode = cfgLoadBool(config_section, "Dynarec.safe-mode", settings.dynarec.safemode); + settings.dynarec.disable_vmem32 = cfgLoadBool(config_section, "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); //disable_nvmem can't be loaded, because nvmem init is before cfg load settings.dreamcast.cable = cfgLoadInt(config_section, "Dreamcast.Cable", settings.dreamcast.cable); settings.dreamcast.region = cfgLoadInt(config_section, "Dreamcast.Region", settings.dreamcast.region); @@ -670,6 +682,7 @@ void SaveSettings() cfgSaveBool("config", "Dynarec.unstable-opt", settings.dynarec.unstable_opt); if (!safemode_game || !settings.dynarec.safemode) cfgSaveBool("config", "Dynarec.safe-mode", settings.dynarec.safemode); + cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language); cfgSaveBool("config", "aica.LimitFPS", settings.aica.LimitFPS); cfgSaveBool("config", "aica.NoBatch", settings.aica.NoBatch); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 74bb3bf1a..a76f796b6 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -39,6 +39,7 @@ using namespace vixl::aarch64; #include "hw/sh4/dyna/ngen.h" #include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_rom.h" +#include "hw/mem/vmem32.h" #include "arm64_regalloc.h" #undef do_sqw_nommu @@ -185,8 +186,8 @@ void ngen_mainloop(void* v_cntx) "stp x29, x30, [sp, #144] \n\t" "stp %[cntx], %[cycle_counter], [sp, #-16]! \n\t" // Push context, cycle_counter address - "mov w27, %[_SH4_TIMESLICE] \n\t" - "str w27, [%[cycle_counter]] \n\t" + "mov w1, %[_SH4_TIMESLICE] \n\t" + "str w1, [%[cycle_counter]] \n\t" "mov x0, %[jmp_env] \n\t" // SETJMP "bl setjmp \n\t" @@ -195,15 +196,17 @@ void ngen_mainloop(void* v_cntx) "ldr x28, [sp] \n\t" // Set context // w29 is next_pc "ldr w29, [x28, %[pc]] \n\t" + // x27 is vmem32_base + "ldr x27, [x28, %[vmem32_base]] \n\t" "b no_update \n" ".hidden intc_sched \n\t" ".globl intc_sched \n\t" "intc_sched: \n\t" - "ldr x27, [sp, #8] \n\t" // &cycle_counter - "ldr w0, [x27] \n\t" // cycle_counter + "ldr x1, [sp, #8] \n\t" // &cycle_counter + "ldr w0, [x1] \n\t" // cycle_counter "add w0, w0, %[_SH4_TIMESLICE] \n\t" - "str w0, [x27] \n\t" + "str w0, [x1] \n\t" "mov x29, lr \n\t" // Trashing pc here but it will be reset at the end of the block or in DoInterrupts "bl UpdateSystem \n\t" "mov lr, x29 \n\t" @@ -260,7 +263,8 @@ void ngen_mainloop(void* v_cntx) [RCB_SIZE] "i" (sizeof(Sh4RCB) >> 16), [SH4CTX_SIZE] "i" (sizeof(Sh4Context)), [jmp_env] "r"(reinterpret_cast(jmp_env)), - [cycle_counter] "r"(reinterpret_cast(&cycle_counter)) + [cycle_counter] "r"(reinterpret_cast(&cycle_counter)), + [vmem32_base] "i"(offsetof(Sh4Context, vmem32_base)) : "memory" ); } @@ -476,10 +480,10 @@ public: regalloc.DoAlloc(block); // scheduler - Mov(x27, reinterpret_cast(&cycle_counter)); - Ldr(w0, MemOperand(x27)); + Mov(x1, reinterpret_cast(&cycle_counter)); + Ldr(w0, MemOperand(x1)); Subs(w0, w0, block->guest_cycles); - Str(w0, MemOperand(x27)); + Str(w0, MemOperand(x1)); Label cycles_remaining; B(&cycles_remaining, pl); GenCallRuntime(intc_sched); @@ -568,11 +572,11 @@ public: break; case shop_readm: - GenReadMemory(op, i); + GenReadMemory(op, i, optimise); break; case shop_writem: - GenWriteMemory(op, i); + GenWriteMemory(op, i, optimise); break; case shop_sync_sr: @@ -1073,10 +1077,10 @@ public: void GenWriteMemorySlow(const shil_opcode& op) { + Instruction *start_instruction = GetCursorAddress(); if (mmu_enabled()) Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - Instruction *start_instruction = GetCursorAddress(); u32 size = op.flags & 0x7f; switch (size) { @@ -1117,7 +1121,10 @@ public: void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) { - regalloc.DoAlloc(block); + this->block = block; + // with full mmu, all regs are flushed before mem ops + if (!mmu_enabled()) + regalloc.DoAlloc(block); regalloc.current_opid = opid; } @@ -1308,14 +1315,14 @@ private: B(&code_label, cond); } - void GenReadMemory(const shil_opcode& op, size_t opid) + void GenReadMemory(const shil_opcode& op, size_t opid, bool optimise) { if (GenReadMemoryImmediate(op)) return; GenMemAddr(op, call_regs[0]); - if (GenReadMemoryFast(op, opid)) + if (optimise && GenReadMemoryFast(op, opid)) return; GenReadMemorySlow(op); @@ -1431,59 +1438,104 @@ private: bool GenReadMemoryFast(const shil_opcode& op, size_t opid) { // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() - if (!_nvmem_enabled() || mmu_enabled()) + if (!_nvmem_enabled() || (mmu_enabled() && !vmem32_enabled())) return false; Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having two ops before the memory access + const XRegister* base_reg; + const XRegister* offset_reg; + // WARNING: the rewrite code relies on having two ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code - Add(w1, *call_regs[0], sizeof(Sh4Context), LeaveFlags); - Bfc(w1, 29, 3); // addr &= ~0xE0000000 + if (!mmu_enabled()) + { + Add(w1, *call_regs[0], sizeof(Sh4Context), LeaveFlags); + Bfc(w1, 29, 3); // addr &= ~0xE0000000 + base_reg = &x28; + offset_reg = &x1; + } + else + { + u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); + // 3 ops before memory access + Mov(w8, exception_pc & 0xFFFF); + Movk(w8, exception_pc >> 16, 16); + Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + base_reg = &x27; + offset_reg = call_regs64[0]; + } //printf("direct read memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); this->block->memory_accesses[GetCursorAddress()] = (u32)opid; u32 size = op.flags & 0x7f; - switch(size) + if (regalloc.IsAllocAny(op.rd)) { - case 1: - Ldrsb(regalloc.MapRegister(op.rd), MemOperand(x28, x1, SXTW)); - break; + switch(size) + { + case 1: + Ldrsb(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + break; - case 2: - Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x28, x1, SXTW)); - break; + case 2: + Ldrsh(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + break; - case 4: - if (!op.rd.is_r32f()) - Ldr(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); - else - Ldr(regalloc.MapVRegister(op.rd), MemOperand(x28, x1)); - break; + case 4: + if (!op.rd.is_r32f()) + Ldr(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + else + Ldr(regalloc.MapVRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + break; - case 8: - Ldr(x1, MemOperand(x28, x1)); - break; - } + case 8: + Ldr(x1, MemOperand(*base_reg, *offset_reg)); + break; + } - if (size == 8) - { + if (size == 8) + { #ifdef EXPLODE_SPANS - verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); - Fmov(regalloc.MapVRegister(op.rd, 0), w1); - Lsr(x1, x1, 32); - Fmov(regalloc.MapVRegister(op.rd, 1), w1); + verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); + Fmov(regalloc.MapVRegister(op.rd, 0), w1); + Lsr(x1, x1, 32); + Fmov(regalloc.MapVRegister(op.rd, 1), w1); #else - Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); + Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); #endif + } + } + else + { + switch(size) + { + case 1: + Ldrsb(w1, MemOperand(*base_reg, *offset_reg)); + break; + + case 2: + Ldrsh(w1, MemOperand(*base_reg, *offset_reg)); + break; + + case 4: + Ldr(w1, MemOperand(*base_reg, *offset_reg)); + break; + + case 8: + Ldr(x1, MemOperand(*base_reg, *offset_reg)); + break; + } + if (size == 8) + Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); + else + Str(w1, sh4_context_mem_operand(op.rd.reg_ptr())); } EnsureCodeSize(start_instruction, read_memory_rewrite_size); return true; } - void GenWriteMemory(const shil_opcode& op, size_t opid) + void GenWriteMemory(const shil_opcode& op, size_t opid, bool optimise) { GenMemAddr(op, call_regs[0]); @@ -1502,7 +1554,7 @@ private: shil_param_to_host_reg(op.rs2, *call_regs64[1]); #endif } - if (GenWriteMemoryFast(op, opid)) + if (optimise && GenWriteMemoryFast(op, opid)) return; GenWriteMemorySlow(op); @@ -1511,15 +1563,31 @@ private: bool GenWriteMemoryFast(const shil_opcode& op, size_t opid) { // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() - if (!_nvmem_enabled() || mmu_enabled()) + if (!_nvmem_enabled() || (mmu_enabled() && !vmem32_enabled())) return false; Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having two ops before the memory access + const XRegister* base_reg; + const XRegister* offset_reg; + // WARNING: the rewrite code relies on having two ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code - Add(w7, *call_regs[0], sizeof(Sh4Context), LeaveFlags); - Bfc(w7, 29, 3); // addr &= ~0xE0000000 + if (!mmu_enabled()) + { + Add(w7, *call_regs[0], sizeof(Sh4Context), LeaveFlags); + Bfc(w7, 29, 3); // addr &= ~0xE0000000 + base_reg = &x28; + offset_reg = &x7; + } + else + { + u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); + Mov(w8, exception_pc & 0xFFFF); + Movk(w8, exception_pc >> 16, 16); + Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + base_reg = &x27; + offset_reg = call_regs64[0]; + } //printf("direct write memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); this->block->memory_accesses[GetCursorAddress()] = (u32)opid; @@ -1528,19 +1596,19 @@ private: switch(size) { case 1: - Strb(w1, MemOperand(x28, x7, SXTW)); + Strb(w1, MemOperand(*base_reg, *offset_reg)); break; case 2: - Strh(w1, MemOperand(x28, x7, SXTW)); + Strh(w1, MemOperand(*base_reg, *offset_reg)); break; case 4: - Str(w1, MemOperand(x28, x7)); + Str(w1, MemOperand(*base_reg, *offset_reg)); break; case 8: - Str(x1, MemOperand(x28, x7)); + Str(x1, MemOperand(*base_reg, *offset_reg)); break; } EnsureCodeSize(start_instruction, write_memory_rewrite_size); @@ -1699,7 +1767,7 @@ private: RuntimeBlockInfo* block = NULL; const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 3; + const int write_memory_rewrite_size = 4; }; static Arm64Assembler* compiler; @@ -1755,7 +1823,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) u32 opid = it->second; verify(opid < block->oplist.size()); const shil_opcode& op = block->oplist[opid]; - Arm64Assembler *assembler = new Arm64Assembler(code_ptr - 2); // Skip the 2 preceding ops (bic, add) + Arm64Assembler *assembler = new Arm64Assembler(code_ptr - 2 - (mmu_enabled() ? 1 : 0)); // Skip the 2 preceding ops (bic, add) assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) assembler->GenReadMemorySlow(op); @@ -1763,11 +1831,16 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) assembler->GenWriteMemorySlow(op); assembler->Finalize(true); delete assembler; - host_pc = (unat)(code_ptr - 2); + host_pc = (unat)(code_ptr - 2 - (mmu_enabled() ? 1 : 0)); return true; } +void ngen_HandleException() +{ + longjmp(jmp_env, 1); +} + u32 DynaRBI::Relink() { if (mmu_enabled()) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 9723ffc43..848cc6d84 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -19,6 +19,7 @@ #include "hw/sh4/sh4_core.h" #include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_rom.h" +#include "hw/mem/vmem32.h" #include "emitter/x86_emitter.h" #include "profiler/profiler.h" #include "oslib/oslib.h" @@ -130,7 +131,6 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") "lea " _U "jmp_env(%rip), %rdi \n\t" #endif "call " _U "setjmp \n\t" -// "testl %rax, %rax \n\t" "1: \n\t" // run_loop "movq " _U "p_sh4rcb(%rip), %rax \n\t" @@ -219,13 +219,8 @@ static void ngen_blockcheckfail(u32 pc) { rdv_BlockCheckFail(pc); } -static u32 exception_raised; - -template -static T ReadMemNoEx(u32 addr, u32 pc) +static void handle_mem_exception(u32 exception_raised, u32 pc) { -#ifndef NO_MMU - T rv = mmu_ReadMemNoEx(addr, &exception_raised); if (exception_raised) { if (pc & 1) @@ -233,8 +228,19 @@ static T ReadMemNoEx(u32 addr, u32 pc) spc = pc - 1; else spc = pc; + cycle_counter += CPU_RATIO * 2; // probably more is needed but no easy way to find out longjmp(jmp_env, 1); } +} + +template +static T ReadMemNoEx(u32 addr, u32 pc) +{ +#ifndef NO_MMU + u32 exception_raised; + T rv = mmu_ReadMemNoEx(addr, &exception_raised); + handle_mem_exception(exception_raised, pc); + return rv; #else // not used @@ -246,32 +252,30 @@ template static void WriteMemNoEx(u32 addr, T data, u32 pc) { #ifndef NO_MMU - exception_raised = mmu_WriteMemNoEx(addr, data); - if (exception_raised) - { - if (pc & 1) - // Delay slot - spc = pc - 1; - else - spc = pc; - longjmp(jmp_env, 1); - } + u32 exception_raised = mmu_WriteMemNoEx(addr, data); + handle_mem_exception(exception_raised, pc); #endif } +static void handle_sh4_exception(SH4ThrownException& ex, u32 pc) +{ + if (pc & 1) + { + // Delay slot + AdjustDelaySlotException(ex); + pc--; + } + Do_Exception(pc, ex.expEvn, ex.callVect); + cycle_counter += CPU_RATIO * 4; // probably more is needed + longjmp(jmp_env, 1); +} + static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) { try { oph(op); } catch (SH4ThrownException& ex) { - if (pc & 1) - { - // Delay slot - AdjustDelaySlotException(ex); - pc--; - } - Do_Exception(pc, ex.expEvn, ex.callVect); - longjmp(jmp_env, 1); + handle_sh4_exception(ex, pc); } } @@ -279,16 +283,8 @@ static void do_sqw_mmu_no_ex(u32 addr, u32 pc) { try { do_sqw_mmu(addr); - exception_raised = 0; } catch (SH4ThrownException& ex) { - if (pc & 1) - { - // Delay slot - AdjustDelaySlotException(ex); - pc--; - } - Do_Exception(pc, ex.expEvn, ex.callVect); - exception_raised = 1; + handle_sh4_exception(ex, pc); } } @@ -300,7 +296,9 @@ static void do_sqw_nommu_local(u32 addr, u8* sqb) class BlockCompiler : public Xbyak::CodeGenerator { public: - BlockCompiler() : Xbyak::CodeGenerator(emit_FreeSpace(), emit_GetCCPtr()), regalloc(this) + BlockCompiler() : BlockCompiler((u8 *)emit_GetCCPtr()) {} + + BlockCompiler(u8 *code_ptr) : Xbyak::CodeGenerator(emit_FreeSpace(), code_ptr), regalloc(this) { #if HOST_OS == OS_WINDOWS call_regs.push_back(ecx); @@ -333,17 +331,11 @@ public: void compile(RuntimeBlockInfo* block, bool force_checks, bool reset, bool staging, bool optimise) { //printf("X86_64 compiling %08x to %p\n", block->addr, emit_GetCCPtr()); + current_opid = -1; if (force_checks) { CheckBlock(block); } - regalloc.DoAlloc(block); - sub(dword[rip + &cycle_counter], block->guest_cycles); -#ifdef PROFILING - mov(rax, (uintptr_t)&guest_cpu_cycles); - mov(ecx, block->guest_cycles); - add(qword[rax], rcx); -#endif #ifdef _WIN32 sub(rsp, 0x28); // 32-byte shadow space + 8 byte alignment #else @@ -364,6 +356,13 @@ public: jmp(exit_block, T_NEAR); L(fpu_enabled); } + sub(dword[rip + &cycle_counter], block->guest_cycles); +#ifdef PROFILING + mov(rax, (uintptr_t)&guest_cpu_cycles); + mov(ecx, block->guest_cycles); + add(qword[rax], rcx); +#endif + regalloc.DoAlloc(block); for (current_opid = 0; current_opid < block->oplist.size(); current_opid++) { @@ -440,98 +439,7 @@ public: break; case shop_readm: - { - u32 size = op.flags & 0x7f; - bool immediate_address = op.rs1.is_imm(); - u32 addr = op.rs1._imm; - if (immediate_address && mmu_enabled()) - { - if ((op.rs1._imm >> 12) != (block->vaddr >> 12)) - { - // When full mmu is on, only consider addresses in the same 4k page - immediate_address = false; - } - else - { - u32 paddr; - u32 rv; - if (size == 2) - rv = mmu_data_translation(addr, paddr); - else if (size == 4) - rv = mmu_data_translation(addr, paddr); - else - die("Invalid immediate size"); - if (rv != MMU_ERROR_NONE) - immediate_address = false; - else - addr = paddr; - } - } - if (immediate_address) - { - bool isram = false; - void* ptr = _vmem_read_const(addr, isram, size); - - if (isram) - { - // Immediate pointer to RAM: super-duper fast access - mov(rax, reinterpret_cast(ptr)); - switch (size) - { - case 2: - if (regalloc.IsAllocg(op.rd)) - movsx(regalloc.MapRegister(op.rd), word[rax]); - else - { - movsx(eax, word[rax]); - mov(rcx, (uintptr_t)op.rd.reg_ptr()); - mov(dword[rcx], eax); - } - break; - - case 4: - if (regalloc.IsAllocg(op.rd)) - mov(regalloc.MapRegister(op.rd), dword[rax]); - else if (regalloc.IsAllocf(op.rd)) - movd(regalloc.MapXRegister(op.rd), dword[rax]); - else - { - mov(eax, dword[rax]); - mov(rcx, (uintptr_t)op.rd.reg_ptr()); - mov(dword[rcx], eax); - } - break; - - default: - die("Invalid immediate size"); - break; - } - } - else - { - // Not RAM: the returned pointer is a memory handler - mov(call_regs[0], addr); - - switch(size) - { - case 2: - GenCall((void (*)())ptr); - movsx(ecx, ax); - break; - - case 4: - GenCall((void (*)())ptr); - mov(ecx, eax); - break; - - default: - die("Invalid immediate size"); - break; - } - host_reg_to_shil_param(op.rd, ecx); - } - } - else + if (!GenReadMemImmediate(op, block)) { // Not an immediate address shil_param_to_host_reg(op.rs1, call_regs[0]); @@ -547,47 +455,10 @@ public: add(call_regs[0], dword[rax]); } } - if (mmu_enabled()) - mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - - if (size == 1) { - if (!mmu_enabled()) - GenCall(ReadMem8); - else - GenCall(ReadMemNoEx); - movsx(ecx, al); - } - else if (size == 2) { - if (!mmu_enabled()) - GenCall(ReadMem16); - else - GenCall(ReadMemNoEx); - movsx(ecx, ax); - } - else if (size == 4) { - if (!mmu_enabled()) - GenCall(ReadMem32); - else - GenCall(ReadMemNoEx); - mov(ecx, eax); - } - else if (size == 8) { - if (!mmu_enabled()) - GenCall(ReadMem64); - else - GenCall(ReadMemNoEx); - mov(rcx, rax); - } - else { - die("1..8 bytes"); - } - -// if (mmu_enabled()) -// { -// test(dword[(void *)&exception_raised], 1); -// jnz(exit_block, T_NEAR); -// } + if (!optimise || !GenReadMemoryFast(op, block)) + GenReadMemorySlow(op, block); + u32 size = op.flags & 0x7f; if (size != 8) host_reg_to_shil_param(op.rd, ecx); else { @@ -606,12 +477,10 @@ public: } } } - } - break; + break; case shop_writem: { - u32 size = op.flags & 0x7f; shil_param_to_host_reg(op.rs1, call_regs[0]); if (!op.rs3.is_null()) { @@ -626,6 +495,7 @@ public: } } + u32 size = op.flags & 0x7f; if (size != 8) shil_param_to_host_reg(op.rs2, call_regs[1]); else { @@ -644,42 +514,8 @@ public: mov(call_regs64[1], qword[rax]); } } - if (mmu_enabled()) - mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - - if (size == 1) { - if (!mmu_enabled()) - GenCall(WriteMem8); - else - GenCall(WriteMemNoEx); - } - else if (size == 2) { - if (!mmu_enabled()) - GenCall(WriteMem16); - else - GenCall(WriteMemNoEx); - } - else if (size == 4) { - if (!mmu_enabled()) - GenCall(WriteMem32); - else - GenCall(WriteMemNoEx); - } - else if (size == 8) { - if (!mmu_enabled()) - GenCall(WriteMem64); - else - GenCall(WriteMemNoEx); - } - else { - die("1..8 bytes"); - } - -// if (mmu_enabled()) -// { -// test(dword[(void *)&exception_raised], 1); -// jnz(exit_block, T_NEAR); -// } + if (!optimise || !GenWriteMemoryFast(op, block)) + GenWriteMemorySlow(op, block); } break; @@ -729,8 +565,8 @@ public: mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); \ if (op.rs2.is_imm()) \ natop(regalloc.MapRegister(op.rd), op.rs2._imm); \ - else if (op.rs2.is_reg()) \ - natop(regalloc.MapRegister(op.rd), Xbyak::Reg8(regalloc.MapRegister(op.rs2).getIdx())); + else \ + die("Unsupported operand"); case shop_shl: SHIFT_OP(shl) break; @@ -925,9 +761,6 @@ public: mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc GenCall(do_sqw_mmu_no_ex); - - test(dword[(void *)&exception_raised], 1); - jnz(exit_block, T_NEAR); } else { @@ -1163,6 +996,7 @@ public: regalloc.OpEnd(&op); } regalloc.Cleanup(); + current_opid = -1; mov(rax, (size_t)&next_pc); @@ -1242,6 +1076,118 @@ public: emit_Skip(getSize()); } + void GenReadMemorySlow(const shil_opcode& op, RuntimeBlockInfo* block) + { + const u8 *start_addr = getCurr(); + if (mmu_enabled()) + mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + u32 size = op.flags & 0x7f; + switch (size) { + case 1: + if (!mmu_enabled()) + GenCall(ReadMem8); + else + GenCall(ReadMemNoEx); + movsx(ecx, al); + break; + case 2: + if (!mmu_enabled()) + GenCall(ReadMem16); + else + GenCall(ReadMemNoEx); + movsx(ecx, ax); + break; + + case 4: + if (!mmu_enabled()) + GenCall(ReadMem32); + else + GenCall(ReadMemNoEx); + mov(ecx, eax); + break; + case 8: + if (!mmu_enabled()) + GenCall(ReadMem64); + else + GenCall(ReadMemNoEx); + mov(rcx, rax); + break; + default: + die("1..8 bytes"); + } + + if (mmu_enabled()) + { + Xbyak::Label quick_exit; + if (getCurr() - start_addr <= read_mem_op_size - 6) + jmp(quick_exit, T_NEAR); + while (getCurr() - start_addr < read_mem_op_size) + nop(); + L(quick_exit); + verify(getCurr() - start_addr == read_mem_op_size); + } + } + + void GenWriteMemorySlow(const shil_opcode& op, RuntimeBlockInfo* block) + { + const u8 *start_addr = getCurr(); + if (mmu_enabled()) + mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + u32 size = op.flags & 0x7f; + switch (size) { + case 1: + if (!mmu_enabled()) + GenCall(WriteMem8); + else + GenCall(WriteMemNoEx); + break; + case 2: + if (!mmu_enabled()) + GenCall(WriteMem16); + else + GenCall(WriteMemNoEx); + break; + case 4: + if (!mmu_enabled()) + GenCall(WriteMem32); + else + GenCall(WriteMemNoEx); + break; + case 8: + if (!mmu_enabled()) + GenCall(WriteMem64); + else + GenCall(WriteMemNoEx); + break; + default: + die("1..8 bytes"); + } + if (mmu_enabled()) + { + Xbyak::Label quick_exit; + if (getCurr() - start_addr <= write_mem_op_size - 6) + jmp(quick_exit, T_NEAR); + while (getCurr() - start_addr < write_mem_op_size) + nop(); + L(quick_exit); + verify(getCurr() - start_addr == write_mem_op_size); + } + } + + void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) + { + // shouldn't be necessary since all regs are flushed before mem access when mmu is enabled + //regalloc.DoAlloc(block); + regalloc.current_opid = opid; + } + + void FinalizeRewrite() + { + ready(); + } + void ngen_CC_Start(const shil_opcode& op) { CC_pars.clear(); @@ -1346,16 +1292,188 @@ private: typedef void (BlockCompiler::*X64BinaryOp)(const Xbyak::Operand&, const Xbyak::Operand&); typedef void (BlockCompiler::*X64BinaryFOp)(const Xbyak::Xmm&, const Xbyak::Operand&); + bool GenReadMemImmediate(const shil_opcode& op, RuntimeBlockInfo* block) + { + if (!op.rs1.is_imm()) + return false; + u32 size = op.flags & 0x7f; + u32 addr = op.rs1._imm; + if (mmu_enabled()) + { + if ((addr >> 12) != (block->vaddr >> 12)) + // When full mmu is on, only consider addresses in the same 4k page + return false; + + u32 paddr; + u32 rv; + if (size == 2) + rv = mmu_data_translation(addr, paddr); + else if (size == 4) + rv = mmu_data_translation(addr, paddr); + else + die("Invalid immediate size"); + if (rv != MMU_ERROR_NONE) + return false; + + addr = paddr; + } + bool isram = false; + void* ptr = _vmem_read_const(addr, isram, size); + + if (isram) + { + // Immediate pointer to RAM: super-duper fast access + mov(rax, reinterpret_cast(ptr)); + switch (size) + { + case 2: + if (regalloc.IsAllocg(op.rd)) + movsx(regalloc.MapRegister(op.rd), word[rax]); + else + { + movsx(eax, word[rax]); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); + } + break; + + case 4: + if (regalloc.IsAllocg(op.rd)) + mov(regalloc.MapRegister(op.rd), dword[rax]); + else if (regalloc.IsAllocf(op.rd)) + movd(regalloc.MapXRegister(op.rd), dword[rax]); + else + { + mov(eax, dword[rax]); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); + } + break; + + default: + die("Invalid immediate size"); + break; + } + } + else + { + // Not RAM: the returned pointer is a memory handler + mov(call_regs[0], addr); + + switch(size) + { + case 2: + GenCall((void (*)())ptr); + movsx(ecx, ax); + break; + + case 4: + GenCall((void (*)())ptr); + mov(ecx, eax); + break; + + default: + die("Invalid immediate size"); + break; + } + host_reg_to_shil_param(op.rd, ecx); + } + + return true; + } + + bool GenReadMemoryFast(const shil_opcode& op, RuntimeBlockInfo* block) + { + if (!mmu_enabled() || !vmem32_enabled()) + return false; + const u8 *start_addr = getCurr(); + + mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); + mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); + + mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); + + u32 size = op.flags & 0x7f; + verify(getCurr() - start_addr == 26); + + block->memory_accesses[(void*)getCurr()] = (u32)current_opid; + switch (size) + { + case 1: + movsx(ecx, byte[rax + call_regs64[0]]); + break; + + case 2: + movsx(ecx, word[rax + call_regs64[0]]); + break; + + case 4: + mov(ecx, dword[rax + call_regs64[0]]); + break; + + case 8: + mov(rcx, qword[rax + call_regs64[0]]); + break; + + default: + die("1..8 bytes"); + } + + while (getCurr() - start_addr < read_mem_op_size) + nop(); + verify(getCurr() - start_addr == read_mem_op_size); + + return true; + } + + bool GenWriteMemoryFast(const shil_opcode& op, RuntimeBlockInfo* block) + { + if (!mmu_enabled() || !vmem32_enabled()) + return false; + const u8 *start_addr = getCurr(); + + mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); + mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); + + mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); + + u32 size = op.flags & 0x7f; + verify(getCurr() - start_addr == 26); + + block->memory_accesses[(void*)getCurr()] = (u32)current_opid; + switch (size) + { + case 1: + mov(byte[rax + call_regs64[0] + 0], Xbyak::Reg8(call_regs[1].getIdx(), call_regs[1] == edi || call_regs[1] == esi)); + break; + + case 2: + mov(word[rax + call_regs64[0]], Xbyak::Reg16(call_regs[1].getIdx())); + break; + + case 4: + mov(dword[rax + call_regs64[0]], call_regs[1]); + break; + + case 8: + mov(qword[rax + call_regs64[0]], call_regs64[1]); + break; + + default: + die("1..8 bytes"); + } + + while (getCurr() - start_addr < write_mem_op_size) + nop(); + verify(getCurr() - start_addr == write_mem_op_size); + + return true; + } + void CheckBlock(RuntimeBlockInfo* block) { mov(call_regs[0], block->addr); -// if (mmu_enabled() && block->asid != 0xFFFFFFFF) -// { -// mov(rax, (uintptr_t)&CCN_PTEH.reg_data); -// cmp(byte[rax], block->asid); -// jne(reinterpret_cast(&ngen_blockcheckfail)); -// } - // FIXME Neither of these tests should be necessary + // FIXME This test shouldn't be necessary // However the decoder makes various assumptions about the current PC value, which are simply not // true in a virtualized memory model. So this can only work if virtual and phy addresses are the // same at compile and run times. @@ -1424,10 +1542,10 @@ private: void GenCall(Ret(*function)(Params...)) { #ifndef _WIN32 - bool xmm8_mapped = regalloc.IsMapped(xmm8, current_opid); - bool xmm9_mapped = regalloc.IsMapped(xmm9, current_opid); - bool xmm10_mapped = regalloc.IsMapped(xmm10, current_opid); - bool xmm11_mapped = regalloc.IsMapped(xmm11, current_opid); + bool xmm8_mapped = current_opid != -1 && regalloc.IsMapped(xmm8, current_opid); + bool xmm9_mapped = current_opid != -1 && regalloc.IsMapped(xmm9, current_opid); + bool xmm10_mapped = current_opid != -1 && regalloc.IsMapped(xmm10, current_opid); + bool xmm11_mapped = current_opid != -1 && regalloc.IsMapped(xmm11, current_opid); // Need to save xmm registers as they are not preserved in linux/mach int offset = 0; @@ -1587,11 +1705,15 @@ private: static const u32 float_sign_mask; static const u32 float_abs_mask; static const f32 cvtf2i_pos_saturation; + static const u32 read_mem_op_size; + static const u32 write_mem_op_size; }; const u32 BlockCompiler::float_sign_mask = 0x80000000; const u32 BlockCompiler::float_abs_mask = 0x7fffffff; const f32 BlockCompiler::cvtf2i_pos_saturation = 2147483520.0f; // IEEE 754: 0x4effffff; +const u32 BlockCompiler::read_mem_op_size = 30; +const u32 BlockCompiler::write_mem_op_size = 30; void X64RegAlloc::Preload(u32 reg, Xbyak::Operand::Code nreg) { @@ -1641,4 +1763,47 @@ void ngen_CC_Call(shil_opcode* op, void* function) void ngen_CC_Finish(shil_opcode* op) { } + +bool ngen_Rewrite(unat& host_pc, unat, unat) +{ + if (!mmu_enabled() || !vmem32_enabled()) + return false; + + //printf("ngen_Rewrite pc %p\n", host_pc); + RuntimeBlockInfo *block = bm_GetBlock((void *)host_pc); + if (block == NULL) + { + printf("ngen_Rewrite: Block at %p not found\n", (void *)host_pc); + return false; + } + u8 *code_ptr = (u8*)host_pc; + auto it = block->memory_accesses.find(code_ptr); + if (it == block->memory_accesses.end()) + { + printf("ngen_Rewrite: memory access at %p not found (%lu entries)\n", code_ptr, block->memory_accesses.size()); + return false; + } + u32 opid = it->second; + verify(opid < block->oplist.size()); + const shil_opcode& op = block->oplist[opid]; + + BlockCompiler *assembler = new BlockCompiler(code_ptr - 26); + assembler->InitializeRewrite(block, opid); + if (op.op == shop_readm) + assembler->GenReadMemorySlow(op, block); + else + assembler->GenWriteMemorySlow(op, block); + assembler->FinalizeRewrite(); + verify(block->host_code_size >= assembler->getSize()); + delete assembler; + block->memory_accesses.erase(it); + host_pc = (unat)(code_ptr - 26); + + return true; +} + +void ngen_HandleException() +{ + longjmp(jmp_env, 1); +} #endif diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index b0480c273..dba4825fd 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -7,6 +7,8 @@ #include "TexCache.h" #include "hw/pvr/pvr_regs.h" #include "hw/mem/_vmem.h" +#include "hw/mem/vmem32.h" +#include "hw/sh4/modules/mmu.h" #include "deps/xbrz/xbrz.h" #include "deps/xxhash/xxhash.h" @@ -213,6 +215,8 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { vram.LockRegion(block->start + VRAM_SIZE, block->len); } + if (mmu_enabled()) + vmem32_protect_vram(block); vramlock_list_add(block); @@ -222,11 +226,8 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user return block; } - -bool VramLockedWrite(u8* address) +bool VramLockedWriteOffset(size_t offset) { - size_t offset=address-vram.data; - if (offset, u16>(PixelBuffer* pb,u8* p_in, #define tex1555_VQ32 texture_VQ, u32> #define tex4444_VQ32 texture_VQ, u32> -#define Is_64_Bit(addr) ((addr &0x1000000)==0) - -//vram_block, vramLockCBFP on plugin headers - - -u32 vramlock_ConvAddrtoOffset64(u32 Address); -u32 vramlock_ConvOffset32toOffset64(u32 offset32); - -void vramlock_Unlock_block(vram_block* block); -vram_block* vramlock_Lock_32(u32 start_offset32,u32 end_offset32,void* userdata); -vram_block* vramlock_Lock_64(u32 start_offset64,u32 end_offset64,void* userdata); - -void vram_LockedWrite(u32 offset64); - void DePosterize(u32* source, u32* dest, int width, int height); void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool has_alpha); diff --git a/core/types.h b/core/types.h index e082e13b0..ec6ed7a43 100644 --- a/core/types.h +++ b/core/types.h @@ -736,6 +736,7 @@ struct settings_t bool unstable_opt; bool safemode; bool disable_nvmem; + bool disable_vmem32; } dynarec; struct diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index d54e44a97..5250a0443 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -1,6 +1,7 @@ #include "oslib\oslib.h" #include "oslib\audiostream.h" #include "imgread\common.h" +#include "hw\mem\vmem32.h" #include "xinput_gamepad.h" #include "win_keyboard.h" @@ -141,6 +142,11 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) u8* address=(u8*)pExceptionRecord->ExceptionInformation[1]; //printf("[EXC] During access to : 0x%X\n", address); +#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) + bool write = false; // TODO? + if (vmem32_handle_signal(ep->ContextRecord->Rcx, write)) + return EXCEPTION_CONTINUE_EXECUTION; +#endif if (VramLockedWrite(address)) { @@ -152,7 +158,8 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) return EXCEPTION_CONTINUE_EXECUTION; } #endif -#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 +#if FEAT_SHREC == DYNAREC_JIT +#if HOST_CPU == CPU_X86 else if ( ngen_Rewrite((unat&)ep->ContextRecord->Eip,*(unat*)ep->ContextRecord->Esp,ep->ContextRecord->Eax) ) { //remove the call from call stack @@ -161,6 +168,11 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) ep->ContextRecord->Ecx=ep->ContextRecord->Eax; return EXCEPTION_CONTINUE_EXECUTION; } +#elif HOST_CPU == CPU_X64 + else if (dyna_cde && ngen_Rewrite((unat&)ep->ContextRecord->Rip, 0, 0)) + { + return EXCEPTION_CONTINUE_EXECUTION; + } #endif else { @@ -576,7 +588,7 @@ _In_opt_ PVOID Context // (DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache); /* Set its scope to the entire program. */ Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase); - Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE; + Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE; Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache); printf("TABLE CALLBACK\n"); //for (;;); @@ -605,13 +617,13 @@ void setup_seh() { //(DWORD)((u8 *)__gnat_SEH_error_handler - CodeCache); /* Set its scope to the entire program. */ Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase); - Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE; + Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE; Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache); /* Register the unwind information. */ RtlAddFunctionTable(Table, 1, (DWORD64)CodeCache); #endif - //verify(RtlInstallFunctionTableCallback((unat)CodeCache | 0x3, (DWORD64)CodeCache, CODE_SIZE, seh_callback, 0, 0)); + //verify(RtlInstallFunctionTableCallback((unat)CodeCache | 0x3, (DWORD64)CodeCache, CODE_SIZE + TEMP_CODE_SIZE, seh_callback, 0, 0)); } #endif From 4f4d99872b3c5ea61f19608256b548f665ac5db2 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 29 Apr 2019 18:33:14 +0200 Subject: [PATCH 017/158] win32 build fix --- core/hw/mem/vmem32.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 472fc561d..32f5fa7f9 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -104,38 +104,32 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w static void vmem32_unmap_buffer(u32 start, u64 end) { -#if HOST_OS == OS_LINUX - mmap(&vmem32_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); -#elif HOST_OS == OS_WINDOWS +#if HOST_OS == OS_WINDOWS VirtualAlloc(&vmem32_base[start], end - start, MEM_RESERVE, PAGE_NOACCESS); #else -#error Unsupported OS + mmap(&vmem32_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); #endif } static void vmem32_protect_buffer(u32 start, u32 size) { verify((start & PAGE_MASK) == 0); -#if HOST_OS == OS_LINUX - mprotect(&vmem32_base[start], size, PROT_READ); -#elif HOST_OS == OS_WINDOWS +#if HOST_OS == OS_WINDOWS DWORD old; VirtualProtect(vmem32_base + start, end - start, PAGE_READONLY, &old); #else -#error Unsupported OS + mprotect(&vmem32_base[start], size, PROT_READ); #endif } static void vmem32_unprotect_buffer(u32 start, u32 size) { verify((start & PAGE_MASK) == 0); -#if HOST_OS == OS_LINUX - mprotect(&vmem32_base[start], size, PROT_READ | PROT_WRITE); -#elif HOST_OS == OS_WINDOWS +#if HOST_OS == OS_WINDOWS DWORD old; VirtualProtect(vmem32_base + start, end - start, PAGE_READWRITE, &old); #else -#error Unsupported OS + mprotect(&vmem32_base[start], size, PROT_READ | PROT_WRITE); #endif } @@ -359,18 +353,16 @@ bool vmem32_init() if (!_nvmem_enabled()) return false; #ifdef HOST_64BIT_CPU -#if HOST_OS == OS_LINUX - void* rv = mmap(0, VMEM32_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); - verify(rv != NULL); - munmap(rv, VMEM32_SIZE); - vmem32_base = (u8*)rv; -#elif HOST_OS == OS_WINDOWS +#if HOST_OS == OS_WINDOWS void* rv = (u8 *)VirtualAlloc(0, VMEM32_SIZE, MEM_RESERVE, PAGE_NOACCESS); if (rv != NULL) VirtualFree(rv, 0, MEM_RELEASE); vmem32_base = (u8*)rv; #else -#error Unsupported OS + void* rv = mmap(0, VMEM32_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + verify(rv != NULL); + munmap(rv, VMEM32_SIZE); + vmem32_base = (u8*)rv; #endif vmem32_unmap_buffer(0, VMEM32_SIZE); @@ -389,7 +381,11 @@ void vmem32_term() { if (vmem32_base != NULL) { +#if HOST_OS == OS_WINDOWS + VirtualFree(vmem32_base, 0, MEM_RELEASE); +#else munmap(vmem32_base, VMEM32_SIZE); +#endif vmem32_base = NULL; } } From 920a93b19cae05b278b9c231e89b6ad6de0b70fc Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 29 Apr 2019 18:38:28 +0200 Subject: [PATCH 018/158] more win32 fix --- core/hw/mem/vmem32.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 32f5fa7f9..811cfd239 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -116,7 +116,7 @@ static void vmem32_protect_buffer(u32 start, u32 size) verify((start & PAGE_MASK) == 0); #if HOST_OS == OS_WINDOWS DWORD old; - VirtualProtect(vmem32_base + start, end - start, PAGE_READONLY, &old); + VirtualProtect(vmem32_base + start, size, PAGE_READONLY, &old); #else mprotect(&vmem32_base[start], size, PROT_READ); #endif @@ -127,7 +127,7 @@ static void vmem32_unprotect_buffer(u32 start, u32 size) verify((start & PAGE_MASK) == 0); #if HOST_OS == OS_WINDOWS DWORD old; - VirtualProtect(vmem32_base + start, end - start, PAGE_READWRITE, &old); + VirtualProtect(vmem32_base + start, size, PAGE_READWRITE, &old); #else mprotect(&vmem32_base[start], size, PROT_READ | PROT_WRITE); #endif From f0fab09d7c8e613775c5c8dd8185261be3b740a6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 29 Apr 2019 18:49:31 +0200 Subject: [PATCH 019/158] yet more win32 fix --- core/windows/winmain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 5250a0443..ef996872b 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -169,10 +169,11 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) return EXCEPTION_CONTINUE_EXECUTION; } #elif HOST_CPU == CPU_X64 - else if (dyna_cde && ngen_Rewrite((unat&)ep->ContextRecord->Rip, 0, 0)) + else if (ngen_Rewrite((unat&)ep->ContextRecord->Rip, 0, 0)) { return EXCEPTION_CONTINUE_EXECUTION; } +#endif #endif else { From 0d19da2b4b6c2e4e2db17b2a3c69cde6a37860eb Mon Sep 17 00:00:00 2001 From: flyinghead Date: Tue, 30 Apr 2019 17:43:21 +0200 Subject: [PATCH 020/158] wince: disable vmem32 on windows --- core/hw/mem/vmem32.cpp | 27 +++++++++++++++++++++++---- core/hw/mem/vmem32.h | 4 ++++ core/windows/winmain.cpp | 4 ++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 811cfd239..e7236cffa 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -53,8 +53,8 @@ static const u64 AREA7_ADDRESS = 0x7C000000L; #define VRAM_PROT_SEGMENT (1024 * 1024) // vram protection regions are grouped by 1MB segment u8* vmem32_base; -unordered_set vram_mapped_pages; -vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +std::unordered_set vram_mapped_pages; +std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; // stats u64 vmem32_page_faults; @@ -105,7 +105,7 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w static void vmem32_unmap_buffer(u32 start, u64 end) { #if HOST_OS == OS_WINDOWS - VirtualAlloc(&vmem32_base[start], end - start, MEM_RESERVE, PAGE_NOACCESS); + UnmapViewOfFile(&vmem32_base[start]); #else mmap(&vmem32_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); #endif @@ -352,6 +352,10 @@ bool vmem32_init() { if (!_nvmem_enabled()) return false; +#if HOST_OS == OS_WINDOWS + // disabled on windows for now + return true; +#endif #ifdef HOST_64BIT_CPU #if HOST_OS == OS_WINDOWS void* rv = (u8 *)VirtualAlloc(0, VMEM32_SIZE, MEM_RESERVE, PAGE_NOACCESS); @@ -382,7 +386,22 @@ void vmem32_term() if (vmem32_base != NULL) { #if HOST_OS == OS_WINDOWS - VirtualFree(vmem32_base, 0, MEM_RELEASE); + vmem32_flush_mmu(); + // Aica ram + vmem32_unmap_buffer(0x80800000, 0x80800000 + 0x00800000); // P1 + vmem32_unmap_buffer(0x82800000, 0x82800000 + ARAM_SIZE); + vmem32_unmap_buffer(0xA0800000, 0xA0800000 + 0x00800000); // P2 + vmem32_unmap_buffer(0xA2800000, 0xA2800000 + ARAM_SIZE); + + // Vram + vmem32_unmap_buffer(0x84000000, 0x84000000 + 0x01000000); // P1 + vmem32_unmap_buffer(0x86000000, 0x86000000 + 0x01000000); + vmem32_unmap_buffer(0xA4000000, 0xA4000000 + 0x01000000); // P2 + vmem32_unmap_buffer(0xA6000000, 0xA6000000 + 0x01000000); + + // System ram + vmem32_unmap_buffer(0x8C000000, 0x8C000000 + 0x04000000); // P1 + vmem32_unmap_buffer(0xAC000000, 0xAC000000 + 0x04000000); // P2 #else munmap(vmem32_base, VMEM32_SIZE); #endif diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index 692d25b5e..f900c472f 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -7,5 +7,9 @@ void vmem32_flush_mmu(); void vmem32_protect_vram(vram_block *block); void vmem32_unprotect_vram(vram_block *block); static inline bool vmem32_enabled() { +#if HOST_OS == OS_WINDOWS + return false; +#else return !settings.dynarec.disable_vmem32; +#endif } diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index ef996872b..fe7b9f137 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -142,9 +142,9 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) u8* address=(u8*)pExceptionRecord->ExceptionInformation[1]; //printf("[EXC] During access to : 0x%X\n", address); -#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) +#if 0 bool write = false; // TODO? - if (vmem32_handle_signal(ep->ContextRecord->Rcx, write)) + if (vmem32_handle_signal(address, write)) return EXCEPTION_CONTINUE_EXECUTION; #endif From f2696a4b47cd0e2bdf44bf6c73a8b07178756508 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 3 May 2019 11:53:14 +0200 Subject: [PATCH 021/158] osx: add new files to project --- core/linux/common.cpp | 2 +- .../reicast-osx.xcodeproj/project.pbxproj | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 347b80235..b4a1cc0b2 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -70,7 +70,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) //ucontext_t* ctx=(ucontext_t*)ctxr; //printf("mprot hit @ ptr 0x%08X @@ code: %08X, %d\n",si->si_addr,ctx->uc_mcontext.arm_pc,dyna_cde); -#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) +#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) && HOST_OS != OS_WINDOWS #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; bool write = (op & 0x00400000) == 0; diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index b50789eb9..2cd7768a6 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -266,6 +266,8 @@ AEE6278E2224762000EC7E89 /* imgui_impl_opengl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6278B2224762000EC7E89 /* imgui_impl_opengl3.cpp */; }; AEE6279422247C0A00EC7E89 /* gui_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6279222247C0A00EC7E89 /* gui_util.cpp */; }; AEE6279622247C2B00EC7E89 /* keyboard_device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEE6279522247C2B00EC7E89 /* keyboard_device.cpp */; }; + AEF25642227C441F00348550 /* vmem32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEF25640227C441F00348550 /* vmem32.cpp */; }; + AEF25646227C442F00348550 /* fastmmu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEF25644227C442F00348550 /* fastmmu.cpp */; }; AEFF7ECC214AEC810068CE11 /* modem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EC7214AEC800068CE11 /* modem.cpp */; }; AEFF7F4D214D9D590068CE11 /* pico_arp.c in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EFA214D9D590068CE11 /* pico_arp.c */; }; AEFF7F4E214D9D590068CE11 /* pico_dev_ppp.c in Sources */ = {isa = PBXBuildFile; fileRef = AEFF7EFE214D9D590068CE11 /* pico_dev_ppp.c */; }; @@ -803,6 +805,11 @@ AEE6279222247C0A00EC7E89 /* gui_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gui_util.cpp; sourceTree = ""; }; AEE6279322247C0A00EC7E89 /* gui_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gui_util.h; sourceTree = ""; }; AEE6279522247C2B00EC7E89 /* keyboard_device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keyboard_device.cpp; sourceTree = ""; }; + AEF25640227C441F00348550 /* vmem32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vmem32.cpp; sourceTree = ""; }; + AEF25641227C441F00348550 /* vmem32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmem32.h; sourceTree = ""; }; + AEF25643227C442F00348550 /* mmu_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mmu_impl.h; sourceTree = ""; }; + AEF25644227C442F00348550 /* fastmmu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fastmmu.cpp; sourceTree = ""; }; + AEF25645227C442F00348550 /* wince.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wince.h; sourceTree = ""; }; AEFF7EC7214AEC800068CE11 /* modem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = modem.cpp; sourceTree = ""; }; AEFF7EC8214AEC800068CE11 /* modem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modem.h; sourceTree = ""; }; AEFF7EC9214AEC800068CE11 /* modem_regs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = modem_regs.h; sourceTree = ""; }; @@ -1355,6 +1362,8 @@ 84B7BDF41B72720100F9733F /* mem */ = { isa = PBXGroup; children = ( + AEF25640227C441F00348550 /* vmem32.cpp */, + AEF25641227C441F00348550 /* vmem32.h */, 84B7BDF51B72720100F9733F /* _vmem.cpp */, 84B7BDF61B72720100F9733F /* _vmem.h */, ); @@ -1450,6 +1459,9 @@ 84B7BE211B72720100F9733F /* modules */ = { isa = PBXGroup; children = ( + AEF25644227C442F00348550 /* fastmmu.cpp */, + AEF25643227C442F00348550 /* mmu_impl.h */, + AEF25645227C442F00348550 /* wince.h */, 84B7BE221B72720100F9733F /* bsc.cpp */, 84B7BE231B72720100F9733F /* ccn.cpp */, 84B7BE241B72720100F9733F /* ccn.h */, @@ -2209,6 +2221,7 @@ buildActionMask = 2147483647; files = ( AE649C01218C552500EF4A81 /* md5.c in Sources */, + AEF25642227C441F00348550 /* vmem32.cpp in Sources */, 84967CC61B8F49EE005F1140 /* pngrio.c in Sources */, 84B7BF741B72720200F9733F /* descrambl.cpp in Sources */, AE649BF9218C552500EF4A81 /* fixed_intrin_ssse3.c in Sources */, @@ -2423,6 +2436,7 @@ AE649BF7218C552500EF4A81 /* fixed.c in Sources */, AEFF7F5B214D9D590068CE11 /* pico_socket_tcp.c in Sources */, AE649C27218C553A00EF4A81 /* BraIA64.c in Sources */, + AEF25646227C442F00348550 /* fastmmu.cpp in Sources */, 84B7BF4A1B72720200F9733F /* ccn.cpp in Sources */, AEFF7F5F214D9D590068CE11 /* pico_udp.c in Sources */, AEFF7F70214D9D590068CE11 /* pico_frame.c in Sources */, From dc7f608461a66463b39cb65a7df779aa091dd3e9 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 8 May 2019 22:31:59 +0200 Subject: [PATCH 022/158] wince: fix vmu issues --- core/hw/maple/maple_devs.cpp | 55 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 3efc18fe8..b06af0a3d 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -90,7 +90,7 @@ enum MapleDeviceRV MDRE_UnknownFunction = 0xFE, //0 words MDRE_UnknownCmd = 0xFD, //0 words - MDRE_TransmitAgain = 0xFC, //1 word, 1 or 2? + MDRE_TransmitAgain = 0xFC, //0 words MDRE_FileError = 0xFB, //1 word, bitfield MDRE_LCDError = 0xFA, //1 word, bitfield MDRE_ARGunError = 0xF9, //1 word, bitfield @@ -152,7 +152,7 @@ struct maple_base: maple_device u8 r8() { u8 rv=*((u8*)dma_buffer_in);dma_buffer_in+=1;dma_count_in-=1; return rv; } u16 r16() { u16 rv=*((u16*)dma_buffer_in);dma_buffer_in+=2;dma_count_in-=2; return rv; } u32 r32() { u32 rv=*(u32*)dma_buffer_in;dma_buffer_in+=4;dma_count_in-=4; return rv; } - void rptr(const void* dst,u32 len) + void rptr(void* dst, u32 len) { u8* dst8=(u8*)dst; while(len--) @@ -205,7 +205,7 @@ struct maple_sega_controller: maple_base virtual u32 dma(u32 cmd) { - //printf("maple_sega_controller::dma Called 0x%X;Command %d\n",device_instance->port,Command); + //printf("maple_sega_controller::dma Called 0x%X;Command %d\n", bus_id, cmd); switch (cmd) { case MDC_DeviceRequest: @@ -275,7 +275,7 @@ struct maple_sega_controller: maple_base return MDRS_DataTransfer; default: - //printf("UNKOWN MAPLE COMMAND %d\n",cmd); + //printf("maple_sega_controller UNKOWN MAPLE COMMAND %d\n",cmd); return MDRE_UnknownCmd; } } @@ -288,24 +288,23 @@ struct maple_sega_controller: maple_base u8 vmu_default[] = { - 0x78,0x9c,0xed,0xd2,0x31,0x4e,0x02,0x61,0x10,0x06,0xd0,0x8f,0x04,0x28,0x4c,0x2c, - 0x28,0x2d,0x0c,0xa5,0x57,0xe0,0x16,0x56,0x16,0x76,0x14,0x1e,0xc4,0x03,0x50,0x98, - 0x50,0x40,0x69,0xc1,0x51,0x28,0xbc,0x8e,0x8a,0x0a,0xeb,0xc2,0xcf,0x66,0x13,0x1a, - 0x13,0xa9,0x30,0x24,0xe6,0xbd,0xc9,0x57,0xcc,0x4c,0x33,0xc5,0x2c,0xb3,0x48,0x6e, - 0x67,0x01,0x00,0x00,0x00,0x00,0x00,0x4e,0xaf,0xdb,0xe4,0x7a,0xd2,0xcf,0x53,0x16, - 0x6d,0x46,0x99,0xb6,0xc9,0x78,0x9e,0x3c,0x5f,0x9c,0xfb,0x3c,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x80,0x5f,0xd5,0x45,0xfd,0xef,0xaa,0xca,0x6b,0xde,0xf2,0x9e,0x55, - 0x3e,0xf2,0x99,0xaf,0xac,0xb3,0x49,0x95,0xef,0xd4,0xa9,0x9a,0xdd,0xdd,0x0f,0x9d, - 0x52,0xca,0xc3,0x91,0x7f,0xb9,0x9a,0x0f,0x6e,0x92,0xfb,0xee,0xa1,0x2f,0x6d,0x76, - 0xe9,0x64,0x9b,0xcb,0xf4,0xf2,0x92,0x61,0x33,0x79,0xfc,0xeb,0xb7,0xe5,0x44,0xf6, - 0x77,0x19,0x06,0xef, + 0x78, 0x9c, 0xed, 0xd2, 0x3d, 0x6a, 0x02, 0x01, 0x10, 0x06, 0xd0, 0x4f, 0x89, 0x41, 0x84, 0x74, + 0x36, 0x16, 0x41, 0x8f, 0x91, 0xda, 0x0b, 0x58, 0xa5, 0xcf, 0x81, 0x52, 0x08, 0x16, 0x5a, 0x5a, + 0x78, 0x14, 0x8b, 0x5c, 0xc7, 0xfc, 0xa8, 0xd9, 0x18, 0xd7, 0x65, 0xc1, 0x46, 0xd0, 0x4a, 0x09, + 0x84, 0xf7, 0x86, 0x0f, 0x66, 0x98, 0x66, 0x8a, 0x59, 0x66, 0x91, 0x8c, 0xa6, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xae, 0xef, 0xae, 0xca, 0xe3, 0xeb, 0x7d, 0xc6, 0x59, 0xd4, 0x79, 0xca, 0xa4, + 0x4e, 0x5e, 0x66, 0xc9, 0xbc, 0xf3, 0xd7, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0xb5, 0x2b, 0xd5, 0xff, 0xae, 0xa2, 0x5c, 0xe5, 0x3d, 0x1f, 0xf9, 0xcc, 0x57, 0xd6, 0xd9, + 0x64, 0x9b, 0xef, 0x14, 0xf9, 0xc9, 0x2e, 0x45, 0xb5, 0x7b, 0x3e, 0xd1, 0x28, 0x2b, 0x17, 0xfe, + 0x65, 0xd0, 0x6b, 0xb5, 0x07, 0xc3, 0x6e, 0xf3, 0x38, 0x97, 0x75, 0xf6, 0x69, 0xe4, 0x37, 0x0f, + 0x55, 0xff, 0x96, 0xfe, 0xcd, 0x7f, 0x96, 0xeb, 0x39, 0x00, 0xcd, 0xca, 0x06, 0x7d, }; struct maple_sega_vmu: maple_base @@ -416,7 +415,7 @@ struct maple_sega_vmu: maple_base } virtual u32 dma(u32 cmd) { - //printf("maple_sega_vmu::dma Called for port 0x%X, Command %d\n",device_instance->port,Command); + //printf("maple_sega_vmu::dma Called for port %d:%d, Command %d\n", bus_id, bus_port, cmd); switch (cmd) { case MDC_DeviceRequest: @@ -504,7 +503,7 @@ struct maple_sega_vmu: maple_base w8(47); //X dots -1 w8(31); //Y dots -1 w8(((1)<<4) | (0)); //1 Color, 0 contrast levels - w8(0); //Padding + w8(2); //Padding return MDRS_DataTransfer; } @@ -791,7 +790,7 @@ struct maple_microphone: maple_base switch (cmd) { case MDC_DeviceRequest: - LOGI("maple_microphone::dma MDC_DeviceRequest"); + LOGI("maple_microphone::dma MDC_DeviceRequest\n"); //this was copied from the controller case with just the id and name replaced! //caps @@ -826,7 +825,7 @@ struct maple_microphone: maple_base case MDCF_GetCondition: { - LOGI("maple_microphone::dma MDCF_GetCondition"); + LOGI("maple_microphone::dma MDCF_GetCondition\n"); //this was copied from the controller case with just the id replaced! //PlainJoystickState pjs; @@ -863,7 +862,7 @@ struct maple_microphone: maple_base case MDC_DeviceReset: //uhhh do nothing? - LOGI("maple_microphone::dma MDC_DeviceReset"); + LOGI("maple_microphone::dma MDC_DeviceReset\n"); return MDRS_DeviceReply; case MDCF_MICControl: @@ -932,7 +931,7 @@ struct maple_microphone: maple_base LOGI("maple_microphone::dma MDCF_MICControl set gain %#010x\n",secondword); return MDRS_DeviceReply; case MDRE_TransmitAgain: - LOGW("maple_microphone::dma MDCF_MICControl MDRE_TransminAgain"); + LOGW("maple_microphone::dma MDCF_MICControl MDRE_TransmitAgain\n"); //apparently this doesnt matter //wptr(micdata, SIZE_OF_MIC_DATA); return MDRS_DeviceReply;//MDRS_DataTransfer; From 05577b64f7cdca746d34886b35241dfbf708cea9 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 9 May 2019 11:25:17 +0200 Subject: [PATCH 023/158] wince: return actual vmu system area in GetMediaInfo revert previous default vmu change --- core/hw/maple/maple_devs.cpp | 61 ++++++++++++------------------------ 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index b06af0a3d..e1b8ae0a4 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -288,23 +288,24 @@ struct maple_sega_controller: maple_base u8 vmu_default[] = { - 0x78, 0x9c, 0xed, 0xd2, 0x3d, 0x6a, 0x02, 0x01, 0x10, 0x06, 0xd0, 0x4f, 0x89, 0x41, 0x84, 0x74, - 0x36, 0x16, 0x41, 0x8f, 0x91, 0xda, 0x0b, 0x58, 0xa5, 0xcf, 0x81, 0x52, 0x08, 0x16, 0x5a, 0x5a, - 0x78, 0x14, 0x8b, 0x5c, 0xc7, 0xfc, 0xa8, 0xd9, 0x18, 0xd7, 0x65, 0xc1, 0x46, 0xd0, 0x4a, 0x09, - 0x84, 0xf7, 0x86, 0x0f, 0x66, 0x98, 0x66, 0x8a, 0x59, 0x66, 0x91, 0x8c, 0xa6, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xae, 0xef, 0xae, 0xca, 0xe3, 0xeb, 0x7d, 0xc6, 0x59, 0xd4, 0x79, 0xca, 0xa4, - 0x4e, 0x5e, 0x66, 0xc9, 0xbc, 0xf3, 0xd7, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0xb5, 0x2b, 0xd5, 0xff, 0xae, 0xa2, 0x5c, 0xe5, 0x3d, 0x1f, 0xf9, 0xcc, 0x57, 0xd6, 0xd9, - 0x64, 0x9b, 0xef, 0x14, 0xf9, 0xc9, 0x2e, 0x45, 0xb5, 0x7b, 0x3e, 0xd1, 0x28, 0x2b, 0x17, 0xfe, - 0x65, 0xd0, 0x6b, 0xb5, 0x07, 0xc3, 0x6e, 0xf3, 0x38, 0x97, 0x75, 0xf6, 0x69, 0xe4, 0x37, 0x0f, - 0x55, 0xff, 0x96, 0xfe, 0xcd, 0x7f, 0x96, 0xeb, 0x39, 0x00, 0xcd, 0xca, 0x06, 0x7d, + 0x78,0x9c,0xed,0xd2,0x31,0x4e,0x02,0x61,0x10,0x06,0xd0,0x8f,0x04,0x28,0x4c,0x2c, + 0x28,0x2d,0x0c,0xa5,0x57,0xe0,0x16,0x56,0x16,0x76,0x14,0x1e,0xc4,0x03,0x50,0x98, + 0x50,0x40,0x69,0xc1,0x51,0x28,0xbc,0x8e,0x8a,0x0a,0xeb,0xc2,0xcf,0x66,0x13,0x1a, + 0x13,0xa9,0x30,0x24,0xe6,0xbd,0xc9,0x57,0xcc,0x4c,0x33,0xc5,0x2c,0xb3,0x48,0x6e, + 0x67,0x01,0x00,0x00,0x00,0x00,0x00,0x4e,0xaf,0xdb,0xe4,0x7a,0xd2,0xcf,0x53,0x16, + 0x6d,0x46,0x99,0xb6,0xc9,0x78,0x9e,0x3c,0x5f,0x9c,0xfb,0x3c,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x80,0x5f,0xd5,0x45,0xfd,0xef,0xaa,0xca,0x6b,0xde,0xf2,0x9e,0x55, + 0x3e,0xf2,0x99,0xaf,0xac,0xb3,0x49,0x95,0xef,0xd4,0xa9,0x9a,0xdd,0xdd,0x0f,0x9d, + 0x52,0xca,0xc3,0x91,0x7f,0xb9,0x9a,0x0f,0x6e,0x92,0xfb,0xee,0xa1,0x2f,0x6d,0x76, + 0xe9,0x64,0x9b,0xcb,0xf4,0xf2,0x92,0x61,0x33,0x79,0xfc,0xeb,0xb7,0xe5,0x44,0xf6, + 0x77,0x19,0x06,0xef, }; struct maple_sega_vmu: maple_base @@ -459,30 +460,8 @@ struct maple_sega_vmu: maple_base { w32(MFID_1_Storage); - //total_size; - w16(0xff); - //partition_number; - w16(0); - //system_area_block; - w16(0xFF); - //fat_area_block; - w16(0xfe); - //number_fat_areas_block; - w16(1); - //file_info_block; - w16(0xfd); - //number_info_blocks; - w16(0xd); - //volume_icon; - w8(0); - //reserved1; - w8(0); - //save_area_block; - w16(0xc8); - //number_of_save_blocks; - w16(0x1f); - //reserverd0 (something for execution files?) - w32(0); + // Get data from the vmu system area (block 0xFF) + wptr(flash_data + 0xFF * 512 + 0x40, 24); return MDRS_DataTransfer;//data transfer } From 77c1389921c03185087551341ee6638e60532b7b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 9 May 2019 21:47:01 +0200 Subject: [PATCH 024/158] wince: disable vmem32 for games that abuse it --- core/nullDC.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index d46cee630..64383b1d9 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -36,6 +36,7 @@ static bool safemode_game; static bool tr_poly_depth_mask_game; static bool extra_depth_game; static bool full_mmu_game; +static bool disable_vmem32_game; cThread emu_thread(&dc_run, NULL); @@ -140,6 +141,7 @@ void LoadSpecialSettings() tr_poly_depth_mask_game = false; extra_depth_game = false; full_mmu_game = false; + disable_vmem32_game = false; if (reios_windows_ce // Half-life @@ -198,6 +200,23 @@ void LoadSpecialSettings() settings.rend.ExtraDepthScale = 10000; extra_depth_game = true; } + // Super Producers + if (!strncmp("T14303M", reios_product_number, 7) + // Giant Killers + || !strncmp("T45401D 50", reios_product_number, 10) + // Wild Metal (US) + || !strncmp("T42101N 00", reios_product_number, 10) + // Wild Metal (EU) + || !strncmp("T40501D-50", reios_product_number, 10) + // Resident Evil 2 (US) + || !strncmp("T1205N", reios_product_number, 6) + // Resident Evil 2 (EU) + || !strncmp("T7004D 50", reios_product_number, 10)) + { + printf("Disabling 32-bit virtual memory for game %s\n", reios_product_number); + settings.dynarec.disable_vmem32 = true; + disable_vmem32_game = true; + } #elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE printf("Game ID is [%s]\n", naomi_game_id); @@ -682,7 +701,8 @@ void SaveSettings() cfgSaveBool("config", "Dynarec.unstable-opt", settings.dynarec.unstable_opt); if (!safemode_game || !settings.dynarec.safemode) cfgSaveBool("config", "Dynarec.safe-mode", settings.dynarec.safemode); - cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); + if (!disable_vmem32_game || !settings.dynarec.disable_vmem32) + cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language); cfgSaveBool("config", "aica.LimitFPS", settings.aica.LimitFPS); cfgSaveBool("config", "aica.NoBatch", settings.aica.NoBatch); From c5a74ccfb789921d2801e5fddbb992e7ff749ef8 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 10 May 2019 16:10:07 +0200 Subject: [PATCH 025/158] Fix Sort-DMA --- core/hw/pvr/pvr_sb_regs.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/hw/pvr/pvr_sb_regs.cpp b/core/hw/pvr/pvr_sb_regs.cpp index 25139d77d..ee73482df 100644 --- a/core/hw/pvr/pvr_sb_regs.cpp +++ b/core/hw/pvr/pvr_sb_regs.cpp @@ -55,7 +55,7 @@ void do_pvr_dma() } DMAC_SAR(0) = (src + len); - DMAC_CHCR(0).full &= 0xFFFFFFFE; + DMAC_CHCR(0).TE = 1; DMAC_DMATCR(0) = 0x00000000; SB_PDST = 0x00000000; @@ -73,7 +73,7 @@ void RegWrite_SB_PDST(u32 addr, u32 data) } u32 calculate_start_link_addr() { - u8* base=&mem_b[SB_SDSTAW & RAM_MASK]; + u8* base = &mem_b[SB_SDSTAW & (RAM_MASK - 31)]; u32 rv; if (SB_SDWLT==0) { @@ -94,9 +94,9 @@ void pvr_do_sort_dma() SB_SDDIV=0;//index is 0 now :) u32 link_addr=calculate_start_link_addr(); - u32 link_base_addr = SB_SDBAAW; + u32 link_base_addr = SB_SDBAAW & ~31; - while (link_addr!=1) + while (link_addr != 2) { if (SB_SDLAS==1) link_addr*=32; @@ -107,7 +107,7 @@ void pvr_do_sort_dma() link_addr=ea_ptr[0x1C>>2];//Next link //transfer global param ta_vtx_data(ea_ptr,ea_ptr[0x18>>2]); - if (link_addr==2) + if (link_addr == 1) { link_addr=calculate_start_link_addr(); } @@ -115,6 +115,7 @@ void pvr_do_sort_dma() // End of DMA :) SB_SDST=0; + SB_SDSTAW += 32; asic_RaiseInterrupt(holly_PVR_SortDMA); } // Auto sort DMA :| From e6794743addeb31ee0bc9e30e6d82b98428eb8cc Mon Sep 17 00:00:00 2001 From: flyinghead Date: Fri, 10 May 2019 21:21:30 +0200 Subject: [PATCH 026/158] wince: rec-x64 fix for win32 fix GDI on windows --- core/imgread/gdi.cpp | 25 ++++++++++++------------- core/rec-x64/rec_x64.cpp | 19 +++++++++++++++---- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index 3f59ea5bf..359f03a8b 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -3,10 +3,22 @@ #include #include +// On windows, transform / to \\ + +string normalize_path_separator(string path) +{ + #if HOST_OS == OS_WINDOWS + std::replace( path.begin(), path.end(), '/', '\\'); + #endif + + return path; +} + // given file/name.ext or file\name.ext returns file/ or file\, depending on the platform // given name.ext returns ./ or .\, depending on the platform string OS_dirname(string file) { + file = normalize_path_separator(file); #if HOST_OS == OS_WINDOWS const char sep = '\\'; #else @@ -25,19 +37,6 @@ string OS_dirname(string file) return file.substr(0, last_slash + 1); } -// On windows, transform / to \\ -// On linux, transform \\ to / -string normalize_path_separator(string path) -{ - #if HOST_OS == OS_WINDOWS - std::replace( path.begin(), path.end(), '/', '\\'); - #else - std::replace( path.begin(), path.end(), '\\', '/'); - #endif - - return path; -} - #if 0 // TODO: Move this to some tests, make it platform agnostic namespace { struct OS_dirname_Test { diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 848cc6d84..8c4013133 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1394,7 +1394,11 @@ private: mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); u32 size = op.flags & 0x7f; - verify(getCurr() - start_addr == 26); + //verify(getCurr() - start_addr == 26); + if (mem_access_offset == 0) + mem_access_offset = getCurr() - start_addr; + else + verify(getCurr() - start_addr == mem_access_offset); block->memory_accesses[(void*)getCurr()] = (u32)current_opid; switch (size) @@ -1438,7 +1442,11 @@ private: mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); u32 size = op.flags & 0x7f; - verify(getCurr() - start_addr == 26); + //verify(getCurr() - start_addr == 26); + if (mem_access_offset == 0) + mem_access_offset = getCurr() - start_addr; + else + verify(getCurr() - start_addr == mem_access_offset); block->memory_accesses[(void*)getCurr()] = (u32)current_opid; switch (size) @@ -1707,6 +1715,8 @@ private: static const f32 cvtf2i_pos_saturation; static const u32 read_mem_op_size; static const u32 write_mem_op_size; +public: + static u32 mem_access_offset; }; const u32 BlockCompiler::float_sign_mask = 0x80000000; @@ -1714,6 +1724,7 @@ const u32 BlockCompiler::float_abs_mask = 0x7fffffff; const f32 BlockCompiler::cvtf2i_pos_saturation = 2147483520.0f; // IEEE 754: 0x4effffff; const u32 BlockCompiler::read_mem_op_size = 30; const u32 BlockCompiler::write_mem_op_size = 30; +u32 BlockCompiler::mem_access_offset = 0; void X64RegAlloc::Preload(u32 reg, Xbyak::Operand::Code nreg) { @@ -1787,7 +1798,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) verify(opid < block->oplist.size()); const shil_opcode& op = block->oplist[opid]; - BlockCompiler *assembler = new BlockCompiler(code_ptr - 26); + BlockCompiler *assembler = new BlockCompiler(code_ptr - BlockCompiler::mem_access_offset); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) assembler->GenReadMemorySlow(op, block); @@ -1797,7 +1808,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) verify(block->host_code_size >= assembler->getSize()); delete assembler; block->memory_accesses.erase(it); - host_pc = (unat)(code_ptr - 26); + host_pc = (unat)(code_ptr - BlockCompiler::mem_access_offset); return true; } From 7f2fcfde6f74fba8d253a060abd6d42f62edb821 Mon Sep 17 00:00:00 2001 From: flyinghead Date: Fri, 10 May 2019 22:31:59 +0200 Subject: [PATCH 027/158] wince: don't use setjmp/longjmp on windows --- core/rec-x64/rec_x64.cpp | 92 +++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 8c4013133..fef796bed 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -125,12 +125,10 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") #endif "movl $" _S(SH4_TIMESLICE) "," _U "cycle_counter(%rip) \n" -#ifdef _WIN32 - "lea " _U "jmp_env(%rip), %rcx \n\t" // SETJMP -#else +#ifndef _WIN32 "lea " _U "jmp_env(%rip), %rdi \n\t" -#endif "call " _U "setjmp \n\t" +#endif "1: \n\t" // run_loop "movq " _U "p_sh4rcb(%rip), %rax \n\t" @@ -229,15 +227,18 @@ static void handle_mem_exception(u32 exception_raised, u32 pc) else spc = pc; cycle_counter += CPU_RATIO * 2; // probably more is needed but no easy way to find out +#ifndef _WIN32 longjmp(jmp_env, 1); +#endif } } +static u32 exception_raised; + template static T ReadMemNoEx(u32 addr, u32 pc) { #ifndef NO_MMU - u32 exception_raised; T rv = mmu_ReadMemNoEx(addr, &exception_raised); handle_mem_exception(exception_raised, pc); @@ -249,11 +250,12 @@ static T ReadMemNoEx(u32 addr, u32 pc) } template -static void WriteMemNoEx(u32 addr, T data, u32 pc) +static u32 WriteMemNoEx(u32 addr, T data, u32 pc) { #ifndef NO_MMU u32 exception_raised = mmu_WriteMemNoEx(addr, data); handle_mem_exception(exception_raised, pc); + return exception_raised; #endif } @@ -267,24 +269,34 @@ static void handle_sh4_exception(SH4ThrownException& ex, u32 pc) } Do_Exception(pc, ex.expEvn, ex.callVect); cycle_counter += CPU_RATIO * 4; // probably more is needed +#ifndef _WIN32 longjmp(jmp_env, 1); +#endif } -static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) +static u32 interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) { try { oph(op); +#ifdef _WIN32 + return 0; +#endif } catch (SH4ThrownException& ex) { handle_sh4_exception(ex, pc); + return 1; } } -static void do_sqw_mmu_no_ex(u32 addr, u32 pc) +static u32 do_sqw_mmu_no_ex(u32 addr, u32 pc) { try { do_sqw_mmu(addr); +#ifdef _WIN32 + return 0; +#endif } catch (SH4ThrownException& ex) { handle_sh4_exception(ex, pc); + return 1; } } @@ -341,7 +353,6 @@ public: #else sub(rsp, 0x8); // align stack #endif - Xbyak::Label exit_block; if (mmu_enabled() && block->has_fpu_op) { @@ -370,28 +381,32 @@ public: regalloc.OpBegin(&op, current_opid); - switch (op.op) { - + switch (op.op) + { case shop_ifb: + if (mmu_enabled()) { - if (mmu_enabled()) - { - mov(call_regs64[1], reinterpret_cast(*OpDesc[op.rs3._imm]->oph)); // op handler - mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - } + mov(call_regs64[1], reinterpret_cast(*OpDesc[op.rs3._imm]->oph)); // op handler + mov(call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + } - if (op.rs1._imm) - { - mov(rax, (size_t)&next_pc); - mov(dword[rax], op.rs2._imm); - } + if (op.rs1._imm) + { + mov(rax, (size_t)&next_pc); + mov(dword[rax], op.rs2._imm); + } - mov(call_regs[0], op.rs3._imm); + mov(call_regs[0], op.rs3._imm); - if (!mmu_enabled()) - GenCall(OpDesc[op.rs3._imm]->oph); - else - GenCall(interpreter_fallback); + if (!mmu_enabled()) + GenCall(OpDesc[op.rs3._imm]->oph); + else + { + GenCall(interpreter_fallback); +#ifdef _WIN32 + test(eax, 1); + jnz(exit_block, T_NEAR); +#endif } break; @@ -761,6 +776,10 @@ public: mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc GenCall(do_sqw_mmu_no_ex); +#ifdef _WIN32 + test(eax, 1); + jnz(exit_block, T_NEAR); +#endif } else { @@ -900,7 +919,7 @@ public: case shop_ftrv: mov(rax, (uintptr_t)op.rs1.reg_ptr()); -#if 0 // vfmadd231ps and vmulps cause rounding proglems +#if 0 // vfmadd231ps and vmulps cause rounding problems if (cpu.has(Xbyak::util::Cpu::tFMA)) { movaps(xmm0, xword[rax]); // fn[0-4] @@ -1117,7 +1136,7 @@ public: die("1..8 bytes"); } - if (mmu_enabled()) + if (mmu_enabled() && vmem32_enabled()) { Xbyak::Label quick_exit; if (getCurr() - start_addr <= read_mem_op_size - 6) @@ -1127,6 +1146,13 @@ public: L(quick_exit); verify(getCurr() - start_addr == read_mem_op_size); } +#ifdef _WIN32 + if (mmu_enabled()) + { + test(dword[(void *)&exception_raised], 1); + jnz(exit_block, T_NEAR); + } +#endif } void GenWriteMemorySlow(const shil_opcode& op, RuntimeBlockInfo* block) @@ -1164,7 +1190,7 @@ public: default: die("1..8 bytes"); } - if (mmu_enabled()) + if (mmu_enabled() && vmem32_enabled()) { Xbyak::Label quick_exit; if (getCurr() - start_addr <= write_mem_op_size - 6) @@ -1174,6 +1200,13 @@ public: L(quick_exit); verify(getCurr() - start_addr == write_mem_op_size); } +#ifdef _WIN32 + if (mmu_enabled()) + { + test(eax, 1); + jnz(exit_block, T_NEAR); + } +#endif } void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) @@ -1710,6 +1743,7 @@ private: X64RegAlloc regalloc; Xbyak::util::Cpu cpu; size_t current_opid; + Xbyak::Label exit_block; static const u32 float_sign_mask; static const u32 float_abs_mask; static const f32 cvtf2i_pos_saturation; From 2434d0183e8d06f36b1c10c70432d9248d4c44fa Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 14 May 2019 12:38:56 +0200 Subject: [PATCH 028/158] wince: better sh4 instr cycle counting. Don't hash blocks if mmu on Use actual instr latency cycles, including fp instr Decrease the WinCE boost ratio to 1.2 Don't hash blocks when mmu on --- core/hw/sh4/dyna/decoder.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index e50f29953..6b93623df 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1072,10 +1072,17 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) else { blk->guest_opcodes++; - if (op>=0xF000) - blk->guest_cycles+=0; + if (!mmu_enabled()) + { + if (op>=0xF000) + blk->guest_cycles+=0; + else + blk->guest_cycles+=CPU_RATIO; + } else - blk->guest_cycles+=CPU_RATIO; + { + blk->guest_cycles += max((int)OpDesc[op]->LatencyCycles, 1); + } if (OpDesc[op]->IsFloatingPoint()) { if (sr.FD == 1) @@ -1158,7 +1165,7 @@ _end: if (settings.dynarec.idleskip) { //Experimental hash-id based idle skip - if (strstr(idle_hash,blk->hash(false,true))) // FIXME don't hash temp blocks. Use xxhash instead of sha1 + if (!mmu_enabled() && strstr(idle_hash,blk->hash(false,true))) // FIXME Use xxhash instead of sha1 { //printf("IDLESKIP: %08X reloc match %s\n",blk->addr,blk->hash(false,true)); blk->guest_cycles=max_cycles*100; @@ -1203,7 +1210,7 @@ _end: } // Win CE boost if (mmu_enabled()) - blk->guest_cycles *= 2; + blk->guest_cycles *= 1.2f; //make sure we don't use wayy-too-many cycles blk->guest_cycles=min(blk->guest_cycles,max_cycles); From f0ebd2b8181cd9ac31dbf151c33fa895f1860ad0 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 15 May 2019 14:00:36 +0200 Subject: [PATCH 029/158] wince: force aica.NoBatch --- core/hw/aica/aica.cpp | 2 +- core/hw/aica/sgc_if.cpp | 4 ++-- core/nullDC.cpp | 8 +++++--- core/types.h | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/core/hw/aica/aica.cpp b/core/hw/aica/aica.cpp index 1eea5a03d..df2f2b6c7 100644 --- a/core/hw/aica/aica.cpp +++ b/core/hw/aica/aica.cpp @@ -98,7 +98,7 @@ void libAICA_TimeStep() SCIPD->SAMPLE_DONE=1; - if (settings.aica.NoBatch) + if (settings.aica.NoBatch || settings.aica.DSPEnabled) AICA_Sample(); //Make sure sh4/arm interrupt system is up to date :) diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 76099a6b7..1e9f90b0a 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -1184,7 +1184,7 @@ u32 samples_gen; //no DSP for now in this version void AICA_Sample32() { - if (settings.aica.NoBatch) + if (settings.aica.NoBatch || settings.aica.DSPEnabled) { return; } @@ -1341,7 +1341,7 @@ void AICA_Sample() DSPData->EXTS[0] = 0; DSPData->EXTS[1] = 0; } - //if (settings.aica.DSPEnabled) + if (settings.aica.DSPEnabled) { dsp_step(); diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 64383b1d9..d2d124c64 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -152,6 +152,7 @@ void LoadSpecialSettings() extra_depth_game = true; settings.dreamcast.FullMMU = true; full_mmu_game = true; + settings.aica.NoBatch = true; } // Tony Hawk's Pro Skater 2 @@ -496,8 +497,9 @@ void InitSettings() settings.dreamcast.broadcast = 4; // default settings.dreamcast.language = 6; // default settings.dreamcast.FullMMU = false; + settings.aica.DSPEnabled = false; settings.aica.LimitFPS = true; - settings.aica.NoBatch = false; // This also controls the DSP. Disabled by default + settings.aica.NoBatch = false; settings.aica.NoSound = false; settings.rend.UseMipmaps = true; settings.rend.WideScreen = false; @@ -572,7 +574,7 @@ void LoadSettings(bool game_specific) settings.dreamcast.language = cfgLoadInt(config_section, "Dreamcast.Language", settings.dreamcast.language); settings.dreamcast.FullMMU = cfgLoadBool(config_section, "Dreamcast.FullMMU", settings.dreamcast.FullMMU); settings.aica.LimitFPS = cfgLoadBool(config_section, "aica.LimitFPS", settings.aica.LimitFPS); - settings.aica.NoBatch = cfgLoadBool(config_section, "aica.NoBatch", settings.aica.NoBatch); + settings.aica.DSPEnabled = cfgLoadBool(config_section, "aica.DSPEnabled", settings.aica.DSPEnabled); settings.aica.NoSound = cfgLoadBool(config_section, "aica.NoSound", settings.aica.NoSound); settings.rend.UseMipmaps = cfgLoadBool(config_section, "rend.UseMipmaps", settings.rend.UseMipmaps); settings.rend.WideScreen = cfgLoadBool(config_section, "rend.WideScreen", settings.rend.WideScreen); @@ -705,7 +707,7 @@ void SaveSettings() cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language); cfgSaveBool("config", "aica.LimitFPS", settings.aica.LimitFPS); - cfgSaveBool("config", "aica.NoBatch", settings.aica.NoBatch); + cfgSaveBool("config", "aica.DSPEnabled", settings.aica.DSPEnabled); cfgSaveBool("config", "aica.NoSound", settings.aica.NoSound); cfgSaveBool("config", "rend.WideScreen", settings.rend.WideScreen); cfgSaveBool("config", "rend.ShowFPS", settings.rend.ShowFPS); diff --git a/core/types.h b/core/types.h index ec6ed7a43..a94766055 100644 --- a/core/types.h +++ b/core/types.h @@ -764,7 +764,7 @@ struct settings_t u32 BufferCount; //BufferCount+2 buffers used , max 60 , default 0 u32 CDDAMute; u32 GlobalMute; - u32 DSPEnabled; //0 -> no, 1 -> yes + bool DSPEnabled; bool NoBatch; bool NoSound; } aica; From 66cbc0acf6f77bd16e90dda0cc198db8fe41556c Mon Sep 17 00:00:00 2001 From: flyinghead Date: Wed, 15 May 2019 15:26:08 +0200 Subject: [PATCH 030/158] wince: dynarec boost 1.2 -> 1.5 --- core/hw/sh4/dyna/decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 6b93623df..61b1bc2c3 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1210,7 +1210,7 @@ _end: } // Win CE boost if (mmu_enabled()) - blk->guest_cycles *= 1.2f; + blk->guest_cycles *= 1.5f; //make sure we don't use wayy-too-many cycles blk->guest_cycles=min(blk->guest_cycles,max_cycles); From 3ef363733d826e45181a92eb8e9fc40d2424de9e Mon Sep 17 00:00:00 2001 From: flyinghead Date: Thu, 16 May 2019 16:57:35 +0200 Subject: [PATCH 031/158] wince: fix setjmp/longjmp on windows --- core/rec-x64/rec_x64.cpp | 52 ++++++++-------------------------------- 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index fef796bed..9abdd14d2 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -123,12 +123,15 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") #else "subq $8, %rsp \n\t" // 8 for stack 16-byte alignment #endif - "movl $" _S(SH4_TIMESLICE) "," _U "cycle_counter(%rip) \n" + "movl $" _S(SH4_TIMESLICE) "," _U "cycle_counter(%rip) \n\t" -#ifndef _WIN32 - "lea " _U "jmp_env(%rip), %rdi \n\t" - "call " _U "setjmp \n\t" +#ifdef _WIN32 + "leaq " _U "jmp_env(%rip), %rcx \n\t" // SETJMP + "xor %rdx, %rdx \n\t" // no frame pointer +#else + "leaq " _U "jmp_env(%rip), %rdi \n\t" #endif + "call " _U "setjmp \n" "1: \n\t" // run_loop "movq " _U "p_sh4rcb(%rip), %rax \n\t" @@ -227,9 +230,7 @@ static void handle_mem_exception(u32 exception_raised, u32 pc) else spc = pc; cycle_counter += CPU_RATIO * 2; // probably more is needed but no easy way to find out -#ifndef _WIN32 longjmp(jmp_env, 1); -#endif } } @@ -269,34 +270,24 @@ static void handle_sh4_exception(SH4ThrownException& ex, u32 pc) } Do_Exception(pc, ex.expEvn, ex.callVect); cycle_counter += CPU_RATIO * 4; // probably more is needed -#ifndef _WIN32 longjmp(jmp_env, 1); -#endif } -static u32 interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) +static void interpreter_fallback(u16 op, OpCallFP *oph, u32 pc) { try { oph(op); -#ifdef _WIN32 - return 0; -#endif } catch (SH4ThrownException& ex) { handle_sh4_exception(ex, pc); - return 1; } } -static u32 do_sqw_mmu_no_ex(u32 addr, u32 pc) +static void do_sqw_mmu_no_ex(u32 addr, u32 pc) { try { do_sqw_mmu(addr); -#ifdef _WIN32 - return 0; -#endif } catch (SH4ThrownException& ex) { handle_sh4_exception(ex, pc); - return 1; } } @@ -401,13 +392,8 @@ public: if (!mmu_enabled()) GenCall(OpDesc[op.rs3._imm]->oph); else - { GenCall(interpreter_fallback); -#ifdef _WIN32 - test(eax, 1); - jnz(exit_block, T_NEAR); -#endif - } + break; case shop_jcond: @@ -776,10 +762,6 @@ public: mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc GenCall(do_sqw_mmu_no_ex); -#ifdef _WIN32 - test(eax, 1); - jnz(exit_block, T_NEAR); -#endif } else { @@ -1146,13 +1128,6 @@ public: L(quick_exit); verify(getCurr() - start_addr == read_mem_op_size); } -#ifdef _WIN32 - if (mmu_enabled()) - { - test(dword[(void *)&exception_raised], 1); - jnz(exit_block, T_NEAR); - } -#endif } void GenWriteMemorySlow(const shil_opcode& op, RuntimeBlockInfo* block) @@ -1200,13 +1175,6 @@ public: L(quick_exit); verify(getCurr() - start_addr == write_mem_op_size); } -#ifdef _WIN32 - if (mmu_enabled()) - { - test(eax, 1); - jnz(exit_block, T_NEAR); - } -#endif } void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) From 8d078a923be11c706dbf4e4f45fd105cd1b183db Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 17 May 2019 17:01:20 +0200 Subject: [PATCH 032/158] wince: force aica.NoBatch (missing change) --- core/rend/gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index c9bf88f83..831b2e2b7 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -981,7 +981,7 @@ static void gui_display_settings() ImGui::Checkbox("Disable Sound", &settings.aica.NoSound); ImGui::SameLine(); ShowHelpMarker("Disable the emulator sound output"); - ImGui::Checkbox("Enable DSP", &settings.aica.NoBatch); + ImGui::Checkbox("Enable DSP", &settings.aica.DSPEnabled); ImGui::SameLine(); ShowHelpMarker("Enable the Dreamcast Digital Sound Processor. Only recommended on fast and arm64 platforms"); ImGui::Checkbox("Limit FPS", &settings.aica.LimitFPS); From ac43a8c54ed733445055d972ee074ca6e082b6cd Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 17 May 2019 17:13:48 +0200 Subject: [PATCH 033/158] don't swap gl buffer until FB_R_SOF is set to the rendered framebuffer Fixes flashing screens in South Park: Chef's Luv Shack, NFL Quarterback Club 2000 Glitchy videos: The Next Tetris, Nightmare Creatures II, Rune Jade Flashing rear-view mirror in Metropolis Street Racer --- core/hw/pvr/Renderer_if.cpp | 28 +++++++++++++++++++++++++++- core/hw/pvr/Renderer_if.h | 1 + core/hw/pvr/pvr_regs.cpp | 17 ++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index fc4db314d..d7ad66589 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -85,6 +85,8 @@ bool renderer_changed = false; // Signals the renderer thread to switch renderer cResetEvent rs(false,true); cResetEvent re(false,true); #endif +static bool swap_pending; +static bool do_swap; int max_idx,max_mvo,max_op,max_pt,max_tr,max_vtx,max_modt, ovrn; @@ -282,6 +284,7 @@ bool rend_single_frame() // Use the rendering start event to wait between two frames but save its value if (rs.Wait(17)) rs.Set(); + swap_pending = false; return true; } else @@ -291,12 +294,18 @@ bool rend_single_frame() if (!rs.Wait(100)) return false; + if (do_swap) + { + do_swap = false; + renderer->Present(); + } } #else if (gui_is_open()) { gui_display_ui(); FinishRender(NULL); + swap_pending = false; return true; } if (renderer != NULL) @@ -309,6 +318,7 @@ bool rend_single_frame() } while (!_pvrrc); bool do_swp = rend_frame(_pvrrc, true); + swap_pending = do_swp && !_pvrrc->rend.isRenderFramebuffer; #if !defined(TARGET_NO_THREADS) if (_pvrrc->rend.isRTT) @@ -363,6 +373,7 @@ void rend_init_renderer() } printf("Selected renderer initialization failed. Falling back to default renderer.\n"); renderer = fallback_renderer; + fallback_renderer = NULL; // avoid double-free } } @@ -391,7 +402,13 @@ void* rend_thread(void* p) while (renderer_enabled) { if (rend_single_frame()) - renderer->Present(); + { + if (FB_R_SOF1 == FB_W_SOF1 || !swap_pending) + { + renderer->Present(); + swap_pending = false; + } + } if (renderer_changed) { renderer_changed = false; @@ -571,3 +588,12 @@ void rend_cancel_emu_wait() #endif } +void rend_swap_frame() +{ + if (swap_pending) + { + swap_pending = false; + do_swap = true; + rs.Set(); + } +} diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index 8bd991835..6619d7f33 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -13,6 +13,7 @@ void rend_start_render(); void rend_end_render(); void rend_cancel_emu_wait(); bool rend_single_frame(); +void rend_swap_frame(); void rend_set_fb_scale(float x,float y); void rend_resize(int width, int height); diff --git a/core/hw/pvr/pvr_regs.cpp b/core/hw/pvr/pvr_regs.cpp index c063c62a3..25df7767d 100644 --- a/core/hw/pvr/pvr_regs.cpp +++ b/core/hw/pvr/pvr_regs.cpp @@ -38,6 +38,8 @@ void pvr_WriteReg(u32 paddr,u32 data) { ta_vtx_ListInit(); data=0; + TA_NEXT_OPB = TA_NEXT_OPB_INIT; + TA_ITP_CURRENT = TA_ISP_BASE; } } @@ -84,12 +86,25 @@ void pvr_WriteReg(u32 paddr,u32 data) } return; } - if (addr == TA_YUV_TEX_BASE_addr || addr == TA_YUV_TEX_CTRL_addr) + if (addr == TA_YUV_TEX_BASE_addr) + { + PvrReg(addr, u32) = data & 0x00FFFFF8; + YUV_init(); + return; + } + else if (addr == TA_YUV_TEX_CTRL_addr) { PvrReg(addr, u32) = data; YUV_init(); return; } + else if (addr == FB_R_SOF1_addr) + { + if (data == FB_W_SOF1) + { + rend_swap_frame(); + } + } if (addr>=PALETTE_RAM_START_addr && PvrReg(addr,u32)!=data) { From 86cabf85533880b01e5aacd3788c60a9a61ad66c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 21 May 2019 19:28:54 +0200 Subject: [PATCH 034/158] wince: delete bogus half-life game id --- core/nullDC.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index d2d124c64..5c5e357a4 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -143,9 +143,7 @@ void LoadSpecialSettings() full_mmu_game = false; disable_vmem32_game = false; - if (reios_windows_ce - // Half-life - || !strncmp("MK-51035", reios_product_number, 8)) + if (reios_windows_ce) { printf("Enabling Full MMU and Extra depth scaling for Windows CE game\n"); settings.rend.ExtraDepthScale = 0.1; From 248f274e24a26b216f4d72eefadd5626d12ba26b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 21 May 2019 19:33:01 +0200 Subject: [PATCH 035/158] wince: fix ci builds --- .travis.yml | 26 ----------- appveyor.yml | 68 ++++++++++++++++------------ bitrise.yml | 56 ++++++++++++++--------- shell/android-studio/travis-build.sh | 10 ++-- 4 files changed, 77 insertions(+), 83 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4a76546f4..0be3fa93a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -notifications: - irc: chat.freenode.net#reicast language: android android: components: @@ -22,10 +20,6 @@ cache: - "$HOME/.gradle/wrapper/" - "$HOME/.android/build-cache" before_install: -- test -z "$encrypted_c726d225a9d9_key" || openssl aes-256-cbc -K $encrypted_c726d225a9d9_key -iv $encrypted_c726d225a9d9_iv -in secure.tar.enc -out secure.tar -d -- test -z "$encrypted_c726d225a9d9_key" || tar -xvf secure.tar -- test -z "$encrypted_c726d225a9d9_key" || mv reicast-beta-cd.jks shell/android-studio/reicast-beta-cd.jks -- test -z "$encrypted_c726d225a9d9_key" || mv reicast-beta-cd.p12 shell/android-studio/reicast-beta-cd.p12 - GIT_HASH=`git log --pretty=format:'%h' -n 1` - GIT_BUILD=`git describe --all --always`-$GIT_HASH - mkdir "$ANDROID_HOME/licenses" || true @@ -41,7 +35,6 @@ install: - export PATH=${PATH}:$ANDROID_HOME/platform-tools - export PATH=${PATH}:$NDK - mkdir -p ~/.android -- test -z "$encrypted_c726d225a9d9_key" || mv debug.keystore ~/.android/debug.keystore before_script: script: - git fetch --depth 250 @@ -49,22 +42,3 @@ script: - export NUMBER_OF_PROCESSORS=2 - sudo chmod 755 travis-build.sh - "./travis-build.sh" -- test -z "$encrypted_c726d225a9d9_key" || ./travis-release.sh -before_deploy: -- cd ../../ -- mkdir -p artifacts/$GIT_BUILD/ -- cp shell/android-studio/reicast/build/outputs/apk/dreamcast/debug/reicast-dreamcast-debug.apk artifacts/$GIT_BUILD/reicast-android-debug-$GIT_HASH.apk -deploy: - provider: s3 - access_key_id: AKIAJR5J3OHAQUP5BHHQ - secret_access_key: - secure: dDmBiadS1cc2XCWWDZ1kwZGIoLkwEOLsdi5nzVdn1dHMsEKxN3u+3WFuuOfJHZYcdrtN7VhojCarPa+eGDDeiVme4m3y+QKMbI9lecHX9+t4jDNUyYep5TpeIVUkZ7fj4JsMi7U9/YFBTg7QnqvVsMAHE9vobkvjegjAYToBrlM= - bucket: reicast-builds - local-dir: artifacts - upload-dir: builds - skip_cleanup: true - on: - all_branches: true - repo: reicast/reicast-emulator -after_deploy: -- echo "done" diff --git a/appveyor.yml b/appveyor.yml index dab32d51c..feb4e19bd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,39 +1,47 @@ version: git-{branch}-{build} image: Visual Studio 2017 -environment: - matrix: - - EXTRA_PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\ - LAUNCH_BUILD: mingw32-make platform=win32 - LAUNCH_PATH: shell\linux\ +configuration: +- fast +- RelWithDebInfo +platform: +- x64 + +before_build: + - cmd: >- + if "%CONFIGURATION%"=="RelWithDebInfo" (set BUILD_PATH=build) + + if "%CONFIGURATION%"=="fast" (set BUILD_PATH=shell\linux) + + set EXTRA_PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\ + + set PATH=%EXTRA_PATH%;%PATH% + + if not exist %BUILD_PATH% (mkdir %BUILD_PATH%) + + if "%CONFIGURATION%"=="RelWithDebInfo" (cmake -B %BUILD_PATH% -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo) + + cd %BUILD_PATH% + build_script: -- cmd: >- - set PATH=%EXTRA_PATH%;%PATH% - - cd %LAUNCH_PATH% - - %LAUNCH_BUILD% - + - cmd: >- + if "%CONFIGURATION%"=="RelWithDebInfo" (msbuild reicast.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll") + + if "%CONFIGURATION%"=="fast" (mingw32-make platform=win32) + after_build: - - cmd: cd ..\.. - - cmd: mkdir artifacts - - cmd: move shell\linux\reicast.exe artifacts/reicast-win_x64-fast-%APPVEYOR_REPO_COMMIT%.exe - - cmd: copy %EXTRA_PATH%\libgcc_s_seh-1.dll artifacts - - cmd: copy %EXTRA_PATH%\libwinpthread-1.dll artifacts - - cmd: copy %EXTRA_PATH%\libgomp-1.dll artifacts + - cmd: >- + if "%CONFIGURATION%"=="RelWithDebInfo" (cd .. && set EXE_PATH=build\RelWithDebInfo\reicast.exe) + + if "%CONFIGURATION%"=="fast" (cd ..\.. && set EXE_PATH=shell\linux\nosym-reicast.exe) + + mkdir artifacts + + move %EXE_PATH% artifacts\reicast-win_%PLATFORM%-%CONFIGURATION%-%APPVEYOR_REPO_COMMIT%.exe + + if "%CONFIGURATION%"=="fast" (copy %EXTRA_PATH%\libgcc_s_seh-1.dll artifacts && copy %EXTRA_PATH%\libwinpthread-1.dll artifacts && copy %EXTRA_PATH%\libgomp-1.dll artifacts) artifacts: - path: artifacts - name: reicast-win_x64-fast-$(APPVEYOR_REPO_COMMIT) - -deploy: -- provider: S3 - access_key_id: AKIAJETEBUZSLZF3YNKA - secret_access_key: - secure: ZxrysCeqMK99dOOzKyoeN4R5aO8JjA4RTrwVAQPQHz8sjyyKuVDZT2fC+9m6lUIi - region: eu-west-1 - bucket: reicast-builds-windows - folder: 'builds/heads/$(APPVEYOR_REPO_BRANCH)-$(APPVEYOR_REPO_COMMIT)' - artifact: reicast-win_x64-fast-$(APPVEYOR_REPO_COMMIT) - set_public: true + name: reicast-win_$(PLATFORM)-$(CONFIGURATION)-$(APPVEYOR_REPO_COMMIT) diff --git a/bitrise.yml b/bitrise.yml index a330c64b4..e29fae404 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -1,54 +1,66 @@ --- -format_version: '5' +format_version: '7' default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git -project_type: ios +project_type: macos trigger_map: - push_branch: "*" - workflow: primary + workflow: deploy - pull_request_source_branch: "*" - workflow: primary + workflow: deploy workflows: - deploy: + deploy-naomi: + envs: + - opts: + is_expand: false + BITRISE_SCHEME: reicast-osx-naomi steps: - - activate-ssh-key@3.1.1: + - activate-ssh-key@4.0.3: run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' - - git-clone@4.0.11: {} + - git-clone@4.0.14: {} - cache-pull@2.0.1: {} - script@1.1.5: title: Do anything with Script step - - certificate-and-profile-installer@1.9.3: {} + - certificate-and-profile-installer@1.10.1: {} - recreate-user-schemes@1.0.2: inputs: - project_path: "$BITRISE_PROJECT_PATH" - - xcode-archive@2.4.8: + - xcode-archive-mac@1.6.2: inputs: - project_path: "$BITRISE_PROJECT_PATH" - scheme: "$BITRISE_SCHEME" - export_method: "$BITRISE_EXPORT_METHOD" - - deploy-to-bitrise-io@1.3.12: {} - - cache-push@2.0.5: {} - primary: + - deploy-to-bitrise-io@1.3.19: {} + - cache-push@2.1.1: {} + deploy: + envs: + - opts: + is_expand: false + BITRISE_SCHEME: reicast-osx steps: - - activate-ssh-key@3.1.1: + - activate-ssh-key@4.0.3: run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' - - git-clone@4.0.11: {} + - git-clone@4.0.14: {} - cache-pull@2.0.1: {} - script@1.1.5: title: Do anything with Script step - - certificate-and-profile-installer@1.9.2: {} + - certificate-and-profile-installer@1.10.1: {} - recreate-user-schemes@1.0.2: inputs: - project_path: "$BITRISE_PROJECT_PATH" - - deploy-to-bitrise-io@1.3.10: {} - - cache-push@2.0.5: {} + - xcode-archive-mac@1.6.2: + inputs: + - project_path: "$BITRISE_PROJECT_PATH" + - scheme: "$BITRISE_SCHEME" + - export_method: "$BITRISE_EXPORT_METHOD" + - deploy-to-bitrise-io@1.3.19: {} + - cache-push@2.1.1: {} + after_run: + - deploy-naomi app: envs: - opts: is_expand: false - BITRISE_PROJECT_PATH: shell/apple/emulator-ios/reicast-ios.xcodeproj + BITRISE_PROJECT_PATH: shell/apple/reicast.xcworkspace - opts: is_expand: false - BITRISE_SCHEME: reicast-ios - - opts: - is_expand: false - BITRISE_EXPORT_METHOD: ad-hoc \ No newline at end of file + BITRISE_EXPORT_METHOD: none diff --git a/shell/android-studio/travis-build.sh b/shell/android-studio/travis-build.sh index 3e42bd164..fb16d017d 100755 --- a/shell/android-studio/travis-build.sh +++ b/shell/android-studio/travis-build.sh @@ -1,7 +1,7 @@ #!/bin/bash set -ev -if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then - ./gradlew build --configure-on-demand -else - ./gradlew assembleDebug --configure-on-demand -fi +#if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then +# ./gradlew build --configure-on-demand --console=plain +#else + ./gradlew assembleDebug --configure-on-demand --console=plain +#fi From 94e03b2cfdd65be6d63b582576e3ec6546a36c89 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 22 May 2019 14:28:11 +0200 Subject: [PATCH 036/158] win32: fix build. disable appveyor msvc build --- appveyor.yml | 1 - core/windows/win_vmem.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index feb4e19bd..25380c839 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,6 @@ image: Visual Studio 2017 configuration: - fast -- RelWithDebInfo platform: - x64 diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp index 682d6b8c4..0e97ce1c6 100644 --- a/core/windows/win_vmem.cpp +++ b/core/windows/win_vmem.cpp @@ -54,7 +54,8 @@ bool mem_region_unmap_file(void *start, size_t len) return UnmapViewOfFile(start); } -static HANDLE mem_handle = INVALID_HANDLE_VALUE, mem_handle2 = INVALID_HANDLE_VALUE; +HANDLE mem_handle = INVALID_HANDLE_VALUE; +static HANDLE mem_handle2 = INVALID_HANDLE_VALUE; static char * base_alloc = NULL; // Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc. From 5b7d07315b71a62d701d50f6f20d095e9d2b819d Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 22 May 2019 15:15:53 +0200 Subject: [PATCH 037/158] wince: clean up unused stuff --- core/build.h | 4 ---- core/hw/sh4/dyna/blockmanager.h | 1 - core/hw/sh4/dyna/driver.cpp | 12 ------------ core/hw/sh4/dyna/ngen.h | 2 -- core/hw/sh4/sh4_core_regs.cpp | 4 ---- 5 files changed, 23 deletions(-) diff --git a/core/build.h b/core/build.h index 1a8eb5626..2736a0cf9 100755 --- a/core/build.h +++ b/core/build.h @@ -309,10 +309,6 @@ #define HOST_64BIT_CPU #endif -#define RAM_SIZE_MAX (32*1024*1024) -#define VRAM_SIZE_MAX (16*1024*1024) -#define ARAM_SIZE_MAX (8*1024*1024) - //Depricated build configs #ifdef HOST_NO_REC #error Dont use HOST_NO_REC diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index df3941aed..88c69fb3c 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -36,7 +36,6 @@ struct RuntimeBlockInfo: RuntimeBlockInfo_Core u32 guest_opcodes; u32 host_opcodes; bool has_fpu_op; - u32 asid; // if not 0xFFFFFFFF then private page belonging to this id u32 blockcheck_failures; bool temp_block; diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 74d37f75f..d7756268b 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -243,7 +243,6 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) BranchBlock=NextBlock=csc_RetCache=0xFFFFFFFF; BlockType=BET_SCL_Intr; has_fpu_op = false; - asid = 0xFFFFFFFF; temp_block = false; vaddr = rpc; @@ -256,8 +255,6 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) DoMMUException(vaddr, rv, MMU_TT_IREAD); return false; } - if (addr != vaddr && !shared) - asid = CCN_PTEH.ASID; } else addr = vaddr; @@ -384,15 +381,6 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) return (DynarecCodeEntryPtr)CC_RW2RX(rdv_CompilePC(blockcheck_failures)); } -//DynarecCodeEntryPtr rdv_FindCode() -//{ -// DynarecCodeEntryPtr rv=bm_GetCode(next_pc); -// if (rv==ngen_FailedToFindBlock) -// return 0; -// -// return rv; -//} - DynarecCodeEntryPtr rdv_FindOrCompile() { DynarecCodeEntryPtr rv = bm_GetCodeByVAddr(next_pc); // Returns exec addr diff --git a/core/hw/sh4/dyna/ngen.h b/core/hw/sh4/dyna/ngen.h index 6507421c5..b3afd856b 100644 --- a/core/hw/sh4/dyna/ngen.h +++ b/core/hw/sh4/dyna/ngen.h @@ -87,8 +87,6 @@ DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock_pc(); DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc); //Called to compile code @pc DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures); -//Returns 0 if there is no code @pc, code ptr otherwise -//DynarecCodeEntryPtr rdv_FindCode(); //Finds or compiles code @pc DynarecCodeEntryPtr rdv_FindOrCompile(); diff --git a/core/hw/sh4/sh4_core_regs.cpp b/core/hw/sh4/sh4_core_regs.cpp index 622cc1b54..0680fc494 100644 --- a/core/hw/sh4/sh4_core_regs.cpp +++ b/core/hw/sh4/sh4_core_regs.cpp @@ -33,10 +33,6 @@ INLINE void ChangeFP() } } -f32 saved_xffr[32]; -u32 saved_fpul; -fpscr_t saved_fpscr; - //called when sr is changed and we must check for reg banks etc.. , returns true if interrupts got bool UpdateSR() { From bc42f8a78554031ad662e57ffebef27ce9df178b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 22 May 2019 16:44:45 +0200 Subject: [PATCH 038/158] wince: revert prior serialize changes --- core/serialize.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/core/serialize.cpp b/core/serialize.cpp index 5ec48ad62..8e8e54b4a 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -35,8 +35,7 @@ enum serialize_version_enum { V2, V3, V4, - V5_LIBRETRO, - V5 = 100 + V5_LIBRETRO } ; //./core/hw/arm7/arm_mem.cpp @@ -423,9 +422,6 @@ extern Sh4RCB* p_sh4rcb; //extern u8* sh4_dyna_rcb; extern u32 old_rm; extern u32 old_dn; -extern f32 saved_xffr[32]; -extern u32 saved_fpul; -extern fpscr_t saved_fpscr; @@ -770,7 +766,7 @@ bool dc_serialize(void **data, unsigned int *total_size) { int i = 0; int j = 0; - serialize_version_enum version = V5 ; + serialize_version_enum version = V4 ; *total_size = 0 ; @@ -977,9 +973,8 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(old_rm); REICAST_S(old_dn); - REICAST_S(saved_xffr); - REICAST_S(saved_fpul); - REICAST_S(saved_fpscr); + + REICAST_S(sh4_sched_ffb); @@ -1529,7 +1524,7 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(version) ; if (version == V5_LIBRETRO) return dc_unserialize_libretro(data, total_size); - if (version != V4 && version < V5) + if (version != V4) { fprintf(stderr, "Save State version not supported: %d\n", version); return false; @@ -1727,12 +1722,9 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(old_rm); REICAST_US(old_dn); - if (version >= V5) - { - REICAST_US(saved_xffr); - REICAST_US(saved_fpul); - REICAST_US(saved_fpscr); - } + + + REICAST_US(sh4_sched_ffb); REICAST_US(sh4_sched_intr); From e3d95f2258a5e1af705138fb73cc6cb7a4e786f1 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 23 May 2019 11:40:33 +0200 Subject: [PATCH 039/158] wince: unify _vmem and vmem32. Use 4GB virtual space on 64-bit arch On 64-bit architectures, _vmem first tries to allocate 4GB then falls back to 512 MB. The same virtual space is now used by _vmem and vmem32 (mmu) --- core/hw/mem/_vmem.cpp | 129 +++++++++++++++++++----- core/hw/mem/_vmem.h | 14 ++- core/hw/mem/vmem32.cpp | 123 ++++------------------ core/hw/mem/vmem32.h | 5 +- core/hw/pvr/pvr_mem.cpp | 1 - core/hw/sh4/dyna/driver.cpp | 19 ++-- core/hw/sh4/interpr/sh4_interpreter.cpp | 4 - core/hw/sh4/modules/mmu.cpp | 1 + core/hw/sh4/sh4_core_regs.cpp | 1 - core/hw/sh4/sh4_if.h | 1 - core/linux/common.cpp | 3 - core/linux/posix_vmem.cpp | 32 ++++-- core/nullDC.cpp | 8 -- core/rec-ARM64/rec_arm64.cpp | 67 +++++------- core/rec-x64/rec_x64.cpp | 4 +- core/rend/TexCache.cpp | 46 +++++++-- 16 files changed, 246 insertions(+), 212 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 3f7cb5947..a14787aec 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -1,4 +1,5 @@ #include "_vmem.h" +#include "vmem32.h" #include "hw/aica/aica_if.h" #include "hw/sh4/dyna/blockmanager.h" @@ -399,6 +400,7 @@ void _vmem_term() {} #include "hw/sh4/sh4_mem.h" u8* virt_ram_base; +bool vmem_4gb_space; void* malloc_pages(size_t size) { #if HOST_OS == OS_WINDOWS @@ -446,6 +448,26 @@ bool BM_LockedWrite(u8* address) { return false; } +static void _vmem_set_p0_mappings() +{ + const vmem_mapping mem_mappings[] = { + // P0/U0 + {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused + {0x00800000, 0x00800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica + {0x00800000 + ARAM_SIZE, 0x02800000, 0, 0, false}, // unused + {0x02800000, 0x02800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror + {0x02800000 + ARAM_SIZE, 0x04000000, 0, 0, false}, // unused + {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) + {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror + {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 + {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0x10000000, 0x80000000, 0, 0, false}, // Area 4-7 (unused) + }; + vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings)); +} + bool _vmem_reserve() { // TODO: Static assert? verify((sizeof(Sh4RCB)%PAGE_SIZE)==0); @@ -480,33 +502,85 @@ bool _vmem_reserve() { printf("Info: nvmem is enabled, with addr space of size %s\n", vmemstatus == MemType4GB ? "4GB" : "512MB"); printf("Info: p_sh4rcb: %p virt_ram_base: %p\n", p_sh4rcb, virt_ram_base); // Map the different parts of the memory file into the new memory range we got. - #define MAP_RAM_START_OFFSET 0 - #define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) - #define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) - const vmem_mapping mem_mappings[] = { - {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused - {0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica, wraps too - {0x20000000, 0x20000000+ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, - {0x01000000, 0x04000000, 0, 0, false}, // More unused - {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) - {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) - {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror - {0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror - {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 - {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) - {0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused) - }; - vmem_platform_create_mappings(&mem_mappings[0], sizeof(mem_mappings) / sizeof(mem_mappings[0])); + if (vmemstatus == MemType512MB) + { + const vmem_mapping mem_mappings[] = { + {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused + {0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica + {0x20000000, 0x20000000+ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, + {0x01000000, 0x04000000, 0, 0, false}, // More unused + {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) + {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror + {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 + {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused) + }; + vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings)); + + // Point buffers to actual data pointers + aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writable AICA addrspace + vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writable and lockable) + mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror + } + else + { + _vmem_set_p0_mappings(); + const vmem_mapping mem_mappings[] = { + // P1 + {0x80000000, 0x80800000, 0, 0, false}, // Area 0 -> unused + {0x80800000, 0x80800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0x80800000 + ARAM_SIZE, 0x82800000, 0, 0, false}, // unused + {0x82800000, 0x82800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0x82800000 + ARAM_SIZE, 0x84000000, 0, 0, false}, // unused + {0x84000000, 0x85000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0x85000000, 0x86000000, 0, 0, false}, // 32 bit path (unused) + {0x86000000, 0x87000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0x87000000, 0x88000000, 0, 0, false}, // 32 bit path (unused) mirror + {0x88000000, 0x8C000000, 0, 0, false}, // Area 2 + {0x8C000000, 0x90000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0x90000000, 0xA0000000, 0, 0, false}, // Area 4-7 (unused) + // P2 + {0xA0000000, 0xA0800000, 0, 0, false}, // Area 0 -> unused + {0xA0800000, 0xA0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0xA0800000 + ARAM_SIZE, 0xA2800000, 0, 0, false}, // unused + {0xA2800000, 0xA2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0xA2800000 + ARAM_SIZE, 0xA4000000, 0, 0, false}, // unused + {0xA4000000, 0xA5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0xA5000000, 0xA6000000, 0, 0, false}, // 32 bit path (unused) + {0xA6000000, 0xA7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0xA7000000, 0xA8000000, 0, 0, false}, // 32 bit path (unused) mirror + {0xA8000000, 0xAC000000, 0, 0, false}, // Area 2 + {0xAC000000, 0xB0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0xB0000000, 0xC0000000, 0, 0, false}, // Area 4-7 (unused) + // P3 + {0xC0000000, 0xC0800000, 0, 0, false}, // Area 0 -> unused + {0xC0800000, 0xC0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0xC0800000 + ARAM_SIZE, 0xC2800000, 0, 0, false}, // unused + {0xC2800000, 0xC2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0xC2800000 + ARAM_SIZE, 0xC4000000, 0, 0, false}, // unused + {0xC4000000, 0xC5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0xC5000000, 0xC6000000, 0, 0, false}, // 32 bit path (unused) + {0xC6000000, 0xC7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0xC7000000, 0xC8000000, 0, 0, false}, // 32 bit path (unused) mirror + {0xC8000000, 0xCC000000, 0, 0, false}, // Area 2 + {0xCC000000, 0xD0000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) + {0xD0000000, 0x100000000L, 0, 0, false}, // Area 4-7 (unused) + }; + vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings)); + + // Point buffers to actual data pointers + aica_ram.data = &virt_ram_base[0x80800000]; // Points to the first AICA addrspace in P1 + vram.data = &virt_ram_base[0x84000000]; // Points to first vram mirror (writable and lockable) in P1 + mem_b.data = &virt_ram_base[0x8C000000]; // Main memory, first mirror in P1 + + vmem_4gb_space = true; + } - // Point buffers to actual data pointers aica_ram.size = ARAM_SIZE; - aica_ram.data = &virt_ram_base[0x20000000]; // Points to the writtable AICA addrspace - vram.size = VRAM_SIZE; - vram.data = &virt_ram_base[0x04000000]; // Points to first vram mirror (writtable and lockable) - mem_b.size = RAM_SIZE; - mem_b.data = &virt_ram_base[0x0C000000]; // Main memory, first mirror } // Clear out memory @@ -531,3 +605,12 @@ void _vmem_release() { } } +void _vmem_disable_mmu() +{ + if (vmem32_enabled()) + { + // Restore P0/U0 mem mappings + vmem32_flush_mmu(); + _vmem_set_p0_mappings(); + } +} diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index e609b1b09..c702b2fe1 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -8,8 +8,8 @@ enum VMemType { }; struct vmem_mapping { - u32 start_address, end_address; - unsigned memoffset, memsize; + u64 start_address, end_address; + u64 memoffset, memsize; bool allow_writes; }; @@ -102,9 +102,17 @@ void* _vmem_get_ptr2(u32 addr,u32& mask); void* _vmem_read_const(u32 addr,bool& ismem,u32 sz); extern u8* virt_ram_base; +extern bool vmem_4gb_space; static inline bool _nvmem_enabled() { return virt_ram_base != 0; } - +static inline bool _nvmem_4gb_space() { + return vmem_4gb_space; +} void _vmem_bm_reset(); +void _vmem_disable_mmu(); + +#define MAP_RAM_START_OFFSET 0 +#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) +#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index e7236cffa..ad06af617 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -41,24 +41,18 @@ extern int vmem_fd; #define VMEM32_ERROR_NOT_MAPPED 0x100 -// FIXME stolen from _vmem.cpp -#define MAP_RAM_START_OFFSET 0 -#define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) -#define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) - static const u64 VMEM32_SIZE = 0x100000000L; static const u64 KERNEL_SPACE = 0x80000000L; static const u64 AREA7_ADDRESS = 0x7C000000L; #define VRAM_PROT_SEGMENT (1024 * 1024) // vram protection regions are grouped by 1MB segment -u8* vmem32_base; -std::unordered_set vram_mapped_pages; -std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +static std::unordered_set vram_mapped_pages; +static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; // stats -u64 vmem32_page_faults; -u64 vmem32_flush; +//u64 vmem32_page_faults; +//u64 vmem32_flush; static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool write) { @@ -68,20 +62,20 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w //printf("MAP32 %08X w/ %d\n",dst,offset); u32 map_times = addrsz / size; #if HOST_OS == OS_WINDOWS - rv = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &vmem32_base[dst]); + rv = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &virt_ram_base[dst]); if (rv == NULL) return NULL; for (u32 i = 1; i < map_times; i++) { dst += size; - ptr = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &vmem32_base[dst]); + ptr = MapViewOfFileEx(mem_handle, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, offset, size, &virt_ram_base[dst]); if (ptr == NULL) return NULL; } #else u32 prot = PROT_READ | (write ? PROT_WRITE : 0); - rv = mmap(&vmem32_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); + rv = mmap(&virt_ram_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); if (MAP_FAILED == rv) { printf("MAP1 failed %d\n", errno); @@ -91,7 +85,7 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w for (u32 i = 1; i < map_times; i++) { dst += size; - ptr = mmap(&vmem32_base[dst], size, prot , MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); + ptr = mmap(&virt_ram_base[dst], size, prot , MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); if (MAP_FAILED == ptr) { printf("MAP2 failed %d\n", errno); @@ -105,9 +99,9 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w static void vmem32_unmap_buffer(u32 start, u64 end) { #if HOST_OS == OS_WINDOWS - UnmapViewOfFile(&vmem32_base[start]); + UnmapViewOfFile(&virt_ram_base[start]); #else - mmap(&vmem32_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); + mmap(&virt_ram_base[start], end - start, PROT_NONE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); #endif } @@ -116,9 +110,9 @@ static void vmem32_protect_buffer(u32 start, u32 size) verify((start & PAGE_MASK) == 0); #if HOST_OS == OS_WINDOWS DWORD old; - VirtualProtect(vmem32_base + start, size, PAGE_READONLY, &old); + VirtualProtect(virt_ram_base + start, size, PAGE_READONLY, &old); #else - mprotect(&vmem32_base[start], size, PROT_READ); + mprotect(&virt_ram_base[start], size, PROT_READ); #endif } @@ -127,15 +121,15 @@ static void vmem32_unprotect_buffer(u32 start, u32 size) verify((start & PAGE_MASK) == 0); #if HOST_OS == OS_WINDOWS DWORD old; - VirtualProtect(vmem32_base + start, size, PAGE_READWRITE, &old); + VirtualProtect(virt_ram_base + start, size, PAGE_READWRITE, &old); #else - mprotect(&vmem32_base[start], size, PROT_READ | PROT_WRITE); + mprotect(&virt_ram_base[start], size, PROT_READ | PROT_WRITE); #endif } void vmem32_protect_vram(vram_block *block) { - if (vmem32_base == NULL) + if (virt_ram_base == NULL) return; for (int i = block->start / VRAM_PROT_SEGMENT; i <= block->end / VRAM_PROT_SEGMENT; i++) { @@ -144,7 +138,7 @@ void vmem32_protect_vram(vram_block *block) } void vmem32_unprotect_vram(vram_block *block) { - if (vmem32_base == NULL) + if (virt_ram_base == NULL) return; for (int page = block->start / VRAM_PROT_SEGMENT; page <= block->end / VRAM_PROT_SEGMENT; page++) { @@ -157,28 +151,6 @@ void vmem32_unprotect_vram(vram_block *block) } } -static bool vmem32_map_areas() -{ - // Aica ram - vmem32_map_buffer(0x80800000, 0x00800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); // P1 - vmem32_map_buffer(0x82800000, ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); - vmem32_map_buffer(0xA0800000, 0x00800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); // P2 - vmem32_map_buffer(0xA2800000, ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true); - - // Vram - // Note: this should be mapped read/write but doesn't seem to be used - vmem32_map_buffer(0x84000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); // P1 - vmem32_map_buffer(0x86000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); - vmem32_map_buffer(0xA4000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); // P2 - vmem32_map_buffer(0xA6000000, 0x01000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, false); - - // System ram - vmem32_map_buffer(0x8C000000, 0x04000000, MAP_RAM_START_OFFSET, RAM_SIZE, true); // P1 - vmem32_map_buffer(0xAC000000, 0x04000000, MAP_RAM_START_OFFSET, RAM_SIZE, true); // P2 - - return true; -} - static const u32 page_sizes[] = { 1024, 4 * 1024, 64 * 1024, 1024 * 1024 }; static u32 vmem32_paddr_to_offset(u32 address) @@ -322,10 +294,10 @@ static u32 vmem32_map_address(u32 address, bool write) #if !defined(NO_MMU) && defined(HOST_64BIT_CPU) bool vmem32_handle_signal(void *fault_addr, bool write) { - if ((u8*)fault_addr < vmem32_base || (u8*)fault_addr >= vmem32_base + VMEM32_SIZE) + if ((u8*)fault_addr < virt_ram_base || (u8*)fault_addr >= virt_ram_base + VMEM32_SIZE) return false; - vmem32_page_faults++; - u32 guest_addr = (u8*)fault_addr - vmem32_base; + //vmem32_page_faults++; + u32 guest_addr = (u8*)fault_addr - virt_ram_base; u32 rv = vmem32_map_address(guest_addr, write); //printf("vmem32_handle_signal handled signal %s @ %p -> %08x rv=%d\n", write ? "W" : "R", fault_addr, guest_addr, rv); if (rv == MMU_ERROR_NONE) @@ -342,70 +314,17 @@ bool vmem32_handle_signal(void *fault_addr, bool write) void vmem32_flush_mmu() { - vmem32_flush++; + //vmem32_flush++; vram_mapped_pages.clear(); vmem32_unmap_buffer(0, KERNEL_SPACE); // TODO flush P3? } -bool vmem32_init() -{ - if (!_nvmem_enabled()) - return false; -#if HOST_OS == OS_WINDOWS - // disabled on windows for now - return true; -#endif -#ifdef HOST_64BIT_CPU -#if HOST_OS == OS_WINDOWS - void* rv = (u8 *)VirtualAlloc(0, VMEM32_SIZE, MEM_RESERVE, PAGE_NOACCESS); - if (rv != NULL) - VirtualFree(rv, 0, MEM_RELEASE); - vmem32_base = (u8*)rv; -#else - void* rv = mmap(0, VMEM32_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); - verify(rv != NULL); - munmap(rv, VMEM32_SIZE); - vmem32_base = (u8*)rv; -#endif - - vmem32_unmap_buffer(0, VMEM32_SIZE); - printf("vmem32_init: allocated %zx bytes from %p to %p\n", VMEM32_SIZE, vmem32_base, vmem32_base + VMEM32_SIZE); - - if (!vmem32_map_areas()) - { - vmem32_term(); - return false; - } -#endif - return true; -} - void vmem32_term() { - if (vmem32_base != NULL) + if (virt_ram_base != NULL) { -#if HOST_OS == OS_WINDOWS vmem32_flush_mmu(); - // Aica ram - vmem32_unmap_buffer(0x80800000, 0x80800000 + 0x00800000); // P1 - vmem32_unmap_buffer(0x82800000, 0x82800000 + ARAM_SIZE); - vmem32_unmap_buffer(0xA0800000, 0xA0800000 + 0x00800000); // P2 - vmem32_unmap_buffer(0xA2800000, 0xA2800000 + ARAM_SIZE); - - // Vram - vmem32_unmap_buffer(0x84000000, 0x84000000 + 0x01000000); // P1 - vmem32_unmap_buffer(0x86000000, 0x86000000 + 0x01000000); - vmem32_unmap_buffer(0xA4000000, 0xA4000000 + 0x01000000); // P2 - vmem32_unmap_buffer(0xA6000000, 0xA6000000 + 0x01000000); - - // System ram - vmem32_unmap_buffer(0x8C000000, 0x8C000000 + 0x04000000); // P1 - vmem32_unmap_buffer(0xAC000000, 0xAC000000 + 0x04000000); // P2 -#else - munmap(vmem32_base, VMEM32_SIZE); -#endif - vmem32_base = NULL; } } diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index f900c472f..809cdf192 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -1,6 +1,5 @@ -#include "types.h" +#include "_vmem.h" -bool vmem32_init(); void vmem32_term(); bool vmem32_handle_signal(void *fault_addr, bool write); void vmem32_flush_mmu(); @@ -10,6 +9,6 @@ static inline bool vmem32_enabled() { #if HOST_OS == OS_WINDOWS return false; #else - return !settings.dynarec.disable_vmem32; + return !settings.dynarec.disable_vmem32 && _nvmem_4gb_space(); #endif } diff --git a/core/hw/pvr/pvr_mem.cpp b/core/hw/pvr/pvr_mem.cpp index 45fb1a721..a9d125ec7 100644 --- a/core/hw/pvr/pvr_mem.cpp +++ b/core/hw/pvr/pvr_mem.cpp @@ -297,7 +297,6 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb) if (SB_LMMODE0 == 0) { // 64b path - u8* vram=sqb+512+0x04000000; MemWrite32(&vram[address_w&(VRAM_MASK-0x1F)],sq); } else diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index d7756268b..324881bb0 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -80,7 +80,7 @@ void clear_temp_cache(bool full) void recSh4_ClearCache() { - printf("recSh4:Dynarec Cache clear at %08X free space %d\n",curr_pc, emit_FreeSpace()); + printf("recSh4:Dynarec Cache clear at %08X free space %d\n", curr_pc, emit_FreeSpace()); LastAddr=LastAddr_min; bm_Reset(); smc_hotspots.clear(); @@ -130,7 +130,7 @@ void emit_Skip(u32 sz) if (emit_ptr) emit_ptr = (u32*)((u8*)emit_ptr + sz); else - LastAddr+=sz; + LastAddr += sz; } u32 emit_FreeSpace() @@ -138,7 +138,7 @@ u32 emit_FreeSpace() if (emit_ptr) return (emit_ptr_limit - emit_ptr) * sizeof(u32); else - return CODE_SIZE-LastAddr; + return CODE_SIZE - LastAddr; } // pc must be a physical address @@ -262,7 +262,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) oplist.clear(); - if (!dec_DecodeBlock(this,SH4_TIMESLICE/2)) + if (!dec_DecodeBlock(this, SH4_TIMESLICE / 2)) return false; AnalyseBlock(this); @@ -293,7 +293,7 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) emit_ptr_limit = (u32 *)(TempCodeCache + TEMP_CODE_SIZE); rbi->temp_block = true; } - bool do_opts = !rbi->temp_block; //((rbi->addr&0x3FFFFFFF)>0x0C010100); + bool do_opts = !rbi->temp_block; rbi->staging_runs=do_opts?100:-100; ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); verify(rbi->code!=0); @@ -505,7 +505,14 @@ void recSh4_Init() verify(rcb_noffs(&p_sh4rcb->cntx.interrupt_pend) == -148); if (_nvmem_enabled()) { - verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000)); + if (!_nvmem_4gb_space()) + { + verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x0C000000)); + } + else + { + verify(mem_b.data==((u8*)p_sh4rcb->sq_buffer+512+0x8C000000)); + } } // Prepare some pointer to the pre-allocated code cache: diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index 40e7519b5..a2074443d 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -124,8 +124,6 @@ void Sh4_int_Skip() } } -extern u8 *vmem32_base; - void Sh4_int_Reset(bool Manual) { if (sh4_int_bCpuRun) @@ -150,8 +148,6 @@ void Sh4_int_Reset(bool Manual) old_fpscr=fpscr; UpdateFPSCR(); - p_sh4rcb->cntx.vmem32_base = vmem32_base; - //Any more registers have default value ? printf("Sh4 Reset\n"); } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 4799cb0fb..4d346aced 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -681,6 +681,7 @@ void mmu_set_state() WriteMem16 = &_vmem_WriteMem16; WriteMem32 = &_vmem_WriteMem32; WriteMem64 = &_vmem_WriteMem64; + _vmem_disable_mmu(); } } diff --git a/core/hw/sh4/sh4_core_regs.cpp b/core/hw/sh4/sh4_core_regs.cpp index 0680fc494..5bbfff5c7 100644 --- a/core/hw/sh4/sh4_core_regs.cpp +++ b/core/hw/sh4/sh4_core_regs.cpp @@ -142,7 +142,6 @@ void SetFloatStatusReg() //called when fpscr is changed and we must check for reg banks etc.. void UpdateFPSCR() { - verify(fpscr.PR == 0 || fpscr.SZ == 0); if (fpscr.FR !=old_fpscr.FR) ChangeFP(); // FPU bank change diff --git a/core/hw/sh4/sh4_if.h b/core/hw/sh4/sh4_if.h index a74ba3a8c..be40f47a2 100644 --- a/core/hw/sh4/sh4_if.h +++ b/core/hw/sh4/sh4_if.h @@ -284,7 +284,6 @@ struct Sh4Context u32 interrupt_pend; u32 exception_pc; - u8 *vmem32_base; }; u64 raw[64-8]; }; diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 358244aee..5d860c9de 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -60,9 +60,6 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) bool dyna_cde = ((unat)CC_RX2RW(ctx.pc) > (unat)CodeCache) && ((unat)CC_RX2RW(ctx.pc) < (unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); - //ucontext_t* ctx=(ucontext_t*)ctxr; - //printf("mprot hit @ ptr 0x%08X @@ code: %08X, %d\n",si->si_addr,ctx->uc_mcontext.arm_pc,dyna_cde); - #if !defined(NO_MMU) && defined(HOST_64BIT_CPU) && HOST_OS != OS_WINDOWS #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index dacb9ce61..59d0687c3 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -156,11 +156,22 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { return MemTypeError; // Now try to allocate a contiguous piece of memory. - unsigned memsize = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000; - void *first_ptr = mem_region_reserve(NULL, memsize); - if (!first_ptr) { - close(vmem_fd); - return MemTypeError; + void *first_ptr = NULL; + VMemType rv; +#ifdef HOST_64BIT_CPU + size_t bigsize = 0x100000000L + sizeof(Sh4RCB) + 0x10000; // 4GB + context size + 64K padding + first_ptr = mem_region_reserve(NULL, bigsize); + rv = MemType4GB; +#endif + if (first_ptr == NULL) + { + unsigned memsize = 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE_MAX + 0x10000; + first_ptr = mem_region_reserve(NULL, memsize); + if (!first_ptr) { + close(vmem_fd); + return MemTypeError; + } + rv = MemType512MB; } // Align pointer to 64KB too, some Linaro bug (no idea but let's just be safe I guess). @@ -173,12 +184,15 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { // Now map the memory for the SH4 context, do not include FPCB on purpose (paged on demand). mem_region_unlock(sh4rcb_base_ptr, sizeof(Sh4RCB) - FPCB_SIZE); - return MemType512MB; + return rv; } // Just tries to wipe as much as possible in the relevant area. void vmem_platform_destroy() { - mem_region_release(virt_ram_base, 0x20000000); + if (vmem_4gb_space) + mem_region_release(virt_ram_base, 0x100000000); + else + mem_region_release(virt_ram_base, 0x20000000); } // Resets a chunk of memory by deleting its data and setting its protection back. @@ -207,12 +221,12 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma continue; // Calculate the number of mirrors - unsigned address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; + u64 address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; unsigned num_mirrors = (address_range_size) / vmem_maps[i].memsize; verify((address_range_size % vmem_maps[i].memsize) == 0 && num_mirrors >= 1); for (unsigned j = 0; j < num_mirrors; j++) { - unsigned offset = vmem_maps[i].start_address + j * vmem_maps[i].memsize; + u64 offset = vmem_maps[i].start_address + j * vmem_maps[i].memsize; verify(mem_region_unmap_file(&virt_ram_base[offset], vmem_maps[i].memsize)); verify(mem_region_map_file((void*)(uintptr_t)vmem_fd, &virt_ram_base[offset], vmem_maps[i].memsize, vmem_maps[i].memoffset, vmem_maps[i].allow_writes) != NULL); diff --git a/core/nullDC.cpp b/core/nullDC.cpp index be9042423..3bf1546ff 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -6,7 +6,6 @@ #include "oslib/oslib.h" #include "oslib/audiostream.h" #include "hw/mem/_vmem.h" -#include "hw/mem/vmem32.h" #include "stdclass.h" #include "cfg/cfg.h" @@ -298,13 +297,6 @@ int reicast_init(int argc, char* argv[]) printf("Failed to alloc mem\n"); return -1; } -#ifdef HOST_64BIT_CPU - if (!vmem32_init()) - { - printf("Failed to alloc 32-bit mem space\n"); - return -1; - } -#endif if (ParseCommandLine(argc, argv)) { return 69; diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 5cf45ef76..701177924 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -153,8 +153,6 @@ void ngen_mainloop(void* v_cntx) "ldr x28, [sp] \n\t" // Set context // w29 is next_pc "ldr w29, [x28, %[pc]] \n\t" - // x27 is vmem32_base - "ldr x27, [x28, %[vmem32_base]] \n\t" "b no_update \n" ".hidden intc_sched \n\t" @@ -220,8 +218,7 @@ void ngen_mainloop(void* v_cntx) [RCB_SIZE] "i" (sizeof(Sh4RCB) >> 16), [SH4CTX_SIZE] "i" (sizeof(Sh4Context)), [jmp_env] "r"(reinterpret_cast(jmp_env)), - [cycle_counter] "r"(reinterpret_cast(&cycle_counter)), - [vmem32_base] "i"(offsetof(Sh4Context, vmem32_base)) + [cycle_counter] "r"(reinterpret_cast(&cycle_counter)) : "memory" ); } @@ -1419,26 +1416,20 @@ private: Instruction *start_instruction = GetCursorAddress(); - const XRegister* base_reg; - const XRegister* offset_reg; - // WARNING: the rewrite code relies on having two ops before the memory access (3 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code - if (!mmu_enabled()) + Add(x1, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); + if (!_nvmem_4gb_space()) { - Add(w1, *call_regs[0], sizeof(Sh4Context), LeaveFlags); Bfc(w1, 29, 3); // addr &= ~0xE0000000 - base_reg = &x28; - offset_reg = &x1; } - else + else if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); // 3 ops before memory access Mov(w8, exception_pc & 0xFFFF); Movk(w8, exception_pc >> 16, 16); Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); - base_reg = &x27; - offset_reg = call_regs64[0]; } //printf("direct read memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); @@ -1450,22 +1441,22 @@ private: switch(size) { case 1: - Ldrsb(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + Ldrsb(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); break; case 2: - Ldrsh(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); break; case 4: if (!op.rd.is_r32f()) - Ldr(regalloc.MapRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + Ldr(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); else - Ldr(regalloc.MapVRegister(op.rd), MemOperand(*base_reg, *offset_reg)); + Ldr(regalloc.MapVRegister(op.rd), MemOperand(x28, x1)); break; case 8: - Ldr(x1, MemOperand(*base_reg, *offset_reg)); + Ldr(x1, MemOperand(x28, x1)); break; } @@ -1486,19 +1477,19 @@ private: switch(size) { case 1: - Ldrsb(w1, MemOperand(*base_reg, *offset_reg)); + Ldrsb(w1, MemOperand(x28, x1)); break; case 2: - Ldrsh(w1, MemOperand(*base_reg, *offset_reg)); + Ldrsh(w1, MemOperand(x28, x1)); break; case 4: - Ldr(w1, MemOperand(*base_reg, *offset_reg)); + Ldr(w1, MemOperand(x28, x1)); break; case 8: - Ldr(x1, MemOperand(*base_reg, *offset_reg)); + Ldr(x1, MemOperand(x28, x1)); break; } if (size == 8) @@ -1544,25 +1535,19 @@ private: Instruction *start_instruction = GetCursorAddress(); - const XRegister* base_reg; - const XRegister* offset_reg; - // WARNING: the rewrite code relies on having two ops before the memory access (3 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code - if (!mmu_enabled()) + Add(x7, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); + if (!_nvmem_4gb_space()) { - Add(w7, *call_regs[0], sizeof(Sh4Context), LeaveFlags); Bfc(w7, 29, 3); // addr &= ~0xE0000000 - base_reg = &x28; - offset_reg = &x7; } - else + else if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); Mov(w8, exception_pc & 0xFFFF); Movk(w8, exception_pc >> 16, 16); Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); - base_reg = &x27; - offset_reg = call_regs64[0]; } //printf("direct write memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); @@ -1572,19 +1557,19 @@ private: switch(size) { case 1: - Strb(w1, MemOperand(*base_reg, *offset_reg)); + Strb(w1, MemOperand(x28, x7)); break; case 2: - Strh(w1, MemOperand(*base_reg, *offset_reg)); + Strh(w1, MemOperand(x28, x7)); break; case 4: - Str(w1, MemOperand(*base_reg, *offset_reg)); + Str(w1, MemOperand(x28, x7)); break; case 8: - Str(x1, MemOperand(*base_reg, *offset_reg)); + Str(x1, MemOperand(x28, x7)); break; } EnsureCodeSize(start_instruction, write_memory_rewrite_size); @@ -1767,7 +1752,7 @@ private: RuntimeBlockInfo* block = NULL; const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 4; // TODO only 3 if !mmu + const int write_memory_rewrite_size = 5; // TODO only 2 if !mmu & 4gb }; static Arm64Assembler* compiler; @@ -1824,7 +1809,9 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) u32 opid = it->second; verify(opid < block->oplist.size()); const shil_opcode& op = block->oplist[opid]; - Arm64Assembler *assembler = new Arm64Assembler(code_ptr - 2 - (mmu_enabled() ? 1 : 0)); // Skip the 2 preceding ops (bic, add) + // Skip the preceding ops (add, bic, ...) + u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 3 : 0); + Arm64Assembler *assembler = new Arm64Assembler(code_rewrite); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) assembler->GenReadMemorySlow(op); @@ -1832,7 +1819,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) assembler->GenWriteMemorySlow(op); assembler->Finalize(true); delete assembler; - host_pc = (unat)CC_RW2RX(code_ptr - 2 - (mmu_enabled() ? 1 : 0)); + host_pc = (unat)CC_RW2RX(code_rewrite); return true; } diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index e932f7f48..61531ba36 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1402,7 +1402,7 @@ private: mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); - mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); + mov(rax, (uintptr_t)virt_ram_base); u32 size = op.flags & 0x7f; //verify(getCurr() - start_addr == 26); @@ -1450,7 +1450,7 @@ private: mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); mov(dword[rax], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); - mov(rax, (uintptr_t)p_sh4rcb->cntx.vmem32_base); + mov(rax, (uintptr_t)virt_ram_base); u32 size = op.flags & 0x7f; //verify(getCurr() - start_addr == 26); diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index ad993b6d8..f906a785d 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -214,8 +214,27 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { vram.LockRegion(block->start + VRAM_SIZE, block->len); } - if (mmu_enabled()) + if (!mmu_enabled()) + { + if (_nvmem_4gb_space()) + { + // In 4GB mode, vram.LockRegion() locks in the P1 area only so we also need to lock P0 + // We should also lock P2 and P3 but they don't seem to be used... + mem_region_lock(virt_ram_base + 0x04000000 + block->start, block->len); + //mem_region_lock(virt_ram_base + 0xA4000000 + block->start, block->len); + //mem_region_lock(virt_ram_base + 0xC4000000 + block->start, block->len); + if (VRAM_SIZE == 0x800000) + { + mem_region_lock(virt_ram_base + 0x04000000 + block->start + VRAM_SIZE, block->len); + //mem_region_lock(virt_ram_base + 0xA4000000 + block->start + VRAM_SIZE, block->len); + //mem_region_lock(virt_ram_base + 0xC4000000 + block->start + VRAM_SIZE, block->len); + } + } + } + else + { vmem32_protect_vram(block); + } vramlock_list_add(block); @@ -252,13 +271,20 @@ bool VramLockedWriteOffset(size_t offset) } list->clear(); - vram.UnLockRegion((u32)offset&(~(PAGE_SIZE-1)),PAGE_SIZE); + u32 aligned_offset = (u32)offset & ~(PAGE_SIZE - 1); + vram.UnLockRegion(aligned_offset, PAGE_SIZE); //TODO: Fix this for 32M wrap as well if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { - vram.UnLockRegion((u32)offset&(~(PAGE_SIZE-1)) + VRAM_SIZE,PAGE_SIZE); + vram.UnLockRegion(aligned_offset + VRAM_SIZE, PAGE_SIZE); } - + if (_nvmem_4gb_space() && !mmu_enabled()) + { + mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset, PAGE_SIZE); + if (VRAM_SIZE == 0x800000) + mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset + VRAM_SIZE, PAGE_SIZE); + } + vramlist_lock.Unlock(); } @@ -274,8 +300,16 @@ bool VramLockedWrite(u8* address) if (offset < 0x01000000) return VramLockedWriteOffset(offset & (VRAM_SIZE - 1)); - else - return false; + if (_nvmem_4gb_space() && !mmu_enabled()) + { + offset = address - virt_ram_base; + if (offset >= 0x04000000 && offset < 0x050000000) + return VramLockedWriteOffset((offset - 0x04000000) & (VRAM_SIZE - 1)); + // 32MB wrap not set yet + //if (offset >= 0x06000000 && offset < 0x070000000) + // return VramLockedWriteOffset((offset - 0x06000000) & (VRAM_SIZE - 1)); + } + return false; } //unlocks mem From 61a867e1adc0be9bbc3fb95782f15fab045c4242 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 24 May 2019 17:40:10 +0200 Subject: [PATCH 040/158] FPCB was only partially mprotected --- core/linux/posix_vmem.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index 59d0687c3..5a2a43456 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -179,10 +179,11 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { ptrint = (ptrint + 0x10000 - 1) & (~0xffff); *sh4rcb_addr = (void*)ptrint; *vmem_base_addr = (void*)(ptrint + sizeof(Sh4RCB)); - void *sh4rcb_base_ptr = (void*)(ptrint + FPCB_SIZE); + const size_t fpcb_size = sizeof(((Sh4RCB *)NULL)->fpcb); + void *sh4rcb_base_ptr = (void*)(ptrint + fpcb_size); // Now map the memory for the SH4 context, do not include FPCB on purpose (paged on demand). - mem_region_unlock(sh4rcb_base_ptr, sizeof(Sh4RCB) - FPCB_SIZE); + mem_region_unlock(sh4rcb_base_ptr, sizeof(Sh4RCB) - fpcb_size); return rv; } From fa10b9ed2f9c68854214c036c8a02cc9a6a47df5 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 24 May 2019 17:44:54 +0200 Subject: [PATCH 041/158] Wrong offset in VramLockedWrite --- core/rend/TexCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index f906a785d..25ef5c03c 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -303,7 +303,7 @@ bool VramLockedWrite(u8* address) if (_nvmem_4gb_space() && !mmu_enabled()) { offset = address - virt_ram_base; - if (offset >= 0x04000000 && offset < 0x050000000) + if (offset >= 0x04000000 && offset < 0x05000000) return VramLockedWriteOffset((offset - 0x04000000) & (VRAM_SIZE - 1)); // 32MB wrap not set yet //if (offset >= 0x06000000 && offset < 0x070000000) From cc4b59f5fa1970878a786548a99e63eb16770ffe Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 24 May 2019 18:18:32 +0200 Subject: [PATCH 042/158] rec-arm64: generate main loop dynamically different code for mmu vs. !mmu Switching mmu state not yet supported --- core/rec-ARM64/rec_arm64.cpp | 370 ++++++++++++++++++++++------------- 1 file changed, 236 insertions(+), 134 deletions(-) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 701177924..23be1a777 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -43,14 +43,17 @@ using namespace vixl::aarch64; #undef do_sqw_nommu -extern "C" void no_update(); -extern "C" void intc_sched(); extern "C" void ngen_blockcheckfail(u32 pc); extern "C" void ngen_LinkBlock_Generic_stub(); extern "C" void ngen_LinkBlock_cond_Branch_stub(); extern "C" void ngen_LinkBlock_cond_Next_stub(); -extern "C" void ngen_FailedToFindBlock_(); +extern "C" void ngen_FailedToFindBlock_mmu(); +extern "C" void ngen_FailedToFindBlock_nommu(); extern void vmem_platform_flush_cache(void *icache_start, void *icache_end, void *dcache_start, void *dcache_end); +static void generate_mainloop(); + +u32 mem_writes, mem_reads; +u32 mem_rewrites_w, mem_rewrites_r; struct DynaRBI : RuntimeBlockInfo { @@ -66,6 +69,10 @@ u64 guest_cpu_cycles; static jmp_buf jmp_env; static u32 cycle_counter; +static void (*mainloop)(void *context); +static void (*arm64_intc_sched)(); +static void (*arm64_no_update)(); + #ifdef PROFILING #include @@ -111,10 +118,16 @@ __asm__ "bl rdv_LinkBlock \n\t" // returns an RX addr "br x0 \n" - ".hidden ngen_FailedToFindBlock_ \n\t" - ".globl ngen_FailedToFindBlock_ \n\t" - "ngen_FailedToFindBlock_: \n\t" -// "mov w0, w29 \n\t" // FIXME w29 might not be up to date anymore (exception in bm_GetCodeByVAddr) + ".hidden ngen_FailedToFindBlock_nommu \n\t" + ".globl ngen_FailedToFindBlock_nommu \n\t" + "ngen_FailedToFindBlock_nommu: \n\t" + "mov w0, w29 \n\t" + "bl rdv_FailedToFindBlock \n\t" + "br x0 \n" + + ".hidden ngen_FailedToFindBlock_mmu \n\t" + ".globl ngen_FailedToFindBlock_mmu \n\t" + "ngen_FailedToFindBlock_mmu: \n\t" "bl rdv_FailedToFindBlock_pc \n\t" "br x0 \n" @@ -127,110 +140,28 @@ __asm__ void ngen_mainloop(void* v_cntx) { - Sh4RCB* ctx = (Sh4RCB*)((u8*)v_cntx - sizeof(Sh4RCB)); + generate_mainloop(); + mainloop(v_cntx); +} - __asm__ - ( - "stp x19, x20, [sp, #-160]! \n\t" - "stp x21, x22, [sp, #16] \n\t" - "stp x23, x24, [sp, #32] \n\t" - "stp x25, x26, [sp, #48] \n\t" - "stp x27, x28, [sp, #64] \n\t" - "stp s14, s15, [sp, #80] \n\t" - "stp s8, s9, [sp, #96] \n\t" - "stp s10, s11, [sp, #112] \n\t" - "stp s12, s13, [sp, #128] \n\t" - "stp x29, x30, [sp, #144] \n\t" - - "stp %[cntx], %[cycle_counter], [sp, #-16]! \n\t" // Push context, cycle_counter address - "mov w1, %[_SH4_TIMESLICE] \n\t" - "str w1, [%[cycle_counter]] \n\t" - - "mov x0, %[jmp_env] \n\t" // SETJMP - "bl setjmp \n\t" - - // Use x28 as sh4 context pointer - "ldr x28, [sp] \n\t" // Set context - // w29 is next_pc - "ldr w29, [x28, %[pc]] \n\t" - "b no_update \n" - - ".hidden intc_sched \n\t" - ".globl intc_sched \n\t" - "intc_sched: \n\t" - "ldr x1, [sp, #8] \n\t" // &cycle_counter - "ldr w0, [x1] \n\t" // cycle_counter - "add w0, w0, %[_SH4_TIMESLICE] \n\t" - "str w0, [x1] \n\t" - "mov x29, lr \n\t" // Trashing pc here but it will be reset at the end of the block or in DoInterrupts - "bl UpdateSystem \n\t" - "mov lr, x29 \n\t" - "cbnz w0, .do_interrupts \n\t" - "ret \n" - - ".do_interrupts: \n\t" - "mov x0, x29 \n\t" - "bl rdv_DoInterrupts \n\t" // Updates next_pc based on host pc - "mov w29, w0 \n" - - ".hidden no_update \n\t" - ".globl no_update \n\t" - "no_update: \n\t" // next_pc _MUST_ be on w29 - "ldr w0, [x28, %[CpuRunning]] \n\t" - "cbz w0, .end_mainloop \n\t" - -#ifdef NO_MMU - "movz x2, %[RCB_SIZE], lsl #16 \n\t" - "sub x2, x28, x2 \n\t" - "add x2, x2, %[SH4CTX_SIZE] \n\t" -#if RAM_SIZE_MAX == 33554432 - "ubfx w1, w29, #1, #24 \n\t" // 24+1 bits: 32 MB -#elif RAM_SIZE_MAX == 16777216 - "ubfx w1, w29, #1, #23 \n\t" // 23+1 bits: 16 MB -#else -#error "Define RAM_SIZE_MAX" -#endif - "ldr x0, [x2, x1, lsl #3] \n\t" - "br x0 \n" -#else - "mov w0, w29 \n\t" - "bl bm_GetCodeByVAddr \n\t" - "br x0 \n" -#endif - - ".end_mainloop: \n\t" - "add sp, sp, #16 \n\t" // Pop context - "ldp x29, x30, [sp, #144] \n\t" - "ldp s12, s13, [sp, #128] \n\t" - "ldp s10, s11, [sp, #112] \n\t" - "ldp s8, s9, [sp, #96] \n\t" - "ldp s14, s15, [sp, #80] \n\t" - "ldp x27, x28, [sp, #64] \n\t" - "ldp x25, x26, [sp, #48] \n\t" - "ldp x23, x24, [sp, #32] \n\t" - "ldp x21, x22, [sp, #16] \n\t" - "ldp x19, x20, [sp], #160 \n\t" - : - : [cntx] "r"(reinterpret_cast(&ctx->cntx)), - [pc] "i"(offsetof(Sh4Context, pc)), - [_SH4_TIMESLICE] "i"(SH4_TIMESLICE), - [CpuRunning] "i"(offsetof(Sh4Context, CpuRunning)), - [RCB_SIZE] "i" (sizeof(Sh4RCB) >> 16), - [SH4CTX_SIZE] "i" (sizeof(Sh4Context)), - [jmp_env] "r"(reinterpret_cast(jmp_env)), - [cycle_counter] "r"(reinterpret_cast(&cycle_counter)) - : "memory" - ); +static int setjmp_local(jmp_buf env) +{ + return setjmp(env); } void ngen_init() { printf("Initializing the ARM64 dynarec\n"); - ngen_FailedToFindBlock = &ngen_FailedToFindBlock_; + ngen_FailedToFindBlock = &ngen_FailedToFindBlock_nommu; } void ngen_ResetBlocks() { + mainloop = NULL; + if (mmu_enabled()) + ngen_FailedToFindBlock = &ngen_FailedToFindBlock_mmu; + else + ngen_FailedToFindBlock = &ngen_FailedToFindBlock_nommu; } void ngen_GetFeatures(ngen_features* dst) @@ -239,11 +170,6 @@ void ngen_GetFeatures(ngen_features* dst) dst->OnlyDynamicEnds = false; } -RuntimeBlockInfo* ngen_AllocateBlock() -{ - return new DynaRBI(); -} - template static T ReadMemNoEx(u32 addr, u32 pc) { @@ -434,13 +360,20 @@ public: regalloc.DoAlloc(block); // scheduler - Mov(x1, reinterpret_cast(&cycle_counter)); - Ldr(w0, MemOperand(x1)); - Subs(w0, w0, block->guest_cycles); - Str(w0, MemOperand(x1)); + if (mmu_enabled()) + { + Mov(x1, reinterpret_cast(&cycle_counter)); + Ldr(w0, MemOperand(x1)); + Subs(w0, w0, block->guest_cycles); + Str(w0, MemOperand(x1)); + } + else + { + Subs(w27, w27, block->guest_cycles); + } Label cycles_remaining; B(&cycles_remaining, pl); - GenCallRuntime(intc_sched); + GenCall(*arm64_intc_sched); Bind(&cycles_remaining); #ifdef PROFILING @@ -1100,7 +1033,7 @@ public: { Mov(w29, block->BranchBlock); Str(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update); + GenBranch(*arm64_no_update); } } else @@ -1134,7 +1067,7 @@ public: { Mov(w29, block->BranchBlock); Str(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update); + GenBranch(*arm64_no_update); } } @@ -1150,7 +1083,7 @@ public: { Mov(w29, block->NextBlock); Str(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update); + GenBranch(*arm64_no_update); } } } @@ -1179,7 +1112,7 @@ public: else { Str(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update); + GenBranch(*arm64_no_update); } break; @@ -1196,8 +1129,8 @@ public: GenCallRuntime(UpdateINTC); Ldr(w29, sh4_context_mem_operand(&next_pc)); + GenBranch(*arm64_no_update); - GenBranchRuntime(no_update); break; default: @@ -1248,6 +1181,130 @@ public: #endif } + void GenMainloop() + { + Label no_update; + Label intc_sched; + + mainloop = (void (*)(void *))GetBuffer()->GetStartAddress(); + + // Save registers + Stp(x19, x20, MemOperand(sp, -160, PreIndex)); + Stp(x21, x22, MemOperand(sp, 16)); + Stp(x23, x24, MemOperand(sp, 32)); + Stp(x25, x26, MemOperand(sp, 48)); + Stp(x27, x28, MemOperand(sp, 64)); + Stp(s14, s15, MemOperand(sp, 80)); + Stp(vixl::aarch64::s8, s9, MemOperand(sp, 96)); + Stp(s10, s11, MemOperand(sp, 112)); + Stp(s12, s13, MemOperand(sp, 128)); + Stp(x29, x30, MemOperand(sp, 144)); + + Sub(x0, x0, sizeof(Sh4Context)); + if (mmu_enabled()) + { + Ldr(x1, reinterpret_cast(&cycle_counter)); + // Push context, cycle_counter address + Stp(x0, x1, MemOperand(sp, -16, PreIndex)); + Mov(w0, SH4_TIMESLICE); + Str(w0, MemOperand(x1)); + + Mov(x0, reinterpret_cast(jmp_env)); + GenCallRuntime(setjmp_local); + + Ldr(x28, MemOperand(sp)); // Set context + } + else + { + // Use x28 as sh4 context pointer + Mov(x28, x0); + // Use x27 as cycle_counter + Mov(w27, SH4_TIMESLICE); + } + Label do_interrupts; + Label end_mainloop; + + // w29 is next_pc + Ldr(w29, MemOperand(x28, offsetof(Sh4Context, pc))); + B(&no_update); + + Bind(&intc_sched); + + Ldr(w0, MemOperand(x28, offsetof(Sh4Context, CpuRunning))); + Cbz(w0, &end_mainloop); + // Add timeslice to cycle counter + if (!mmu_enabled()) + { + Add(w27, w27, SH4_TIMESLICE); + } + else + { + Ldr(x1, MemOperand(sp, 8)); // &cycle_counter + Ldr(w0, MemOperand(x1)); // cycle_counter + Add(w0, w0, SH4_TIMESLICE); + Str(w0, MemOperand(x1)); + } + Mov(x29, lr); // Trashing pc here but it will be reset at the end of the block or in DoInterrupts + GenCallRuntime(UpdateSystem); + Mov(lr, x29); + Cbnz(w0, &do_interrupts); + Ret(); + + Bind(&do_interrupts); + Mov(x0, x29); + GenCallRuntime(rdv_DoInterrupts); // Updates next_pc based on host pc + Mov(w29, w0); + + Bind(&no_update); // next_pc _MUST_ be on w29 + + if (!mmu_enabled()) + { + Sub(x2, x28, offsetof(Sh4RCB, cntx)); + if (RAM_SIZE == 32 * 1024 * 1024) + Ubfx(w1, w29, 1, 24); // 24+1 bits: 32 MB + else if (RAM_SIZE == 16 * 1024 * 1024) + Ubfx(w1, w29, 1, 23); // 23+1 bits: 16 MB + else + die("Unsupported RAM_SIZE"); + Ldr(x0, MemOperand(x2, x1, LSL, 3)); + } + else + { + Mov(w0, w29); + GenCallRuntime(bm_GetCodeByVAddr); + } + Br(x0); + + Bind(&end_mainloop); + if (mmu_enabled()) + // Pop context + Add(sp, sp, 16); + // Restore registers + Ldp(x29, x30, MemOperand(sp, 144)); + Ldp(s12, s13, MemOperand(sp, 128)); + Ldp(s10, s11, MemOperand(sp, 112)); + Ldp(vixl::aarch64::s8, s9, MemOperand(sp, 96)); + Ldp(s14, s15, MemOperand(sp, 80)); + Ldp(x27, x28, MemOperand(sp, 64)); + Ldp(x25, x26, MemOperand(sp, 48)); + Ldp(x23, x24, MemOperand(sp, 32)); + Ldp(x21, x22, MemOperand(sp, 16)); + Ldp(x19, x20, MemOperand(sp, 160, PostIndex)); + Ret(); + + FinalizeCode(); + emit_Skip(GetBuffer()->GetSizeInBytes()); + + arm64_intc_sched = (void (*)())GetBuffer()->GetOffsetAddress(intc_sched.GetLocation()); + arm64_no_update = (void (*)())GetBuffer()->GetOffsetAddress(no_update.GetLocation()); + + // Flush and invalidate caches + vmem_platform_flush_cache( + CC_RW2RX(GetBuffer()->GetStartAddress()), CC_RW2RX(GetBuffer()->GetEndAddress()), + GetBuffer()->GetStartAddress(), GetBuffer()->GetEndAddress()); + } + + private: // Runtime branches/calls need to be adjusted if rx space is different to rw space. // Therefore can't mix GenBranch with GenBranchRuntime! @@ -1263,6 +1320,17 @@ private: Bl(&function_label); } + template + void GenCall(R (*function)(P...)) + { + ptrdiff_t offset = reinterpret_cast(function) - GetBuffer()->GetStartAddress(); + verify(offset >= -128 * 1024 * 1024 && offset <= 128 * 1024 * 1024); + verify((offset & 3) == 0); + Label function_label; + BindToOffset(&function_label, offset); + Bl(&function_label); + } + template void GenBranchRuntime(R (*target)(P...)) { @@ -1336,7 +1404,7 @@ private: switch (size) { case 2: - Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x1, xzr, SXTW)); + Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x1)); break; case 4: @@ -1356,7 +1424,7 @@ private: switch (size) { case 2: - Ldrsh(w1, MemOperand(x1, xzr, SXTW)); + Ldrsh(w1, MemOperand(x1)); break; case 4: @@ -1413,23 +1481,28 @@ private: // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() if (!_nvmem_enabled() || (mmu_enabled() && !vmem32_enabled())) return false; + mem_reads++; Instruction *start_instruction = GetCursorAddress(); // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code - Add(x1, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); if (!_nvmem_4gb_space()) { - Bfc(w1, 29, 3); // addr &= ~0xE0000000 + Ubfx(x1, *call_regs64[0], 0, 29); + Add(x1, x1, sizeof(Sh4Context), LeaveFlags); } - else if (mmu_enabled()) + else { - u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - // 3 ops before memory access - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + Add(x1, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); + if (mmu_enabled()) + { + u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); + // 3 ops before memory access + Mov(w8, exception_pc & 0xFFFF); + Movk(w8, exception_pc >> 16, 16); + Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + } } //printf("direct read memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); @@ -1532,22 +1605,27 @@ private: // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() if (!_nvmem_enabled() || (mmu_enabled() && !vmem32_enabled())) return false; + mem_writes++; Instruction *start_instruction = GetCursorAddress(); // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code - Add(x7, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); if (!_nvmem_4gb_space()) { - Bfc(w7, 29, 3); // addr &= ~0xE0000000 + Ubfx(x7, *call_regs64[0], 0, 29); + Add(x7, x7, sizeof(Sh4Context), LeaveFlags); } - else if (mmu_enabled()) + else { - u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + Add(x7, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); + if (mmu_enabled()) + { + u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); + Mov(w8, exception_pc & 0xFFFF); + Movk(w8, exception_pc >> 16, 16); + Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); // TODO Store exception_pc is w27 ? + } } //printf("direct write memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); @@ -1676,7 +1754,7 @@ private: Mov(*call_regs[2], 0x100); // vector CallRuntime(Do_Exception); Ldr(w29, sh4_context_mem_operand(&next_pc)); - GenBranch(no_update); + GenBranch(*arm64_no_update); Bind(&fpu_enabled); } @@ -1814,9 +1892,15 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) Arm64Assembler *assembler = new Arm64Assembler(code_rewrite); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) + { + mem_rewrites_r++; assembler->GenReadMemorySlow(op); + } else + { + mem_rewrites_w++; assembler->GenWriteMemorySlow(op); + } assembler->Finalize(true); delete assembler; host_pc = (unat)CC_RW2RX(code_rewrite); @@ -1824,6 +1908,24 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) return true; } +static void generate_mainloop() +{ + if (mainloop != NULL) + return; + compiler = new Arm64Assembler(); + + compiler->GenMainloop(); + + delete compiler; + compiler = NULL; +} + +RuntimeBlockInfo* ngen_AllocateBlock() +{ + generate_mainloop(); + return new DynaRBI(); +} + void ngen_HandleException() { longjmp(jmp_env, 1); From e7e387b443bb9616e68cf8d09b32e6e0ea1752f6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 24 May 2019 18:19:33 +0200 Subject: [PATCH 043/158] wince: enable/disable vmem32 based on mmu state --- core/hw/mem/_vmem.cpp | 22 +++++++++++++--------- core/hw/mem/_vmem.h | 2 +- core/hw/mem/vmem32.cpp | 24 ++++++++++++++++++++---- core/hw/mem/vmem32.h | 9 ++++----- core/hw/sh4/modules/mmu.cpp | 3 ++- core/linux/common.cpp | 2 +- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index a14787aec..7e4172ef1 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -530,9 +530,9 @@ bool _vmem_reserve() { const vmem_mapping mem_mappings[] = { // P1 {0x80000000, 0x80800000, 0, 0, false}, // Area 0 -> unused - {0x80800000, 0x80800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0x80800000, 0x80800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica {0x80800000 + ARAM_SIZE, 0x82800000, 0, 0, false}, // unused - {0x82800000, 0x82800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0x82800000, 0x82800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror {0x82800000 + ARAM_SIZE, 0x84000000, 0, 0, false}, // unused {0x84000000, 0x85000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0x85000000, 0x86000000, 0, 0, false}, // 32 bit path (unused) @@ -543,9 +543,9 @@ bool _vmem_reserve() { {0x90000000, 0xA0000000, 0, 0, false}, // Area 4-7 (unused) // P2 {0xA0000000, 0xA0800000, 0, 0, false}, // Area 0 -> unused - {0xA0800000, 0xA0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0xA0800000, 0xA0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica {0xA0800000 + ARAM_SIZE, 0xA2800000, 0, 0, false}, // unused - {0xA2800000, 0xA2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0xA2800000, 0xA2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror {0xA2800000 + ARAM_SIZE, 0xA4000000, 0, 0, false}, // unused {0xA4000000, 0xA5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0xA5000000, 0xA6000000, 0, 0, false}, // 32 bit path (unused) @@ -556,9 +556,9 @@ bool _vmem_reserve() { {0xB0000000, 0xC0000000, 0, 0, false}, // Area 4-7 (unused) // P3 {0xC0000000, 0xC0800000, 0, 0, false}, // Area 0 -> unused - {0xC0800000, 0xC0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica + {0xC0800000, 0xC0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica {0xC0800000 + ARAM_SIZE, 0xC2800000, 0, 0, false}, // unused - {0xC2800000, 0xC2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true},// Aica mirror + {0xC2800000, 0xC2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror {0xC2800000 + ARAM_SIZE, 0xC4000000, 0, 0, false}, // unused {0xC4000000, 0xC5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0xC5000000, 0xC6000000, 0, 0, false}, // 32 bit path (unused) @@ -605,12 +605,16 @@ void _vmem_release() { } } -void _vmem_disable_mmu() +void _vmem_enable_mmu(bool enable) { - if (vmem32_enabled()) + if (enable) + { + vmem32_init(); + } + else { // Restore P0/U0 mem mappings - vmem32_flush_mmu(); + vmem32_term(); _vmem_set_p0_mappings(); } } diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index c702b2fe1..5ea610c68 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -111,7 +111,7 @@ static inline bool _nvmem_4gb_space() { return vmem_4gb_space; } void _vmem_bm_reset(); -void _vmem_disable_mmu(); +void _vmem_enable_mmu(bool enable); #define MAP_RAM_START_OFFSET 0 #define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index ad06af617..65aec9958 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -50,6 +50,8 @@ static const u64 AREA7_ADDRESS = 0x7C000000L; static std::unordered_set vram_mapped_pages; static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +bool vmem32_inited; + // stats //u64 vmem32_page_faults; //u64 vmem32_flush; @@ -129,7 +131,7 @@ static void vmem32_unprotect_buffer(u32 start, u32 size) void vmem32_protect_vram(vram_block *block) { - if (virt_ram_base == NULL) + if (!vmem32_inited) return; for (int i = block->start / VRAM_PROT_SEGMENT; i <= block->end / VRAM_PROT_SEGMENT; i++) { @@ -138,7 +140,7 @@ void vmem32_protect_vram(vram_block *block) } void vmem32_unprotect_vram(vram_block *block) { - if (virt_ram_base == NULL) + if (!vmem32_inited) return; for (int page = block->start / VRAM_PROT_SEGMENT; page <= block->end / VRAM_PROT_SEGMENT; page++) { @@ -294,7 +296,7 @@ static u32 vmem32_map_address(u32 address, bool write) #if !defined(NO_MMU) && defined(HOST_64BIT_CPU) bool vmem32_handle_signal(void *fault_addr, bool write) { - if ((u8*)fault_addr < virt_ram_base || (u8*)fault_addr >= virt_ram_base + VMEM32_SIZE) + if (!vmem32_inited || (u8*)fault_addr < virt_ram_base || (u8*)fault_addr >= virt_ram_base + VMEM32_SIZE) return false; //vmem32_page_faults++; u32 guest_addr = (u8*)fault_addr - virt_ram_base; @@ -320,10 +322,24 @@ void vmem32_flush_mmu() // TODO flush P3? } +bool vmem32_init() +{ +#if HOST_OS == OS_WINDOWS + return false; +#else + if (settings.dynarec.disable_vmem32 || !_nvmem_4gb_space()) + return false; + + vmem32_inited = true; + return true; +#endif +} + void vmem32_term() { - if (virt_ram_base != NULL) + if (vmem32_inited) { + vmem32_inited = false; vmem32_flush_mmu(); } } diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index 809cdf192..977221b65 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -1,14 +1,13 @@ #include "_vmem.h" +bool vmem32_init(); void vmem32_term(); bool vmem32_handle_signal(void *fault_addr, bool write); void vmem32_flush_mmu(); void vmem32_protect_vram(vram_block *block); void vmem32_unprotect_vram(vram_block *block); + +extern bool vmem32_inited; static inline bool vmem32_enabled() { -#if HOST_OS == OS_WINDOWS - return false; -#else - return !settings.dynarec.disable_vmem32 && _nvmem_4gb_space(); -#endif + return vmem32_inited; } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 4d346aced..fdc152dc5 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -667,6 +667,7 @@ void mmu_set_state() WriteMem16 = &mmu_WriteMem; WriteMem32 = &mmu_WriteMem; WriteMem64 = &mmu_WriteMem; + _vmem_enable_mmu(true); mmu_flush_table(); } else @@ -681,7 +682,7 @@ void mmu_set_state() WriteMem16 = &_vmem_WriteMem16; WriteMem32 = &_vmem_WriteMem32; WriteMem64 = &_vmem_WriteMem64; - _vmem_disable_mmu(); + _vmem_enable_mmu(false); } } diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 5d860c9de..914354111 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -60,7 +60,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) bool dyna_cde = ((unat)CC_RX2RW(ctx.pc) > (unat)CodeCache) && ((unat)CC_RX2RW(ctx.pc) < (unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); -#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) && HOST_OS != OS_WINDOWS +#if !defined(NO_MMU) && defined(HOST_64BIT_CPU) #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; bool write = (op & 0x00400000) == 0; From 2c91ca96fcf0366f89fdf665b2e3c3851d2d036f Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 25 May 2019 18:03:18 +0200 Subject: [PATCH 044/158] rec-arm64: fix transitions to/from mmu exit mainloop() before regenerating it make sure dynarec cache is cleared between runs when deserializing, clear dynarec cache after setting mmu state --- core/hw/sh4/dyna/driver.cpp | 3 +- core/nullDC.cpp | 6 +-- core/rec-ARM64/rec_arm64.cpp | 85 +++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 324881bb0..6c5021e60 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -80,7 +80,7 @@ void clear_temp_cache(bool full) void recSh4_ClearCache() { - printf("recSh4:Dynarec Cache clear at %08X free space %d\n", curr_pc, emit_FreeSpace()); + printf("recSh4:Dynarec Cache clear at %08X free space %d\n", next_pc, emit_FreeSpace()); LastAddr=LastAddr_min; bm_Reset(); smc_hotspots.clear(); @@ -488,6 +488,7 @@ void recSh4_Skip() void recSh4_Reset(bool Manual) { Sh4_int_Reset(Manual); + recSh4_ClearCache(); } void recSh4_Init() diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 3bf1546ff..4325468bd 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -746,8 +746,8 @@ void SaveSettings() cfgSaveBool("config", "Dynarec.safe-mode", settings.dynarec.safemode); cfgSaveInt("config", "Dynarec.SmcCheckLevel", (int)settings.dynarec.SmcCheckLevel); - if (!disable_vmem32_game || !settings.dynarec.disable_vmem32) - cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); +// if (!disable_vmem32_game || !settings.dynarec.disable_vmem32) +// cfgSaveBool("config", "Dynarec.DisableVmem32", settings.dynarec.disable_vmem32); cfgSaveInt("config", "Dreamcast.Language", settings.dreamcast.language); cfgSaveInt("config", "aica.LimitFPS", (int)settings.aica.LimitFPS); cfgSaveBool("config", "aica.DSPEnabled", settings.aica.DSPEnabled); @@ -947,7 +947,6 @@ void dc_loadstate() data_ptr = data ; - sh4_cpu.ResetCache(); #if FEAT_AREC == DYNAREC_JIT FlushCache(); #endif @@ -964,6 +963,7 @@ void dc_loadstate() } mmu_set_state(); + sh4_cpu.ResetCache(); dsp.dyndirty = true; sh4_sched_ffts(); CalculateSync(); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 23be1a777..b1847ae60 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -138,15 +138,18 @@ __asm__ "br x0 \n" ); +static bool restarting; + void ngen_mainloop(void* v_cntx) { - generate_mainloop(); - mainloop(v_cntx); -} + do { + restarting = false; + generate_mainloop(); -static int setjmp_local(jmp_buf env) -{ - return setjmp(env); + mainloop(v_cntx); + if (restarting) + p_sh4rcb->cntx.CpuRunning = 1; + } while (restarting); } void ngen_init() @@ -162,6 +165,12 @@ void ngen_ResetBlocks() ngen_FailedToFindBlock = &ngen_FailedToFindBlock_mmu; else ngen_FailedToFindBlock = &ngen_FailedToFindBlock_nommu; + if (p_sh4rcb->cntx.CpuRunning) + { + // Force the dynarec out of mainloop() to regenerate it + p_sh4rcb->cntx.CpuRunning = 0; + restarting = true; + } } void ngen_GetFeatures(ngen_features* dst) @@ -1185,8 +1194,37 @@ public: { Label no_update; Label intc_sched; + Label end_mainloop; - mainloop = (void (*)(void *))GetBuffer()->GetStartAddress(); + // void intc_sched() + arm64_intc_sched = GetCursorAddress(); + B(&intc_sched); + + // void no_update() + Bind(&no_update); // next_pc _MUST_ be on w29 + + Ldr(w0, MemOperand(x28, offsetof(Sh4Context, CpuRunning))); + Cbz(w0, &end_mainloop); + if (!mmu_enabled()) + { + Sub(x2, x28, offsetof(Sh4RCB, cntx)); + if (RAM_SIZE == 32 * 1024 * 1024) + Ubfx(w1, w29, 1, 24); // 24+1 bits: 32 MB + else if (RAM_SIZE == 16 * 1024 * 1024) + Ubfx(w1, w29, 1, 23); // 23+1 bits: 16 MB + else + die("Unsupported RAM_SIZE"); + Ldr(x0, MemOperand(x2, x1, LSL, 3)); + } + else + { + Mov(w0, w29); + GenCallRuntime(bm_GetCodeByVAddr); + } + Br(x0); + + // void mainloop(void *context) + mainloop = GetCursorAddress(); // Save registers Stp(x19, x20, MemOperand(sp, -160, PreIndex)); @@ -1209,8 +1247,9 @@ public: Mov(w0, SH4_TIMESLICE); Str(w0, MemOperand(x1)); - Mov(x0, reinterpret_cast(jmp_env)); - GenCallRuntime(setjmp_local); + Ldr(x0, reinterpret_cast(jmp_env)); + Ldr(x1, reinterpret_cast(&setjmp)); + Blr(x1); Ldr(x28, MemOperand(sp)); // Set context } @@ -1222,7 +1261,6 @@ public: Mov(w27, SH4_TIMESLICE); } Label do_interrupts; - Label end_mainloop; // w29 is next_pc Ldr(w29, MemOperand(x28, offsetof(Sh4Context, pc))); @@ -1230,8 +1268,6 @@ public: Bind(&intc_sched); - Ldr(w0, MemOperand(x28, offsetof(Sh4Context, CpuRunning))); - Cbz(w0, &end_mainloop); // Add timeslice to cycle counter if (!mmu_enabled()) { @@ -1255,25 +1291,7 @@ public: GenCallRuntime(rdv_DoInterrupts); // Updates next_pc based on host pc Mov(w29, w0); - Bind(&no_update); // next_pc _MUST_ be on w29 - - if (!mmu_enabled()) - { - Sub(x2, x28, offsetof(Sh4RCB, cntx)); - if (RAM_SIZE == 32 * 1024 * 1024) - Ubfx(w1, w29, 1, 24); // 24+1 bits: 32 MB - else if (RAM_SIZE == 16 * 1024 * 1024) - Ubfx(w1, w29, 1, 23); // 23+1 bits: 16 MB - else - die("Unsupported RAM_SIZE"); - Ldr(x0, MemOperand(x2, x1, LSL, 3)); - } - else - { - Mov(w0, w29); - GenCallRuntime(bm_GetCodeByVAddr); - } - Br(x0); + B(&no_update); Bind(&end_mainloop); if (mmu_enabled()) @@ -1295,8 +1313,7 @@ public: FinalizeCode(); emit_Skip(GetBuffer()->GetSizeInBytes()); - arm64_intc_sched = (void (*)())GetBuffer()->GetOffsetAddress(intc_sched.GetLocation()); - arm64_no_update = (void (*)())GetBuffer()->GetOffsetAddress(no_update.GetLocation()); + arm64_no_update = GetLabelAddress(&no_update); // Flush and invalidate caches vmem_platform_flush_cache( @@ -1933,8 +1950,6 @@ void ngen_HandleException() u32 DynaRBI::Relink() { - if (mmu_enabled()) - return 0; //printf("DynaRBI::Relink %08x\n", this->addr); Arm64Assembler *compiler = new Arm64Assembler((u8 *)this->code + this->relink_offset); From 506756ea370e2907db6e0af53eabec6b7753b4f1 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 25 May 2019 18:48:00 +0200 Subject: [PATCH 045/158] android: use common rend_thread() instead of a specific one fixes the swap pending issue (double swap) on android --- core/hw/pvr/Renderer_if.cpp | 13 ++++++-- core/hw/pvr/Renderer_if.h | 6 ++-- core/rend/gui.cpp | 1 - .../reicast/src/main/jni/src/Android.cpp | 32 +++---------------- 4 files changed, 20 insertions(+), 32 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index d7ce6720b..52fff6364 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -78,8 +78,9 @@ u32 FrameCount=1; Renderer* renderer; static Renderer* fallback_renderer; -bool renderer_enabled = true; // Signals the renderer thread to exit -bool renderer_changed = false; // Signals the renderer thread to switch renderer +volatile bool renderer_enabled = true; // Signals the renderer thread to exit +volatile bool renderer_changed = false; // Signals the renderer thread to switch renderer +volatile bool renderer_reinit_requested = false; // Signals the renderer thread to reinit the renderer #if !defined(TARGET_NO_THREADS) cResetEvent rs, re; @@ -398,6 +399,8 @@ void rend_term_renderer() void* rend_thread(void* p) { + renderer_enabled = true; + rend_init_renderer(); //we don't know if this is true, so let's not speculate here @@ -416,10 +419,16 @@ void* rend_thread(void* p) if (renderer_changed) { renderer_changed = false; + renderer_reinit_requested = false; rend_term_renderer(); rend_create_renderer(); rend_init_renderer(); } + else if (renderer_reinit_requested) + { + renderer_reinit_requested = false; + rend_init_renderer(); + } } rend_term_renderer(); diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index 2cdec4db4..6784d2db0 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -14,6 +14,7 @@ void rend_end_render(); void rend_cancel_emu_wait(); bool rend_single_frame(); void rend_swap_frame(); +void *rend_thread(void *); void rend_set_fb_scale(float x,float y); void rend_resize(int width, int height); @@ -52,8 +53,9 @@ struct Renderer }; extern Renderer* renderer; -extern bool renderer_enabled; // Signals the renderer thread to exit -extern bool renderer_changed; // Signals the renderer thread to switch renderer +extern volatile bool renderer_enabled; // Signals the renderer thread to exit +extern volatile bool renderer_changed; // Signals the renderer thread to switch renderer +extern volatile bool renderer_reinit_requested; // Signals the renderer thread to reinit the renderer Renderer* rend_GLES2(); #if !defined(GLES) && HOST_OS != OS_DARWIN diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 69327efcf..c2d4d46ca 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -62,7 +62,6 @@ extern u32 mo_buttons; extern f32 mo_x_delta; extern f32 mo_y_delta; extern f32 mo_wheel_delta; -extern bool renderer_changed; int screen_dpi = 96; diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 07521e6ee..3800636ae 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -401,36 +401,14 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env, job return 0; } -extern void gl_swap(); extern void egl_stealcntx(); -volatile static bool render_running; -volatile static bool render_reinit; -void *render_thread_func(void *) +static void *render_thread_func(void *) { - render_running = true; + rend_thread(NULL); - rend_init_renderer(); - - while (render_running) { - if (render_reinit) - { - render_reinit = false; - rend_init_renderer(); - } - else - if (!egl_makecurrent()) - break;; - - bool ret = rend_single_frame(); - if (ret) - gl_swap(); - } - egl_makecurrent(); - rend_term_renderer(); - ANativeWindow_release(g_window); + ANativeWindow_release(g_window); g_window = NULL; - render_running = false; return NULL; } @@ -443,11 +421,11 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv { if (surface == NULL) { - render_running = false; + renderer_enabled = false; render_thread.WaitToEnd(); } else - render_reinit = true; + renderer_reinit_requested = true; } else if (surface != NULL) { From 5b2cef3fdd58e497836f714126f171e9c0409712 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 26 May 2019 13:30:05 +0200 Subject: [PATCH 046/158] dynarec: add negc and xtrct op codes native implementation of negc and xtrct for x64 and arm64 rec-arm64: pass exception pc in w27 instead of sh4 context inline mmu_intruction_translation() and clean up --- core/hw/mem/vmem32.cpp | 6 ++- core/hw/mem/vmem32.h | 2 +- core/hw/sh4/dyna/blockmanager.cpp | 5 +- core/hw/sh4/dyna/decoder.cpp | 4 ++ core/hw/sh4/dyna/driver.cpp | 3 +- core/hw/sh4/dyna/shil_canonical.h | 38 ++++++++++++++ core/hw/sh4/modules/fastmmu.cpp | 85 ------------------------------- core/hw/sh4/modules/mmu.cpp | 9 ++-- core/hw/sh4/modules/mmu.h | 21 +++++++- core/hw/sh4/sh4_opcode_list.cpp | 4 +- core/hw/sh4/sh4_opcode_list.h | 1 + core/linux/common.cpp | 4 +- core/linux/context.cpp | 1 + core/linux/context.h | 2 + core/rec-ARM64/rec_arm64.cpp | 32 +++++++----- core/rec-x64/rec_x64.cpp | 37 +++++++++++++- core/windows/winmain.cpp | 2 +- 17 files changed, 139 insertions(+), 117 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 65aec9958..21056982a 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -294,7 +294,7 @@ static u32 vmem32_map_address(u32 address, bool write) } #if !defined(NO_MMU) && defined(HOST_64BIT_CPU) -bool vmem32_handle_signal(void *fault_addr, bool write) +bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc) { if (!vmem32_inited || (u8*)fault_addr < virt_ram_base || (u8*)fault_addr >= virt_ram_base + VMEM32_SIZE) return false; @@ -306,7 +306,11 @@ bool vmem32_handle_signal(void *fault_addr, bool write) return true; if (rv == VMEM32_ERROR_NOT_MAPPED) return false; +#if HOST_CPU == CPU_ARM64 + p_sh4rcb->cntx.pc = exception_pc; +#else p_sh4rcb->cntx.pc = p_sh4rcb->cntx.exception_pc; +#endif DoMMUException(guest_addr, rv, write ? MMU_TT_DWRITE : MMU_TT_DREAD); ngen_HandleException(); // not reached diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index 977221b65..de11ce2ed 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -2,7 +2,7 @@ bool vmem32_init(); void vmem32_term(); -bool vmem32_handle_signal(void *fault_addr, bool write); +bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc); void vmem32_flush_mmu(); void vmem32_protect_vram(vram_block *block); void vmem32_unprotect_vram(vram_block *block); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 5c75ea41f..0b841c250 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -144,12 +144,11 @@ DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) } u32 paddr; - bool shared; - u32 rv = mmu_instruction_translation(addr, paddr, shared); + u32 rv = mmu_instruction_translation(addr, paddr); if (rv != MMU_ERROR_NONE) { DoMMUException(addr, rv, MMU_TT_IREAD); - mmu_instruction_translation(next_pc, paddr, shared); + mmu_instruction_translation(next_pc, paddr); } return bm_GetCode(paddr); diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 61b1bc2c3..1d98ac412 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -980,6 +980,10 @@ bool dec_generic(u32 op) } break; + case DM_NEGC: + Emit(natop, rs1, rs2, mk_reg(reg_sr_T), 0, shil_param(), mk_reg(reg_sr_T)); + break; + default: verify(false); } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 6c5021e60..77d75bce1 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -248,8 +248,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) vaddr = rpc; if (mmu_enabled()) { - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) { DoMMUException(vaddr, rv, MMU_TT_IREAD); diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index b8624e4e0..ad9035cad 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -347,6 +347,28 @@ shil_compile ) shil_opc_end() +//shop_negc - Negate with carry +shil_opc(negc) +shil_canonical +( +u64,f1,(u32 r1, u32 C), + u64 res = -(u64)r1 - C; + + u64 rv; + ((u32*)&rv)[0]=res; + ((u32*)&rv)[1]=(res>>32)&1; + + return rv; +) + +shil_compile +( + shil_cf_arg_u32(rs2); + shil_cf_arg_u32(rs1); + shil_cf(f1); + shil_cf_rv_u64(rd); +) +shil_opc_end() //shop_ror shil_opc(ror) @@ -1002,6 +1024,22 @@ shil_compile ) shil_opc_end() +//shop_xtrct +shil_opc(xtrct) +shil_canonical +( +u32,f1,(u32 r1, u32 r2), + return (r1 >> 16) | (r2 << 16); +) +shil_compile +( + shil_cf_arg_ptr(rs2); + shil_cf_arg_ptr(rs1); + shil_cf_arg_ptr(rd); + shil_cf(f1); +) +shil_opc_end() + SHIL_END diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index 2211e3e04..a2723ea96 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -26,7 +26,6 @@ extern u32 sq_remap[64]; #define printf_win32(...) extern const u32 mmu_mask[4]; -extern const u32 fast_reg_lut[8]; const TLB_Entry *lru_entry = NULL; static u32 lru_mask; @@ -276,20 +275,12 @@ u32 mmu_data_translation(u32 va, u32& rv) } } -// if ((sr.MD == 0) && (va & 0x80000000) != 0) -// { -// //if on kernel, and not SQ addr -> error -// return MMU_ERROR_BADADDR; -// } - if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000)) { rv = va; return MMU_ERROR_NONE; } - // Not called if CCN_MMUCR.AT == 0 - //if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) if (fast_reg_lut[va >> 29] != 0) { rv = va; @@ -299,9 +290,6 @@ u32 mmu_data_translation(u32 va, u32& rv) const TLB_Entry *entry; u32 lookup = mmu_full_lookup(va, &entry, rv); -// if (lookup != MMU_ERROR_NONE) -// return lookup; - #ifdef TRACE_WINCE_SYSCALLS if (unresolved_unicode_string != 0 && lookup == MMU_ERROR_NONE) { @@ -313,34 +301,6 @@ u32 mmu_data_translation(u32 va, u32& rv) } #endif -// u32 md = entry->Data.PR >> 1; -// -// //0X & User mode-> protection violation -// //Priv mode protection -// if ((md == 0) && sr.MD == 0) -// { -// die("MMU_ERROR_PROTECTED"); -// return MMU_ERROR_PROTECTED; -// } -// -// //X0 -> read olny -// //X1 -> read/write , can be FW -// -// //Write Protection (Lock or FW) -// if (translation_type == MMU_TT_DWRITE) -// { -// if ((entry->Data.PR & 1) == 0) -// { -// die("MMU_ERROR_PROTECTED"); -// return MMU_ERROR_PROTECTED; -// } -// else if (entry->Data.D == 0) -// { -// die("MMU_ERROR_FIRSTWRITE"); -// return MMU_ERROR_FIRSTWRITE; -// } -// } - return lookup; } template u32 mmu_data_translation(u32 va, u32& rv); @@ -353,53 +313,8 @@ template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) -{ - if (va & 1) - { - return MMU_ERROR_BADADDR; - } -// if ((sr.MD == 0) && (va & 0x80000000) != 0) -// { -// //if SQ disabled , or if if SQ on but out of SQ mem then BAD ADDR ;) -// if (va >= 0xE0000000) -// return MMU_ERROR_BADADDR; -// } - - if ((CCN_MMUCR.AT == 0) || (fast_reg_lut[va >> 29] != 0)) - { - rv = va; - return MMU_ERROR_NONE; - } - - // Hack fast implementation - const TLB_Entry *tlb_entry; - u32 lookup = mmu_full_lookup(va, &tlb_entry, rv); - if (lookup != MMU_ERROR_NONE) - return lookup; - u32 md = tlb_entry->Data.PR >> 1; - //0X & User mode-> protection violation - //Priv mode protection -// if ((md == 0) && sr.MD == 0) -// { -// return MMU_ERROR_PROTECTED; -// } - shared = tlb_entry->Data.SH == 1; - return MMU_ERROR_NONE; -} - void mmu_flush_table() { -// printf("MMU tables flushed\n"); - -// ITLB[0].Data.V = 0; -// ITLB[1].Data.V = 0; -// ITLB[2].Data.V = 0; -// ITLB[3].Data.V = 0; -// -// for (u32 i = 0; i < 64; i++) -// UTLB[i].Data.V = 0; - lru_entry = NULL; flush_cache(); } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index fdc152dc5..b8a416c53 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -562,7 +562,7 @@ template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); template u32 mmu_data_translation(u32 va, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared) +u32 mmu_instruction_translation(u32 va, u32& rv) { if (va & 1) { @@ -603,7 +603,6 @@ retry_ITLB_Match: nom++; //VPN->PPN | low bits rv = ((ITLB[i].Data.PPN << 10)&mask) | (va&(~mask)); - shared = ITLB[i].Data.SH == 1; } } } @@ -745,8 +744,7 @@ T DYNACALL mmu_ReadMem(u32 adr) u16 DYNACALL mmu_IReadMem16(u32 vaddr) { u32 addr; - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) mmu_raise_exception(rv, vaddr, MMU_TT_IREAD); return _vmem_ReadMem16(addr); @@ -787,8 +785,7 @@ template u64 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) { u32 addr; - bool shared; - u32 rv = mmu_instruction_translation(vaddr, addr, shared); + u32 rv = mmu_instruction_translation(vaddr, addr); if (rv != MMU_ERROR_NONE) { DoMMUException(vaddr, rv, MMU_TT_IREAD); diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index 98f81a1ca..15a1c1648 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -36,6 +36,7 @@ struct TLB_Entry extern TLB_Entry UTLB[64]; extern TLB_Entry ITLB[4]; extern u32 sq_remap[64]; +extern const u32 fast_reg_lut[8]; //These are working only for SQ remaps on ndce bool UTLB_Sync(u32 entry); @@ -56,7 +57,25 @@ static INLINE bool mmu_enabled() template u32 mmu_full_lookup(u32 va, const TLB_Entry **entry, u32& rv); -u32 mmu_instruction_translation(u32 va, u32& rv, bool& shared); + +#ifdef FAST_MMU +static INLINE u32 mmu_instruction_translation(u32 va, u32& rv) +{ + if (va & 1) + return MMU_ERROR_BADADDR; + if (fast_reg_lut[va >> 29] != 0) + { + rv = va; + return MMU_ERROR_NONE; + } + + const TLB_Entry *tlb_entry; + return mmu_full_lookup(va, &tlb_entry, rv); +} +#else +u32 mmu_instruction_translation(u32 va, u32& rv); +#endif + template extern u32 mmu_data_translation(u32 va, u32& rv); void DoMMUException(u32 addr, u32 error_code, u32 access_type); diff --git a/core/hw/sh4/sh4_opcode_list.cpp b/core/hw/sh4/sh4_opcode_list.cpp index 617e01662..7ae9b64ef 100644 --- a/core/hw/sh4/sh4_opcode_list.cpp +++ b/core/hw/sh4/sh4_opcode_list.cpp @@ -159,7 +159,7 @@ sh4_opcodelistentry opcodes[]= {0 ,i0010_nnnn_mmmm_1010 ,Mask_n_m ,0x200A ,Normal ,"xor ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xor)}, //xor , {0 ,i0010_nnnn_mmmm_1011 ,Mask_n_m ,0x200B ,Normal ,"or ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_or)}, //or , {0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal |NO_FP,"cmp/str ," ,1,1,MT,fix_none ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str , - {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal |NO_FP,"xtrct ," ,1,1,EX,fix_none}, //xtrct , + {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal |NO_FP,"xtrct ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xtrct)}, //xtrct , {0 ,i0010_nnnn_mmmm_1110 ,Mask_n_m ,0x200E ,Normal ,"mulu.w ," ,1,4,CO,fix_none ,dec_mul(16)}, //mulu.w , {0 ,i0010_nnnn_mmmm_1111 ,Mask_n_m ,0x200F ,Normal ,"muls.w ," ,1,4,CO,fix_none ,dec_mul(-16)}, //muls.w , {0 ,i0011_nnnn_mmmm_0000 ,Mask_n_m ,0x3000 ,Normal ,"cmp/eq ," ,1,1,MT,fix_none ,dec_cmp(shop_seteq,PRM_RN,PRM_RM)}, // cmp/eq , @@ -317,7 +317,7 @@ sh4_opcodelistentry opcodes[]= {0 ,i0110_nnnn_mmmm_0111 ,Mask_n_m ,0x6007 ,Normal ,"not ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_not)}, //not , {0 ,i0110_nnnn_mmmm_1000 ,Mask_n_m ,0x6008 ,Normal ,"swap.b ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_swaplb)}, //swap.b , {0 ,i0110_nnnn_mmmm_1001 ,Mask_n_m ,0x6009 ,Normal ,"swap.w ," ,1,1,EX,fix_none ,dec_Fill(DM_Rot,PRM_RN,PRM_RM,shop_ror,16|0x1000)}, //swap.w , - {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,fix_none}, //negc , + {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,fix_none ,dec_Fill(DM_NEGC,PRM_RN,PRM_RM,shop_negc)}, //negc , {0 ,i0110_nnnn_mmmm_1011 ,Mask_n_m ,0x600B ,Normal ,"neg ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_neg)}, //neg , {0 ,i0110_nnnn_mmmm_1100 ,Mask_n_m ,0x600C ,Normal ,"extu.b ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,1)}, //extu.b , {0 ,i0110_nnnn_mmmm_1101 ,Mask_n_m ,0x600D ,Normal ,"extu.w ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,2)}, //extu.w , diff --git a/core/hw/sh4/sh4_opcode_list.h b/core/hw/sh4/sh4_opcode_list.h index 0f6dfbf64..d65436097 100644 --- a/core/hw/sh4/sh4_opcode_list.h +++ b/core/hw/sh4/sh4_opcode_list.h @@ -152,4 +152,5 @@ enum DecMode DM_MUL, DM_DIV0, DM_ADC, + DM_NEGC, }; diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 914354111..9d12aae26 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -64,10 +64,12 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; bool write = (op & 0x00400000) == 0; + u32 exception_pc = ctx.x27; #elif HOST_CPU == CPU_X64 bool write = false; // TODO? + u32 exception_pc = 0; #endif - if (vmem32_handle_signal(si->si_addr, write)) + if (vmem32_handle_signal(si->si_addr, write, exception_pc)) return; #endif if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) diff --git a/core/linux/context.cpp b/core/linux/context.cpp index 7c317c401..ca63b6e47 100644 --- a/core/linux/context.cpp +++ b/core/linux/context.cpp @@ -53,6 +53,7 @@ void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_se #endif #elif HOST_CPU == CPU_ARM64 bicopy(reictx->pc, MCTX(.pc), to_segfault); + bicopy(reictx->x27, MCTX(.regs[27]), to_segfault); #elif HOST_CPU == CPU_X86 #if defined(__FreeBSD__) bicopy(reictx->pc, MCTX(.mc_eip), to_segfault); diff --git a/core/linux/context.h b/core/linux/context.h index c97de30e9..30c5b0bb8 100644 --- a/core/linux/context.h +++ b/core/linux/context.h @@ -14,6 +14,8 @@ struct rei_host_context_t { u32 esp; #elif HOST_CPU == CPU_ARM u32 r[15]; +#elif HOST_CPU == CPU_ARM64 + u64 x27; #endif }; diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index b1847ae60..7d1b02a76 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -545,6 +545,11 @@ public: Sbcs(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); // (C,rd) = rs1 - rs2 - ~rs3(C) Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C break; + case shop_negc: + Cmp(wzr, regalloc.MapRegister(op.rs2)); // C = ~rs2 + Sbcs(regalloc.MapRegister(op.rd), wzr, regalloc.MapRegister(op.rs1)); // (C,rd) = 0 - rs1 - ~rs2(C) + Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + break; case shop_rocr: Ubfx(w0, regalloc.MapRegister(op.rs1), 0, 1); // w0 = rs1[0] (new C) @@ -703,6 +708,12 @@ public: Sxth(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); break; + case shop_xtrct: + Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), 16); + Lsl(w0, regalloc.MapRegister(op.rs2), 16); + Orr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w0); + break; + // // FPU // @@ -1502,7 +1513,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1515,10 +1526,8 @@ private: if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - // 3 ops before memory access - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); + Mov(w27, exception_pc & 0xFFFF); + Movk(w27, exception_pc >> 16, 16); } } @@ -1626,7 +1635,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (4 when mmu is enabled) + // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1639,9 +1648,8 @@ private: if (mmu_enabled()) { u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - Mov(w8, exception_pc & 0xFFFF); - Movk(w8, exception_pc >> 16, 16); - Str(w8, sh4_context_mem_operand(&p_sh4rcb->cntx.exception_pc)); // TODO Store exception_pc is w27 ? + Mov(w27, exception_pc & 0xFFFF); + Movk(w27, exception_pc >> 16, 16); } } @@ -1845,9 +1853,9 @@ private: std::vector call_fregs; Arm64RegAlloc regalloc; RuntimeBlockInfo* block = NULL; - const int read_memory_rewrite_size = 6; // worst case for u64: add, bfc, ldr, fmov, lsr, fmov + const int read_memory_rewrite_size = 5; // worst case for u64/mmu: add, mov, movk, ldr, str // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 5; // TODO only 2 if !mmu & 4gb + const int write_memory_rewrite_size = 4; // TODO only 2 if !mmu & 4gb }; static Arm64Assembler* compiler; @@ -1905,7 +1913,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) verify(opid < block->oplist.size()); const shil_opcode& op = block->oplist[opid]; // Skip the preceding ops (add, bic, ...) - u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 3 : 0); + u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 2 : 0); Arm64Assembler *assembler = new Arm64Assembler(code_rewrite); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 61531ba36..37b66e578 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -43,6 +43,9 @@ extern "C" { double host_cpu_time; u64 guest_cpu_cycles; +u32 mem_writes, mem_reads; +u32 mem_rewrites_w, mem_rewrites_r; + #ifdef PROFILING static double slice_start; extern "C" @@ -597,9 +600,9 @@ public: cmp(regalloc.MapRegister(op.rs3), 1); // C = ~rs3 cmc(); // C = rs3 adc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2)); // (C,rd)=rs1+rs2+rs3(C) - setc(al); - movzx(regalloc.MapRegister(op.rd2), al); // rd2 = C + setc(regalloc.MapRegister(op.rd2).cvt8()); // rd2 = C break; + /* FIXME buggy case shop_sbc: if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) @@ -614,6 +617,19 @@ public: cmovc(regalloc.MapRegister(op.rd2), ecx); // rd2 = C break; */ + case shop_negc: + { + if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + Xbyak::Reg64 rd64 = regalloc.MapRegister(op.rd).cvt64(); + neg(rd64); + sub(rd64, regalloc.MapRegister(op.rs2).cvt64()); + Xbyak::Reg64 rd2_64 = regalloc.MapRegister(op.rd2).cvt64(); + mov(rd2_64, rd64); + shr(rd2_64, 63); + } + break; + case shop_rocr: case shop_rocl: if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) @@ -797,6 +813,15 @@ public: movsx(regalloc.MapRegister(op.rd), Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); break; + case shop_xtrct: + if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + shr(regalloc.MapRegister(op.rd), 16); + mov(eax, regalloc.MapRegister(op.rs2)); + shl(eax, 16); + or_(regalloc.MapRegister(op.rd), eax); + break; + // // FPU // @@ -1397,6 +1422,7 @@ private: { if (!mmu_enabled() || !vmem32_enabled()) return false; + mem_reads++; const u8 *start_addr = getCurr(); mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); @@ -1445,6 +1471,7 @@ private: { if (!mmu_enabled() || !vmem32_enabled()) return false; + mem_writes++; const u8 *start_addr = getCurr(); mov(rax, (uintptr_t)&p_sh4rcb->cntx.exception_pc); @@ -1839,9 +1866,15 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) BlockCompiler *assembler = new BlockCompiler(code_ptr - BlockCompiler::mem_access_offset); assembler->InitializeRewrite(block, opid); if (op.op == shop_readm) + { + mem_rewrites_r++; assembler->GenReadMemorySlow(op, block); + } else + { + mem_rewrites_w++; assembler->GenWriteMemorySlow(op, block); + } assembler->FinalizeRewrite(); verify(block->host_code_size >= assembler->getSize()); delete assembler; diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 0c3ed0a12..4418f0523 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -146,7 +146,7 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) //printf("[EXC] During access to : 0x%X\n", address); #if 0 bool write = false; // TODO? - if (vmem32_handle_signal(address, write)) + if (vmem32_handle_signal(address, write, 0)) return EXCEPTION_CONTINUE_EXECUTION; #endif From c6e92028f2bf7e3a8fe9ecb68089a77cf57042ea Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 27 May 2019 22:44:51 +0200 Subject: [PATCH 047/158] regalloc: cleanup. no functional change --- core/hw/sh4/dyna/regalloc.h | 219 ++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 123 deletions(-) diff --git a/core/hw/sh4/dyna/regalloc.h b/core/hw/sh4/dyna/regalloc.h index 774d3d4a6..4b3fd7b04 100644 --- a/core/hw/sh4/dyna/regalloc.h +++ b/core/hw/sh4/dyna/regalloc.h @@ -228,10 +228,10 @@ struct RegAlloc bool IsAllocg(Sh4RegType reg) { - for (u32 sid=0;sidregstart==(u32)reg && all_spans[sid]->contains(current_opid)) - return !all_spans[sid]->fpr; + if (span->regstart == (u32)reg && span->contains(current_opid)) + return !span->fpr; } return false; @@ -252,10 +252,10 @@ struct RegAlloc bool IsAllocf(Sh4RegType reg) { - for (u32 sid=0;sidregstart==(u32)reg && all_spans[sid]->contains(current_opid)) - return all_spans[sid]->fpr; + if (span->regstart == (u32)reg && span->contains(current_opid)) + return span->fpr; } return false; @@ -405,11 +405,11 @@ struct RegAlloc RegSpan* FindSpan(Sh4RegType reg, u32 opid) { - for (u32 sid=0;sidregstart==(u32)reg && all_spans[sid]->contains(opid)) + if (span->regstart == (u32)reg && span->contains(opid)) { - return all_spans[sid]; + return span; } } die("Failed to find span"); @@ -432,13 +432,6 @@ struct RegAlloc { op=&block->oplist[opid]; - /* - if (op->op!=shop_readm && op->op!=shop_writem && ( op->rd.is_vector() ||op->rs1.is_vector())) - { - // __asm int 3; - }*/ - - //if (op->op != shop_readm && op->op != shop_writem && op->op != shop_jcond && op->op != shop_jdyn && op->op != shop_mov32 && op->op != shop_mov64 && (op->op != shop_add || block->addr<=0x8c0DA0BA)) if (IsFlushOp(block,opid)) { bool fp=false,gpr_b=false,all=false; @@ -564,29 +557,29 @@ struct RegAlloc { reg_rd.erase(*iter); { - if ((*iter).is_reg()) + if (iter->is_reg()) { //r~w - if ((*iter).is_r32()) + if (iter->is_r32()) { - if (spans[(*iter)._reg]==0) + if (spans[iter->_reg]==0) { - spans[(*iter)._reg] = new RegSpan((*iter),opid,AM_READWRITE); - all_spans.push_back(spans[(*iter)._reg]); + spans[iter->_reg] = new RegSpan(*iter, opid, AM_READWRITE); + all_spans.push_back(spans[iter->_reg]); } else { - spans[(*iter)._reg]->Access(opid,AM_READWRITE); + spans[iter->_reg]->Access(opid, AM_READWRITE); } } else { - for (u32 i=0; i<(*iter).count(); i++) + for (u32 i = 0; i < iter->count(); i++) { - if (spans[(*iter)._reg+i]!=0) - spans[(*iter)._reg+i]->Flush(); + if (spans[iter->_reg + i] != 0) + spans[iter->_reg + i]->Flush(); - spans[(*iter)._reg+i]=0; + spans[iter->_reg + i]=0; } } } @@ -594,65 +587,65 @@ struct RegAlloc } else { - if ((*iter).is_reg()) + if (iter->is_reg()) { - for (u32 i=0; i<(*iter).count(); i++) + for (u32 i = 0; i < iter->count(); i++) { - if (spans[(*iter)._reg+i]!=0) + if (spans[iter->_reg + i] != 0) { //hack// //this is a bug on the current reg alloc code, affects fipr. //generally, vector registers aren't treated correctly //as groups of phy registers. I really need a better model //to accommodate for that on the reg alloc side of things .. - if ((*iter).count()==1 && iter->_reg==op->rs1._reg+3) - spans[(*iter)._reg+i]->Flush(); + if (iter->count() == 1 && iter->_reg == op->rs1._reg + 3) + spans[iter->_reg + i]->Flush(); else - spans[(*iter)._reg+i]->Kill(); + spans[iter->_reg + i]->Kill(); } - spans[(*iter)._reg+i]=0; + spans[iter->_reg + i] = 0; } //w - if ((*iter).is_r32()) + if (iter->is_r32()) { - if (spans[(*iter)._reg]!=0) - spans[(*iter)._reg]->Kill(); + if (spans[iter->_reg] != 0) + spans[iter->_reg]->Kill(); - spans[(*iter)._reg]= new RegSpan((*iter),opid,AM_WRITE); - all_spans.push_back(spans[(*iter)._reg]); + spans[iter->_reg] = new RegSpan(*iter, opid, AM_WRITE); + all_spans.push_back(spans[iter->_reg]); } } } ++iter; } - iter=reg_rd.begin(); - while( iter != reg_rd.end() ) + iter = reg_rd.begin(); + while (iter != reg_rd.end()) { //r - if ((*iter).is_reg()) + if (iter->is_reg()) { - if ((*iter).is_r32()) + if (iter->is_r32()) { - if (spans[(*iter)._reg]==0) + if (spans[iter->_reg] == 0) { - spans[(*iter)._reg] = new RegSpan((*iter),opid,AM_READ); - all_spans.push_back(spans[(*iter)._reg]); + spans[iter->_reg] = new RegSpan((*iter), opid, AM_READ); + all_spans.push_back(spans[iter->_reg]); } else { - spans[(*iter)._reg]->Access(opid,AM_READ); + spans[iter->_reg]->Access(opid, AM_READ); } } else { - for (u32 i=0; i<(*iter).count(); i++) + for (u32 i = 0; i < iter->count(); i++) { - if (spans[(*iter)._reg+i]!=0) - spans[(*iter)._reg+i]->Flush(); + if (spans[iter->_reg + i] != 0) + spans[iter->_reg + i]->Flush(); - spans[(*iter)._reg+i]=0; + spans[iter->_reg + i] = 0; } } } @@ -698,11 +691,11 @@ struct RegAlloc u32 cc_g=0; u32 cc_f=0; - for (u32 sid=0;sidcontains(opid)) + if (span->contains(opid)) { - if (all_spans[sid]->fpr) + if (span->fpr) cc_f++; else cc_g++; @@ -768,22 +761,20 @@ struct RegAlloc if (!alias_mov) { - for (u32 sid=0;sidbegining(opid)) + if (span->begining(opid)) { - if (spn->fpr) + if (span->fpr) { verify(regsf.size()>0); - spn->nregf=regsf.back(); + span->nregf=regsf.back(); regsf.pop_back(); } else { verify(regs.size()>0); - spn->nreg=regs.back(); + span->nreg=regs.back(); regs.pop_back(); //printf("rALOC %d from %d\n",spn->regstart,spn->nreg); @@ -791,21 +782,19 @@ struct RegAlloc } } } - for (u32 sid=0;sidending(opid) && !spn->aliased) + if (span->ending(opid) && !span->aliased) { - if (spn->fpr) + if (span->fpr) { verify(regsf.size()nregf); + regsf.push_front(span->nregf); } else { verify(regs.size()nreg); + regs.push_front(span->nreg); //printf("rFREE %d from %d\n",spn->regstart,spn->nreg); } } @@ -970,41 +959,39 @@ struct RegAlloc RegSpan* last_pacc=0; RegSpan* last_nacc=0; - for (u32 sid=0;sidcontains(opid) && fpr==spn->fpr) + if (span->contains(opid) && fpr==span->fpr) { - if (!spn->cacc(opid)) + if (!span->cacc(opid)) { - if (!last_nacc || spn->nacc(opid)>last_nacc->nacc(opid)) - last_nacc=spn; + if (!last_nacc || span->nacc(opid)>last_nacc->nacc(opid)) + last_nacc=span; - if (!last_pacc || spn->pacc(opid)pacc(opid)) - last_pacc=spn; + if (!last_pacc || span->pacc(opid)pacc(opid)) + last_pacc=span; } if (was_large) - printf("\t[%c]span: %d (r%d), [%d:%d],n: %d, p: %d\n",spn->cacc(opid)?'x':' ',sid,all_spans[sid]->regstart,all_spans[sid]->start,all_spans[sid]->end,all_spans[sid]->nacc(opid),all_spans[sid]->pacc(opid)); + printf("\t[%c]span: r%d, [%d:%d],n: %d, p: %d\n",span->cacc(opid)?'x':' ',span->regstart,span->start,span->end,span->nacc(opid),span->pacc(opid)); } } //printf("Last pacc: %d, vlen %d | reg r%d\n",last_pacc->nacc(opid)-opid,last_pacc->nacc(opid)-last_pacc->pacc(opid),last_pacc->regstart); //printf("Last nacc: %d, vlen %d | reg r%d\n",last_nacc->nacc(opid)-opid,last_nacc->nacc(opid)-last_nacc->pacc(opid),last_nacc->regstart); - RegSpan* spn= new RegSpan(*last_nacc); - spn->start=last_nacc->nacc(opid); + RegSpan* span= new RegSpan(*last_nacc); + span->start=last_nacc->nacc(opid); last_nacc->end=last_nacc->pacc(opid); //trim the access arrays as required .. - spn->trim_access(); + span->trim_access(); last_nacc->trim_access(); - spn->preload=spn->NeedsPL(); + span->preload=span->NeedsPL(); last_nacc->writeback=last_nacc->NeedsWB(); //add it to the span list ! - all_spans.push_back(spn); + all_spans.push_back(span); spills++; cc--; } @@ -1014,9 +1001,9 @@ struct RegAlloc { verify(reg!=-1); int cc=0; - for (u32 sid=0;sidregstart==reg && all_spans[sid]->contains(opid)) + if (span->regstart == reg && span->contains(opid)) cc++; } return cc; @@ -1026,9 +1013,9 @@ struct RegAlloc { verify(nreg!=-1); int cc=0; - for (u32 sid=0;sidnreg==nreg && all_spans[sid]->contains(opid)) + if (span->nreg == nreg && span->contains(opid)) cc++; } return cc; @@ -1038,9 +1025,9 @@ struct RegAlloc { verify(nregf!=-1); int cc=0; - for (u32 sid=0;sidnregf==nregf && all_spans[sid]->contains(opid)) + if (span->nregf == nregf && span->contains(opid)) cc++; } return cc; @@ -1050,11 +1037,9 @@ struct RegAlloc { int rv=0; - for (u32 sid=0;sidpreload && spn->begining(opid)) + if (span->preload && span->begining(opid)) rv++; } @@ -1065,11 +1050,9 @@ struct RegAlloc { int rv=0; - for (u32 sid=0;sidwriteback && spn->ending(opid)) + if (span->writeback && span->ending(opid)) rv++; } @@ -1080,23 +1063,21 @@ struct RegAlloc { current_opid=opid; - for (u32 sid=0;sidbegining(current_opid) && spn->preload) + if (span->begining(current_opid) && span->preload) { - if (spn->fpr) + if (span->fpr) { //printf("Op %d: Preloading f%d to %d\n",current_opid,spn->regstart,spn->nregf); preload_fpu++; - Preload_FPU(spn->regstart,spn->nregf); + Preload_FPU(span->regstart,span->nregf); } else { //printf("Op %d: Preloading r%d to %d\n",current_opid,spn->regstart,spn->nreg); preload_gpr++; - Preload(spn->regstart,spn->nreg); + Preload(span->regstart,span->nreg); } } } @@ -1104,23 +1085,21 @@ struct RegAlloc void OpEnd(shil_opcode* op) { - for (u32 sid=0;sidending(current_opid) && spn->writeback) + if (span->ending(current_opid) && span->writeback) { - if (spn->fpr) + if (span->fpr) { //printf("Op %d: Writing back f%d from %d\n",current_opid,spn->regstart,spn->nregf); writeback_fpu++; - Writeback_FPU(spn->regstart,spn->nregf); + Writeback_FPU(span->regstart,span->nregf); } else { //printf("Op %d: Writing back r%d from %d\n",current_opid,spn->regstart,spn->nreg); writeback_gpr++; - Writeback(spn->regstart,spn->nreg); + Writeback(span->regstart,span->nreg); } } } @@ -1128,23 +1107,17 @@ struct RegAlloc void BailOut(u32 opid) { - for (u32 sid = 0; sid < all_spans.size(); sid++) + for (RegSpan *span : all_spans) { - RegSpan* spn = all_spans[sid]; - - if (spn->end >= opid && spn->start < opid && spn->writeback) + if (span->end >= opid && span->start < opid && span->writeback) { - if (spn->fpr) + if (span->fpr) { - //printf("Op %d: Writing back f%d from %d\n",current_opid,spn->regstart,spn->nregf); - writeback_fpu++; - Writeback_FPU(spn->regstart,spn->nregf); + Writeback_FPU(span->regstart, span->nregf); } else { - //printf("Op %d: Writing back r%d from %d\n",current_opid,spn->regstart,spn->nreg); - writeback_gpr++; - Writeback(spn->regstart,spn->nreg); + Writeback(span->regstart, span->nreg); } } } @@ -1161,8 +1134,8 @@ struct RegAlloc spans[sid]=0; } - for (size_t sid=0;sid Date: Tue, 28 May 2019 19:37:24 +0200 Subject: [PATCH 048/158] regalloc: handle mem ops differently in wince mode Flush all current writeback spans before the op Flush instead of killing spans in case the mem access throws an exception Some optimizations --- core/hw/sh4/dyna/regalloc.h | 117 +++++++++++++++--------------------- 1 file changed, 47 insertions(+), 70 deletions(-) diff --git a/core/hw/sh4/dyna/regalloc.h b/core/hw/sh4/dyna/regalloc.h index 4b3fd7b04..3a24c275c 100644 --- a/core/hw/sh4/dyna/regalloc.h +++ b/core/hw/sh4/dyna/regalloc.h @@ -362,14 +362,17 @@ struct RegAlloc } } + bool IsExceptionOp(shil_opcode* op) + { + return mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref); + } bool IsFlushOp(RuntimeBlockInfo* block, int opid) { verify(opid>=0 && opidoplist.size()); shil_opcode* op=&block->oplist[opid]; - return op->op == shop_sync_fpscr || op->op == shop_sync_sr || op->op == shop_ifb - || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref)); + return op->op == shop_sync_fpscr || op->op == shop_sync_sr || op->op == shop_ifb; } bool IsRegWallOp(RuntimeBlockInfo* block, int opid, bool is_fpr) @@ -490,12 +493,6 @@ struct RegAlloc { fp=true; } - else - { - all = true; - fp = true; - gpr_b = true; - } if (all) { @@ -536,6 +533,19 @@ struct RegAlloc } else { + if (IsExceptionOp(op)) + { + // If the current op may throw an exception, flush all writeback spans before the op + for (int regid = 0; regid < sh4_reg_count; regid++) + { + RegSpan *span = spans[regid]; + if (span && span->writeback) + { + span->Flush(); + spans[regid] = 0; + } + } + } set reg_wt; set reg_rd; @@ -601,7 +611,12 @@ struct RegAlloc if (iter->count() == 1 && iter->_reg == op->rs1._reg + 3) spans[iter->_reg + i]->Flush(); else - spans[iter->_reg + i]->Kill(); + { + if (IsExceptionOp(op)) + spans[iter->_reg + i]->Flush(); + else + spans[iter->_reg + i]->Kill(); + } } spans[iter->_reg + i] = 0; } @@ -610,7 +625,12 @@ struct RegAlloc if (iter->is_r32()) { if (spans[iter->_reg] != 0) - spans[iter->_reg]->Kill(); + { + if (IsExceptionOp(op)) + spans[iter->_reg]->Flush(); + else + spans[iter->_reg]->Kill(); + } spans[iter->_reg] = new RegSpan(*iter, opid, AM_WRITE); all_spans.push_back(spans[iter->_reg]); @@ -722,68 +742,25 @@ struct RegAlloc //Allocate the registers to the spans ! for (size_t opid=0;opidoplist.size();opid++) { - bool alias_mov=false; - - if (block->oplist[opid].op==shop_mov32 && - ( - (block->oplist[opid].rd.is_r32i() && block->oplist[opid].rs1.is_r32i() ) || - (block->oplist[opid].rd.is_r32f() && block->oplist[opid].rs1.is_r32f() ) - )) - { - //FindSpan(block->oplist[opid].rd._reg); - RegSpan* x=FindSpan(block->oplist[opid].rs1._reg,opid); - if (0 && x->nacc_w(opid)==-1 && (x->nreg!=-1 || x->nregf!=-1) && !x->aliased) - { - RegSpan* d=FindSpan(block->oplist[opid].rd._reg,opid); - int nwa=d->nacc_w(opid); - - if (nwa==-1 || nwa>=x->end) - { - - verify(d->fpr==x->fpr); - d->nreg=x->nreg; - d->nregf=x->nregf; - //x->aliased=true; - - verify(d->begining(opid) && !d->preload); - //verify(d->end>=x->end); - - if (d->end>=x->end) - x->aliased=true; - else - d->aliased=true; - - //printf("[%08X] rALIA %d from %d\n",spn,spn->regstart,spn->nreg); - alias_mov=true; - } - } - } - - if (!alias_mov) - { - for (RegSpan *span : all_spans) - { - if (span->begining(opid)) - { - if (span->fpr) - { - verify(regsf.size()>0); - span->nregf=regsf.back(); - regsf.pop_back(); - } - else - { - verify(regs.size()>0); - span->nreg=regs.back(); - regs.pop_back(); - - //printf("rALOC %d from %d\n",spn->regstart,spn->nreg); - } - } - } - } for (RegSpan *span : all_spans) { + if (span->begining(opid)) + { + if (span->fpr) + { + verify(regsf.size()>0); + span->nregf=regsf.back(); + regsf.pop_back(); + } + else + { + verify(regs.size()>0); + span->nreg=regs.back(); + regs.pop_back(); + + //printf("rALOC %d from %d\n",spn->regstart,spn->nreg); + } + } if (span->ending(opid) && !span->aliased) { if (span->fpr) From 8cb86de02608de94fe262c26cc76b84be0ad4483 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 28 May 2019 19:40:30 +0200 Subject: [PATCH 049/158] Make SMCCheck=Fast work on arm64 The issue is that flushing the dynarec cache makes rewriting fail for the currently executing block. So this avoids flushing the cache too often but the problem remains. --- core/hw/sh4/modules/ccn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/sh4/modules/ccn.cpp b/core/hw/sh4/modules/ccn.cpp index 7ed472e3f..459771393 100644 --- a/core/hw/sh4/modules/ccn.cpp +++ b/core/hw/sh4/modules/ccn.cpp @@ -88,7 +88,7 @@ void CCN_CCR_write(u32 addr, u32 value) if (temp.ICI) { printf_smc("Sh4: i-cache invalidation %08X\n",curr_pc); - if (settings.dynarec.SmcCheckLevel != FullCheck) { + if (settings.dynarec.SmcCheckLevel == NoCheck) { //TODO: Add skip/check vectors for Shikigami No Shiro II (uses ICI frequently) //which game is 0xAC13DBF8 from ? if (curr_pc != 0xAC13DBF8) From 4540acc22e6404a96bf968041ef0a6573e579c7a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 28 May 2019 19:41:21 +0200 Subject: [PATCH 050/158] mmu: optimize mmu_full_SQ() --- core/hw/sh4/modules/fastmmu.cpp | 17 +++++++++++++++++ core/hw/sh4/modules/mmu.cpp | 6 +++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index a2723ea96..59d4cfac5 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -254,6 +254,23 @@ u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) } template u32 mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv); +template +u32 mmu_full_SQ(u32 va, u32& rv) +{ + //Address=Dest&0xFFFFFFE0; + + const TLB_Entry *entry; + u32 lookup = mmu_full_lookup(va, &entry, rv); + + if (lookup != MMU_ERROR_NONE) + return lookup; + + rv &= ~31;//lower 5 bits are forced to 0 + + return MMU_ERROR_NONE; +} +template u32 mmu_full_SQ(u32 va, u32& rv); + template u32 mmu_data_translation(u32 va, u32& rv) { diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index b8a416c53..db65ae1d2 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -263,7 +263,7 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) void DoMMUException(u32 address, u32 mmu_error, u32 access_type) { - printf_mmu("DoMMUException -> pc = 0x%X : ", next_pc); + printf_mmu("DoMMUException -> pc = 0x%X : %d ", next_pc, access_type); CCN_TEA = address; CCN_PTEH.VPN = address >> 10; @@ -431,6 +431,7 @@ u32 mmu_QACR_SQ(u32 va) return QACR + va; } +#ifndef FAST_MMU template u32 mmu_full_SQ(u32 va, u32& rv) { @@ -476,9 +477,8 @@ u32 mmu_full_SQ(u32 va, u32& rv) } return MMU_ERROR_NONE; } -template u32 mmu_full_SQ(u32 va, u32& rv); +template u32 mmu_full_SQ(u32 va, u32& rv); -#ifndef FAST_MMU template u32 mmu_data_translation(u32 va, u32& rv) { From cafd1c3c49e66f54729016fa7992f5404cf865ee Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 28 May 2019 19:43:17 +0200 Subject: [PATCH 051/158] rec-arm64: do a full regalloc when rewriting mem access in mmu mode --- core/rec-ARM64/rec_arm64.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 7d1b02a76..43e658319 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -1029,9 +1029,7 @@ public: void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) { this->block = block; - // with full mmu, all regs are flushed before mem ops - if (!mmu_enabled()) - regalloc.DoAlloc(block); + regalloc.DoAlloc(block); regalloc.current_opid = opid; } @@ -1114,9 +1112,9 @@ public: case BET_DynamicRet: // next_pc = *jdyn; + Str(w29, sh4_context_mem_operand(&next_pc)); if (!mmu_enabled()) { - Str(w29, sh4_context_mem_operand(&next_pc)); // TODO Call no_update instead (and check CpuRunning less frequently?) Mov(x2, sizeof(Sh4RCB)); Sub(x2, x28, x2); @@ -1131,7 +1129,6 @@ public: } else { - Str(w29, sh4_context_mem_operand(&next_pc)); GenBranch(*arm64_no_update); } From 714de0303e27d0107f2004bb7cec121273dff2a8 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 28 May 2019 19:43:56 +0200 Subject: [PATCH 052/158] rec-x64: don't save fp regs when calling mem access handlers --- core/rec-x64/rec_x64.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 37b66e578..44f9d1556 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1124,14 +1124,14 @@ public: if (!mmu_enabled()) GenCall(ReadMem8); else - GenCall(ReadMemNoEx); + GenCall(ReadMemNoEx, true); movsx(ecx, al); break; case 2: if (!mmu_enabled()) GenCall(ReadMem16); else - GenCall(ReadMemNoEx); + GenCall(ReadMemNoEx, true); movsx(ecx, ax); break; @@ -1139,14 +1139,14 @@ public: if (!mmu_enabled()) GenCall(ReadMem32); else - GenCall(ReadMemNoEx); + GenCall(ReadMemNoEx, true); mov(ecx, eax); break; case 8: if (!mmu_enabled()) GenCall(ReadMem64); else - GenCall(ReadMemNoEx); + GenCall(ReadMemNoEx, true); mov(rcx, rax); break; default: @@ -1177,25 +1177,25 @@ public: if (!mmu_enabled()) GenCall(WriteMem8); else - GenCall(WriteMemNoEx); + GenCall(WriteMemNoEx, true); break; case 2: if (!mmu_enabled()) GenCall(WriteMem16); else - GenCall(WriteMemNoEx); + GenCall(WriteMemNoEx, true); break; case 4: if (!mmu_enabled()) GenCall(WriteMem32); else - GenCall(WriteMemNoEx); + GenCall(WriteMemNoEx, true); break; case 8: if (!mmu_enabled()) GenCall(WriteMem64); else - GenCall(WriteMemNoEx); + GenCall(WriteMemNoEx, true); break; default: die("1..8 bytes"); @@ -1611,13 +1611,13 @@ private: } template - void GenCall(Ret(*function)(Params...)) + void GenCall(Ret(*function)(Params...), bool skip_floats = false) { #ifndef _WIN32 - bool xmm8_mapped = current_opid != -1 && regalloc.IsMapped(xmm8, current_opid); - bool xmm9_mapped = current_opid != -1 && regalloc.IsMapped(xmm9, current_opid); - bool xmm10_mapped = current_opid != -1 && regalloc.IsMapped(xmm10, current_opid); - bool xmm11_mapped = current_opid != -1 && regalloc.IsMapped(xmm11, current_opid); + bool xmm8_mapped = !skip_floats && current_opid != -1 && regalloc.IsMapped(xmm8, current_opid); + bool xmm9_mapped = !skip_floats && current_opid != -1 && regalloc.IsMapped(xmm9, current_opid); + bool xmm10_mapped = !skip_floats && current_opid != -1 && regalloc.IsMapped(xmm10, current_opid); + bool xmm11_mapped = !skip_floats && current_opid != -1 && regalloc.IsMapped(xmm11, current_opid); // Need to save xmm registers as they are not preserved in linux/mach int offset = 0; From b8a00b9c7d436829ef076018963d289c169b4dbb Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 28 May 2019 20:03:08 +0200 Subject: [PATCH 053/158] rec-arm64/x64: only do regalloc on rewrite when needed --- core/rec-ARM64/rec_arm64.cpp | 8 ++++++-- core/rec-x64/rec_x64.cpp | 3 --- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 43e658319..6ff6c2ec5 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -1029,8 +1029,12 @@ public: void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) { this->block = block; - regalloc.DoAlloc(block); - regalloc.current_opid = opid; + // writem rewrite doesn't use regalloc + if (block->oplist[opid].op == shop_readm) + { + regalloc.DoAlloc(block); + regalloc.current_opid = opid; + } } u32 RelinkBlock(RuntimeBlockInfo *block) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 44f9d1556..4c7db5854 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1214,9 +1214,6 @@ public: void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) { - // shouldn't be necessary since all regs are flushed before mem access when mmu is enabled - //regalloc.DoAlloc(block); - regalloc.current_opid = opid; } void FinalizeRewrite() From 692556ca5ddfedc116d1eaaf44bcd2d70a61bf8a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 4 Jun 2019 21:20:34 +0200 Subject: [PATCH 054/158] dynarec: ssa initial commit --- core/hw/sh4/dyna/blockmanager.h | 1 - core/hw/sh4/dyna/decoder.cpp | 2 +- core/hw/sh4/dyna/shil.h | 11 +- core/hw/sh4/dyna/ssa.h | 1020 +++++++++++++++++++++++++++++++ 4 files changed, 1028 insertions(+), 6 deletions(-) create mode 100644 core/hw/sh4/dyna/ssa.h diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index 88c69fb3c..375fba25c 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -1,7 +1,6 @@ /* In case you wonder, the extern "C" stuff are for the assembly code on beagleboard/pandora */ -#include #include "types.h" #include "decoder.h" #pragma once diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 1d98ac412..25b52a3b8 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1152,7 +1152,7 @@ _end: verify(blk->oplist.size() <= BLOCK_MAX_SH_OPS_HARD); -#if HOST_OS == OS_WINDOWS +#if 0 switch(rbi->addr) { case 0x8C09ED16: diff --git a/core/hw/sh4/dyna/shil.h b/core/hw/sh4/dyna/shil.h index 315ab806a..d8bfbeeb2 100644 --- a/core/hw/sh4/dyna/shil.h +++ b/core/hw/sh4/dyna/shil.h @@ -41,6 +41,7 @@ struct shil_param { type=FMT_NULL; _imm=0xFFFFFFFF; + memset(version, 0, sizeof(version)); } shil_param(u32 type,u32 imm) { @@ -48,6 +49,7 @@ struct shil_param if (type >= FMT_REG_BASE) new (this) shil_param((Sh4RegType)imm); _imm=imm; + memset(version, 0, sizeof(version)); } shil_param(Sh4RegType reg) @@ -88,7 +90,7 @@ struct shil_param type=FMT_I32; _reg=reg; } - + memset(version, 0, sizeof(version)); } union { @@ -96,6 +98,7 @@ struct shil_param Sh4RegType _reg; }; u32 type; + u16 version[16]; bool is_null() const { return type==FMT_NULL; } bool is_imm() const { return type==FMT_IMM; } @@ -118,7 +121,7 @@ struct shil_param s32 reg_nofs() const { verify(is_reg()); return (s32)((u8*)GetRegPtr(_reg) - (u8*)GetRegPtr(reg_xf_0)-sizeof(Sh4cntx)); } u32 reg_aofs() const { return -reg_nofs(); } - u32 imm_value() { verify(is_imm()); return _imm; } + u32 imm_value() const { verify(is_imm()); return _imm; } bool is_vector() const { return type>=FMT_VECTOR_BASE; } @@ -153,9 +156,9 @@ struct shil_opcode u16 guest_offs; bool delay_slot; - string dissasm(); + string dissasm() const; }; const char* shil_opcode_name(int op); -string name_reg(u32 reg); +string name_reg(Sh4RegType reg); diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h new file mode 100644 index 000000000..233c11d31 --- /dev/null +++ b/core/hw/sh4/dyna/ssa.h @@ -0,0 +1,1020 @@ +/* + Created on: Jun 2, 2019 + + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ +#include +#include +#include +#include +#include +#include "types.h" +#include "decoder.h" +#include "hw/sh4/modules/mmu.h" + +class SSAOptimizer +{ +public: + SSAOptimizer(RuntimeBlockInfo* blk) : block(blk) {} + + void Optimize() + { + AddVersionPass(); +#if DEBUG + printf("BEFORE\n"); + PrintBlock(); +#endif + + ConstPropPass(); + DeadCodeRemovalPass(); + ConstantExpressionsPass(); + //DeadRegisterPass(); + //DoRegAlloc(); + +#if DEBUG + if (stats.prop_constants > 0 || stats.dead_code_ops > 0 || stats.constant_ops_replaced > 0 + || stats.constant_ops_removed || stats.dead_registers > 0) + { + printf("AFTER\n"); + PrintBlock(); + printf("STATS: constants %d constant ops replaced %d removed %d dead code %d dead regs %d\n\n", stats.prop_constants, stats.constant_ops_replaced, + stats.constant_ops_removed, stats.dead_code_ops, stats.dead_registers); + } +#endif + } + +private: + // References a specific version of a register value + class RegValue : public std::pair + { + public: + RegValue(const shil_param& param, int index = 0) + : std::pair((Sh4RegType)(param._reg + index), param.version[index]) + { + verify(param.is_reg()); + verify(index >= 0 && index < param.count()); + } + RegValue() : std::pair() { } + + Sh4RegType get_reg() const { return first; } + u32 get_version() const { return second; } + }; + + struct reg_alloc { + u32 host_reg; + u16 version; + bool write_back; + }; + + void PrintBlock() + { + for (const shil_opcode& op : block->oplist) + { + printf("%08x %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + } + } + void AddVersionToOperand(shil_param& param, bool define) + { + if (param.is_reg()) + { + if (define) + { + for (int i = 0; i < param.count(); i++) + reg_versions[param._reg + i]++; + } + for (int i = 0; i < param.count(); i++) + param.version[i] = reg_versions[param._reg + i]; + } + } + + void AddVersionPass() + { + memset(reg_versions, 0, sizeof(reg_versions)); + + for (shil_opcode& op : block->oplist) + { + AddVersionToOperand(op.rs1, false); + AddVersionToOperand(op.rs2, false); + AddVersionToOperand(op.rs3, false); + AddVersionToOperand(op.rd, true); + AddVersionToOperand(op.rd2, true); + } + } + + // mov rd, #v + void ReplaceByMov32(shil_opcode& op, u32 v) + { + op.op = shop_mov32; + op.rs1 = shil_param(FMT_IMM, v); + op.rs2.type = FMT_NULL; + op.rs3.type = FMT_NULL; + stats.constant_ops_replaced++; + } + + // mov rd, rs1 + void ReplaceByMov32(shil_opcode& op) + { + op.op = shop_mov32; + op.rs2.type = FMT_NULL; + op.rs3.type = FMT_NULL; + } + + void ConstPropOperand(shil_param& param) + { + if (param.is_r32()) + { + auto it = constprop_values.find(RegValue(param)); + if (it != constprop_values.end()) + { + param.type = FMT_IMM; + param._imm = it->second; + stats.prop_constants++; + } + } + } + + void ConstPropPass() + { + for (int opnum = 0; opnum < block->oplist.size(); opnum++) + { + shil_opcode& op = block->oplist[opnum]; + + if (op.op != shop_setab && op.op != shop_setae && op.op != shop_setgt && op.op != shop_setge && op.op != shop_sub && op.op != shop_fsetgt + && op.op != shop_fseteq && op.op != shop_fdiv && op.op != shop_fsub && op.op != shop_fmac) + ConstPropOperand(op.rs1); + if (op.op != shop_rocr && op.op != shop_rocl && op.op != shop_fsetgt && op.op != shop_fseteq && op.op != shop_fmac) + ConstPropOperand(op.rs2); + if (op.op != shop_fmac && op.op != shop_adc) + ConstPropOperand(op.rs3); + + if (op.op == shop_readm || op.op == shop_writem) + { + if (op.rs1.is_imm()) + { + if (op.rs3.is_imm()) + { + // Merge base addr and offset + op.rs1._imm += op.rs3.imm_value(); + op.rs3.type = FMT_NULL; + } + else if (op.rs3.is_reg()) + { + // Swap rs1 and rs3 so that rs1 is never an immediate operand + shil_param t = op.rs1; + op.rs1 = op.rs3; + op.rs3 = t; + } + } + } + else if (!op.rs1.is_reg() && !op.rs2.is_reg() && !op.rs3.is_reg() + && (op.rs1.is_imm() || op.rs2.is_imm() || op.rs3.is_imm()) + && op.rd.is_r32()) + { + // Only immediate operands -> execute the op at compile time + //printf("%08x IMM %s --> \n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + const RegValue dest_reg(op.rd); + + if (op.op == shop_mov32) + { + constprop_values[dest_reg] = op.rs1.imm_value(); + } + else if (op.op == shop_add) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() + op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_sub) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() - op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_shl) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() << op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_shr) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() >> op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_sar) + { + u32 v = constprop_values[dest_reg] + = (s32)op.rs1.imm_value() >> op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_ror) + { + u32 v = constprop_values[dest_reg] + = (op.rs1.imm_value() >> op.rs2.imm_value()) + | (op.rs1.imm_value() << (32 - op.rs2.imm_value())); + ReplaceByMov32(op, v); + } + else if (op.op == shop_shld) + { + u32 r1 = op.rs1.imm_value(); + u32 r2 = op.rs2.imm_value(); + u32 rd = shil_opcl_shld::f1::impl(r1, r2); + + constprop_values[dest_reg] = rd; + ReplaceByMov32(op, rd); + } + else if (op.op == shop_shad) + { + u32 r1 = op.rs1.imm_value(); + u32 r2 = op.rs2.imm_value(); + u32 rd = shil_opcl_shad::f1::impl(r1, r2); + + constprop_values[dest_reg] = rd; + ReplaceByMov32(op, rd); + } + else if (op.op == shop_or) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() | op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_and) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() & op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_xor) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() ^ op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_not) + { + u32 v = constprop_values[dest_reg] + = ~op.rs1.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_ext_s16) + { + u32 v = constprop_values[dest_reg] + = (s32)(s16)op.rs1.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_ext_s8) + { + u32 v = constprop_values[dest_reg] + = (s32)(s8)op.rs1.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_mul_i32) + { + u32 v = constprop_values[dest_reg] + = op.rs1.imm_value() * op.rs2.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_mul_u16) + { + u32 v = constprop_values[dest_reg] + = (u16)(op.rs1.imm_value() * op.rs2.imm_value()); + ReplaceByMov32(op, v); + } + else if (op.op == shop_mul_s16) + { + u32 v = constprop_values[dest_reg] + = (s16)(op.rs1.imm_value() * op.rs2.imm_value()); + ReplaceByMov32(op, v); + } + else if (op.op == shop_test) + { + u32 v = constprop_values[dest_reg] + = (op.rs1.imm_value() & op.rs2.imm_value()) == 0; + ReplaceByMov32(op, v); + } + else if (op.op == shop_neg) + { + u32 v = constprop_values[dest_reg] + = -op.rs1.imm_value(); + ReplaceByMov32(op, v); + } + else if (op.op == shop_swaplb) + { + u32 v = shil_opcl_swaplb::f1::impl(op.rs1.imm_value()); + constprop_values[dest_reg] = v; + ReplaceByMov32(op, v); + } + else if (op.op == shop_seteq || op.op == shop_setgt || op.op == shop_setge || op.op == shop_setab || op.op == shop_setae) + { + u32 r1 = op.rs1.imm_value(); + u32 r2 = op.rs2.imm_value(); + u32 rd; + switch (op.op) + { + case shop_seteq: + rd = r1 == r2; + break; + case shop_setge: + rd = (s32)r1 >= (s32)r2; + break; + case shop_setgt: + rd = (s32)r1 > (s32)r2; + break; + case shop_setab: + rd = r1 > r2; + break; + case shop_setae: + rd = r1 >= r2; + break; + } + constprop_values[dest_reg] = rd; + ReplaceByMov32(op, rd); + } + else if (op.op == shop_jdyn) + { + // TODO check this + verify(BET_GET_CLS(block->BlockType) == BET_CLS_Dynamic); + switch ((block->BlockType >> 1) & 3) + { + case BET_SCL_Jump: + case BET_SCL_Ret: + block->BlockType = BET_StaticJump; + block->BranchBlock = op.rs1.imm_value(); + break; + case BET_SCL_Call: + block->BlockType = BET_StaticCall; + block->BranchBlock = op.rs1.imm_value(); + break; + case BET_SCL_Intr: + block->BlockType = BET_StaticIntr; + block->NextBlock = op.rs1.imm_value(); + break; + default: + die("Unexpected block end type\n"); + } + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + //printf("DEAD\n"); + continue; + } + else if (op.op == shop_jcond) + { + if (op.rs1.imm_value() != (block->BlockType & 1)) + { + block->BranchBlock = block->NextBlock; + } + block->BlockType = BET_StaticJump; + block->NextBlock = 0xFFFFFFFF; + block->has_jcond = false; + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + //printf("DEAD\n"); + continue; + } + else if (op.op == shop_fneg) + { + u32 rd = constprop_values[dest_reg] = op.rs1.imm_value() ^ 0x80000000; + ReplaceByMov32(op, rd); + } + else if (op.op == shop_fadd) + { + f32 rd = reinterpret_cast(op.rs1._imm) + reinterpret_cast(op.rs2._imm); + constprop_values[dest_reg] = reinterpret_cast(rd); + ReplaceByMov32(op, reinterpret_cast(rd)); + } + else if (op.op == shop_fmul) + { + f32 rd = reinterpret_cast(op.rs1._imm) * reinterpret_cast(op.rs2._imm); + constprop_values[dest_reg] = reinterpret_cast(rd); + ReplaceByMov32(op, reinterpret_cast(rd)); + } + else if (op.op == shop_cvt_i2f_n || op.op == shop_cvt_i2f_z) + { + f32 rd = (float)(s32)op.rs1._imm; + constprop_values[dest_reg] = reinterpret_cast(rd); + ReplaceByMov32(op, reinterpret_cast(rd)); + } + else if (op.op == shop_fsqrt) + { + f32 rd = sqrtf(reinterpret_cast(op.rs1._imm)); + constprop_values[dest_reg] = reinterpret_cast(rd); + ReplaceByMov32(op, reinterpret_cast(rd)); + } + else + { + printf("unhandled constant op %d\n", op.op); + die("RHHAAA"); + } + + //printf("%s\n", op.dissasm().c_str()); + } + else if ((op.op == shop_and || op.op == shop_or || op.op == shop_xor || op.op == shop_add || op.op == shop_mul_s16 || op.op == shop_mul_u16 + || op.op == shop_mul_i32 || op.op == shop_test || op.op == shop_seteq || op.op == shop_fseteq || op.op == shop_fadd || op.op == shop_fmul) + && op.rs1.is_imm() && op.rs2.is_reg()) + { + // swap rs1 and rs2 so that rs1 is never an immediate operand + shil_param t = op.rs1; + op.rs1 = op.rs2; + op.rs2 = t; + } + } + } + + void DeadCodeRemovalPass() + { + u32 last_versions[sh4_reg_count]; + std::set uses; + + memset(last_versions, -1, sizeof(last_versions)); + for (int opnum = block->oplist.size() - 1; opnum >= 0; opnum--) + { + shil_opcode& op = block->oplist[opnum]; + bool dead_code = false; + + if (op.op == shop_ifb || (mmu_enabled() && (op.op == shop_readm || op.op == shop_writem))) + { + // if mmu enabled, mem accesses can throw an exception + // so last_versions must be reset so the regs are correctly saved beforehand + memset(last_versions, -1, sizeof(last_versions)); + continue; + } + if (op.op == shop_pref) + { + if (op.rs1.is_imm() && (op.rs1.imm_value() & 0xFC000000) != 0xE0000000) + dead_code = true; + else if (mmu_enabled()) + { + memset(last_versions, -1, sizeof(last_versions)); + continue; + } + } + if (op.op == shop_sync_sr) + { + last_versions[reg_sr_T] = -1; + last_versions[reg_sr_status] = -1; + last_versions[reg_old_sr_status] = -1; + for (int i = reg_r0; i <= reg_r7; i++) + last_versions[i] = -1; + for (int i = reg_r0_Bank; i <= reg_r7_Bank; i++) + last_versions[i] = -1; + continue; + } + if (op.op == shop_sync_fpscr) + { + last_versions[reg_fpscr] = -1; + last_versions[reg_old_fpscr] = -1; + for (int i = reg_fr_0; i <= reg_xf_15; i++) + last_versions[i] = -1; + continue; + } + + if (op.rd.is_reg()) + { + bool unused_rd = true; + for (int i = 0; i < op.rd.count(); i++) + { + if (last_versions[op.rd._reg + i] == -1) + { + last_versions[op.rd._reg + i] = op.rd.version[i]; + unused_rd = false; + writeback_values.insert(RegValue(op.rd, i)); + } + else + { + verify(op.rd.version[i] < last_versions[op.rd._reg + i]); + if (uses.find(RegValue(op.rd, i)) != uses.end()) + { + unused_rd = false; + } + } + } + dead_code = dead_code || unused_rd; + } + if (op.rd2.is_reg()) + { + bool unused_rd = true; + for (int i = 0; i < op.rd2.count(); i++) + { + if (last_versions[op.rd2._reg + i] == -1) + { + last_versions[op.rd2._reg + i] = op.rd2.version[i]; + unused_rd = false; + writeback_values.insert(RegValue(op.rd2, i)); + } + else + { + verify(op.rd2.version[i] < last_versions[op.rd2._reg + i]); + if (uses.find(RegValue(op.rd2, i)) != uses.end()) + { + unused_rd = false; + } + } + } + dead_code = dead_code && unused_rd; + } + if (dead_code && op.op != shop_readm) // TODO Can we also remove dead readm? + { + //printf("%08x DEAD %s\n", blk->vaddr + op.guest_offs, op.dissasm().c_str()); + block->oplist.erase(block->oplist.begin() + opnum); + stats.dead_code_ops++; + } + else + { + //printf("%08x %s\n", blk->vaddr + op.guest_offs, op.dissasm().c_str()); + if (op.rs1.is_reg()) + { + for (int i = 0; i < op.rs1.count(); i++) + uses.insert(RegValue(op.rs1, i)); + } + if (op.rs2.is_reg()) + { + for (int i = 0; i < op.rs2.count(); i++) + uses.insert(RegValue(op.rs2, i)); + } + if (op.rs3.is_reg()) + { + for (int i = 0; i < op.rs3.count(); i++) + uses.insert(RegValue(op.rs3, i)); + } + if (op.op == shop_mov32 && op.rs1.is_reg()) + { + RegValue dest_reg(op.rd); + RegValue src_reg(op.rs1); + auto it = aliases.find(src_reg); + if (it != aliases.end()) + // use the final value if the dest is itself aliased + aliases[dest_reg] = it->second; + else + aliases[dest_reg] = src_reg; + } + } + } + } + + void ConstantExpressionsPass() + { + for (int opnum = 0; opnum < block->oplist.size(); opnum++) + { + shil_opcode& op = block->oplist[opnum]; + if (op.rs2.is_imm()) + { + if (op.rs2.imm_value() == 0) + { + // a & 0 == 0 + // a * 0 == 0 + if (op.op == shop_and || op.op == shop_mul_i32 || op.op == shop_mul_s16 || op.op == shop_mul_u16 + || op.op == shop_fmul) + { + //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + ReplaceByMov32(op, 0); + } + // a * 0 == 0 + /* TODO 64-bit result + else if (op.op == shop_mul_u64 || op.op == shop_mul_s64) + { + printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + ReplaceByMov32(op, 0); + } + */ + // a + 0 == a + // a - 0 == a + // a | 0 == a + // a ^ 0 == a + // a >> 0 == a + // a << 0 == a + else if (op.op == shop_add || op.op == shop_sub || op.op == shop_or || op.op == shop_xor + || op.op == shop_shl || op.op == shop_shr || op.op == shop_sar || op.op == shop_shad || op.op == shop_shld + || op.op == shop_fadd || op.op == shop_fsub) + { + //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + if (op.rd._reg == op.rs1._reg) + { + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + } + else + { + ReplaceByMov32(op); + } + continue; + } + } + // a * 1 == a + else if (op.rs2.imm_value() == 1 + && (op.op == shop_mul_i32 || op.op == shop_mul_s16 || op.op == shop_mul_u16)) + { + //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + if (op.rd._reg == op.rs1._reg) + { + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + } + else + { + ReplaceByMov32(op); + } + continue; + } + // TODO very rare + // a * 1.0 == a + // a / 1.0 == a + else if (op.rs2.imm_value() == 0x3f800000 // 1.0 + && (op.op == shop_fmul || op.op == shop_fdiv)) + { + //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + if (op.rd._reg == op.rs1._reg) + { + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + } + else + { + ReplaceByMov32(op); + } + continue; + } + } + // Not sure it's worth the trouble, except for the xor perhaps + else if (op.rs1.is_r32i() && op.rs1._reg == op.rs2._reg) + { + // a ^ a == 0 + if (op.op == shop_xor) + { + //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + ReplaceByMov32(op, 0); + } + // a & a == a + // a | a == a + else if (op.op == shop_and || op.op == shop_or) + { + //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + if (op.rd._reg == op.rs1._reg) + { + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.constant_ops_removed++; + } + else + { + ReplaceByMov32(op); + } + } + } + } + } + + void DeadRegisterPass() + { + for (auto alias : aliases) + { + if (writeback_values.count(alias.first) == 0) + { + // Do a first pass to check that we can replace the reg + size_t defnum = -1; + size_t usenum = -1; + size_t aliasdef = -1; + for (int opnum = 0; opnum < block->oplist.size(); opnum++) + { + shil_opcode* op = &block->oplist[opnum]; + if (op->rd.is_r32() && RegValue(op->rd) == alias.first) + defnum = opnum; + else if (op->rd2.is_r32() && RegValue(op->rd2) == alias.first) + defnum = opnum; + if (defnum == -1) + continue; + if (op->rd.is_reg() && alias.second.get_reg() >= op->rd._reg && alias.second.get_reg() < (Sh4RegType)(op->rd._reg + op->rd.count()) + && op->rd.version[alias.second.get_reg() - op->rd._reg] > alias.second.get_version() && aliasdef == -1) + aliasdef = opnum; + else if (op->rd2.is_reg() && alias.second.get_reg() >= op->rd2._reg && alias.second.get_reg() < (Sh4RegType)(op->rd2._reg + op->rd2.count()) + && op->rd2.version[alias.second.get_reg() - op->rd2._reg] > alias.second.get_version() && aliasdef == -1) + aliasdef = opnum; + if (op->rs1.is_r32() && op->rs1._reg == alias.first.get_reg() && op->rs1.version[0] == alias.first.get_version()) + usenum = opnum; + if (op->rs2.is_r32() && op->rs2._reg == alias.first.get_reg() && op->rs2.version[0] == alias.first.get_version()) + usenum = opnum; + if (op->rs3.is_r32() && op->rs3._reg == alias.first.get_reg() && op->rs3.version[0] == alias.first.get_version()) + usenum = opnum; + } + verify(defnum != -1); + // If the alias is redefined before any use we can't do it + if (aliasdef != -1 && usenum != -1 && aliasdef < usenum) + continue; + if (alias.first.get_reg() <= reg_r15) + continue; +// if (alias.first.get_reg() >= reg_fr_0 && alias.first.get_reg() <= reg_xf_15) +// continue; + for (opnum = defnum + 1; opnum <= usenum && usenum != -1; opnum++) + { + shil_opcode* op = &block->oplist[opnum]; + if (op->rs1.is_reg() && op->rs1.count() == 1 && op->rs1._reg == alias.first.first) + { + op->rs1._reg = alias.second.first; + op->rs1.version[0] = alias.second.second; + printf("DeadRegisterAlias rs1 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, + name_reg(alias.second.first).c_str(), alias.second.second); + } + if (op->rs2.is_reg() && op->rs2.count() == 1 && op->rs2._reg == alias.first.first) + { + op->rs2._reg = alias.second.first; + op->rs2.version[0] = alias.second.second; + printf("DeadRegisterAlias rs2 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, + name_reg(alias.second.first).c_str(), alias.second.second); + } + if (op->rs3.is_reg() && op->rs3.count() == 1 && op->rs3._reg == alias.first.first) + { + op->rs3._reg = alias.second.first; + op->rs3.version[0] = alias.second.second; + printf("DeadRegisterAlias rs3 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, + name_reg(alias.second.first).c_str(), alias.second.second); + } + } + stats.dead_registers++; + block->oplist.erase(block->oplist.begin() + defnum); + } + } + } + + void DoRegAlloc() + { + host_gregs.clear(); + for (int i = 0; i < 6; i++) // FIXME reg count + host_gregs.push_front(i); + host_fregs.clear(); + for (int i = 0; i < 4; i++) // FIXME reg count + host_fregs.push_front(i); + + printf("BLOCK\n"); + for (opnum = 0; opnum < block->oplist.size(); opnum++) + { + shil_opcode* op = &block->oplist[opnum]; + if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref))) + FlushAllWritebacks(); + // Flush regs used by vector ops + if (op->rs1.count() > 1 || op->rs2.count() > 1 || op->rs3.count() > 1) + { + for (int i = 0; i < op->rs1.count(); i++) + { + auto reg = reg_alloced.find((Sh4RegType)(op->rs1._reg + i)); + if (reg != reg_alloced.end() && reg->second.version == op->rs1.version[i]) + FlushReg((Sh4RegType)(op->rs1._reg + i), true); + } + for (int i = 0; i < op->rs2.count(); i++) + { + auto reg = reg_alloced.find((Sh4RegType)(op->rs2._reg + i)); + if (reg != reg_alloced.end() && reg->second.version == op->rs2.version[i]) + FlushReg((Sh4RegType)(op->rs2._reg + i), true); + } + for (int i = 0; i < op->rs3.count(); i++) + { + auto reg = reg_alloced.find((Sh4RegType)(op->rs3._reg + i)); + if (reg != reg_alloced.end() && reg->second.version == op->rs3.version[i]) + FlushReg((Sh4RegType)(op->rs3._reg + i), true); + } + } + AllocSourceReg(op->rs1); + AllocSourceReg(op->rs2); + AllocSourceReg(op->rs3); + AllocDestReg(op->rd); + AllocDestReg(op->rd2); + printf("%08x %s\n", block->vaddr + op->guest_offs, op->dissasm().c_str()); + } + FlushAllWritebacks(); + } + + void FlushReg(Sh4RegType reg_num, bool full) + { + auto reg = reg_alloced.find(reg_num); + verify(reg != reg_alloced.end()); + if (reg->second.write_back) + { + printf("WB %s.%d\n", name_reg(reg_num).c_str(), reg->second.version); + reg->second.write_back = false; + } + if (full) + { + u32 host_reg = reg->second.host_reg; + if (reg_num >= reg_fr_0 && reg_num <= reg_xf_15) + host_fregs.push_front(host_reg); + else + host_gregs.push_front(host_reg); + reg_alloced.erase(reg); + } + } + + void FlushAllWritebacks() + { + for (auto reg : reg_alloced) + { + FlushReg(reg.first, false); + } + } + + void AllocSourceReg(const shil_param& param) + { + if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? + { + auto it = reg_alloced.find(param._reg); + if (it == reg_alloced.end()) + { + u32 host_reg; + if (param.is_r32i()) + { + if (host_gregs.empty()) + { + SpillReg(false, true); + verify(!host_gregs.empty()); + } + host_reg = host_gregs.back(); + host_gregs.pop_back(); + } + else + { + if (host_fregs.empty()) + { + SpillReg(true, true); + verify(!host_fregs.empty()); + } + host_reg = host_fregs.back(); + host_fregs.pop_back(); + } + reg_alloced[param._reg] = { host_reg, param.version[0], false }; + printf("PL %s -> %cx\n", name_reg(param._reg).c_str(), 'a' + host_reg); + } + } + } + + bool NeedsWriteBack(Sh4RegType reg, u32 version) + { + u32 last_version = -1; + for (int i = opnum + 1; i < block->oplist.size(); i++) + { + shil_opcode* op = &block->oplist[i]; + // if a subsequent op needs all regs flushed to mem + if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref))) + return true; + // reg is used by a subsequent vector op that doesn't use reg allocation + if (UsesReg(op, reg, version, true)) + return true; + if (op->rd.is_reg() && reg >= op->rd._reg && reg < (Sh4RegType)(op->rd._reg + op->rd.count())) + last_version = op->rd.version[reg - op->rd._reg]; + else if (op->rd2.is_reg() && reg >= op->rd2._reg && reg < (Sh4RegType)(op->rd2._reg + op->rd2.count())) + last_version = op->rd2.version[reg - op->rd2._reg]; + } + return last_version == -1 || version == last_version; + } + + void AllocDestReg(const shil_param& param) + { + if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? + { + auto it = reg_alloced.find(param._reg); + if (it == reg_alloced.end()) + { + u32 host_reg; + if (param.is_r32i()) + { + if (host_gregs.empty()) + { + SpillReg(false, false); + verify(!host_gregs.empty()); + } + host_reg = host_gregs.back(); + host_gregs.pop_back(); + } + else + { + if (host_fregs.empty()) + { + SpillReg(true, false); + verify(!host_fregs.empty()); + } + host_reg = host_fregs.back(); + host_fregs.pop_back(); + } + reg_alloced[param._reg] = { host_reg, param.version[0], NeedsWriteBack(param._reg, param.version[0]) }; + printf(" %s -> %cx\n", name_reg(param._reg).c_str(), 'a' + host_reg); + } + else + { + reg_alloc& reg = reg_alloced[param._reg]; + reg.write_back = NeedsWriteBack(param._reg, param.version[0]); + reg.version = param.version[0]; + } + } + } + + void SpillReg(bool freg, bool source) + { + Sh4RegType not_used_reg = NoReg; + Sh4RegType best_reg = NoReg; + int best_first_use = -1; + + for (auto reg : reg_alloced) + { + if ((reg.first >= reg_fr_0 && reg.first <= reg_xf_15) != freg) + continue; + + // Find the first use, but prefer no write back + int first_use = -1; + for (int i = opnum + (source ? 0 : 1); i < block->oplist.size() /* && (first_use == -1 || write_back) */; i++) + { + shil_opcode* op = &block->oplist[i]; + if (UsesReg(op, reg.first, reg.second.version)) + { + first_use = i; + break; + } + } + if (first_use == -1) + { + not_used_reg = reg.first; + break; + } + if (first_use > best_first_use && first_use > opnum) + { + best_first_use = first_use; + best_reg = reg.first; + } + } + Sh4RegType spilled_reg; + if (not_used_reg != NoReg) + spilled_reg = not_used_reg; + else + { + printf("RegAlloc: non optimal alloc? reg %s used in op %d\n", name_reg(best_reg).c_str(), best_first_use); + spilled_reg = best_reg; + } + verify(spilled_reg != NoReg); + + if (reg_alloced[spilled_reg].write_back) + { + printf("WB %s.%d\n", name_reg(spilled_reg).c_str(), reg_alloced[spilled_reg].version); + } + u32 host_reg = reg_alloced[spilled_reg].host_reg; + reg_alloced.erase(spilled_reg); + if (freg) + host_fregs.push_front(host_reg); + else + host_gregs.push_front(host_reg); + } + + bool UsesReg(shil_opcode* op, Sh4RegType reg, u32 version, bool vector = false) + { + if (op->rs1.is_reg() && reg >= op->rs1._reg && reg < (Sh4RegType)(op->rs1._reg + op->rs1.count()) + && version == op->rs1.version[reg - op->rs1._reg] + && (!vector || op->rs1.count() > 1)) + return true; + if (op->rs2.is_reg() && reg >= op->rs2._reg && reg < (Sh4RegType)(op->rs2._reg + op->rs2.count()) + && version == op->rs2.version[reg - op->rs2._reg] + && (!vector || op->rs2.count() > 1)) + return true; + if (op->rs3.is_reg() && reg >= op->rs3._reg && reg < (Sh4RegType)(op->rs3._reg + op->rs3.count()) + && version == op->rs3.version[reg - op->rs3._reg] + && (!vector || op->rs3.count() > 1)) + return true; + return false; + } + + RuntimeBlockInfo* block; + std::set writeback_values; + std::map aliases; // (dest reg, version) -> (source reg, version) + + struct { + u32 prop_constants = 0; + u32 constant_ops_replaced = 0; + u32 constant_ops_removed = 0; + u32 dead_code_ops = 0; + u32 dead_registers = 0; + } stats; + // transient vars + int opnum = 0; + // add version pass + u32 reg_versions[sh4_reg_count]; + // const prop pass + std::map constprop_values; // (reg num, version) -> value + // reg alloc + deque host_gregs; + deque host_fregs; + std::map reg_alloced; +}; From 0890150dda337e27039eb969c4f2e7ac5baf522c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 4 Jun 2019 21:27:45 +0200 Subject: [PATCH 055/158] dynarec: ssa missing changes --- core/hw/sh4/dyna/shil.cpp | 144 ++++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 54 deletions(-) diff --git a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp index 1d5af9f64..2fe2f4e6d 100644 --- a/core/hw/sh4/dyna/shil.cpp +++ b/core/hw/sh4/dyna/shil.cpp @@ -3,6 +3,8 @@ */ #include +#include +#include #include "types.h" #include "shil.h" @@ -488,11 +490,11 @@ void constprop(RuntimeBlockInfo* blk) if (op->rs2.is_imm()) { - op->rs1.type=1; + op->rs1.type = FMT_IMM; op->rs1._imm= op->op==shop_add ? (rv[op->rs1._reg]+op->rs2._imm): (rv[op->rs1._reg]-op->rs2._imm); - op->rs2.type=0; + op->rs2.type = FMT_NULL; printf("%s -> mov32!\n",op->op==shop_add?"shop_add":"shop_sub"); op->op=shop_mov32; } @@ -501,7 +503,7 @@ void constprop(RuntimeBlockInfo* blk) { u32 immy=rv[op->rs1._reg]; op->rs1=op->rs2; - op->rs2.type=1; + op->rs2.type = FMT_IMM; op->rs2._imm=immy; printf("%s -> imm prm (%08X)!\n",op->op==shop_add?"shop_add":"shop_sub",immy); } @@ -523,7 +525,7 @@ void constprop(RuntimeBlockInfo* blk) //NOT WORKING //WE NEED PROPER PAGELOCKS - if (op->op==shop_readm && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16 && op->flags==0x4 && op->rs3.is_null()) + if (false && op->op==shop_readm && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16 && op->flags==0x4 && op->rs3.is_null()) { u32 baddr=blk->addr&0x0FFFFFFF; @@ -864,10 +866,34 @@ void srt_waw(RuntimeBlockInfo* blk) } +#include "hw/sh4/modules/ccn.h" +#include "ngen.h" +#include "hw/sh4/sh4_core.h" +#include "hw/sh4/sh4_mmr.h" + + +#define SHIL_MODE 1 +#include "shil_canonical.h" + +#define SHIL_MODE 4 +#include "shil_canonical.h" + +//#define SHIL_MODE 2 +//#include "shil_canonical.h" + +#if FEAT_SHREC != DYNAREC_NONE +#define SHIL_MODE 3 +#include "shil_canonical.h" +#endif + +#include "ssa.h" + //Simplistic Write after Write without read pass to remove (a few) dead opcodes //Seems to be working void AnalyseBlock(RuntimeBlockInfo* blk) { + //SSAOptimizer optim(blk); + //optim.Optimize(); u32 st[sh4_reg_count]={0}; /* @@ -1000,47 +1026,68 @@ void AnalyseBlock(RuntimeBlockInfo* blk) //printf("\nBlock: %d affecter regs %d c\n",affregs,blk->guest_cycles); } -void UpdateFPSCR(); -bool UpdateSR(); -#include "hw/sh4/modules/ccn.h" -#include "ngen.h" -#include "hw/sh4/sh4_core.h" -#include "hw/sh4/sh4_mmr.h" - - -#define SHIL_MODE 1 -#include "shil_canonical.h" - -#define SHIL_MODE 4 -#include "shil_canonical.h" - -//#define SHIL_MODE 2 -//#include "shil_canonical.h" - -#if FEAT_SHREC != DYNAREC_NONE -#define SHIL_MODE 3 -#include "shil_canonical.h" -#endif - -string name_reg(u32 reg) +string name_reg(Sh4RegType reg) { stringstream ss; - if (reg>=reg_fr_0 && reg<=reg_xf_15) - ss << "f" << (reg-16); - else if (reg<=reg_r15) + if (reg >= reg_fr_0 && reg <= reg_xf_15) + ss << "f" << (reg - reg_fr_0); + else if (reg <= reg_r15) ss << "r" << reg; - else if (reg == reg_sr_T) - ss << "sr.T"; - else if (reg == reg_fpscr) - ss << "fpscr"; - else if (reg == reg_sr_status) - ss << "sr"; + else if (reg <= reg_r7_Bank) + ss << "r" << (reg - reg_r0_Bank) << "b"; else - ss << "s" << reg; + { + switch (reg) + { + case reg_sr_T: + ss << "sr.T"; + break; + case reg_fpscr: + ss << "fpscr"; + break; + case reg_sr_status: + ss << "sr"; + break; + case reg_pc_dyn: + ss << "pc_dyn"; + break; + case reg_macl: + ss << "macl"; + break; + case reg_mach: + ss << "mach"; + break; + case reg_pr: + ss << "pr"; + break; + case reg_gbr: + ss << "gbr"; + break; + case reg_nextpc: + ss << "pc"; + break; + case reg_fpul: + ss << "fpul"; + break; + case reg_old_fpscr: + ss << "old_fpscr"; + break; + case reg_old_sr_status: + ss << "old_sr_status"; + break; + case reg_ssr: + ss << "ssr"; + break; + default: + ss << "s" << reg; + break; + } + } return ss.str(); } + string dissasm_param(const shil_param& prm, bool comma) { stringstream ss; @@ -1057,37 +1104,26 @@ string dissasm_param(const shil_param& prm, bool comma) } else if (prm.is_reg()) { - if (!prm.is_r32i()) - ss << "f" << (prm._reg-16); - else if (prm._reg<=reg_r15) - ss << "r" << prm._reg; - else if (prm._reg == reg_sr_T) - ss << "sr.T"; - else if (prm._reg == reg_fpscr) - ss << "fpscr"; - else if (prm._reg == reg_sr_status) - ss << "sr"; - else - ss << "s" << prm._reg; - + ss << name_reg(prm._reg); - if (prm.count()>1) + if (prm.count() > 1) { ss << "v" << prm.count(); } + ss << "." << prm.version[0]; } return ss.str(); } -string shil_opcode::dissasm() +string shil_opcode::dissasm() const { stringstream ss; - ss << shilop_str[op] << " " << dissasm_param(rd,false) << dissasm_param(rd2,true) << " <= " << dissasm_param(rs1,false) << dissasm_param(rs2,true) << dissasm_param(rs3,true); + ss << shilop_str[op] << " " << dissasm_param(rd,false) << dissasm_param(rd2,true) << " <- " << dissasm_param(rs1,false) << dissasm_param(rs2,true) << dissasm_param(rs3,true); return ss.str(); } const char* shil_opcode_name(int op) { return shilop_str[op]; -} \ No newline at end of file +} From bd30752b8677b3c0fca3c7eabc25b1bb3f60111e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 8 Jun 2019 13:04:35 +0200 Subject: [PATCH 056/158] Use auto& to avoid copy when iterating. Inline mmu_Read/WriteMemNoEx --- core/hw/flashrom/flashrom.h | 2 +- core/hw/mem/vmem32.h | 20 ++++++++++++++ core/hw/sh4/dyna/blockmanager.cpp | 2 +- core/hw/sh4/modules/fastmmu.cpp | 28 ++++++++++++++----- core/hw/sh4/modules/mmu.cpp | 46 +------------------------------ core/hw/sh4/modules/mmu.h | 36 ++++++++++++++++++++++-- core/hw/sh4/modules/wince.h | 18 ++++++++++++ core/input/mapping.cpp | 8 +++--- core/linux-dist/evdev_gamepad.h | 4 +-- core/nullDC.cpp | 2 +- core/rend/gui.cpp | 6 ++-- core/rend/gui_util.cpp | 2 +- core/sdl/sdl_gamepad.h | 2 +- 13 files changed, 108 insertions(+), 68 deletions(-) diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index 8e0e3e665..89c5305ce 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -233,7 +233,7 @@ struct DCFlashChip : MemChip state = FS_Normal; } - virtual u8 Read8(u32 addr) + virtual u8 Read8(u32 addr) override { #if DC_PLATFORM == DC_PLATFORM_DREAMCAST switch (addr) diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index de11ce2ed..60e20a7b8 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -1,3 +1,23 @@ +/* + Created on: Apr 11, 2019 + + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ #include "_vmem.h" bool vmem32_init(); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 0b841c250..b39031ce0 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -477,7 +477,7 @@ void bm_ResetTempCache(bool full) { if (!full) { - for (auto block : all_temp_blocks) + for (auto& block : all_temp_blocks) { FPCA(block->addr) = ngen_FailedToFindBlock; auto it = blkmap.find(block); diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index 59d4cfac5..798d1cd50 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -1,3 +1,21 @@ +/* + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ #include "mmu.h" #include "hw/sh4/sh4_if.h" #include "hw/sh4/sh4_interrupts.h" @@ -36,9 +54,9 @@ struct TLB_LinkedEntry { TLB_LinkedEntry *next_entry; }; #define NBUCKETS 65536 -TLB_LinkedEntry full_table[65536]; -u32 full_table_size; -TLB_LinkedEntry *entry_buckets[NBUCKETS]; +static TLB_LinkedEntry full_table[65536]; +static u32 full_table_size; +static TLB_LinkedEntry *entry_buckets[NBUCKETS]; static u16 bucket_index(u32 address, int size) { @@ -283,10 +301,6 @@ u32 mmu_data_translation(u32 va, u32& rv) { if ((va & 0xFC000000) == 0xE0000000) { - u32 lookup = mmu_full_SQ(va, rv); - if (lookup != MMU_ERROR_NONE) - return lookup; - rv = va; //SQ writes are not translated, only write backs are. return MMU_ERROR_NONE; } diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index db65ae1d2..312ddcb3b 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -4,10 +4,6 @@ #include "hw/sh4/sh4_core.h" #include "types.h" - -#include "hw/mem/_vmem.h" - - TLB_Entry UTLB[64]; TLB_Entry ITLB[4]; @@ -760,28 +756,6 @@ void DYNACALL mmu_WriteMem(u32 adr, T data) _vmem_writet(addr, data); } -template -T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred) -{ - u32 addr; - u32 rv = mmu_data_translation(adr, addr); - if (rv != MMU_ERROR_NONE) - { - DoMMUException(adr, rv, MMU_TT_DREAD); - *exception_occurred = 1; - return 0; - } - else - { - *exception_occurred = 0; - return _vmem_readt(addr); - } -} -template u8 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); -template u16 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); -template u32 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); -template u64 mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); - u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) { u32 addr; @@ -799,24 +773,6 @@ u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) } } -template -u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data) -{ - u32 addr; - u32 rv = mmu_data_translation(adr, addr); - if (rv != MMU_ERROR_NONE) - { - DoMMUException(adr, rv, MMU_TT_DWRITE); - return 1; - } - _vmem_writet(addr, data); - return 0; -} -template u32 mmu_WriteMemNoEx(u32 adr, u8 data); -template u32 mmu_WriteMemNoEx(u32 adr, u16 data); -template u32 mmu_WriteMemNoEx(u32 adr, u32 data); -template u32 mmu_WriteMemNoEx(u32 adr, u64 data); - bool mmu_TranslateSQW(u32 adr, u32* out) { if (!settings.dreamcast.FullMMU) @@ -830,7 +786,7 @@ bool mmu_TranslateSQW(u32 adr, u32* out) { u32 addr; u32 tv = mmu_full_SQ(adr, addr); - if (tv != 0) + if (tv != MMU_ERROR_NONE) { mmu_raise_exception(tv, adr, MMU_TT_DREAD); return false; diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index 15a1c1648..a03195e6a 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -1,6 +1,7 @@ #pragma once #include "types.h" #include "hw/sh4/sh4_mmr.h" +#include "hw/mem/_vmem.h" //Translation Types //Opcode read @@ -95,6 +96,37 @@ void DoMMUException(u32 addr, u32 error_code, u32 access_type); bool mmu_TranslateSQW(u32 addr, u32* mapped); u16 DYNACALL mmu_IReadMem16NoEx(u32 adr, u32 *exception_occurred); - template T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred); - template u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data); + + template + T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred) + { + u32 addr; + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(adr, rv, MMU_TT_DREAD); + *exception_occurred = 1; + return 0; + } + else + { + *exception_occurred = 0; + return _vmem_readt(addr); + } + } + + template + u32 DYNACALL mmu_WriteMemNoEx(u32 adr, T data) + { + u32 addr; + u32 rv = mmu_data_translation(adr, addr); + if (rv != MMU_ERROR_NONE) + { + DoMMUException(adr, rv, MMU_TT_DWRITE); + return 1; + } + _vmem_writet(addr, data); + return 0; + } + #endif diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index 50a662e68..eb724c64c 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -1,3 +1,21 @@ +/* + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ #include "hw/sh4/sh4_sched.h" #define PUserKData 0x00005800 diff --git a/core/input/mapping.cpp b/core/input/mapping.cpp index 0157fb922..898e10727 100644 --- a/core/input/mapping.cpp +++ b/core/input/mapping.cpp @@ -135,7 +135,7 @@ void InputMapping::load(FILE* fp) u32 InputMapping::get_button_code(DreamcastKey key) { - for (auto it : buttons) + for (auto& it : buttons) { if (it.second == key) return it.first; @@ -145,7 +145,7 @@ u32 InputMapping::get_button_code(DreamcastKey key) u32 InputMapping::get_axis_code(DreamcastKey key) { - for (auto it : axes) + for (auto& it : axes) { if (it.second == key) return it.first; @@ -192,7 +192,7 @@ bool InputMapping::save(const char *name) for (int i = 0; i < ARRAY_SIZE(button_list); i++) { - for (auto it : buttons) + for (auto& it : buttons) { if (it.second == button_list[i].id) mf.set_int(button_list[i].section, button_list[i].option, (int)it.first); @@ -201,7 +201,7 @@ bool InputMapping::save(const char *name) for (int i = 0; i < ARRAY_SIZE(axis_list); i++) { - for (auto it : axes) + for (auto& it : axes) { if (it.second == axis_list[i].id) { diff --git a/core/linux-dist/evdev_gamepad.h b/core/linux-dist/evdev_gamepad.h index 2d06ce4fe..05eef706c 100644 --- a/core/linux-dist/evdev_gamepad.h +++ b/core/linux-dist/evdev_gamepad.h @@ -88,7 +88,7 @@ public: static std::shared_ptr GetControllerForPort(int port) { - for (auto pair : evdev_gamepads) + for (auto& pair : evdev_gamepads) if (pair.second->maple_port() == port) return pair.second; return NULL; @@ -104,7 +104,7 @@ public: static void PollDevices() { - for (auto pair : evdev_gamepads) + for (auto& pair : evdev_gamepads) pair.second->read_input(); } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 4325468bd..b97a9cd59 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -811,7 +811,7 @@ void SaveSettings() } // FIXME This should never be a game-specific setting std::string paths; - for (auto path : settings.dreamcast.ContentPath) + for (auto& path : settings.dreamcast.ContentPath) { if (!paths.empty()) paths += ";"; diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index c2d4d46ca..46fdf786a 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -754,7 +754,7 @@ static void gui_display_settings() static int current_item; std::vector paths; - for (auto path : settings.dreamcast.ContentPath) + for (auto& path : settings.dreamcast.ContentPath) paths.push_back(path.c_str()); ImVec2 size; @@ -1410,7 +1410,7 @@ static void fetch_game_list() if (game_list_done) return; game_list.clear(); - for (auto path : settings.dreamcast.ContentPath) + for (auto& path : settings.dreamcast.ContentPath) add_game_directory(path, game_list); std::stable_sort(game_list.begin(), game_list.end()); game_list_done = true; @@ -1495,7 +1495,7 @@ static void gui_display_content() ImGui::PopID(); #endif - for (auto game : game_list) + for (auto& game : game_list) if (filter.PassFilter(game.name.c_str())) { ImGui::PushID(game.path.c_str()); diff --git a/core/rend/gui_util.cpp b/core/rend/gui_util.cpp index 5fb9e9d02..36ca09565 100644 --- a/core/rend/gui_util.cpp +++ b/core/rend/gui_util.cpp @@ -196,7 +196,7 @@ void select_directory_popup(const char *prompt, float scaling, StringCallback ca ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * scaling, 20 * scaling)); // from 8, 4 - for (auto name : select_subfolders) + for (auto& name : select_subfolders) { std::string child_path; if (name == "..") diff --git a/core/sdl/sdl_gamepad.h b/core/sdl/sdl_gamepad.h index edf23ae9d..ea8321d2e 100644 --- a/core/sdl/sdl_gamepad.h +++ b/core/sdl/sdl_gamepad.h @@ -131,7 +131,7 @@ public: } static void UpdateRumble() { - for (auto pair : sdl_gamepads) + for (auto& pair : sdl_gamepads) pair.second->update_rumble(); } From 623d70d7101f4e41f6e6cdbfdb62a3c082d7ae79 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 9 Jun 2019 19:41:42 +0200 Subject: [PATCH 057/158] ssa register allocator and more ssa stuff --- core/hw/sh4/dyna/ssa.cpp | 368 ++++++++++++++ core/hw/sh4/dyna/ssa.h | 846 ++++++++------------------------ core/hw/sh4/dyna/ssa_regalloc.h | 584 ++++++++++++++++++++++ 3 files changed, 1168 insertions(+), 630 deletions(-) create mode 100644 core/hw/sh4/dyna/ssa.cpp create mode 100644 core/hw/sh4/dyna/ssa_regalloc.h diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp new file mode 100644 index 000000000..6ba3000c5 --- /dev/null +++ b/core/hw/sh4/dyna/ssa.cpp @@ -0,0 +1,368 @@ +/* + Created on: Jun 5, 2019 + + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ +#include "blockmanager.h" +#include "ssa.h" + +#define SHIL_MODE 2 +#include "shil_canonical.h" + +void SSAOptimizer::InsertMov32Op(const shil_param& rd, const shil_param& rs) +{ + shil_opcode op2(block->oplist[opnum]); + op2.op = shop_mov32; + op2.rd = rd; + op2.rd2 = shil_param(); + op2.rs1 = rs; + op2.rs2 = shil_param(); + op2.rs3 = shil_param(); + + block->oplist.insert(block->oplist.begin() + opnum + 1, op2); + opnum++; + + +} +bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) +{ + if (!op.rs1.is_reg() && !op.rs2.is_reg() && !op.rs3.is_reg() + && (op.rs1.is_imm() || op.rs2.is_imm() || op.rs3.is_imm()) + && op.rd.is_reg()) + { + // Only immediate operands -> execute the op at compile time + + u32 rs1 = op.rs1.is_imm() ? op.rs1.imm_value() : 0; + u32 rs2 = op.rs2.is_imm() ? op.rs2.imm_value() : 0; + u32 rs3 = op.rs3.is_imm() ? op.rs3.imm_value() : 0; + u32 rd; + u32 rd2; + + switch (op.op) + { + case shop_mov32: + rd = rs1; + break; + case shop_add: + rd = rs1 + rs2; + break; + case shop_sub: + rd = rs1 - rs2; + break; + case shop_adc: + case shop_sbc: + case shop_negc: + case shop_rocl: + case shop_rocr: + { + u64 v; + if (op.op == shop_adc) + v = shil_opcl_adc::f1::impl(rs1, rs2, rs3); + else if (op.op == shop_sbc) + v = shil_opcl_sbc::f1::impl(rs1, rs2, rs3); + else if (op.op == shop_rocl) + v = shil_opcl_rocl::f1::impl(rs1, rs2); + else if (op.op == shop_rocr) + v = shil_opcl_rocr::f1::impl(rs1, rs2); + else + v = shil_opcl_negc::f1::impl(rs1, rs2); + rd = (u32)v; + rd2 = (u32)(v >> 32); + + shil_param op2_rd = shil_param(op.rd2._reg); + op2_rd.version[0] = op.rd2.version[0]; + InsertMov32Op(op2_rd, shil_param(FMT_IMM, (u32)(v >> 32))); + + op.rd2 = shil_param(); + } + break; + case shop_shl: + rd = rs1 << rs2; + break; + case shop_shr: + rd = rs1 >> rs2; + break; + case shop_sar: + rd = (s32) rs1 >> rs2; + break; + case shop_ror: + rd = (rs1 >> rs2) + | (rs1 << (32 - rs2)); + break; + case shop_shld: + rd = shil_opcl_shld::f1::impl(rs1, rs2); + break; + case shop_shad: + rd = shil_opcl_shad::f1::impl(rs1, rs2); + break; + case shop_or: + rd = rs1 | rs2; + break; + case shop_and: + rd = rs1 & rs2; + break; + case shop_xor: + rd = rs1 ^ rs2; + break; + case shop_not: + rd = ~rs1; + break; + case shop_ext_s16: + rd = (s32)(s16)rs1; + break; + case shop_ext_s8: + rd = (s32)(s8)rs1; + break; + case shop_mul_i32: + rd = rs1 * rs2; + break; + case shop_mul_u16: + rd = (u16)(rs1 * rs2); + break; + case shop_mul_s16: + rd = (s16)(rs1 * rs2); + break; + case shop_mul_u64: + case shop_mul_s64: + { + u64 v; + if (op.op == shop_mul_u64) + v = shil_opcl_mul_u64::f1::impl(rs1, rs2); + else + v = shil_opcl_mul_s64::f1::impl(rs1, rs2); + rd = (u32)v; + rd2 = (u32)(v >> 32); + + shil_param op2_rd = shil_param(op.rd2._reg); + op2_rd.version[0] = op.rd2.version[0]; + InsertMov32Op(op2_rd, shil_param(FMT_IMM, rd2)); + + op.rd2 = shil_param(); + } + break; + case shop_test: + rd = (rs1 & rs2) == 0; + break; + case shop_neg: + rd = -rs1; + break; + case shop_swaplb: + rd = shil_opcl_swaplb::f1::impl(rs1); + break; + case shop_swap: + rd = shil_opcl_swap::f1::impl(rs1); + break; + case shop_seteq: + case shop_setgt: + case shop_setge: + case shop_setab: + case shop_setae: + { + switch (op.op) + { + case shop_seteq: + rd = rs1 == rs2; + break; + case shop_setge: + rd = (s32)rs1 >= (s32)rs2; + break; + case shop_setgt: + rd = (s32)rs1 > (s32)rs2; + break; + case shop_setab: + rd = rs1 > rs2; + break; + case shop_setae: + rd = rs1 >= rs2; + break; + } + } + break; + case shop_setpeq: + rd = shil_opcl_setpeq::f1::impl(rs1, rs2); + break; + case shop_xtrct: + rd = shil_opcl_xtrct::f1::impl(rs1, rs2); + break; + + case shop_div32u: + case shop_div32s: + { + u64 res = op.op == shop_div32u ? shil_opcl_div32u::f1::impl(rs1, rs2) : shil_opcl_div32s::f1::impl(rs1, rs2); + rd = (u32)res; + constprop_values[RegValue(op.rd, 1)] = res >> 32; + + shil_param op2_rd = shil_param((Sh4RegType)(op.rd._reg + 1)); + op2_rd.version[0] = op.rd.version[1]; + InsertMov32Op(op2_rd, shil_param(FMT_IMM, res >> 32)); + } + break; + case shop_div32p2: + rd = shil_opcl_div32p2::f1::impl(rs1, rs2, rs3); + break; + + case shop_jdyn: + { + verify(BET_GET_CLS(block->BlockType) == BET_CLS_Dynamic); + switch ((block->BlockType >> 1) & 3) + { + case BET_SCL_Jump: + case BET_SCL_Ret: + block->BlockType = BET_StaticJump; + block->BranchBlock = rs1; + break; + case BET_SCL_Call: + block->BlockType = BET_StaticCall; + block->BranchBlock = rs1; + break; + case BET_SCL_Intr: + block->BlockType = BET_StaticIntr; + block->NextBlock = rs1; + break; + default: + die("Unexpected block end type\n") + ; + } + // rd (that is jdyn) won't be updated but since it's not a real register + // it shouldn't be a problem + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.dyn_to_stat_blocks++; + + return true; + } + case shop_jcond: + { + if (rs1 != (block->BlockType & 1)) + { + block->BranchBlock = block->NextBlock; + } + block->BlockType = BET_StaticJump; + block->NextBlock = 0xFFFFFFFF; + block->has_jcond = false; + // same remark regarding jdyn as in the previous case + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.dyn_to_stat_blocks++; + + return true; + } + case shop_fneg: + rd = rs1 ^ 0x80000000; + break; + case shop_fadd: + { + f32 frd = reinterpret_cast(rs1) + reinterpret_cast(rs2); + rd = reinterpret_cast(frd); + } + break; + case shop_fsub: + { + f32 frd = reinterpret_cast(rs1) - reinterpret_cast(rs2); + rd = reinterpret_cast(frd); + } + break; + case shop_fmul: + { + f32 frd = reinterpret_cast(rs1) * reinterpret_cast(rs2); + rd = reinterpret_cast(frd); + } + break; + case shop_fdiv: + { + f32 frd = reinterpret_cast(rs1) / reinterpret_cast(rs2); + rd = reinterpret_cast(frd); + } + break; + case shop_cvt_i2f_n: + case shop_cvt_i2f_z: + { + f32 frd = (float)(s32) rs1; + rd = reinterpret_cast(frd); + } + break; + case shop_fsqrt: + { + f32 frd = sqrtf(reinterpret_cast(rs1)); + rd = reinterpret_cast(frd); + } + break; + case shop_cvt_f2i_t: + { + f32 r1 = reinterpret_cast(rs1); + rd = shil_opcl_cvt_f2i_t::f1::impl(r1); + } + break; + case shop_fsrra: + { + f32 frd = shil_opcl_fsrra::f1::impl(reinterpret_cast(rs1)); + rd = reinterpret_cast(frd); + } + break; + case shop_fsca: + { + f32 tmp[2]; + shil_opcl_fsca::fsca_table::impl(tmp, rs1); + rd = reinterpret_cast(tmp[0]); + u32 rd_1 = reinterpret_cast(tmp[1]); + constprop_values[RegValue(op.rd, 1)] = rd_1; + + shil_param op2_rd = shil_param((Sh4RegType)(op.rd._reg + 1)); + op2_rd.version[0] = op.rd.version[1]; + InsertMov32Op(op2_rd, shil_param(FMT_IMM, rd_1)); + + op.rd.type = FMT_F32; + } + break; + case shop_fabs: + { + f32 frd = shil_opcl_fabs::f1::impl(reinterpret_cast(rs1)); + rd = reinterpret_cast(frd); + } + break; + case shop_fmac: + { + f32 frd = shil_opcl_fmac::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2), reinterpret_cast(rs3)); + rd = reinterpret_cast(frd); + } + break; + case shop_fseteq: + rd = shil_opcl_fseteq::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); + break; + case shop_fsetgt: + rd = shil_opcl_fsetgt::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); + break; + + default: + printf("unhandled constant op %d\n", op.op); + die("unhandled constant op"); + break; + } + + constprop_values[RegValue(op.rd)] = rd; + if (op.rd2.is_r32()) + constprop_values[RegValue(op.rd2)] = rd2; + ReplaceByMov32(op, rd); + + return true; + } + else + { + return false; + } +} diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 233c11d31..d454732c6 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -43,21 +43,37 @@ public: ConstPropPass(); DeadCodeRemovalPass(); ConstantExpressionsPass(); - //DeadRegisterPass(); - //DoRegAlloc(); + CombineShiftsPass(); + DeadRegisterPass(); + IdentityMovePass(); #if DEBUG if (stats.prop_constants > 0 || stats.dead_code_ops > 0 || stats.constant_ops_replaced > 0 - || stats.constant_ops_removed || stats.dead_registers > 0) + || stats.dead_registers > 0 || stats.dyn_to_stat_blocks > 0) { - printf("AFTER\n"); - PrintBlock(); - printf("STATS: constants %d constant ops replaced %d removed %d dead code %d dead regs %d\n\n", stats.prop_constants, stats.constant_ops_replaced, - stats.constant_ops_removed, stats.dead_code_ops, stats.dead_registers); + //printf("AFTER %08x\n", block->vaddr); + //PrintBlock(); + printf("STATS: %08x ops %zd constants %d constops replaced %d dead code %d dead regs %d dyn2stat blks %d\n", block->vaddr, block->oplist.size(), + stats.prop_constants, stats.constant_ops_replaced, + stats.dead_code_ops, stats.dead_registers, stats.dyn_to_stat_blocks); } #endif } + void AddVersionPass() + { + memset(reg_versions, 0, sizeof(reg_versions)); + + for (shil_opcode& op : block->oplist) + { + AddVersionToOperand(op.rs1, false); + AddVersionToOperand(op.rs2, false); + AddVersionToOperand(op.rs3, false); + AddVersionToOperand(op.rd, true); + AddVersionToOperand(op.rd2, true); + } + } + private: // References a specific version of a register value class RegValue : public std::pair @@ -69,18 +85,14 @@ private: verify(param.is_reg()); verify(index >= 0 && index < param.count()); } + RegValue(Sh4RegType reg, u32 version) + : std::pair(reg, version) { } RegValue() : std::pair() { } Sh4RegType get_reg() const { return first; } u32 get_version() const { return second; } }; - struct reg_alloc { - u32 host_reg; - u16 version; - bool write_back; - }; - void PrintBlock() { for (const shil_opcode& op : block->oplist) @@ -102,23 +114,10 @@ private: } } - void AddVersionPass() - { - memset(reg_versions, 0, sizeof(reg_versions)); - - for (shil_opcode& op : block->oplist) - { - AddVersionToOperand(op.rs1, false); - AddVersionToOperand(op.rs2, false); - AddVersionToOperand(op.rs3, false); - AddVersionToOperand(op.rd, true); - AddVersionToOperand(op.rd2, true); - } - } - // mov rd, #v void ReplaceByMov32(shil_opcode& op, u32 v) { + verify(op.rd2.is_null()); op.op = shop_mov32; op.rs1 = shil_param(FMT_IMM, v); op.rs2.type = FMT_NULL; @@ -129,11 +128,15 @@ private: // mov rd, rs1 void ReplaceByMov32(shil_opcode& op) { + verify(op.rd2.is_null()); op.op = shop_mov32; op.rs2.type = FMT_NULL; op.rs3.type = FMT_NULL; } + // mov rd, rs + void InsertMov32Op(const shil_param& rd, const shil_param& rs); + void ConstPropOperand(shil_param& param) { if (param.is_r32()) @@ -148,9 +151,11 @@ private: } } + bool ExecuteConstOp(shil_opcode& op); + void ConstPropPass() { - for (int opnum = 0; opnum < block->oplist.size(); opnum++) + for (opnum = 0; opnum < block->oplist.size(); opnum++) { shil_opcode& op = block->oplist[opnum]; @@ -181,259 +186,52 @@ private: } } } - else if (!op.rs1.is_reg() && !op.rs2.is_reg() && !op.rs3.is_reg() - && (op.rs1.is_imm() || op.rs2.is_imm() || op.rs3.is_imm()) - && op.rd.is_r32()) + else if (ExecuteConstOp(op)) { - // Only immediate operands -> execute the op at compile time - //printf("%08x IMM %s --> \n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - const RegValue dest_reg(op.rd); - - if (op.op == shop_mov32) + } + else if (op.op == shop_and || op.op == shop_or || op.op == shop_xor || op.op == shop_add || op.op == shop_mul_s16 || op.op == shop_mul_u16 + || op.op == shop_mul_i32 || op.op == shop_test || op.op == shop_seteq || op.op == shop_fseteq || op.op == shop_fadd || op.op == shop_fmul + || op.op == shop_mul_u64 || op.op == shop_mul_s64 || op.op == shop_adc) + { + if (op.rs1.is_imm() && op.rs2.is_reg()) { - constprop_values[dest_reg] = op.rs1.imm_value(); + // Swap rs1 and rs2 so that rs1 is never an immediate operand + shil_param t = op.rs1; + op.rs1 = op.rs2; + op.rs2 = t; } - else if (op.op == shop_add) + } + else if ((op.op == shop_shld || op.op == shop_shad) && op.rs2.is_imm()) + { + // Replace shld/shad with shl/shr/sar + u32 r2 = op.rs2.imm_value(); + if ((r2 & 0x80000000) == 0) { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() + op.rs2.imm_value(); - ReplaceByMov32(op, v); + // rd = r1 << (r2 & 0x1F) + op.op = shop_shl; + op.rs2._imm = r2 & 0x1F; + stats.constant_ops_replaced++; } - else if (op.op == shop_sub) + else if ((r2 & 0x1F) == 0) { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() - op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_shl) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() << op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_shr) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() >> op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_sar) - { - u32 v = constprop_values[dest_reg] - = (s32)op.rs1.imm_value() >> op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_ror) - { - u32 v = constprop_values[dest_reg] - = (op.rs1.imm_value() >> op.rs2.imm_value()) - | (op.rs1.imm_value() << (32 - op.rs2.imm_value())); - ReplaceByMov32(op, v); - } - else if (op.op == shop_shld) - { - u32 r1 = op.rs1.imm_value(); - u32 r2 = op.rs2.imm_value(); - u32 rd = shil_opcl_shld::f1::impl(r1, r2); - - constprop_values[dest_reg] = rd; - ReplaceByMov32(op, rd); - } - else if (op.op == shop_shad) - { - u32 r1 = op.rs1.imm_value(); - u32 r2 = op.rs2.imm_value(); - u32 rd = shil_opcl_shad::f1::impl(r1, r2); - - constprop_values[dest_reg] = rd; - ReplaceByMov32(op, rd); - } - else if (op.op == shop_or) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() | op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_and) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() & op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_xor) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() ^ op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_not) - { - u32 v = constprop_values[dest_reg] - = ~op.rs1.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_ext_s16) - { - u32 v = constprop_values[dest_reg] - = (s32)(s16)op.rs1.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_ext_s8) - { - u32 v = constprop_values[dest_reg] - = (s32)(s8)op.rs1.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_mul_i32) - { - u32 v = constprop_values[dest_reg] - = op.rs1.imm_value() * op.rs2.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_mul_u16) - { - u32 v = constprop_values[dest_reg] - = (u16)(op.rs1.imm_value() * op.rs2.imm_value()); - ReplaceByMov32(op, v); - } - else if (op.op == shop_mul_s16) - { - u32 v = constprop_values[dest_reg] - = (s16)(op.rs1.imm_value() * op.rs2.imm_value()); - ReplaceByMov32(op, v); - } - else if (op.op == shop_test) - { - u32 v = constprop_values[dest_reg] - = (op.rs1.imm_value() & op.rs2.imm_value()) == 0; - ReplaceByMov32(op, v); - } - else if (op.op == shop_neg) - { - u32 v = constprop_values[dest_reg] - = -op.rs1.imm_value(); - ReplaceByMov32(op, v); - } - else if (op.op == shop_swaplb) - { - u32 v = shil_opcl_swaplb::f1::impl(op.rs1.imm_value()); - constprop_values[dest_reg] = v; - ReplaceByMov32(op, v); - } - else if (op.op == shop_seteq || op.op == shop_setgt || op.op == shop_setge || op.op == shop_setab || op.op == shop_setae) - { - u32 r1 = op.rs1.imm_value(); - u32 r2 = op.rs2.imm_value(); - u32 rd; - switch (op.op) + if (op.op == shop_shl) + // rd = 0 + ReplaceByMov32(op, 0); + else { - case shop_seteq: - rd = r1 == r2; - break; - case shop_setge: - rd = (s32)r1 >= (s32)r2; - break; - case shop_setgt: - rd = (s32)r1 > (s32)r2; - break; - case shop_setab: - rd = r1 > r2; - break; - case shop_setae: - rd = r1 >= r2; - break; + // rd = r1 >> 31; + op.op = shop_sar; + op.rs2._imm = 31; + stats.constant_ops_replaced++; } - constprop_values[dest_reg] = rd; - ReplaceByMov32(op, rd); - } - else if (op.op == shop_jdyn) - { - // TODO check this - verify(BET_GET_CLS(block->BlockType) == BET_CLS_Dynamic); - switch ((block->BlockType >> 1) & 3) - { - case BET_SCL_Jump: - case BET_SCL_Ret: - block->BlockType = BET_StaticJump; - block->BranchBlock = op.rs1.imm_value(); - break; - case BET_SCL_Call: - block->BlockType = BET_StaticCall; - block->BranchBlock = op.rs1.imm_value(); - break; - case BET_SCL_Intr: - block->BlockType = BET_StaticIntr; - block->NextBlock = op.rs1.imm_value(); - break; - default: - die("Unexpected block end type\n"); - } - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - //printf("DEAD\n"); - continue; - } - else if (op.op == shop_jcond) - { - if (op.rs1.imm_value() != (block->BlockType & 1)) - { - block->BranchBlock = block->NextBlock; - } - block->BlockType = BET_StaticJump; - block->NextBlock = 0xFFFFFFFF; - block->has_jcond = false; - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - //printf("DEAD\n"); - continue; - } - else if (op.op == shop_fneg) - { - u32 rd = constprop_values[dest_reg] = op.rs1.imm_value() ^ 0x80000000; - ReplaceByMov32(op, rd); - } - else if (op.op == shop_fadd) - { - f32 rd = reinterpret_cast(op.rs1._imm) + reinterpret_cast(op.rs2._imm); - constprop_values[dest_reg] = reinterpret_cast(rd); - ReplaceByMov32(op, reinterpret_cast(rd)); - } - else if (op.op == shop_fmul) - { - f32 rd = reinterpret_cast(op.rs1._imm) * reinterpret_cast(op.rs2._imm); - constprop_values[dest_reg] = reinterpret_cast(rd); - ReplaceByMov32(op, reinterpret_cast(rd)); - } - else if (op.op == shop_cvt_i2f_n || op.op == shop_cvt_i2f_z) - { - f32 rd = (float)(s32)op.rs1._imm; - constprop_values[dest_reg] = reinterpret_cast(rd); - ReplaceByMov32(op, reinterpret_cast(rd)); - } - else if (op.op == shop_fsqrt) - { - f32 rd = sqrtf(reinterpret_cast(op.rs1._imm)); - constprop_values[dest_reg] = reinterpret_cast(rd); - ReplaceByMov32(op, reinterpret_cast(rd)); } else { - printf("unhandled constant op %d\n", op.op); - die("RHHAAA"); + // rd = r1 >> ((~r2 & 0x1F) + 1) + op.op = op.op == shop_shad ? shop_sar : shop_shr; + op.rs2._imm = (~r2 & 0x1F) + 1; + stats.constant_ops_replaced++; } - - //printf("%s\n", op.dissasm().c_str()); - } - else if ((op.op == shop_and || op.op == shop_or || op.op == shop_xor || op.op == shop_add || op.op == shop_mul_s16 || op.op == shop_mul_u16 - || op.op == shop_mul_i32 || op.op == shop_test || op.op == shop_seteq || op.op == shop_fseteq || op.op == shop_fadd || op.op == shop_fmul) - && op.rs1.is_imm() && op.rs2.is_reg()) - { - // swap rs1 and rs2 so that rs1 is never an immediate operand - shil_param t = op.rs1; - op.rs1 = op.rs2; - op.rs2 = t; } } } @@ -530,15 +328,14 @@ private: } dead_code = dead_code && unused_rd; } - if (dead_code && op.op != shop_readm) // TODO Can we also remove dead readm? + if (dead_code && op.op != shop_readm) // memory read on registers can have side effects { - //printf("%08x DEAD %s\n", blk->vaddr + op.guest_offs, op.dissasm().c_str()); + //printf("%08x DEAD %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); block->oplist.erase(block->oplist.begin() + opnum); stats.dead_code_ops++; } else { - //printf("%08x %s\n", blk->vaddr + op.guest_offs, op.dissasm().c_str()); if (op.rs1.is_reg()) { for (int i = 0; i < op.rs1.count(); i++) @@ -554,17 +351,6 @@ private: for (int i = 0; i < op.rs3.count(); i++) uses.insert(RegValue(op.rs3, i)); } - if (op.op == shop_mov32 && op.rs1.is_reg()) - { - RegValue dest_reg(op.rd); - RegValue src_reg(op.rs1); - auto it = aliases.find(src_reg); - if (it != aliases.end()) - // use the final value if the dest is itself aliased - aliases[dest_reg] = it->second; - else - aliases[dest_reg] = src_reg; - } } } } @@ -605,17 +391,7 @@ private: || op.op == shop_fadd || op.op == shop_fsub) { //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - if (op.rd._reg == op.rs1._reg) - { - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - } - else - { - ReplaceByMov32(op); - } - continue; + ReplaceByMov32(op); } } // a * 1 == a @@ -623,35 +399,8 @@ private: && (op.op == shop_mul_i32 || op.op == shop_mul_s16 || op.op == shop_mul_u16)) { //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - if (op.rd._reg == op.rs1._reg) - { - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - } - else - { - ReplaceByMov32(op); - } - continue; - } - // TODO very rare - // a * 1.0 == a - // a / 1.0 == a - else if (op.rs2.imm_value() == 0x3f800000 // 1.0 - && (op.op == shop_fmul || op.op == shop_fdiv)) - { - //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - if (op.rd._reg == op.rs1._reg) - { - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - } - else - { - ReplaceByMov32(op); - } + ReplaceByMov32(op); + continue; } } @@ -669,352 +418,189 @@ private: else if (op.op == shop_and || op.op == shop_or) { //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - if (op.rd._reg == op.rs1._reg) - { - block->oplist.erase(block->oplist.begin() + opnum); - opnum--; - stats.constant_ops_removed++; - } - else - { - ReplaceByMov32(op); - } + ReplaceByMov32(op); } } } } + bool DefinesHigherVersion(const shil_param& param, RegValue reg_ver) + { + return param.is_reg() + && reg_ver.get_reg() >= param._reg + && reg_ver.get_reg() < (Sh4RegType)(param._reg + param.count()) + && param.version[reg_ver.get_reg() - param._reg] > reg_ver.get_version(); + } + + bool UsesRegValue(const shil_param& param, RegValue reg_ver) + { + return param.is_reg() + && reg_ver.get_reg() >= param._reg + && reg_ver.get_reg() < (Sh4RegType)(param._reg + param.count()) + && param.version[reg_ver.get_reg() - param._reg] == reg_ver.get_version(); + } + + void ReplaceByAlias(shil_param& param, const RegValue& from, const RegValue& to) + { + if (param.is_r32() && param._reg == from.get_reg()) + { + verify(param.version[0] == from.get_version()); + param._reg = to.get_reg(); + param.version[0] = to.get_version(); + //printf("DeadRegisterPass replacing %s.%d by %s.%d\n", name_reg(from.get_reg()).c_str(), from.get_version(), + // name_reg(to.get_reg()).c_str(), to.get_version()); + } + } + void DeadRegisterPass() { - for (auto alias : aliases) + std::map aliases; // (dest reg, version) -> (source reg, version) + + // Find aliases + for (shil_opcode& op : block->oplist) { - if (writeback_values.count(alias.first) == 0) + // ignore moves from/to int regs to/from fpu regs + if (op.op == shop_mov32 && op.rs1.is_reg() && op.rd.is_r32i() == op.rs1.is_r32i()) { - // Do a first pass to check that we can replace the reg - size_t defnum = -1; - size_t usenum = -1; - size_t aliasdef = -1; - for (int opnum = 0; opnum < block->oplist.size(); opnum++) - { - shil_opcode* op = &block->oplist[opnum]; - if (op->rd.is_r32() && RegValue(op->rd) == alias.first) - defnum = opnum; - else if (op->rd2.is_r32() && RegValue(op->rd2) == alias.first) - defnum = opnum; - if (defnum == -1) - continue; - if (op->rd.is_reg() && alias.second.get_reg() >= op->rd._reg && alias.second.get_reg() < (Sh4RegType)(op->rd._reg + op->rd.count()) - && op->rd.version[alias.second.get_reg() - op->rd._reg] > alias.second.get_version() && aliasdef == -1) - aliasdef = opnum; - else if (op->rd2.is_reg() && alias.second.get_reg() >= op->rd2._reg && alias.second.get_reg() < (Sh4RegType)(op->rd2._reg + op->rd2.count()) - && op->rd2.version[alias.second.get_reg() - op->rd2._reg] > alias.second.get_version() && aliasdef == -1) - aliasdef = opnum; - if (op->rs1.is_r32() && op->rs1._reg == alias.first.get_reg() && op->rs1.version[0] == alias.first.get_version()) - usenum = opnum; - if (op->rs2.is_r32() && op->rs2._reg == alias.first.get_reg() && op->rs2.version[0] == alias.first.get_version()) - usenum = opnum; - if (op->rs3.is_r32() && op->rs3._reg == alias.first.get_reg() && op->rs3.version[0] == alias.first.get_version()) - usenum = opnum; - } - verify(defnum != -1); - // If the alias is redefined before any use we can't do it - if (aliasdef != -1 && usenum != -1 && aliasdef < usenum) - continue; - if (alias.first.get_reg() <= reg_r15) - continue; -// if (alias.first.get_reg() >= reg_fr_0 && alias.first.get_reg() <= reg_xf_15) -// continue; - for (opnum = defnum + 1; opnum <= usenum && usenum != -1; opnum++) - { - shil_opcode* op = &block->oplist[opnum]; - if (op->rs1.is_reg() && op->rs1.count() == 1 && op->rs1._reg == alias.first.first) - { - op->rs1._reg = alias.second.first; - op->rs1.version[0] = alias.second.second; - printf("DeadRegisterAlias rs1 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, - name_reg(alias.second.first).c_str(), alias.second.second); - } - if (op->rs2.is_reg() && op->rs2.count() == 1 && op->rs2._reg == alias.first.first) - { - op->rs2._reg = alias.second.first; - op->rs2.version[0] = alias.second.second; - printf("DeadRegisterAlias rs2 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, - name_reg(alias.second.first).c_str(), alias.second.second); - } - if (op->rs3.is_reg() && op->rs3.count() == 1 && op->rs3._reg == alias.first.first) - { - op->rs3._reg = alias.second.first; - op->rs3.version[0] = alias.second.second; - printf("DeadRegisterAlias rs3 replacing %s.%d by %s.%d\n", name_reg(alias.first.first).c_str(), alias.first.second, - name_reg(alias.second.first).c_str(), alias.second.second); - } - } - stats.dead_registers++; - block->oplist.erase(block->oplist.begin() + defnum); - } - } - } - - void DoRegAlloc() - { - host_gregs.clear(); - for (int i = 0; i < 6; i++) // FIXME reg count - host_gregs.push_front(i); - host_fregs.clear(); - for (int i = 0; i < 4; i++) // FIXME reg count - host_fregs.push_front(i); - - printf("BLOCK\n"); - for (opnum = 0; opnum < block->oplist.size(); opnum++) - { - shil_opcode* op = &block->oplist[opnum]; - if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref))) - FlushAllWritebacks(); - // Flush regs used by vector ops - if (op->rs1.count() > 1 || op->rs2.count() > 1 || op->rs3.count() > 1) - { - for (int i = 0; i < op->rs1.count(); i++) - { - auto reg = reg_alloced.find((Sh4RegType)(op->rs1._reg + i)); - if (reg != reg_alloced.end() && reg->second.version == op->rs1.version[i]) - FlushReg((Sh4RegType)(op->rs1._reg + i), true); - } - for (int i = 0; i < op->rs2.count(); i++) - { - auto reg = reg_alloced.find((Sh4RegType)(op->rs2._reg + i)); - if (reg != reg_alloced.end() && reg->second.version == op->rs2.version[i]) - FlushReg((Sh4RegType)(op->rs2._reg + i), true); - } - for (int i = 0; i < op->rs3.count(); i++) - { - auto reg = reg_alloced.find((Sh4RegType)(op->rs3._reg + i)); - if (reg != reg_alloced.end() && reg->second.version == op->rs3.version[i]) - FlushReg((Sh4RegType)(op->rs3._reg + i), true); - } - } - AllocSourceReg(op->rs1); - AllocSourceReg(op->rs2); - AllocSourceReg(op->rs3); - AllocDestReg(op->rd); - AllocDestReg(op->rd2); - printf("%08x %s\n", block->vaddr + op->guest_offs, op->dissasm().c_str()); - } - FlushAllWritebacks(); - } - - void FlushReg(Sh4RegType reg_num, bool full) - { - auto reg = reg_alloced.find(reg_num); - verify(reg != reg_alloced.end()); - if (reg->second.write_back) - { - printf("WB %s.%d\n", name_reg(reg_num).c_str(), reg->second.version); - reg->second.write_back = false; - } - if (full) - { - u32 host_reg = reg->second.host_reg; - if (reg_num >= reg_fr_0 && reg_num <= reg_xf_15) - host_fregs.push_front(host_reg); - else - host_gregs.push_front(host_reg); - reg_alloced.erase(reg); - } - } - - void FlushAllWritebacks() - { - for (auto reg : reg_alloced) - { - FlushReg(reg.first, false); - } - } - - void AllocSourceReg(const shil_param& param) - { - if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? - { - auto it = reg_alloced.find(param._reg); - if (it == reg_alloced.end()) - { - u32 host_reg; - if (param.is_r32i()) - { - if (host_gregs.empty()) - { - SpillReg(false, true); - verify(!host_gregs.empty()); - } - host_reg = host_gregs.back(); - host_gregs.pop_back(); - } + RegValue dest_reg(op.rd); + RegValue src_reg(op.rs1); + auto it = aliases.find(src_reg); + if (it != aliases.end()) + // use the final value if the src is itself aliased + aliases[dest_reg] = it->second; else - { - if (host_fregs.empty()) - { - SpillReg(true, true); - verify(!host_fregs.empty()); - } - host_reg = host_fregs.back(); - host_fregs.pop_back(); - } - reg_alloced[param._reg] = { host_reg, param.version[0], false }; - printf("PL %s -> %cx\n", name_reg(param._reg).c_str(), 'a' + host_reg); + aliases[dest_reg] = src_reg; } } - } - bool NeedsWriteBack(Sh4RegType reg, u32 version) - { - u32 last_version = -1; - for (int i = opnum + 1; i < block->oplist.size(); i++) + // Attempt to eliminate them + for (auto& alias : aliases) { - shil_opcode* op = &block->oplist[i]; - // if a subsequent op needs all regs flushed to mem - if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref))) - return true; - // reg is used by a subsequent vector op that doesn't use reg allocation - if (UsesReg(op, reg, version, true)) - return true; - if (op->rd.is_reg() && reg >= op->rd._reg && reg < (Sh4RegType)(op->rd._reg + op->rd.count())) - last_version = op->rd.version[reg - op->rd._reg]; - else if (op->rd2.is_reg() && reg >= op->rd2._reg && reg < (Sh4RegType)(op->rd2._reg + op->rd2.count())) - last_version = op->rd2.version[reg - op->rd2._reg]; - } - return last_version == -1 || version == last_version; - } - - void AllocDestReg(const shil_param& param) - { - if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? - { - auto it = reg_alloced.find(param._reg); - if (it == reg_alloced.end()) - { - u32 host_reg; - if (param.is_r32i()) - { - if (host_gregs.empty()) - { - SpillReg(false, false); - verify(!host_gregs.empty()); - } - host_reg = host_gregs.back(); - host_gregs.pop_back(); - } - else - { - if (host_fregs.empty()) - { - SpillReg(true, false); - verify(!host_fregs.empty()); - } - host_reg = host_fregs.back(); - host_fregs.pop_back(); - } - reg_alloced[param._reg] = { host_reg, param.version[0], NeedsWriteBack(param._reg, param.version[0]) }; - printf(" %s -> %cx\n", name_reg(param._reg).c_str(), 'a' + host_reg); - } - else - { - reg_alloc& reg = reg_alloced[param._reg]; - reg.write_back = NeedsWriteBack(param._reg, param.version[0]); - reg.version = param.version[0]; - } - } - } - - void SpillReg(bool freg, bool source) - { - Sh4RegType not_used_reg = NoReg; - Sh4RegType best_reg = NoReg; - int best_first_use = -1; - - for (auto reg : reg_alloced) - { - if ((reg.first >= reg_fr_0 && reg.first <= reg_xf_15) != freg) + if (writeback_values.count(alias.first) > 0) continue; - // Find the first use, but prefer no write back - int first_use = -1; - for (int i = opnum + (source ? 0 : 1); i < block->oplist.size() /* && (first_use == -1 || write_back) */; i++) + // Do a first pass to check that we can replace the value + size_t defnum = -1; + size_t usenum = -1; + size_t aliasdef = -1; + for (int opnum = 0; opnum < block->oplist.size(); opnum++) { - shil_opcode* op = &block->oplist[i]; - if (UsesReg(op, reg.first, reg.second.version)) + shil_opcode* op = &block->oplist[opnum]; + // find def + if (op->rd.is_r32() && RegValue(op->rd) == alias.first) + defnum = opnum; + else if (op->rd2.is_r32() && RegValue(op->rd2) == alias.first) + defnum = opnum; + + // find alias redef + if (DefinesHigherVersion(op->rd, alias.second) && aliasdef == -1) + aliasdef = opnum; + else if (DefinesHigherVersion(op->rd2, alias.second) && aliasdef == -1) + aliasdef = opnum; + + // find last use + if (UsesRegValue(op->rs1, alias.first)) { - first_use = i; - break; + if (op->rs1.count() == 1) + usenum = opnum; + else + { + usenum = 0xFFFF; // Can't alias values used by vectors cuz they need adjacent regs + aliasdef = 0; + break; + } + } + else if (UsesRegValue(op->rs2, alias.first)) + { + if (op->rs2.count() == 1) + usenum = opnum; + else + { + usenum = 0xFFFF; + aliasdef = 0; + break; + } + } + else if (UsesRegValue(op->rs3, alias.first)) + { + if (op->rs3.count() == 1) + usenum = opnum; + else + { + usenum = 0xFFFF; + aliasdef = 0; + break; + } } } - if (first_use == -1) - { - not_used_reg = reg.first; - break; - } - if (first_use > best_first_use && first_use > opnum) - { - best_first_use = first_use; - best_reg = reg.first; - } - } - Sh4RegType spilled_reg; - if (not_used_reg != NoReg) - spilled_reg = not_used_reg; - else - { - printf("RegAlloc: non optimal alloc? reg %s used in op %d\n", name_reg(best_reg).c_str(), best_first_use); - spilled_reg = best_reg; - } - verify(spilled_reg != NoReg); + verify(defnum != -1); + // If the alias is redefined before any use we can't use it + if (aliasdef != -1 && usenum != -1 && aliasdef < usenum) + continue; - if (reg_alloced[spilled_reg].write_back) - { - printf("WB %s.%d\n", name_reg(spilled_reg).c_str(), reg_alloced[spilled_reg].version); + for (int opnum = defnum + 1; opnum <= usenum && usenum != -1; opnum++) + { + shil_opcode* op = &block->oplist[opnum]; + ReplaceByAlias(op->rs1, alias.first, alias.second); + ReplaceByAlias(op->rs2, alias.first, alias.second); + ReplaceByAlias(op->rs3, alias.first, alias.second); + } + stats.dead_registers++; + //printf("%08x DREG %s\n", block->vaddr + block->oplist[defnum].guest_offs, block->oplist[defnum].dissasm().c_str()); + block->oplist.erase(block->oplist.begin() + defnum); } - u32 host_reg = reg_alloced[spilled_reg].host_reg; - reg_alloced.erase(spilled_reg); - if (freg) - host_fregs.push_front(host_reg); - else - host_gregs.push_front(host_reg); } - bool UsesReg(shil_opcode* op, Sh4RegType reg, u32 version, bool vector = false) + void IdentityMovePass() { - if (op->rs1.is_reg() && reg >= op->rs1._reg && reg < (Sh4RegType)(op->rs1._reg + op->rs1.count()) - && version == op->rs1.version[reg - op->rs1._reg] - && (!vector || op->rs1.count() > 1)) - return true; - if (op->rs2.is_reg() && reg >= op->rs2._reg && reg < (Sh4RegType)(op->rs2._reg + op->rs2.count()) - && version == op->rs2.version[reg - op->rs2._reg] - && (!vector || op->rs2.count() > 1)) - return true; - if (op->rs3.is_reg() && reg >= op->rs3._reg && reg < (Sh4RegType)(op->rs3._reg + op->rs3.count()) - && version == op->rs3.version[reg - op->rs3._reg] - && (!vector || op->rs3.count() > 1)) - return true; - return false; + // This pass creates holes in reg versions and should be run last + // The versioning pass must be re-run if needed + for (int opnum = 0; opnum < block->oplist.size(); opnum++) + { + shil_opcode& op = block->oplist[opnum]; + if (op.op == shop_mov32 && op.rs1.is_reg() && op.rd._reg == op.rs1._reg) + { + //printf("%08x DIDN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.dead_code_ops++; + } + } + } + + void CombineShiftsPass() + { + for (int opnum = 0; opnum < (int)block->oplist.size() - 1; opnum++) + { + shil_opcode& op = block->oplist[opnum]; + shil_opcode& next_op = block->oplist[opnum + 1]; + if (op.op == next_op.op && (op.op == shop_shl || op.op == shop_shr || op.op == shop_sar) && next_op.rs1.is_r32i() && op.rd._reg == next_op.rs1._reg) + { + if (next_op.rs2._imm + op.rs2._imm <= 31) + { + next_op.rs2._imm += op.rs2._imm; + //printf("%08x SHFT %s -> %d\n", block->vaddr + op.guest_offs, op.dissasm().c_str(), next_op.rs2._imm); + ReplaceByMov32(op); + } + } + } } RuntimeBlockInfo* block; std::set writeback_values; - std::map aliases; // (dest reg, version) -> (source reg, version) struct { u32 prop_constants = 0; u32 constant_ops_replaced = 0; - u32 constant_ops_removed = 0; u32 dead_code_ops = 0; u32 dead_registers = 0; + u32 dyn_to_stat_blocks = 0; } stats; + // transient vars - int opnum = 0; // add version pass u32 reg_versions[sh4_reg_count]; // const prop pass std::map constprop_values; // (reg num, version) -> value - // reg alloc - deque host_gregs; - deque host_fregs; - std::map reg_alloced; + int opnum = 0; }; diff --git a/core/hw/sh4/dyna/ssa_regalloc.h b/core/hw/sh4/dyna/ssa_regalloc.h new file mode 100644 index 000000000..6b12f6ed7 --- /dev/null +++ b/core/hw/sh4/dyna/ssa_regalloc.h @@ -0,0 +1,584 @@ +/* + Created on: Jun 5, 2019 + + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . + */ +#pragma once +#include +#include +#include "types.h" +#include "decoder.h" +#include "hw/sh4/modules/mmu.h" +#include "ssa.h" + +#define ssa_printf(...) + +template +class RegAlloc +{ +public: + RegAlloc() {} + virtual ~RegAlloc() {} + + void DoAlloc(RuntimeBlockInfo* block, const nreg_t* regs_avail, const nregf_t* regsf_avail) + { + this->block = block; + SSAOptimizer optim(block); + optim.AddVersionPass(); + + while (*regs_avail != (nreg_t)-1) + host_gregs.push_back(*regs_avail++); + + while (*regsf_avail != (nregf_t)-1) + host_fregs.push_back(*regsf_avail++); + } + + void OpBegin(shil_opcode* op, int opid) + { + opnum = opid; + if (op->op == shop_ifb) + { + FlushAllRegs(true); + } + else if (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref)) + { + FlushAllRegs(false); + } + else if (op->op == shop_sync_sr) + { + //FlushReg(reg_sr_T, true); + FlushReg(reg_sr_status, true); + FlushReg(reg_old_sr_status, true); + for (int i = reg_r0; i <= reg_r7; i++) + FlushReg((Sh4RegType)i, true); + for (int i = reg_r0_Bank; i <= reg_r7_Bank; i++) + FlushReg((Sh4RegType)i, true); + } + else if (op->op == shop_sync_fpscr) + { + FlushReg(reg_fpscr, true); + FlushReg(reg_old_fpscr, true); + for (int i = reg_fr_0; i <= reg_xf_15; i++) + FlushReg((Sh4RegType)i, true); + } + // Flush regs used by vector ops + if (op->rs1.is_reg() && op->rs1.count() > 1) + { + for (int i = 0; i < op->rs1.count(); i++) + FlushReg((Sh4RegType)(op->rs1._reg + i), false); + } + if (op->rs2.is_reg() && op->rs2.count() > 1) + { + for (int i = 0; i < op->rs2.count(); i++) + FlushReg((Sh4RegType)(op->rs2._reg + i), false); + } + if (op->rs3.is_reg() && op->rs3.count() > 1) + { + for (int i = 0; i < op->rs3.count(); i++) + FlushReg((Sh4RegType)(op->rs3._reg + i), false); + } + if (op->op != shop_ifb) + { + AllocSourceReg(op->rs1); + AllocSourceReg(op->rs2); + AllocSourceReg(op->rs3); + // Hard flush vector ops destination regs + // Note that this is incorrect if a reg is both src (scalar) and dest (vec). However such an op doesn't exist. + if (op->rd.is_reg() && op->rd.count() > 1) + { + for (int i = 0; i < op->rd.count(); i++) + { + verify(reg_alloced.count((Sh4RegType)(op->rd._reg + i)) == 0 || !reg_alloced[(Sh4RegType)(op->rd._reg + i)].write_back); + FlushReg((Sh4RegType)(op->rd._reg + i), true); + } + } + if (op->rd2.is_reg() && op->rd2.count() > 1) + { + for (int i = 0; i < op->rd2.count(); i++) + { + verify(reg_alloced.count((Sh4RegType)(op->rd2._reg + i)) == 0 || !reg_alloced[(Sh4RegType)(op->rd2._reg + i)].write_back); + FlushReg((Sh4RegType)(op->rd2._reg + i), true); + } + } + AllocDestReg(op->rd); + AllocDestReg(op->rd2); + } + ssa_printf("%08x %s gregs %ld fregs %ld\n", block->vaddr + op->guest_offs, op->dissasm().c_str(), host_gregs.size(), host_fregs.size()); + } + + void OpEnd(shil_opcode* op) + { + for (Sh4RegType reg : pending_flushes) + { + verify(!reg_alloced[reg].write_back); + reg_alloced.erase(reg); + } + pending_flushes.clear(); + + // Flush normally + for (auto const& reg : reg_alloced) + { + FlushReg(reg.first, false); + } + + // Hard flush all dirty regs. Useful for troubleshooting +// while (!reg_alloced.empty()) +// { +// auto it = reg_alloced.begin(); +// +// if (it->second.dirty) +// it->second.write_back = true; +// FlushReg(it->first, true); +// } + + // Final writebacks + if (op >= &block->oplist.back()) + { + FlushAllRegs(false); + final_opend = true; + } + } + + void SetOpnum(int num) + { + fast_forwarding = true; + for (int i = 0; i < num; i++) + { + shil_opcode* op = &block->oplist[i]; + OpBegin(op, i); + OpEnd(op); + } + OpBegin(&block->oplist[num], num); + fast_forwarding = false; + } + + bool IsAllocAny(const shil_param& prm) + { + if (prm.is_reg()) + { + bool rv = IsAllocAny(prm._reg); + if (prm.count() != 1) + { + for (u32 i = 1;i < prm.count(); i++) + verify(IsAllocAny((Sh4RegType)(prm._reg + i)) == rv); + } + return rv; + } + else + { + return false; + } + } + + bool IsAllocg(const shil_param& prm) + { + if (prm.is_reg()) + { + verify(prm.count() == 1); + return IsAllocg(prm._reg); + } + else + { + return false; + } + } + + bool IsAllocf(const shil_param& prm) + { + if (prm.is_reg()) + { + verify(prm.count() == 1); + return IsAllocf(prm._reg); + } + else + { + return false; + } + } + + nreg_t mapg(const shil_param& prm) + { + verify(IsAllocg(prm)); + verify(prm.count() == 1); + return mapg(prm._reg); + } + + nregf_t mapf(const shil_param& prm) + { + verify(IsAllocf(prm)); + verify(prm.count() == 1); + return mapf(prm._reg); + } + + bool reg_used(nreg_t host_reg) + { + for (auto const& reg : reg_alloced) + if ((nreg_t)reg.second.host_reg == host_reg && !IsFloat(reg.first)) + return true; + return false; + } + + bool regf_used(nregf_t host_reg) + { + for (auto const& reg : reg_alloced) + if ((nregf_t)reg.second.host_reg == host_reg && IsFloat(reg.first)) + return true; + return false; + } + + void Cleanup() { + verify(final_opend || block->oplist.size() == 0); + } + + virtual void Preload(u32 reg, nreg_t nreg) = 0; + virtual void Writeback(u32 reg, nreg_t nreg) = 0; + virtual void CheckReg(u32 reg, nreg_t nreg) = 0; + + virtual void Preload_FPU(u32 reg, nregf_t nreg) = 0; + virtual void Writeback_FPU(u32 reg, nregf_t nreg) = 0; + virtual void CheckReg_FPU(u32 reg, nregf_t nreg) = 0; + +private: + struct reg_alloc { + u32 host_reg; + u16 version; + bool write_back; + bool dirty; + }; + + bool IsFloat(Sh4RegType reg) + { + return reg >= reg_fr_0 && reg <= reg_xf_15; + } + + nreg_t mapg(Sh4RegType reg) + { + verify(reg_alloced.count(reg)); + return (nreg_t)reg_alloced[reg].host_reg; + } + + nregf_t mapf(Sh4RegType reg) + { + verify(reg_alloced.count(reg)); + return (nregf_t)reg_alloced[reg].host_reg; + } + + bool IsAllocf(Sh4RegType reg) + { + if (!IsFloat(reg)) + return false; + return reg_alloced.find(reg) != reg_alloced.end(); + } + + bool IsAllocg(Sh4RegType reg) + { + if (IsFloat(reg)) + return false; + return reg_alloced.find(reg) != reg_alloced.end(); + } + + bool IsAllocAny(Sh4RegType reg) + { + return IsAllocg(reg) || IsAllocf(reg); + } + + void WriteBackReg(Sh4RegType reg_num, struct reg_alloc& reg_alloc) + { + if (reg_alloc.write_back) + { + if (!fast_forwarding) + { + ssa_printf("WB %s.%d <- %cx\n", name_reg(reg_num).c_str(), reg_alloc.version, 'a' + reg_alloc.host_reg); + if (IsFloat(reg_num)) + Writeback_FPU(reg_num, (nregf_t)reg_alloc.host_reg); + else + Writeback(reg_num, (nreg_t)reg_alloc.host_reg); + } + reg_alloc.write_back = false; + reg_alloc.dirty = false; + } + } + + void FlushReg(Sh4RegType reg_num, bool hard) + { + auto reg = reg_alloced.find(reg_num); + if (reg != reg_alloced.end()) + { + WriteBackReg(reg->first, reg->second); + if (hard) + { + u32 host_reg = reg->second.host_reg; + reg_alloced.erase(reg); + if (IsFloat(reg_num)) + host_fregs.push_front((nregf_t)host_reg); + else + host_gregs.push_front((nreg_t)host_reg); + } + } + } + + void FlushAllRegs(bool hard) + { + if (hard) + { + while (!reg_alloced.empty()) + FlushReg(reg_alloced.begin()->first, true); + } + else + { + for (auto const& reg : reg_alloced) + FlushReg(reg.first, false); + } + } + + void AllocSourceReg(const shil_param& param) + { + if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? + { + auto it = reg_alloced.find(param._reg); + if (it == reg_alloced.end()) + { + u32 host_reg; + if (param.is_r32i()) + { + if (host_gregs.empty()) + { + SpillReg(false, true); + verify(!host_gregs.empty()); + } + host_reg = host_gregs.back(); + host_gregs.pop_back(); + } + else + { + if (host_fregs.empty()) + { + SpillReg(true, true); + verify(!host_fregs.empty()); + } + host_reg = host_fregs.back(); + host_fregs.pop_back(); + } + reg_alloced[param._reg] = { host_reg, param.version[0], false, false }; + if (!fast_forwarding) + { + ssa_printf("PL %s.%d -> %cx\n", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg); + if (IsFloat(param._reg)) + Preload_FPU(param._reg, (nregf_t)host_reg); + else + Preload(param._reg, (nreg_t)host_reg); + } + } + } + } + + bool NeedsWriteBack(Sh4RegType reg, u32 version) + { + for (int i = opnum + 1; i < block->oplist.size(); i++) + { + shil_opcode* op = &block->oplist[i]; + // if a subsequent op needs all or some regs flushed to mem + // TODO we could look at the ifb op to optimize what to flush + if (op->op == shop_ifb || (mmu_enabled() && (op->op == shop_readm || op->op == shop_writem || op->op == shop_pref))) + return true; + if (op->op == shop_sync_sr && (/*reg == reg_sr_T ||*/ reg == reg_sr_status || reg == reg_old_sr_status || (reg >= reg_r0 && reg <= reg_r7) + || (reg >= reg_r0_Bank && reg <= reg_r7_Bank))) + return true; + if (op->op == shop_sync_fpscr && (reg == reg_fpscr || reg == reg_old_fpscr || (reg >= reg_fr_0 && reg <= reg_xf_15))) + return true; + // if reg is used by a subsequent vector op that doesn't use reg allocation + if (UsesReg(op, reg, version, true)) + return true; + // no writeback needed if redefined + if (DefsReg(op, reg, true)) + return false; + if (DefsReg(op, reg, false)) + return false; + } + + return true; + } + + void AllocDestReg(const shil_param& param) + { + if (param.is_reg() && param.count() == 1) // TODO EXPLODE_SPANS? + { + auto it = reg_alloced.find(param._reg); + if (it == reg_alloced.end()) + { + u32 host_reg; + if (param.is_r32i()) + { + if (host_gregs.empty()) + { + SpillReg(false, false); + verify(!host_gregs.empty()); + } + host_reg = host_gregs.back(); + host_gregs.pop_back(); + } + else + { + if (host_fregs.empty()) + { + SpillReg(true, false); + verify(!host_fregs.empty()); + } + host_reg = host_fregs.back(); + host_fregs.pop_back(); + } + reg_alloced[param._reg] = { host_reg, param.version[0], NeedsWriteBack(param._reg, param.version[0]), true }; + ssa_printf(" %s.%d -> %cx %s\n", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg, reg_alloced[param._reg].write_back ? "(wb)" : ""); + } + else + { + reg_alloc& reg = reg_alloced[param._reg]; + verify(!reg.write_back); + reg.write_back = NeedsWriteBack(param._reg, param.version[0]); + reg.dirty = true; + reg.version = param.version[0]; + } + verify(reg_alloced[param._reg].dirty); + } + } + + void SpillReg(bool freg, bool source) + { + Sh4RegType spilled_reg = Sh4RegType::NoReg; + int latest_use = -1; + + for (auto const& reg : reg_alloced) + { + if (IsFloat(reg.first) != freg) + continue; + // Don't spill already spilled regs + bool pending = false; + for (auto& pending_reg : pending_flushes) + if (pending_reg == reg.first) + { + pending = true; + break; + } + if (pending) + continue; + + // Don't spill current op scalar dest regs + shil_opcode* op = &block->oplist[opnum]; + if (DefsReg(op, reg.first, false)) + continue; + + // Find the first use, but ignore vec ops + int first_use = -1; + for (int i = opnum + (source ? 0 : 1); i < block->oplist.size(); i++) + { + op = &block->oplist[i]; + // Vector ops don't use reg alloc + if (UsesReg(op, reg.first, reg.second.version, false)) + { + first_use = i; + break; + } + } + if (first_use == -1) + { + latest_use = -1; + spilled_reg = reg.first; + break; + } + if (first_use > latest_use && first_use > opnum) + { + latest_use = first_use; + spilled_reg = reg.first; + } + } + if (latest_use != -1) + { + ssa_printf("RegAlloc: non optimal alloc? reg %s used in op %d\n", name_reg(spilled_reg).c_str(), latest_use); + spills++; + // need to write-back if dirty so reload works + if (reg_alloced[spilled_reg].dirty) + reg_alloced[spilled_reg].write_back = true; + } + verify(spilled_reg != Sh4RegType::NoReg); + + if (source) + FlushReg(spilled_reg, true); + else + { + // Delay the eviction of spilled regs from the map due to dest register allocation. + // It's possible that the same host reg is allocated to a source operand + // and to the (future) dest operand. In this case we want to keep both mappings + // until the current op is done. + WriteBackReg(spilled_reg, reg_alloced[spilled_reg]); + u32 host_reg = reg_alloced[spilled_reg].host_reg; + if (IsFloat(spilled_reg)) + host_fregs.push_front((nregf_t)host_reg); + else + host_gregs.push_front((nreg_t)host_reg); + pending_flushes.push_back(spilled_reg); + } + } + + bool IsVectorOp(shil_opcode* op) + { + return op->rs1.count() > 1 || op->rs2.count() > 1 || op->rs3.count() > 1 || op->rd.count() > 1 || op->rd2.count() > 1; + } + + bool UsesReg(shil_opcode* op, Sh4RegType reg, u32 version, bool vector) + { + if (op->rs1.is_reg() && reg >= op->rs1._reg && reg < (Sh4RegType)(op->rs1._reg + op->rs1.count()) + && version == op->rs1.version[reg - op->rs1._reg] + && vector == (op->rs1.count() > 1)) + return true; + if (op->rs2.is_reg() && reg >= op->rs2._reg && reg < (Sh4RegType)(op->rs2._reg + op->rs2.count()) + && version == op->rs2.version[reg - op->rs2._reg] + && vector == (op->rs2.count() > 1)) + return true; + if (op->rs3.is_reg() && reg >= op->rs3._reg && reg < (Sh4RegType)(op->rs3._reg + op->rs3.count()) + && version == op->rs3.version[reg - op->rs3._reg] + && vector == (op->rs3.count() > 1)) + return true; + + return false; + } + + bool DefsReg(shil_opcode* op, Sh4RegType reg, bool vector) + { + if (op->rd.is_reg() && reg >= op->rd._reg && reg < (Sh4RegType)(op->rd._reg + op->rd.count()) + && vector == (op->rd.count() > 1)) + return true; + if (op->rd2.is_reg() && reg >= op->rd2._reg && reg < (Sh4RegType)(op->rd2._reg + op->rd2.count()) + && vector == (op->rd2.count() > 1)) + return true; + return false; + } + + RuntimeBlockInfo* block = NULL; + deque host_gregs; + deque host_fregs; + vector pending_flushes; + std::map reg_alloced; + int opnum = 0; + + bool final_opend = false; + bool fast_forwarding = false; +public: + u32 spills = 0; +}; + +#undef printf From 3dd16e80d25995eefbc05e4758fc86f643c505c2 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 13:57:10 +0200 Subject: [PATCH 058/158] arm64 and x64 recs use ssa regalloc --- core/hw/mem/_vmem.cpp | 40 +++ core/hw/mem/_vmem.h | 1 + core/hw/sh4/dyna/shil.cpp | 7 +- core/hw/sh4/dyna/ssa.cpp | 2 + core/hw/sh4/dyna/ssa.h | 17 +- core/hw/sh4/dyna/ssa_regalloc.h | 2 - core/rec-ARM64/arm64_regalloc.h | 13 +- core/rec-ARM64/rec_arm64.cpp | 532 +++++++++++++++++++++++++---- core/rec-x64/rec_x64.cpp | 575 +++++++++++++++++++++++++------- core/rec-x64/x64_regalloc.h | 14 + 10 files changed, 1005 insertions(+), 198 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 7e4172ef1..9585dd657 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -97,6 +97,46 @@ void* _vmem_read_const(u32 addr,bool& ismem,u32 sz) return 0; } +void* _vmem_write_const(u32 addr,bool& ismem,u32 sz) +{ + u32 page=addr>>24; + unat iirf=(unat)_vmem_MemInfo_ptr[page]; + void* ptr=(void*)(iirf&~HANDLER_MAX); + + if (ptr==0) + { + ismem=false; + const unat id=iirf; + if (sz==1) + { + return (void*)_vmem_WF8[id/4]; + } + else if (sz==2) + { + return (void*)_vmem_WF16[id/4]; + } + else if (sz==4) + { + return (void*)_vmem_WF32[id/4]; + } + else + { + die("Invalid size"); + } + } + else + { + ismem=true; + addr<<=iirf; + addr>>=iirf; + + return &(((u8*)ptr)[addr]); + } + die("Invalid memory size"); + + return 0; +} + void* _vmem_page_info(u32 addr,bool& ismem,u32 sz,u32& page_sz,bool rw) { u32 page=addr>>24; diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index 5ea610c68..f93d4842b 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -100,6 +100,7 @@ void _vmem_release(); void _vmem_get_ptrs(u32 sz,bool write,void*** vmap,void*** func); void* _vmem_get_ptr2(u32 addr,u32& mask); void* _vmem_read_const(u32 addr,bool& ismem,u32 sz); +void* _vmem_write_const(u32 addr,bool& ismem,u32 sz); extern u8* virt_ram_base; extern bool vmem_4gb_space; diff --git a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp index 2fe2f4e6d..47b963b4c 100644 --- a/core/hw/sh4/dyna/shil.cpp +++ b/core/hw/sh4/dyna/shil.cpp @@ -824,7 +824,7 @@ void constlink(RuntimeBlockInfo* blk) else if (def==NoReg && op->rs1.is_imm() && op->rs1._imm==0) { //def=op->rd._reg; - val=op->rs1._imm; + val = op->rs1._imm; } } } @@ -892,8 +892,9 @@ void srt_waw(RuntimeBlockInfo* blk) //Seems to be working void AnalyseBlock(RuntimeBlockInfo* blk) { - //SSAOptimizer optim(blk); - //optim.Optimize(); + SSAOptimizer optim(blk); + optim.Optimize(); + return; u32 st[sh4_reg_count]={0}; /* diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp index 6ba3000c5..b40e9f2fd 100644 --- a/core/hw/sh4/dyna/ssa.cpp +++ b/core/hw/sh4/dyna/ssa.cpp @@ -190,6 +190,8 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_setae: rd = rs1 >= rs2; break; + default: + break; } } break; diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index d454732c6..8dd2b287e 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -42,7 +42,7 @@ public: ConstPropPass(); DeadCodeRemovalPass(); - ConstantExpressionsPass(); + SimplifyExpressionPass(); CombineShiftsPass(); DeadRegisterPass(); IdentityMovePass(); @@ -355,7 +355,7 @@ private: } } - void ConstantExpressionsPass() + void SimplifyExpressionPass() { for (int opnum = 0; opnum < block->oplist.size(); opnum++) { @@ -404,11 +404,12 @@ private: continue; } } - // Not sure it's worth the trouble, except for the xor perhaps + // Not sure it's worth the trouble, except for the 'and' and 'xor' else if (op.rs1.is_r32i() && op.rs1._reg == op.rs2._reg) { // a ^ a == 0 - if (op.op == shop_xor) + // a - a == 0 + if (op.op == shop_xor || op.op == shop_sub) { //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op, 0); @@ -420,6 +421,14 @@ private: //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op); } + // a + a == a * 2 == a << 1 + else if (op.op == shop_add) + { + // There's quite a few of these + //printf("%08x +t<< %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + op.op = shop_shl; + op.rs2 = shil_param(FMT_IMM, 1); + } } } } diff --git a/core/hw/sh4/dyna/ssa_regalloc.h b/core/hw/sh4/dyna/ssa_regalloc.h index 6b12f6ed7..509e2f767 100644 --- a/core/hw/sh4/dyna/ssa_regalloc.h +++ b/core/hw/sh4/dyna/ssa_regalloc.h @@ -247,11 +247,9 @@ public: virtual void Preload(u32 reg, nreg_t nreg) = 0; virtual void Writeback(u32 reg, nreg_t nreg) = 0; - virtual void CheckReg(u32 reg, nreg_t nreg) = 0; virtual void Preload_FPU(u32 reg, nregf_t nreg) = 0; virtual void Writeback_FPU(u32 reg, nregf_t nreg) = 0; - virtual void CheckReg_FPU(u32 reg, nregf_t nreg) = 0; private: struct reg_alloc { diff --git a/core/rec-ARM64/arm64_regalloc.h b/core/rec-ARM64/arm64_regalloc.h index 63a23545f..92404a345 100644 --- a/core/rec-ARM64/arm64_regalloc.h +++ b/core/rec-ARM64/arm64_regalloc.h @@ -20,8 +20,11 @@ #ifndef CORE_REC_ARM64_ARM64_REGALLOC_H_ #define CORE_REC_ARM64_ARM64_REGALLOC_H_ - +#ifdef OLD_REGALLOC #include "hw/sh4/dyna/regalloc.h" +#else +#include "hw/sh4/dyna/ssa_regalloc.h" +#endif #include "deps/vixl/aarch64/macro-assembler-aarch64.h" using namespace vixl::aarch64; @@ -67,7 +70,15 @@ struct Arm64RegAlloc : RegAlloc(op.rs1._imm)); else if (regalloc.IsAllocf(op.rs1)) Fmov(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1)); else @@ -483,9 +483,13 @@ public: break; case shop_swaplb: - Mov(w9, Operand(regalloc.MapRegister(op.rs1), LSR, 16)); - Rev16(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - Bfi(regalloc.MapRegister(op.rd), w9, 16, 16); + { + const Register rs1 = regalloc.MapRegister(op.rs1); + const Register rd = regalloc.MapRegister(op.rd); + Mov(w9, Operand(rs1, LSR, 16)); + Rev16(rd, rs1); + Bfi(rd, w9, 16, 16); + } break; case shop_neg: @@ -536,60 +540,182 @@ public: break; case shop_adc: - Cmp(regalloc.MapRegister(op.rs3), 1); // C = rs3 - Adcs(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); // (C,rd)=rs1+rs2+rs3(C) - Cset(regalloc.MapRegister(op.rd2), cs); // rd2 = C + { + Register reg1; + Operand op2; + Register reg3; + if (op.rs1.is_imm()) + { + Mov(w0, op.rs1.imm_value()); + reg1 = w0; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } + if (op.rs2.is_imm()) + op2 = Operand(op.rs2.imm_value()); + else + op2 = regalloc.MapRegister(op.rs2); + if (op.rs3.is_imm()) + { + Mov(w1, op.rs3.imm_value()); + reg3 = w1; + } + else + { + reg3 = regalloc.MapRegister(op.rs3); + } + Cmp(reg3, 1); // C = rs3 + Adcs(regalloc.MapRegister(op.rd), reg1, op2); // (C,rd)=rs1+rs2+rs3(C) + Cset(regalloc.MapRegister(op.rd2), cs); // rd2 = C + } break; case shop_sbc: - Cmp(wzr, regalloc.MapRegister(op.rs3)); // C = ~rs3 - Sbcs(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); // (C,rd) = rs1 - rs2 - ~rs3(C) - Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + { + Register reg1; + Operand op2; + Operand op3; + if (op.rs1.is_imm()) + { + Mov(w0, op.rs1.imm_value()); + reg1 = w0; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } + if (op.rs2.is_imm()) + op2 = Operand(op.rs2.imm_value()); + else + op2 = regalloc.MapRegister(op.rs2); + if (op.rs3.is_imm()) + op3 = Operand(op.rs3.imm_value()); + else + op3 = regalloc.MapRegister(op.rs3); + Cmp(wzr, op3); // C = ~rs3 + Sbcs(regalloc.MapRegister(op.rd), reg1, op2); // (C,rd) = rs1 - rs2 - ~rs3(C) + Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + } break; case shop_negc: - Cmp(wzr, regalloc.MapRegister(op.rs2)); // C = ~rs2 - Sbcs(regalloc.MapRegister(op.rd), wzr, regalloc.MapRegister(op.rs1)); // (C,rd) = 0 - rs1 - ~rs2(C) - Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + { + Operand op1; + Operand op2; + if (op.rs1.is_imm()) + op1 = Operand(op.rs1.imm_value()); + else + op1 = regalloc.MapRegister(op.rs1); + if (op.rs2.is_imm()) + op2 = Operand(op.rs2.imm_value()); + else + op2 = regalloc.MapRegister(op.rs2); + Cmp(wzr, op2); // C = ~rs2 + Sbcs(regalloc.MapRegister(op.rd), wzr, op1); // (C,rd) = 0 - rs1 - ~rs2(C) + Cset(regalloc.MapRegister(op.rd2), cc); // rd2 = ~C + } break; case shop_rocr: - Ubfx(w0, regalloc.MapRegister(op.rs1), 0, 1); // w0 = rs1[0] (new C) - Mov(regalloc.MapRegister(op.rd), Operand(regalloc.MapRegister(op.rs1), LSR, 1)); // rd = rs1 >> 1 - Bfi(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2), 31, 1); // rd |= C << 31 - Mov(regalloc.MapRegister(op.rd2), w0); // rd2 = w0 (new C) + { + Register reg1; + Register reg2; + if (op.rs1.is_imm()) + { + Mov(w1, op.rs1.imm_value()); + reg1 = w1; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Mov(w2, op.rs2.imm_value()); + reg2 = w2; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Ubfx(w0, reg1, 0, 1); // w0 = rs1[0] (new C) + const Register rd = regalloc.MapRegister(op.rd); + Mov(rd, Operand(reg1, LSR, 1)); // rd = rs1 >> 1 + Bfi(rd, reg2, 31, 1); // rd |= C << 31 + Mov(regalloc.MapRegister(op.rd2), w0); // rd2 = w0 (new C) + } break; case shop_rocl: - Tst(regalloc.MapRegister(op.rs1), 0x80000000); // Z = ~rs1[31] - Orr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2), Operand(regalloc.MapRegister(op.rs1), LSL, 1)); // rd = rs1 << 1 | rs2(C) - Cset(regalloc.MapRegister(op.rd2), ne); // rd2 = ~Z(C) + { + Register reg1; + Register reg2; + if (op.rs1.is_imm()) + { + Mov(w0, op.rs1.imm_value()); + reg1 = w0; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Mov(w1, op.rs2.imm_value()); + reg2 = w1; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Tst(reg1, 0x80000000); // Z = ~rs1[31] + Orr(regalloc.MapRegister(op.rd), reg2, Operand(reg1, LSL, 1)); // rd = rs1 << 1 | rs2(C) + Cset(regalloc.MapRegister(op.rd2), ne); // rd2 = ~Z(C) + } break; case shop_shld: case shop_shad: { + Register reg1; + if (op.rs1.is_imm()) + { + Mov(w0, op.rs1.imm_value()); + reg1 = w0; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } Label positive_shift, negative_shift, end; - Tbz(regalloc.MapRegister(op.rs2), 31, &positive_shift); - Cmn(regalloc.MapRegister(op.rs2), 32); + const Register rs2 = regalloc.MapRegister(op.rs2); + Tbz(rs2, 31, &positive_shift); + Cmn(rs2, 32); B(&negative_shift, ne); + const Register rd = regalloc.MapRegister(op.rd); + // rs2 == -32 => rd = 0 (logical) or 0/-1 (arith) if (op.op == shop_shld) // Logical shift - Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), 31); + //Lsr(rd, reg1, 31); + Mov(rd, wzr); else // Arithmetic shift - Asr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), 31); + Asr(rd, reg1, 31); B(&end); Bind(&positive_shift); - Lsl(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + // rs2 >= 0 => left shift + Lsl(rd, reg1, rs2); B(&end); Bind(&negative_shift); - Neg(w1, regalloc.MapRegister(op.rs2)); + // rs2 < 0 => right shift + Neg(w1, rs2); if (op.op == shop_shld) // Logical shift - Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w1); + Lsr(rd, reg1, w1); else // Arithmetic shift - Asr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), w1); + Asr(rd, reg1, w1); Bind(&end); } break; @@ -601,19 +727,20 @@ public: case shop_setae: case shop_setab: { + const Register rs1 = regalloc.MapRegister(op.rs1); if (op.op == shop_test) { if (op.rs2.is_imm()) - Tst(regalloc.MapRegister(op.rs1), op.rs2._imm); + Tst(rs1, op.rs2._imm); else - Tst(regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + Tst(rs1, regalloc.MapRegister(op.rs2)); } else { if (op.rs2.is_imm()) - Cmp(regalloc.MapRegister(op.rs1), op.rs2._imm); + Cmp(rs1, op.rs2._imm); else - Cmp(regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + Cmp(rs1, regalloc.MapRegister(op.rs2)); } static const Condition shop_conditions[] = { eq, eq, ge, gt, hs, hi }; @@ -622,32 +749,90 @@ public: } break; case shop_setpeq: - Eor(w1, regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); - - Mov(regalloc.MapRegister(op.rd), wzr); - Mov(w2, wzr); // wzr not supported by csinc (?!) - Tst(w1, 0xFF000000); - Csinc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2, ne); - Tst(w1, 0x00FF0000); - Csinc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2, ne); - Tst(w1, 0x0000FF00); - Csinc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2, ne); - Tst(w1, 0x000000FF); - Csinc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w2, ne); + { + Register reg1; + Register reg2; + if (op.rs1.is_imm()) + { + Mov(w0, op.rs1.imm_value()); + reg1 = w0; + } + else + { + reg1 = regalloc.MapRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Mov(w1, op.rs2.imm_value()); + reg2 = w1; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Eor(w1, reg1, reg2); + const Register rd = regalloc.MapRegister(op.rd); + Mov(rd, wzr); + Mov(w2, wzr); // wzr not supported by csinc (?!) + Tst(w1, 0xFF000000); + Csinc(rd, rd, w2, ne); + Tst(w1, 0x00FF0000); + Csinc(rd, rd, w2, ne); + Tst(w1, 0x0000FF00); + Csinc(rd, rd, w2, ne); + Tst(w1, 0x000000FF); + Csinc(rd, rd, w2, ne); + } break; case shop_mul_u16: - Uxth(w10, regalloc.MapRegister(op.rs1)); - Uxth(w11, regalloc.MapRegister(op.rs2)); - Mul(regalloc.MapRegister(op.rd), w10, w11); + { + Register reg2; + if (op.rs2.is_imm()) + { + Mov(w0, op.rs2.imm_value()); + reg2 = w0; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Uxth(w10, regalloc.MapRegister(op.rs1)); + Uxth(w11, reg2); + Mul(regalloc.MapRegister(op.rd), w10, w11); + } break; case shop_mul_s16: - Sxth(w10, regalloc.MapRegister(op.rs1)); - Sxth(w11, regalloc.MapRegister(op.rs2)); - Mul(regalloc.MapRegister(op.rd), w10, w11); + { + Register reg2; + if (op.rs2.is_imm()) + { + Mov(w0, op.rs2.imm_value()); + reg2 = w0; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Sxth(w10, regalloc.MapRegister(op.rs1)); + Sxth(w11, reg2); + Mul(regalloc.MapRegister(op.rd), w10, w11); + } break; case shop_mul_i32: - Mul(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + { + Register reg2; + if (op.rs2.is_imm()) + { + Mov(w0, op.rs2.imm_value()); + reg2 = w0; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } + Mul(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), reg2); + } break; case shop_mul_u64: case shop_mul_s64: @@ -709,9 +894,12 @@ public: break; case shop_xtrct: - Lsr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), 16); - Lsl(w0, regalloc.MapRegister(op.rs2), 16); - Orr(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd), w0); + { + const Register rd = regalloc.MapRegister(op.rd); + Lsr(rd, regalloc.MapRegister(op.rs1), 16); + Lsl(w0, regalloc.MapRegister(op.rs2), 16); + Orr(rd, rd, w0); + } break; // @@ -719,16 +907,104 @@ public: // case shop_fadd: - Fadd(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1), regalloc.MapVRegister(op.rs2)); + { + VRegister reg1; + VRegister reg2; + if (op.rs1.is_imm()) + { + Fmov(s0, reinterpret_cast(op.rs1._imm)); + reg1 = s0; + } + else + { + reg1 = regalloc.MapVRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Fmov(s1, reinterpret_cast(op.rs2._imm)); + reg2 = s1; + } + else + { + reg2 = regalloc.MapVRegister(op.rs2); + } + Fadd(regalloc.MapVRegister(op.rd), reg1, reg2); + } break; case shop_fsub: - Fsub(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1), regalloc.MapVRegister(op.rs2)); + { + VRegister reg1; + VRegister reg2; + if (op.rs1.is_imm()) + { + Fmov(s0, reinterpret_cast(op.rs1._imm)); + reg1 = s0; + } + else + { + reg1 = regalloc.MapVRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Fmov(s1, reinterpret_cast(op.rs2._imm)); + reg2 = s1; + } + else + { + reg2 = regalloc.MapVRegister(op.rs2); + } + Fsub(regalloc.MapVRegister(op.rd), reg1, reg2); + } break; case shop_fmul: - Fmul(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1), regalloc.MapVRegister(op.rs2)); + { + VRegister reg1; + VRegister reg2; + if (op.rs1.is_imm()) + { + Fmov(s0, reinterpret_cast(op.rs1._imm)); + reg1 = s0; + } + else + { + reg1 = regalloc.MapVRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Fmov(s1, reinterpret_cast(op.rs2._imm)); + reg2 = s1; + } + else + { + reg2 = regalloc.MapVRegister(op.rs2); + } + Fmul(regalloc.MapVRegister(op.rd), reg1, reg2); + } break; case shop_fdiv: - Fdiv(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1), regalloc.MapVRegister(op.rs2)); + { + VRegister reg1; + VRegister reg2; + if (op.rs1.is_imm()) + { + Fmov(s0, reinterpret_cast(op.rs1._imm)); + reg1 = s0; + } + else + { + reg1 = regalloc.MapVRegister(op.rs1); + } + if (op.rs2.is_imm()) + { + Fmov(s1, reinterpret_cast(op.rs2._imm)); + reg2 = s1; + } + else + { + reg2 = regalloc.MapVRegister(op.rs2); + } + Fdiv(regalloc.MapVRegister(op.rd), reg1, reg2); + } break; case shop_fabs: @@ -888,12 +1164,12 @@ public: break; case CPT_f32: - if (prm.is_reg()) { + if (prm.is_reg()) Fmov(*call_fregs[fregused], regalloc.MapVRegister(prm)); - } - else { + else if (prm.is_imm()) + Fmov(*call_fregs[fregused], reinterpret_cast(prm._imm)); + else verify(prm.is_null()); - } fregused++; break; @@ -1033,7 +1309,7 @@ public: if (block->oplist[opid].op == shop_readm) { regalloc.DoAlloc(block); - regalloc.current_opid = opid; + regalloc.SetOpnum(opid); } } @@ -1181,9 +1457,8 @@ public: vmem_platform_flush_cache( CC_RW2RX(GetBuffer()->GetStartAddress()), CC_RW2RX(GetBuffer()->GetEndAddress()), GetBuffer()->GetStartAddress(), GetBuffer()->GetEndAddress()); - #if 0 -// if (rewrite) + if (rewrite && block != NULL) { Instruction* instr_start = (Instruction*)block->code; // Instruction* instr_end = GetLabelAddress(&code_end); @@ -1432,6 +1707,10 @@ private: { switch (size) { + case 1: + Ldrsb(regalloc.MapRegister(op.rd), MemOperand(x1)); + break; + case 2: Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x1)); break; @@ -1452,6 +1731,10 @@ private: { switch (size) { + case 1: + Ldrsb(w1, MemOperand(x1)); + break; + case 2: Ldrsh(w1, MemOperand(x1)); break; @@ -1460,11 +1743,18 @@ private: Ldr(w1, MemOperand(x1)); break; + case 8: + Ldr(x1, MemOperand(x1)); + break; + default: die("Invalid size"); break; } - Str(w1, sh4_context_mem_operand(op.rd.reg_ptr())); + if (size == 8) + Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); + else + Str(w1, sh4_context_mem_operand(op.rd.reg_ptr())); } } else @@ -1568,7 +1858,7 @@ private: Lsr(x1, x1, 32); Fmov(regalloc.MapVRegister(op.rd, 1), w1); #else - Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); + die("GenReadMemoryFast: size == 8 and !explode_spans"); #endif } } @@ -1604,6 +1894,9 @@ private: void GenWriteMemory(const shil_opcode& op, size_t opid, bool optimise) { + if (GenWriteMemoryImmediate(op)) + return; + GenMemAddr(op, call_regs[0]); u32 size = op.flags & 0x7f; @@ -1627,6 +1920,111 @@ private: GenWriteMemorySlow(op); } + bool GenWriteMemoryImmediate(const shil_opcode& op) + { + if (!op.rs1.is_imm()) + return false; + + u32 size = op.flags & 0x7f; + u32 addr = op.rs1._imm; + if (mmu_enabled()) + { + if ((addr >> 12) != (block->vaddr >> 12)) + // When full mmu is on, only consider addresses in the same 4k page + return false; + u32 paddr; + u32 rv; + switch (size) + { + case 1: + rv = mmu_data_translation(addr, paddr); + break; + case 2: + rv = mmu_data_translation(addr, paddr); + break; + case 4: + case 8: + rv = mmu_data_translation(addr, paddr); + break; + } + if (rv != MMU_ERROR_NONE) + return false; + addr = paddr; + } + bool isram = false; + void* ptr = _vmem_write_const(addr, isram, size); + + Register reg2; + if (op.rs2.is_imm()) + { + Mov(w0, op.rs2._imm); + reg2 = w0; + } + else if (regalloc.IsAllocg(op.rs2)) + { + reg2 = regalloc.MapRegister(op.rs2); + } + else if (regalloc.IsAllocf(op.rs2)) + { + Fmov(w0, regalloc.MapVRegister(op.rs2)); + reg2 = w0; + } + else + die("Invalid rs2 param"); + if (isram) + { + Ldr(x1, reinterpret_cast(ptr)); + switch (size) + { + case 1: + Strb(reg2, MemOperand(x1)); + break; + + case 2: + Strh(reg2, MemOperand(x1)); + break; + + case 4: + if (op.rs2.is_r32f()) + Str(reg2, MemOperand(x1)); + else + Str(reg2, MemOperand(x1)); + break; + + default: + die("Invalid size"); + break; + } + } + else + { + // Not RAM + Mov(w1, reg2); + Mov(w0, addr); + + switch(size) + { + case 1: + GenCallRuntime((void (*)())ptr); + break; + + case 2: + GenCallRuntime((void (*)())ptr); + break; + + case 4: + GenCallRuntime((void (*)())ptr); + break; + + case 8: + die("SZ_64F not supported"); + break; + } + } + + return true; + } + bool GenWriteMemoryFast(const shil_opcode& op, size_t opid) { // Direct memory access. Need to handle SIGSEGV and rewrite block as needed. See ngen_Rewrite() diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 4c7db5854..ed73b74d3 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -3,8 +3,9 @@ #if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64 #include -#define EXPLODE_SPANS +//#define EXPLODE_SPANS //#define PROFILING +//#define CANONICAL_TEST #include "deps/xbyak/xbyak.h" #include "deps/xbyak/xbyak_util.h" @@ -40,23 +41,32 @@ extern "C" { int cycle_counter; } -double host_cpu_time; -u64 guest_cpu_cycles; +u64 host_cpu_time; u32 mem_writes, mem_reads; u32 mem_rewrites_w, mem_rewrites_r; #ifdef PROFILING -static double slice_start; +static clock_t slice_start; +int start_cycle; extern "C" { -static __attribute((used)) void start_slice() +static __attribute((used)) void* start_slice(void *p) { - slice_start = os_GetSeconds(); + slice_start = clock(); + start_cycle = cycle_counter; + return p; } static __attribute((used)) void end_slice() { - host_cpu_time += os_GetSeconds() - slice_start; + clock_t now = clock(); + if (slice_start != 0) + { + host_cpu_time += now - slice_start; + guest_cpu_cycles += start_cycle - cycle_counter; + } + slice_start = now; + start_cycle = cycle_counter; } } #endif @@ -158,15 +168,15 @@ WIN32_ONLY( ".seh_pushreg %r14 \n\t") #endif "call " _U "bm_GetCodeByVAddr \n\t" "call *%rax \n\t" +#ifdef PROFILING + "call end_slice \n\t" +#endif "movl " _U "cycle_counter(%rip), %ecx \n\t" "testl %ecx, %ecx \n\t" "jg 2b \n\t" // slice_loop "addl $" _S(SH4_TIMESLICE) ", %ecx \n\t" "movl %ecx, " _U "cycle_counter(%rip) \n\t" -#ifdef PROFILING - "call end_slice \n\t" -#endif "call " _U "UpdateSystem_INTC \n\t" "jmp 1b \n" // run_loop @@ -371,11 +381,6 @@ public: sub(dword[rax], block->guest_cycles); #else sub(dword[rip + &cycle_counter], block->guest_cycles); -#endif -#ifdef PROFILING - mov(rax, (uintptr_t)&guest_cpu_cycles); - mov(ecx, block->guest_cycles); - add(qword[rax], rcx); #endif regalloc.DoAlloc(block); @@ -412,14 +417,12 @@ public: case shop_jcond: case shop_jdyn: { + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + Xbyak::Reg32 rs1 = regalloc.MapRegister(op.rs1); + if (rd != rs1) + mov(rd, rs1); if (op.rs2.is_imm()) - { - mov(ecx, regalloc.MapRegister(op.rs1)); - add(ecx, op.rs2._imm); - mov(regalloc.MapRegister(op.rd), ecx); - } - else - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + add(rd, op.rs2._imm); } break; @@ -495,41 +498,44 @@ public: case shop_writem: { - shil_param_to_host_reg(op.rs1, call_regs[0]); - if (!op.rs3.is_null()) + if (!GenWriteMemImmediate(op, block)) { - if (op.rs3.is_imm()) - add(call_regs[0], op.rs3._imm); - else if (regalloc.IsAllocg(op.rs3)) - add(call_regs[0], regalloc.MapRegister(op.rs3)); - else + shil_param_to_host_reg(op.rs1, call_regs[0]); + if (!op.rs3.is_null()) { - mov(rax, (uintptr_t)op.rs3.reg_ptr()); - add(call_regs[0], dword[rax]); + if (op.rs3.is_imm()) + add(call_regs[0], op.rs3._imm); + else if (regalloc.IsAllocg(op.rs3)) + add(call_regs[0], regalloc.MapRegister(op.rs3)); + else + { + mov(rax, (uintptr_t)op.rs3.reg_ptr()); + add(call_regs[0], dword[rax]); + } } - } - u32 size = op.flags & 0x7f; - if (size != 8) - shil_param_to_host_reg(op.rs2, call_regs[1]); - else { + u32 size = op.flags & 0x7f; + if (size != 8) + shil_param_to_host_reg(op.rs2, call_regs[1]); + else { #ifdef EXPLODE_SPANS - if (op.rs2.count() == 2 && regalloc.IsAllocf(op.rs2, 0) && regalloc.IsAllocf(op.rs2, 1)) - { - movd(call_regs[1], regalloc.MapXRegister(op.rs2, 1)); - shl(call_regs64[1], 32); - movd(eax, regalloc.MapXRegister(op.rs2, 0)); - or_(call_regs64[1], rax); - } - else + if (op.rs2.count() == 2 && regalloc.IsAllocf(op.rs2, 0) && regalloc.IsAllocf(op.rs2, 1)) + { + movd(call_regs[1], regalloc.MapXRegister(op.rs2, 1)); + shl(call_regs64[1], 32); + movd(eax, regalloc.MapXRegister(op.rs2, 0)); + or_(call_regs64[1], rax); + } + else #endif - { - mov(rax, (uintptr_t)op.rs2.reg_ptr()); - mov(call_regs64[1], qword[rax]); + { + mov(rax, (uintptr_t)op.rs2.reg_ptr()); + mov(call_regs64[1], qword[rax]); + } } + if (!optimise || !GenWriteMemoryFast(op, block)) + GenWriteMemorySlow(op, block); } - if (!optimise || !GenWriteMemoryFast(op, block)) - GenWriteMemorySlow(op, block); } break; @@ -544,7 +550,7 @@ public: case shop_swaplb: if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - ror(Xbyak::Reg16(regalloc.MapRegister(op.rd).getIdx()), 8); + ror(regalloc.MapRegister(op.rd).cvt16(), 8); break; case shop_neg: @@ -595,12 +601,30 @@ public: break; case shop_adc: - if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - cmp(regalloc.MapRegister(op.rs3), 1); // C = ~rs3 - cmc(); // C = rs3 - adc(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2)); // (C,rd)=rs1+rs2+rs3(C) - setc(regalloc.MapRegister(op.rd2).cvt8()); // rd2 = C + { + cmp(regalloc.MapRegister(op.rs3), 1); // C = ~rs3 + Xbyak::Reg32 rs2; + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + if (op.rs2.is_reg()) + { + rs2 = regalloc.MapRegister(op.rs2); + if (regalloc.mapg(op.rd) == regalloc.mapg(op.rs2)) + { + mov(ecx, rs2); + rs2 = ecx; + } + } + if (op.rs1.is_imm()) + mov(rd, op.rs1.imm_value()); + else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(rd, regalloc.MapRegister(op.rs1)); + cmc(); // C = rs3 + if (op.rs2.is_reg()) + adc(rd, rs2); // (C,rd)=rs1+rs2+rs3(C) + else + adc(rd, op.rs2.imm_value()); + setc(regalloc.MapRegister(op.rd2).cvt8()); // rd2 = C + } break; /* FIXME buggy @@ -619,11 +643,27 @@ public: */ case shop_negc: { - if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - Xbyak::Reg64 rd64 = regalloc.MapRegister(op.rd).cvt64(); + Xbyak::Reg32 rs2; + if (op.rs2.is_reg()) + { + rs2 = regalloc.MapRegister(op.rs2); + if (regalloc.mapg(op.rd) == regalloc.mapg(op.rs2)) + { + mov(ecx, rs2); + rs2 = ecx; + } + } + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + if (op.rs1.is_imm()) + mov(rd, op.rs1.imm_value()); + else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(rd, regalloc.MapRegister(op.rs1)); + Xbyak::Reg64 rd64 = rd.cvt64(); neg(rd64); - sub(rd64, regalloc.MapRegister(op.rs2).cvt64()); + if (op.rs2.is_imm()) + sub(rd64, op.rs2.imm_value()); + else + sub(rd64, rs2.cvt64()); Xbyak::Reg64 rd2_64 = regalloc.MapRegister(op.rd2).cvt64(); mov(rd2_64, rd64); shr(rd2_64, 63); @@ -632,48 +672,60 @@ public: case shop_rocr: case shop_rocl: - if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - cmp(regalloc.MapRegister(op.rs2), 1); // C = ~rs2 - cmc(); // C = rs2 - if (op.op == shop_rocr) - rcr(regalloc.MapRegister(op.rd), 1); - else - rcl(regalloc.MapRegister(op.rd), 1); - setc(al); - movzx(regalloc.MapRegister(op.rd2), al); // rd2 = C + { + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + cmp(regalloc.MapRegister(op.rs2), 1); // C = ~rs2 + if (op.rs1.is_imm()) + mov(rd, op.rs1.imm_value()); + else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(rd, regalloc.MapRegister(op.rs1)); + cmc(); // C = rs2 + if (op.op == shop_rocr) + rcr(rd, 1); + else + rcl(rd, 1); + setc(al); + movzx(regalloc.MapRegister(op.rd2), al); // rd2 = C + } break; case shop_shld: case shop_shad: { - if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + if (op.rs2.is_reg()) + mov(ecx, regalloc.MapRegister(op.rs2)); + else + // This shouldn't happen. If arg is imm -> shop_shl/shr/sar + mov(ecx, op.rs2.imm_value()); + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + if (op.rs1.is_imm()) + mov(rd, op.rs1.imm_value()); + else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + mov(rd, regalloc.MapRegister(op.rs1)); Xbyak::Label negative_shift; Xbyak::Label non_zero; Xbyak::Label exit; - mov(ecx, regalloc.MapRegister(op.rs2)); cmp(ecx, 0); js(negative_shift); - shl(regalloc.MapRegister(op.rd), cl); + shl(rd, cl); jmp(exit); L(negative_shift); test(ecx, 0x1f); jnz(non_zero); if (op.op == shop_shld) - xor_(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rd)); + xor_(rd, rd); else - sar(regalloc.MapRegister(op.rd), 31); + sar(rd, 31); jmp(exit); L(non_zero); neg(ecx); if (op.op == shop_shld) - shr(regalloc.MapRegister(op.rd), cl); + shr(rd, cl); else - sar(regalloc.MapRegister(op.rd), cl); + sar(rd, cl); L(exit); } break; @@ -730,25 +782,40 @@ public: break; */ case shop_mul_u16: - movzx(eax, Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); - movzx(ecx, Xbyak::Reg16(regalloc.MapRegister(op.rs2).getIdx())); + movzx(eax, regalloc.MapRegister(op.rs1).cvt16()); + if (op.rs2.is_reg()) + movzx(ecx, regalloc.MapRegister(op.rs2).cvt16()); + else + mov(ecx, op.rs2._imm & 0xFFFF); mul(ecx); mov(regalloc.MapRegister(op.rd), eax); break; case shop_mul_s16: - movsx(eax, Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); - movsx(ecx, Xbyak::Reg16(regalloc.MapRegister(op.rs2).getIdx())); + movsx(eax, regalloc.MapRegister(op.rs1).cvt16()); + if (op.rs2.is_reg()) + movsx(ecx, regalloc.MapRegister(op.rs2).cvt16()); + else + mov(ecx, (s32)(s16)op.rs2._imm); mul(ecx); mov(regalloc.MapRegister(op.rd), eax); break; case shop_mul_i32: mov(eax, regalloc.MapRegister(op.rs1)); - mul(regalloc.MapRegister(op.rs2)); + if (op.rs2.is_reg()) + mul(regalloc.MapRegister(op.rs2)); + else + { + mov(ecx, op.rs2._imm); + mul(ecx); + } mov(regalloc.MapRegister(op.rd), eax); break; case shop_mul_u64: mov(eax, regalloc.MapRegister(op.rs1)); - mov(ecx, regalloc.MapRegister(op.rs2)); + if (op.rs2.is_reg()) + mov(ecx, regalloc.MapRegister(op.rs2)); + else + mov(ecx, op.rs2._imm); mul(rcx); mov(regalloc.MapRegister(op.rd), eax); shr(rax, 32); @@ -756,7 +823,10 @@ public: break; case shop_mul_s64: movsxd(rax, regalloc.MapRegister(op.rs1)); - movsxd(rcx, regalloc.MapRegister(op.rs2)); + if (op.rs2.is_reg()) + movsxd(rcx, regalloc.MapRegister(op.rs2)); + else + mov(rcx, (s64)(s32)op.rs2._imm); mul(rcx); mov(regalloc.MapRegister(op.rd), eax); shr(rax, 32); @@ -764,6 +834,33 @@ public: break; case shop_pref: + if (op.rs1.is_imm()) + { + // this test shouldn't be necessary + if ((op.rs1._imm & 0xFC000000) == 0xE0000000) + { + mov(call_regs[0], op.rs1._imm); + if (mmu_enabled()) + { + mov(call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc + + GenCall(do_sqw_mmu_no_ex); + } + else + { + if (CCN_MMUCR.AT == 1) + { + GenCall(do_sqw_mmu); + } + else + { + mov(call_regs64[1], (uintptr_t)sq_both); + GenCall(&do_sqw_nommu_local); + } + } + } + } + else { Xbyak::Reg32 rn; if (regalloc.IsAllocg(op.rs1)) @@ -810,16 +907,31 @@ public: movsx(regalloc.MapRegister(op.rd), al); break; case shop_ext_s16: - movsx(regalloc.MapRegister(op.rd), Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); + movsx(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1).cvt16()); break; case shop_xtrct: - if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - shr(regalloc.MapRegister(op.rd), 16); - mov(eax, regalloc.MapRegister(op.rs2)); - shl(eax, 16); - or_(regalloc.MapRegister(op.rd), eax); + { + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + Xbyak::Reg32 rs1 = regalloc.MapRegister(op.rs1); + Xbyak::Reg32 rs2 = regalloc.MapRegister(op.rs2); + if (regalloc.mapg(op.rd) == regalloc.mapg(op.rs2)) + { + shl(rd, 16); + mov(eax, rs1); + shr(eax, 16); + or_(rd, eax); + break; + } + else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + { + mov(rd, rs1); + } + shr(rd, 16); + mov(eax, rs2); + shl(eax, 16); + or_(rd, eax); + } break; // @@ -859,15 +971,38 @@ public: break; case shop_fmac: - if (regalloc.mapf(op.rd) != regalloc.mapf(op.rs1)) - movss(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs1)); - if (cpu.has(Xbyak::util::Cpu::tFMA)) - vfmadd231ss(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs2), regalloc.MapXRegister(op.rs3)); - else { - movss(xmm0, regalloc.MapXRegister(op.rs2)); - mulss(xmm0, regalloc.MapXRegister(op.rs3)); - addss(regalloc.MapXRegister(op.rd), xmm0); + Xbyak::Xmm rs1 = regalloc.MapXRegister(op.rs1); + Xbyak::Xmm rs2 = regalloc.MapXRegister(op.rs2); + Xbyak::Xmm rs3 = regalloc.MapXRegister(op.rs3); + Xbyak::Xmm rd = regalloc.MapXRegister(op.rd); + if (rd == rs2) + { + movss(xmm1, rs2); + rs2 = xmm1; + } + if (rd == rs3) + { + movss(xmm2, rs3); + rs3 = xmm2; + } + if (op.rs1.is_imm()) + { + mov(eax, op.rs1._imm); + movd(rd, eax); + } + else if (rd != rs1) + { + movss(rd, rs1); + } + if (cpu.has(Xbyak::util::Cpu::tFMA)) + vfmadd231ss(rd, rs2, rs3); + else + { + movss(xmm0, rs2); + mulss(xmm0, rs3); + addss(rd, xmm0); + } } break; @@ -898,7 +1033,7 @@ public: break; case shop_fsca: - movzx(rax, Xbyak::Reg16(regalloc.MapRegister(op.rs1).getIdx())); + movzx(rax, regalloc.MapRegister(op.rs1).cvt16()); mov(rcx, (uintptr_t)&sin_table); #ifdef EXPLODE_SPANS movss(regalloc.MapXRegister(op.rd, 0), dword[rcx + rax * 8]); @@ -1359,6 +1494,17 @@ private: mov(rax, reinterpret_cast(ptr)); switch (size) { + case 1: + if (regalloc.IsAllocg(op.rd)) + movsx(regalloc.MapRegister(op.rd), byte[rax]); + else + { + movsx(eax, byte[rax]); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); + } + break; + case 2: if (regalloc.IsAllocg(op.rd)) movsx(regalloc.MapRegister(op.rd), word[rax]); @@ -1383,6 +1529,23 @@ private: } break; + case 8: + mov(rcx, qword[rax]); +#ifdef EXPLODE_SPANS + if (op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)) + { + movd(regalloc.MapXRegister(op.rd, 0), ecx); + shr(rcx, 32); + movd(regalloc.MapXRegister(op.rd, 1), ecx); + } + else +#endif + { + mov(rax, (uintptr_t)op.rd.reg_ptr()); + mov(qword[rax], rcx); + } + break; + default: die("Invalid immediate size"); break; @@ -1395,6 +1558,11 @@ private: switch(size) { + case 1: + GenCall((void (*)())ptr); + movsx(ecx, al); + break; + case 2: GenCall((void (*)())ptr); movsx(ecx, ax); @@ -1415,6 +1583,122 @@ private: return true; } + bool GenWriteMemImmediate(const shil_opcode& op, RuntimeBlockInfo* block) + { + if (!op.rs1.is_imm()) + return false; + u32 size = op.flags & 0x7f; + u32 addr = op.rs1._imm; + if (mmu_enabled()) + { + if ((addr >> 12) != (block->vaddr >> 12)) + // When full mmu is on, only consider addresses in the same 4k page + return false; + + u32 paddr; + u32 rv; + switch (size) + { + case 1: + rv = mmu_data_translation(addr, paddr); + break; + case 2: + rv = mmu_data_translation(addr, paddr); + break; + case 4: + case 8: + rv = mmu_data_translation(addr, paddr); + break; + } + if (rv != MMU_ERROR_NONE) + return false; + + addr = paddr; + } + bool isram = false; + void* ptr = _vmem_write_const(addr, isram, size); + + if (isram) + { + // Immediate pointer to RAM: super-duper fast access + mov(rax, reinterpret_cast(ptr)); + switch (size) + { + case 1: + if (regalloc.IsAllocg(op.rs2)) + mov(byte[rax], regalloc.MapRegister(op.rs2)); + else if (op.rs2.is_imm()) + mov(byte[rax], op.rs2._imm); + else + { + mov(rcx, (uintptr_t)op.rs2.reg_ptr()); + mov(ecx, dword[rcx]); + mov(byte[rax], ecx); + } + break; + + case 2: + if (regalloc.IsAllocg(op.rs2)) + mov(word[rax], regalloc.MapRegister(op.rs2)); + else if (op.rs2.is_imm()) + mov(word[rax], op.rs2._imm); + else + { + mov(rcx, (uintptr_t)op.rs2.reg_ptr()); + mov(ecx, dword[rcx]); + mov(word[rax], ecx); + } + break; + + case 4: + if (regalloc.IsAllocg(op.rs2)) + mov(dword[rax], regalloc.MapRegister(op.rs2)); + else if (regalloc.IsAllocf(op.rs2)) + movd(dword[rax], regalloc.MapXRegister(op.rs2)); + else if (op.rs2.is_imm()) + mov(dword[rax], op.rs2._imm); + else + { + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(ecx, dword[rcx]); + mov(dword[rax], ecx); + } + break; + + case 8: +#ifdef EXPLODE_SPANS + if (op.rs2.count() == 2 && regalloc.IsAllocf(op.rs2, 0) && regalloc.IsAllocf(op.rs2, 1)) + { + movd(call_regs[1], regalloc.MapXRegister(op.rs2, 1)); + shl(call_regs64[1], 32); + movd(eax, regalloc.MapXRegister(op.rs2, 0)); + or_(call_regs64[1], rax); + } + else +#endif + { + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(rcx, qword[rcx]); + mov(qword[rax], rcx); + } + + default: + die("Invalid immediate size"); + break; + } + } + else + { + // Not RAM: the returned pointer is a memory handler + mov(call_regs[0], addr); + shil_param_to_host_reg(op.rs2, call_regs[1]); + + GenCall((void (*)())ptr); + } + + return true; + } + bool GenReadMemoryFast(const shil_opcode& op, RuntimeBlockInfo* block) { if (!mmu_enabled() || !vmem32_enabled()) @@ -1487,11 +1771,11 @@ private: switch (size) { case 1: - mov(byte[rax + call_regs64[0] + 0], Xbyak::Reg8(call_regs[1].getIdx(), call_regs[1] == edi || call_regs[1] == esi)); + mov(byte[rax + call_regs64[0] + 0], call_regs[1].cvt8()); break; case 2: - mov(word[rax + call_regs64[0]], Xbyak::Reg16(call_regs[1].getIdx())); + mov(word[rax + call_regs64[0]], call_regs[1].cvt16()); break; case 4: @@ -1589,22 +1873,67 @@ private: void GenBinaryOp(const shil_opcode &op, X64BinaryOp natop) { + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + const shil_param *rs2 = &op.rs2; if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) - mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + { + if (op.rs2.is_reg() && regalloc.mapg(op.rd) == regalloc.mapg(op.rs2)) + { + if (op.op == shop_sub) + { + // This op isn't commutative + mov(ecx, regalloc.MapRegister(op.rs2)); + mov(rd, regalloc.MapRegister(op.rs1)); + (this->*natop)(rd, ecx); + + return; + } + // otherwise just swap the operands + rs2 = &op.rs1; + } + else + mov(rd, regalloc.MapRegister(op.rs1)); + } if (op.rs2.is_imm()) { mov(ecx, op.rs2._imm); - (this->*natop)(regalloc.MapRegister(op.rd), ecx); + (this->*natop)(rd, ecx); } else - (this->*natop)(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs2)); + (this->*natop)(rd, regalloc.MapRegister(*rs2)); } void GenBinaryFOp(const shil_opcode &op, X64BinaryFOp natop) { + Xbyak::Xmm rd = regalloc.MapXRegister(op.rd); + const shil_param *rs2 = &op.rs2; if (regalloc.mapf(op.rd) != regalloc.mapf(op.rs1)) - movss(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs1)); - (this->*natop)(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs2)); + { + if (op.rs2.is_reg() && regalloc.mapf(op.rd) == regalloc.mapf(op.rs2)) + { + if (op.op == shop_fsub || op.op == shop_fdiv) + { + // these ops aren't commutative so we need a scratch reg + movss(xmm0, regalloc.MapXRegister(op.rs2)); + movss(rd, regalloc.MapXRegister(op.rs1)); + (this->*natop)(rd, xmm0); + + return; + } + // otherwise just swap the operands + rs2 = &op.rs1; + } + else + movss(rd, regalloc.MapXRegister(op.rs1)); + } + if (op.rs2.is_imm()) + { + mov(eax, op.rs2._imm); + movd(xmm0, eax); + (this->*natop)(rd, xmm0); + } + else + (this->*natop)(rd, regalloc.MapXRegister(*rs2)); } template @@ -1693,10 +2022,11 @@ private: { if (regalloc.IsAllocf(param)) { + Xbyak::Xmm sreg = regalloc.MapXRegister(param); if (!reg.isXMM()) - movd((const Xbyak::Reg32 &)reg, regalloc.MapXRegister(param)); - else - movss((const Xbyak::Xmm &)reg, regalloc.MapXRegister(param)); + movd((const Xbyak::Reg32 &)reg, sreg); + else if (reg != sreg) + movss((const Xbyak::Xmm &)reg, sreg); } else { @@ -1709,10 +2039,11 @@ private: { if (regalloc.IsAllocg(param)) { - if (!reg.isXMM()) - mov((const Xbyak::Reg32 &)reg, regalloc.MapRegister(param)); - else - movd((const Xbyak::Xmm &)reg, regalloc.MapRegister(param)); + Xbyak::Reg32 sreg = regalloc.MapRegister(param); + if (reg.isXMM()) + movd((const Xbyak::Xmm &)reg, sreg); + else if (reg != sreg) + mov((const Xbyak::Reg32 &)reg, sreg); } else { @@ -1735,17 +2066,19 @@ private: { if (regalloc.IsAllocg(param)) { + Xbyak::Reg32 sreg = regalloc.MapRegister(param); if (!reg.isXMM()) - mov(regalloc.MapRegister(param), (const Xbyak::Reg32 &)reg); - else - movd(regalloc.MapRegister(param), (const Xbyak::Xmm &)reg); + mov(sreg, (const Xbyak::Reg32 &)reg); + else if (reg != sreg) + movd(sreg, (const Xbyak::Xmm &)reg); } else if (regalloc.IsAllocf(param)) { + Xbyak::Xmm sreg = regalloc.MapXRegister(param); if (!reg.isXMM()) - movd(regalloc.MapXRegister(param), (const Xbyak::Reg32 &)reg); - else - movss(regalloc.MapXRegister(param), (const Xbyak::Xmm &)reg); + movd(sreg, (const Xbyak::Reg32 &)reg); + else if (reg != sreg) + movss(sreg, (const Xbyak::Xmm &)reg); } else { diff --git a/core/rec-x64/x64_regalloc.h b/core/rec-x64/x64_regalloc.h index 7614ba1f6..fe0de219d 100644 --- a/core/rec-x64/x64_regalloc.h +++ b/core/rec-x64/x64_regalloc.h @@ -20,8 +20,14 @@ #ifndef CORE_REC_X64_X64_REGALLOC_H_ #define CORE_REC_X64_X64_REGALLOC_H_ +//#define OLD_REGALLOC + #include "deps/xbyak/xbyak.h" +#ifdef OLD_REGALLOC #include "hw/sh4/dyna/regalloc.h" +#else +#include "hw/sh4/dyna/ssa_regalloc.h" +#endif #ifdef _WIN32 static Xbyak::Operand::Code alloc_regs[] = { Xbyak::Operand::RBX, Xbyak::Operand::RBP, Xbyak::Operand::RDI, Xbyak::Operand::RSI, @@ -65,7 +71,11 @@ struct X64RegAlloc : RegAllocnregf == xmm.getIdx() && all_spans[sid]->contains(opid)) return true; } return false; +#endif } BlockCompiler *compiler; From 62e14f6b4c31b07f511e024efaac1a342a54cf79 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 14:07:58 +0200 Subject: [PATCH 059/158] osx: add files to project --- .../emulator-osx/reicast-osx.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index f0da70b68..8f6f008ee 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -188,6 +188,7 @@ 84B7BF861B72871600F9733F /* EmuGLView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7BF851B72871600F9733F /* EmuGLView.swift */; }; AE1E293B2095FB1600FC6BA2 /* rec_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE1E293A2095FB1600FC6BA2 /* rec_cpp.cpp */; }; AE1E294020A96B0B00FC6BA2 /* rec_x64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE1E293F20A96B0B00FC6BA2 /* rec_x64.cpp */; }; + AE2A24DA22AE7EB600DD3034 /* ssa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A24D922AE7EB600DD3034 /* ssa.cpp */; }; AE2A2D5A21D68470004B308D /* gdcartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D4E21D6846F004B308D /* gdcartridge.cpp */; }; AE2A2D5B21D68470004B308D /* m1cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D5221D6846F004B308D /* m1cartridge.cpp */; }; AE2A2D5C21D68470004B308D /* awcartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D5321D6846F004B308D /* awcartridge.cpp */; }; @@ -638,6 +639,9 @@ AE1E293F20A96B0B00FC6BA2 /* rec_x64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rec_x64.cpp; sourceTree = ""; }; AE2A234922941A0500DD3034 /* NaomiConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = NaomiConfig.xcconfig; sourceTree = ""; }; AE2A234A22941AF000DD3034 /* DreamcastConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DreamcastConfig.xcconfig; sourceTree = ""; }; + AE2A24D722AE7EB600DD3034 /* ssa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssa.h; sourceTree = ""; }; + AE2A24D822AE7EB600DD3034 /* ssa_regalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ssa_regalloc.h; sourceTree = ""; }; + AE2A24D922AE7EB600DD3034 /* ssa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ssa.cpp; sourceTree = ""; }; AE2A2D4921D6820D004B308D /* glcache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glcache.h; sourceTree = ""; }; AE2A2D4D21D6846F004B308D /* awcartridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = awcartridge.h; sourceTree = ""; }; AE2A2D4E21D6846F004B308D /* gdcartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gdcartridge.cpp; sourceTree = ""; }; @@ -1443,6 +1447,9 @@ 84B7BE181B72720100F9733F /* shil.cpp */, 84B7BE191B72720100F9733F /* shil.h */, 84B7BE1A1B72720100F9733F /* shil_canonical.h */, + AE2A24D922AE7EB600DD3034 /* ssa.cpp */, + AE2A24D722AE7EB600DD3034 /* ssa.h */, + AE2A24D822AE7EB600DD3034 /* ssa_regalloc.h */, ); path = dyna; sourceTree = ""; @@ -2365,6 +2372,7 @@ AEFF7F72214D9D590068CE11 /* pico_protocol.c in Sources */, 84B7BF6A1B72720200F9733F /* audiobackend_pulseaudio.cpp in Sources */, 84B7BF3F1B72720200F9733F /* ta.cpp in Sources */, + AE2A24DA22AE7EB600DD3034 /* ssa.cpp in Sources */, 84B7BF751B72720200F9733F /* gdrom_hle.cpp in Sources */, 84B7BEFF1B72720200F9733F /* zip_name_locate.c in Sources */, AE649BFD218C552500EF4A81 /* lpc_intrin_avx2.c in Sources */, From 8819c9d53638153af8fa04daf748368a20513840 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 14:35:27 +0200 Subject: [PATCH 060/158] arm64: handle pref with imm arg. some refactoring --- core/rec-ARM64/rec_arm64.cpp | 174 ++++++++++++----------------------- 1 file changed, 61 insertions(+), 113 deletions(-) diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 65b9aa7ca..e051359e1 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -251,6 +251,7 @@ class Arm64Assembler : public MacroAssembler { typedef void (MacroAssembler::*Arm64Op_RRO)(const Register&, const Register&, const Operand&); typedef void (MacroAssembler::*Arm64Op_RROF)(const Register&, const Register&, const Operand&, enum FlagsUpdate); + typedef void (MacroAssembler::*Arm64Fop_RRR)(const VRegister&, const VRegister&, const VRegister&); public: Arm64Assembler() : Arm64Assembler(emit_GetCCPtr()) @@ -303,6 +304,31 @@ public: ((*this).*arm_op2)(regalloc.MapRegister(op->rd), regalloc.MapRegister(op->rs1), op3, LeaveFlags); } + void ngen_BinaryFop(shil_opcode* op, Arm64Fop_RRR arm_op) + { + VRegister reg1; + VRegister reg2; + if (op->rs1.is_imm()) + { + Fmov(s0, reinterpret_cast(op->rs1._imm)); + reg1 = s0; + } + else + { + reg1 = regalloc.MapVRegister(op->rs1); + } + if (op->rs2.is_imm()) + { + Fmov(s1, reinterpret_cast(op->rs2._imm)); + reg2 = s1; + } + else + { + reg2 = regalloc.MapVRegister(op->rs2); + } + ((*this).*arm_op)(regalloc.MapVRegister(op->rd), reg1, reg2); + } + const Register& GenMemAddr(const shil_opcode& op, const Register* raddr = NULL) { const Register* ret_reg = raddr == NULL ? &w0 : raddr; @@ -422,12 +448,15 @@ public: case shop_jcond: case shop_jdyn: - if (op.rs2.is_imm()) - Add(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1), op.rs2._imm); - else - Mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); - // Save it for the branching at the end of the block - Mov(w29, regalloc.MapRegister(op.rd)); + { + const Register rd = regalloc.MapRegister(op.rd); + if (op.rs2.is_imm()) + Add(rd, regalloc.MapRegister(op.rs1), op.rs2._imm); + else + Mov(rd, regalloc.MapRegister(op.rs1)); + // Save it for the branching at the end of the block + Mov(w29, rd); + } break; case shop_mov32: @@ -436,21 +465,23 @@ public: if (regalloc.IsAllocf(op.rd)) { + const VRegister rd = regalloc.MapVRegister(op.rd); if (op.rs1.is_imm()) - Fmov(regalloc.MapVRegister(op.rd), reinterpret_cast(op.rs1._imm)); + Fmov(rd, reinterpret_cast(op.rs1._imm)); else if (regalloc.IsAllocf(op.rs1)) - Fmov(regalloc.MapVRegister(op.rd), regalloc.MapVRegister(op.rs1)); + Fmov(rd, regalloc.MapVRegister(op.rs1)); else - Fmov(regalloc.MapVRegister(op.rd), regalloc.MapRegister(op.rs1)); + Fmov(rd, regalloc.MapRegister(op.rs1)); } else { + const Register rd = regalloc.MapRegister(op.rd); if (op.rs1.is_imm()) - Mov(regalloc.MapRegister(op.rd), op.rs1._imm); + Mov(rd, op.rs1._imm); else if (regalloc.IsAllocg(op.rs1)) - Mov(regalloc.MapRegister(op.rd), regalloc.MapRegister(op.rs1)); + Mov(rd, regalloc.MapRegister(op.rs1)); else - Fmov(regalloc.MapRegister(op.rd), regalloc.MapVRegister(op.rs1)); + Fmov(rd, regalloc.MapVRegister(op.rs1)); } break; @@ -849,18 +880,23 @@ public: case shop_pref: { - if (regalloc.IsAllocg(op.rs1)) - Lsr(w1, regalloc.MapRegister(op.rs1), 26); + Label not_sqw; + if (op.rs1.is_imm()) + Mov(*call_regs[0], op.rs1._imm); else { - Ldr(w0, sh4_context_mem_operand(op.rs1.reg_ptr())); - Lsr(w1, w0, 26); + if (regalloc.IsAllocg(op.rs1)) + Lsr(w1, regalloc.MapRegister(op.rs1), 26); + else + { + Ldr(w0, sh4_context_mem_operand(op.rs1.reg_ptr())); + Lsr(w1, w0, 26); + } + Cmp(w1, 0x38); + B(¬_sqw, ne); + if (regalloc.IsAllocg(op.rs1)) + Mov(w0, regalloc.MapRegister(op.rs1)); } - Cmp(w1, 0x38); - Label not_sqw; - B(¬_sqw, ne); - if (regalloc.IsAllocg(op.rs1)) - Mov(w0, regalloc.MapRegister(op.rs1)); if (mmu_enabled()) { @@ -907,104 +943,16 @@ public: // case shop_fadd: - { - VRegister reg1; - VRegister reg2; - if (op.rs1.is_imm()) - { - Fmov(s0, reinterpret_cast(op.rs1._imm)); - reg1 = s0; - } - else - { - reg1 = regalloc.MapVRegister(op.rs1); - } - if (op.rs2.is_imm()) - { - Fmov(s1, reinterpret_cast(op.rs2._imm)); - reg2 = s1; - } - else - { - reg2 = regalloc.MapVRegister(op.rs2); - } - Fadd(regalloc.MapVRegister(op.rd), reg1, reg2); - } + ngen_BinaryFop(&op, &MacroAssembler::Fadd); break; case shop_fsub: - { - VRegister reg1; - VRegister reg2; - if (op.rs1.is_imm()) - { - Fmov(s0, reinterpret_cast(op.rs1._imm)); - reg1 = s0; - } - else - { - reg1 = regalloc.MapVRegister(op.rs1); - } - if (op.rs2.is_imm()) - { - Fmov(s1, reinterpret_cast(op.rs2._imm)); - reg2 = s1; - } - else - { - reg2 = regalloc.MapVRegister(op.rs2); - } - Fsub(regalloc.MapVRegister(op.rd), reg1, reg2); - } + ngen_BinaryFop(&op, &MacroAssembler::Fsub); break; case shop_fmul: - { - VRegister reg1; - VRegister reg2; - if (op.rs1.is_imm()) - { - Fmov(s0, reinterpret_cast(op.rs1._imm)); - reg1 = s0; - } - else - { - reg1 = regalloc.MapVRegister(op.rs1); - } - if (op.rs2.is_imm()) - { - Fmov(s1, reinterpret_cast(op.rs2._imm)); - reg2 = s1; - } - else - { - reg2 = regalloc.MapVRegister(op.rs2); - } - Fmul(regalloc.MapVRegister(op.rd), reg1, reg2); - } + ngen_BinaryFop(&op, &MacroAssembler::Fmul); break; case shop_fdiv: - { - VRegister reg1; - VRegister reg2; - if (op.rs1.is_imm()) - { - Fmov(s0, reinterpret_cast(op.rs1._imm)); - reg1 = s0; - } - else - { - reg1 = regalloc.MapVRegister(op.rs1); - } - if (op.rs2.is_imm()) - { - Fmov(s1, reinterpret_cast(op.rs2._imm)); - reg2 = s1; - } - else - { - reg2 = regalloc.MapVRegister(op.rs2); - } - Fdiv(regalloc.MapVRegister(op.rd), reg1, reg2); - } + ngen_BinaryFop(&op, &MacroAssembler::Fdiv); break; case shop_fabs: From 2c3b5163413caa3e058ba516f12bb3463b60f8a0 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 14:48:54 +0200 Subject: [PATCH 061/158] x64: use eax instead of ecx for mem reads return value --- core/rec-x64/rec_x64.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index ed73b74d3..21a207d52 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -477,20 +477,20 @@ public: u32 size = op.flags & 0x7f; if (size != 8) - host_reg_to_shil_param(op.rd, ecx); + host_reg_to_shil_param(op.rd, eax); else { #ifdef EXPLODE_SPANS if (op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)) { - movd(regalloc.MapXRegister(op.rd, 0), ecx); - shr(rcx, 32); - movd(regalloc.MapXRegister(op.rd, 1), ecx); + movd(regalloc.MapXRegister(op.rd, 0), eax); + shr(rax, 32); + movd(regalloc.MapXRegister(op.rd, 1), eax); } else #endif { - mov(rax, (uintptr_t)op.rd.reg_ptr()); - mov(qword[rax], rcx); + mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(qword[rcx], rax); } } } @@ -1260,14 +1260,14 @@ public: GenCall(ReadMem8); else GenCall(ReadMemNoEx, true); - movsx(ecx, al); + movsx(eax, al); break; case 2: if (!mmu_enabled()) GenCall(ReadMem16); else GenCall(ReadMemNoEx, true); - movsx(ecx, ax); + movsx(eax, ax); break; case 4: @@ -1275,14 +1275,12 @@ public: GenCall(ReadMem32); else GenCall(ReadMemNoEx, true); - mov(ecx, eax); break; case 8: if (!mmu_enabled()) GenCall(ReadMem64); else GenCall(ReadMemNoEx, true); - mov(rcx, rax); break; default: die("1..8 bytes"); @@ -1560,24 +1558,23 @@ private: { case 1: GenCall((void (*)())ptr); - movsx(ecx, al); + movsx(eax, al); break; case 2: GenCall((void (*)())ptr); - movsx(ecx, ax); + movsx(eax, ax); break; case 4: GenCall((void (*)())ptr); - mov(ecx, eax); break; default: die("Invalid immediate size"); break; } - host_reg_to_shil_param(op.rd, ecx); + host_reg_to_shil_param(op.rd, eax); } return true; @@ -1722,19 +1719,19 @@ private: switch (size) { case 1: - movsx(ecx, byte[rax + call_regs64[0]]); + movsx(eax, byte[rax + call_regs64[0]]); break; case 2: - movsx(ecx, word[rax + call_regs64[0]]); + movsx(eax, word[rax + call_regs64[0]]); break; case 4: - mov(ecx, dword[rax + call_regs64[0]]); + mov(eax, dword[rax + call_regs64[0]]); break; case 8: - mov(rcx, qword[rax + call_regs64[0]]); + mov(rax, qword[rax + call_regs64[0]]); break; default: From a4453c0a81d8433ff738d074fee36b96ba47ff1a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 19:01:56 +0200 Subject: [PATCH 062/158] Fix vmem in 512MB mode --- core/hw/mem/_vmem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 9585dd657..a1f42ff2b 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -655,6 +655,7 @@ void _vmem_enable_mmu(bool enable) { // Restore P0/U0 mem mappings vmem32_term(); - _vmem_set_p0_mappings(); + if (_nvmem_4gb_space()) + _vmem_set_p0_mappings(); } } From ff745ee4fe379c3dc69fd2f382b9b39e4bee048f Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 10 Jun 2019 19:17:24 +0200 Subject: [PATCH 063/158] fix xtrct canonical implementation --- core/hw/sh4/dyna/shil_canonical.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index ad9035cad..dc8a6f7a0 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -1033,10 +1033,10 @@ u32,f1,(u32 r1, u32 r2), ) shil_compile ( - shil_cf_arg_ptr(rs2); - shil_cf_arg_ptr(rs1); - shil_cf_arg_ptr(rd); + shil_cf_arg_u32(rs2); + shil_cf_arg_u32(rs1); shil_cf(f1); + shil_cf_rv_u32(rd); ) shil_opc_end() From e537d92bcc7cb6b7c4767971a727dd3f6bc60f4b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 12 Jun 2019 08:52:42 +0200 Subject: [PATCH 064/158] ssa: don't simplify FPU ops because of Inf of NaN --- core/hw/sh4/dyna/ssa.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 8dd2b287e..807cb878f 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -366,8 +366,8 @@ private: { // a & 0 == 0 // a * 0 == 0 - if (op.op == shop_and || op.op == shop_mul_i32 || op.op == shop_mul_s16 || op.op == shop_mul_u16 - || op.op == shop_fmul) + // Not true for FPU ops because of Inf and NaN + if (op.op == shop_and || op.op == shop_mul_i32 || op.op == shop_mul_s16 || op.op == shop_mul_u16) { //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op, 0); @@ -386,9 +386,9 @@ private: // a ^ 0 == a // a >> 0 == a // a << 0 == a + // Not true for FPU ops because of Inf and NaN else if (op.op == shop_add || op.op == shop_sub || op.op == shop_or || op.op == shop_xor - || op.op == shop_shl || op.op == shop_shr || op.op == shop_sar || op.op == shop_shad || op.op == shop_shld - || op.op == shop_fadd || op.op == shop_fsub) + || op.op == shop_shl || op.op == shop_shr || op.op == shop_sar || op.op == shop_shad || op.op == shop_shld) { //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op); From c49694599cd70f42cf2ff12b1f19bb260d021847 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 12 Jun 2019 17:31:37 +0200 Subject: [PATCH 065/158] rec-arm: use ssa regalloc add `subc a,a` expression to simplify --- core/hw/sh4/dyna/ssa.h | 26 +- core/hw/sh4/dyna/ssa_regalloc.h | 9 + core/rec-ARM/rec_arm.cpp | 863 +++++++++++++++++++------------- 3 files changed, 546 insertions(+), 352 deletions(-) diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 807cb878f..e322af7b8 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -407,13 +407,29 @@ private: // Not sure it's worth the trouble, except for the 'and' and 'xor' else if (op.rs1.is_r32i() && op.rs1._reg == op.rs2._reg) { + // a + a == a * 2 == a << 1 + if (op.op == shop_add) + { + // There's quite a few of these + //printf("%08x +t<< %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + op.op = shop_shl; + op.rs2 = shil_param(FMT_IMM, 1); + } // a ^ a == 0 // a - a == 0 - if (op.op == shop_xor || op.op == shop_sub) + else if (op.op == shop_xor || op.op == shop_sub) { //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op, 0); } + // SBC a, a == SBC 0,0 + else if (op.op == shop_sbc) + { + //printf("%08x ZERO %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + op.rs1 = shil_param(FMT_IMM, 0); + op.rs2 = shil_param(FMT_IMM, 0); + stats.prop_constants += 2; + } // a & a == a // a | a == a else if (op.op == shop_and || op.op == shop_or) @@ -421,14 +437,6 @@ private: //printf("%08x IDEN %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); ReplaceByMov32(op); } - // a + a == a * 2 == a << 1 - else if (op.op == shop_add) - { - // There's quite a few of these - //printf("%08x +t<< %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); - op.op = shop_shl; - op.rs2 = shil_param(FMT_IMM, 1); - } } } } diff --git a/core/hw/sh4/dyna/ssa_regalloc.h b/core/hw/sh4/dyna/ssa_regalloc.h index 509e2f767..930446b4b 100644 --- a/core/hw/sh4/dyna/ssa_regalloc.h +++ b/core/hw/sh4/dyna/ssa_regalloc.h @@ -41,9 +41,11 @@ public: SSAOptimizer optim(block); optim.AddVersionPass(); + verify(host_gregs.empty()); while (*regs_avail != (nreg_t)-1) host_gregs.push_back(*regs_avail++); + verify(host_fregs.empty()); while (*regsf_avail != (nregf_t)-1) host_fregs.push_back(*regsf_avail++); } @@ -243,6 +245,13 @@ public: void Cleanup() { verify(final_opend || block->oplist.size() == 0); + final_opend = false; + FlushAllRegs(true); + verify(reg_alloced.empty()); + verify(pending_flushes.empty()); + block = NULL; + host_fregs.clear(); + host_gregs.clear(); } virtual void Preload(u32 reg, nreg_t nreg) = 0; diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index 33109d11d..ba6cc1983 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -11,6 +11,9 @@ #include "hw/sh4/dyna/ngen.h" #include "hw/sh4/sh4_mem.h" +#define _DEVEL 1 +#include "arm_emitter/arm_emitter.h" + /* ARM ABI @@ -48,6 +51,7 @@ struct DynaRBI: RuntimeBlockInfo { } + ARM::eReg T_reg; }; @@ -168,9 +172,6 @@ asm void CacheFlush(void* code, void* pEnd) } #endif -#define _DEVEL 1 - -#include "arm_emitter/arm_emitter.h" using namespace ARM; @@ -214,40 +215,12 @@ void StoreSh4Reg_mem(eReg Rt,u32 Sh4_Reg, eCC CC=CC_AL) STR(Rt, r8, shRegOffs, Offset, CC); } - -EmitAPI LoadSh4Reg_mem(eReg Rt, shil_param Sh4_Reg, eCC CC=CC_AL) -{ - if (!Sh4_Reg.is_r32()) - printf("REG FAIL: %d\n",Sh4_Reg._reg); - verify(Sh4_Reg.is_r32()); - LoadSh4Reg_mem(Rt,Sh4_Reg._reg,CC); -} - -EmitAPI StoreSh4Reg_mem(eReg Rt, shil_param Sh4_Reg, eCC CC=CC_AL) -{ - verify(Sh4_Reg.is_r32()); - StoreSh4Reg_mem(Rt,Sh4_Reg._reg,CC); -} - - -EmitAPI LoadSh4Reg64(eReg Rt, shil_param Sh4_Reg, eCC CC=CC_AL) -{ - verify(Sh4_Reg.is_r64()); - //possibly use ldm/ldrd ? - LoadSh4Reg_mem(Rt,Sh4_Reg._reg,CC); - LoadSh4Reg_mem((eReg)(Rt+1),Sh4_Reg._reg+1,CC); -} - -EmitAPI StoreSh4Reg64(eReg Rt, shil_param Sh4_Reg, eCC CC=CC_AL) -{ - verify(Sh4_Reg.is_r64()); - //possibly use stm/strd ? - StoreSh4Reg_mem(Rt,Sh4_Reg._reg,CC); - StoreSh4Reg_mem((eReg)(Rt+1),Sh4_Reg._reg+1,CC); -} - - +//#define OLD_REGALLOC +#ifdef OLD_REGALLOC #include "hw/sh4/dyna/regalloc.h" +#else +#include "hw/sh4/dyna/ssa_regalloc.h" +#endif #if HOST_OS == OS_DARWIN eReg alloc_regs[]={r5,r6,r7,r10,(eReg)-1}; @@ -259,17 +232,6 @@ eFSReg alloc_fpu[]={f16,f17,f18,f19,f20,f21,f22,f23, struct arm_reg_alloc: RegAlloc { - - virtual eFSReg FpuMap(u32 reg) - { - if (reg>=reg_fr_0 && reg<=reg_fr_15) - { - return alloc_fpu[reg-reg_fr_0]; - } - else - return (eFSReg)-1; - } - virtual void Preload(u32 reg,eReg nreg) { verify(reg!=reg_pc_dyn); @@ -278,7 +240,9 @@ struct arm_reg_alloc: RegAlloc virtual void Writeback(u32 reg,eReg nreg) { if (reg==reg_pc_dyn) - ;//MOV(r4,nreg); + // reg_pc_dyn has been stored in r4 by the jdyn op implementation + // No need to write it back since it won't be used past the end of the block + ; //MOV(r4,nreg); else StoreSh4Reg_mem(nreg,reg); } @@ -295,36 +259,21 @@ struct arm_reg_alloc: RegAlloc VSTR((nreg),r8,shRegOffs/4); } - /* - eFSReg fd0_to_fs(eFDReg fd0) - { - eFSReg rv=(eFSReg)(fd0*2); - verify(rv<32); - return rv; - } - */ eFSReg mapfs(const shil_param& prm) { return mapf(prm); } - }; - arm_reg_alloc reg; - #ifdef naked #undef naked #define naked __attribute__((naked)) #endif - - - u32 blockno=0; - extern "C" void no_update(); extern "C" void intc_sched(); extern "C" void ngen_blockcheckfail(); @@ -374,8 +323,15 @@ u32 DynaRBI::Relink() { if (!has_jcond) { - printf("SLOW COND PATH %d\n",oplist[oplist.size()-1].op); - LoadSh4Reg_mem(r4,reg_sr_T); + if (T_reg != (eReg)-1) + { + MOV(r4, T_reg); + } + else + { + printf("SLOW COND PATH %d\n", oplist.empty() ? -1 : oplist[oplist.size()-1].op); + LoadSh4Reg_mem(r4, reg_sr_T); + } } CMP(r4,(BlockType&1)); @@ -521,31 +477,49 @@ u32 DynaRBI::Relink() return sz; } +eReg GetParam(const shil_param& param, eReg raddr = r0) +{ + if (param.is_imm()) + { + MOV32(raddr, param._imm); + return raddr; + } + else if (param.is_r32i()) + { + return reg.mapg(param); + } + else + { + die("Invalid parameter"); + return (eReg)-1; + } +} + void ngen_Unary(shil_opcode* op, UnaryOP unop) { unop(reg.mapg(op->rd),reg.mapg(op->rs1)); } -void ngen_Binary(shil_opcode* op, BinaryOP dtop,BinaryOPImm dtopimm, bool has_imm=true) +void ngen_Binary(shil_opcode* op, BinaryOP dtop, BinaryOPImm dtopimm) { - verify(reg.mapg(op->rd)!=r0 && reg.mapg(op->rs1)!=r0); + eReg rs1 = GetParam(op->rs1); - eReg rs2=r0; - if (has_imm && op->rs2.is_imm()) // **FIXME** ??? + eReg rs2 = r1; + if (op->rs2.is_imm()) { if (is_i8r4(op->rs2._imm)) { - dtopimm(reg.mapg(op->rd), reg.mapg(op->rs1), op->rs2._imm, CC_AL); + dtopimm(reg.mapg(op->rd), rs1, op->rs2._imm, CC_AL); return; } else { - MOV32(rs2,(u32)op->rs2._imm); + MOV32(rs2, op->rs2._imm); } } - else if (op->rs2.is_r32i()) // **FIXME** Correct? + else if (op->rs2.is_r32i()) { - rs2=reg.mapg(op->rs2); + rs2 = reg.mapg(op->rs2); } else { @@ -553,22 +527,42 @@ void ngen_Binary(shil_opcode* op, BinaryOP dtop,BinaryOPImm dtopimm, bool has_im verify(false); } - dtop(reg.mapg(op->rd),reg.mapg(op->rs1), rs2, CC_AL); + dtop(reg.mapg(op->rd), rs1, rs2, CC_AL); } void ngen_fp_bin(shil_opcode* op, const FPBinOP fpop) { - verify(op->rs1.is_r32f()); - verify(op->rs2.is_r32f()); + eFSReg rs1 = f0; + if (op->rs1.is_imm()) + { + MOV32(r0, op->rs1._imm); + VMOV(rs1, r0); + } + else + { + rs1 = reg.mapf(op->rs1); + } - fpop(reg.mapfs(op->rd),reg.mapfs(op->rs1),reg.mapfs(op->rs2),CC_AL); + eFSReg rs2 = f1; + if (op->rs2.is_imm()) + { + MOV32(r0, op->rs2._imm); + VMOV(rs2, r0); + } + else + { + rs2 = reg.mapf(op->rs2); + } + + fpop(reg.mapfs(op->rd), rs1, rs2, CC_AL); } + void ngen_fp_una(shil_opcode* op, const FPUnOP fpop) { verify(op->rd.is_r32f()); verify(op->rs1.is_r32f()); - fpop(reg.mapfs(op->rd),reg.mapfs(op->rs1),CC_AL); + fpop(reg.mapfs(op->rd), reg.mapfs(op->rs1), CC_AL); } struct CC_PS @@ -615,6 +609,8 @@ void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp) //VMOV(reg.mapf(*par),0,r0); %d\n",reg.map(*par)); VMOV(reg.mapfs(*par),r0); } + else + die("unhandled param"); } break; @@ -704,10 +700,6 @@ void ngen_CC_Finish(shil_opcode* op) CC_pars.clear(); } -void* _vmem_read_const(u32 addr,bool& ismem,u32 sz); -void* _vmem_page_info(u32 addr,bool& ismem,u32 sz,u32& page_sz, bool rw); - - enum mem_op_type { SZ_8, @@ -1028,19 +1020,12 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr) return (u32*)ptr; } -extern u8* virt_ram_base; - EAPI NEG(eReg Rd,eReg Rs) { RSB(Rd,Rs,0); } -EAPI NEG(eReg Rd,eReg Rs, bool S, ConditionCode cond = CC_AL) -{ - RSB(Rd,Rs,0, S, cond); -} - -eReg GenMemAddr(shil_opcode* op,eReg raddr=r0) +eReg GenMemAddr(shil_opcode* op, eReg raddr = r0) { if (op->rs3.is_imm()) { @@ -1063,6 +1048,10 @@ eReg GenMemAddr(shil_opcode* op,eReg raddr=r0) printf("rs3: %08X\n",op->rs3.type); die("invalid rs3"); } + else if (op->rs1.is_imm()) + { + MOV32(raddr, op->rs1._imm); + } else { raddr = reg.mapg(op->rs1); @@ -1071,116 +1060,192 @@ eReg GenMemAddr(shil_opcode* op,eReg raddr=r0) return raddr; } +bool ngen_readm_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool staging, bool optimise) +{ + if (!op->rs1.is_imm()) + return false; + + mem_op_type optp = memop_type(op); + bool isram = false; + void* ptr = _vmem_read_const(op->rs1._imm, isram, memop_bytes(optp)); + eReg rd = (optp != SZ_32F && optp != SZ_64F) ? reg.mapg(op->rd) : r0; + + if (isram) + { + switch(optp) + { + case SZ_8: + { + verify(false); + MOV32(r0, (u32)ptr); + LDRB(rd, r0); + SXTB(rd, rd); + } + break; + + case SZ_16: + { + LoadImmBase16(rd, (u32)ptr, true); // true for sx + } + break; + + case SZ_32I: + { + verify(reg.IsAllocg(op->rd)); + { + if (optimise && staging && !is_s8(*(u32*)ptr) && abs((int)op->rs1._imm - (int)block->addr) <= 1024) + { + op->flags |= 0x40000000; + + MOV32(r0, (u32)ptr); + LDR(rd, r0); + MOV32(r1, *(u32*)ptr); + CMP(rd, r1); + //JUMP((unat)EMIT_GET_PTR() + 24, CC_EQ); + MOV32(r1, (u32)&op->flags); + MOV32(r2, ~0x40000000); + LDR(r3, r1); + AND(r3, r3, r2, CC_NE); + STR(r3, r1); + } + else if (optimise && !staging && (op->flags & 0x40000000)) + { + MOV32(rd, *(u32*)ptr); + } + else + { + MOV32(r0, (u32)ptr); + LDR(rd, r0); + } + } + } + break; + + case SZ_32F: + { + verify(reg.IsAllocf(op->rd)); + MOV32(r0, (u32)ptr); + VLDR(reg.mapfs(op->rd), r0, 0); + + } + break; + + case SZ_64F: + { + MOV32(r0, (u32)ptr); + VLDR(d0, r0, 0); + VSTR(d0, r8, op->rd.reg_nofs() / 4); + } + break; + } + } + else + { + MOV32(r0, op->rs1._imm); + + switch(optp) + { + case SZ_8: + CALL((u32)ptr); + SXTB(r0, r0); + break; + + case SZ_16: + CALL((u32)ptr); + SXTH(r0, r0); + break; + + case SZ_32I: + case SZ_32F: + CALL((u32)ptr); + break; + + case SZ_64F: + die("SZ_64F not supported"); + break; + } + + if (reg.IsAllocg(op->rd)) + MOV(rd, r0); + else if (reg.IsAllocf(op->rd)) + VMOV(reg.mapfs(op->rd), r0); + } + + return true; +} + +bool ngen_writemem_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool staging, bool optimise) +{ + if (!op->rs1.is_imm()) + return false; + + mem_op_type optp = memop_type(op); + bool isram = false; + void* ptr = _vmem_write_const(op->rs1._imm, isram, memop_bytes(optp)); + + eReg rs2 = r1; + eFSReg rs2f = f1; + if (op->rs2.is_imm()) + { + MOV32(rs2, op->rs2._imm); + if (optp == SZ_32F) + VMOV(rs2f, rs2); + } + else + { + if (optp == SZ_32F) + rs2f = reg.mapf(op->rs2); + else + rs2 = reg.mapg(op->rs2); + } + if (isram) + { + MOV32(r0, (u32)ptr); + switch(optp) + { + case SZ_8: + STRB(rs2, r0); + break; + + case SZ_16: + STRH(rs2, r0); + break; + + case SZ_32I: + STR(rs2, r0); + break; + + case SZ_32F: + VSTR(rs2f, r0, 0); + break; + + default: + die("Invalid size"); + break; + } + } + else + { + if (optp == SZ_64F) + die("SZ_64F not supported"); + MOV32(r0, op->rs1._imm); + if (r1 != rs2) + MOV(r1, rs2); + + CALL((u32)ptr); + } + return true; +} + void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, bool optimise) { switch(op->op) { case shop_readm: { - mem_op_type optp=memop_type(op); - if (op->rs1.is_imm()) - { - bool isram=false; - void* ptr=_vmem_read_const(op->rs1._imm,isram,memop_bytes(optp)); - - verify(optp!=SZ_64F); - - if (isram) - { - switch(optp) - { - case SZ_8: - { - verify(false); - MOV32(r0,(u32)ptr); - LDRB(reg.mapg(op->rd),r0); - SXTB(reg.mapg(op->rd),reg.mapg(op->rd)); - } - break; - - case SZ_16: - { - LoadImmBase16(reg.mapg(op->rd),(u32)ptr,true); // true for sx - } - break; - - case SZ_32I: - { - verify(reg.IsAllocg(op->rd)); - { - if (optimise && staging && !is_s8(*(u32*)ptr) && abs((int)op->rs1._imm-(int)block->addr)<=1024) - { - op->flags|=0x40000000; - - MOV32(r0,(u32)ptr); - LDR(reg.mapg(op->rd),r0); - MOV32(r1,*(u32*)ptr); - CMP(reg.mapg(op->rd),r1); - //JUMP((unat)EMIT_GET_PTR()+24,CC_EQ); - MOV32(r1,(u32)&op->flags); - MOV32(r2,~0x40000000); - LDR(r3,r1); - AND(r3,r3,r2,CC_NE); - STR(r3,r1); - } - else if (optimise && !staging && op->flags & 0x40000000) - { - MOV32(reg.mapg(op->rd),*(u32*)ptr); - } - else - { - MOV32(r0,(u32)ptr); - LDR(reg.mapg(op->rd),r0); - } - } - } - break; - - case SZ_32F: - { - verify(reg.IsAllocf(op->rd)); - MOV32(r0,(u32)ptr); - VLDR(reg.mapfs(op->rd),r0,0); - - } - break; - - case SZ_64F: - { - verify(false); - MOV32(r0,(u32)ptr); - LDR(r1,r0,4); - LDR(r0,r0,0); - } - break; - } - } - else - { - MOV32(r0,op->rs1._imm); - - switch(optp) - { - case SZ_8: CALL((u32)ptr); SXTB(r0,r0); break; - - case SZ_16: CALL((u32)ptr); SXTH(r0,r0); break; - - case SZ_32I: - case SZ_32F: CALL((u32)ptr); break; - - case SZ_64F: - die("SZ_64F not supported"); - break; - } - - if (reg.IsAllocg(op->rd)) - MOV(reg.mapg(op->rd),r0); - else - VMOV(reg.mapfs(op->rd),r0); - } - } - else + if (!ngen_readm_immediate(block, op, staging, optimise)) { + mem_op_type optp = memop_type(op); eReg raddr=GenMemAddr(op); if (_nvmem_enabled()) { @@ -1244,94 +1309,112 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_writem: { - mem_op_type optp=memop_type(op); + if (!ngen_writemem_immediate(block, op, staging, optimise)) + { + mem_op_type optp = memop_type(op); - eReg raddr=GenMemAddr(op); - - //TODO: use reg alloc - if (optp == SZ_64F) - VLDR(d0,r8,op->rs2.reg_nofs()/4); + eReg raddr=GenMemAddr(op); - if (_nvmem_enabled()) { - BIC(r1,raddr,0xE0000000); - //UBFX(r1,raddr,0,29); - //SUB(r1,raddr,raddr); - - s32 sq_offs=rcb_noffs(sq_both); - switch(optp) + eReg rs2 = r2; + eFSReg rs2f = f2; + + //TODO: use reg alloc + if (optp == SZ_64F) + VLDR(d0,r8,op->rs2.reg_nofs()/4); + else if (op->rs2.is_imm()) { - case SZ_8: - STRB(reg.mapg(op->rs2),r1,r8,Offset,true); - break; - - case SZ_16: - STRH(reg.mapg(op->rs2),r1,r8,true); - break; - - case SZ_32I: - if (op->flags2!=0x1337) - STR(reg.mapg(op->rs2),r1,r8,Offset,true); - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - STR(reg.mapg(op->rs2),r1,sq_offs); - } - break; - - case SZ_32F: - if (op->flags2!=0x1337) - { - ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ - VSTR(reg.mapf(op->rs2),r1,0); - } - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - VSTR(reg.mapf(op->rs2),r1,sq_offs/4); - } - break; - - case SZ_64F: - if (op->flags2!=0x1337) - { - ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ - VSTR(d0,r1,0); //TODO: use reg alloc - } - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - VSTR(d0,r1,sq_offs/4); - } - break; + MOV32(rs2, op->rs2._imm); + if (optp == SZ_32F) + VMOV(rs2f, rs2); } - } else { - switch(optp) + else { - case SZ_8: - vmem_slowpath(raddr, reg.mapg(op->rs2), f0, d0, optp, false); - break; + if (optp == SZ_32F) + rs2f = reg.mapf(op->rs2); + else + rs2 = reg.mapg(op->rs2); + } + if (_nvmem_enabled()) { + BIC(r1,raddr,0xE0000000); + //UBFX(r1,raddr,0,29); + //SUB(r1,raddr,raddr); - case SZ_16: - vmem_slowpath(raddr, reg.mapg(op->rs2), f0, d0, optp, false); - break; + s32 sq_offs=rcb_noffs(sq_both); + switch(optp) + { + case SZ_8: + STRB(rs2, r1, r8, Offset, true); + break; - case SZ_32I: - vmem_slowpath(raddr, reg.mapg(op->rs2), f0, d0, optp, false); - break; + case SZ_16: + STRH(rs2, r1, r8, true); + break; - case SZ_32F: - vmem_slowpath(raddr, r0, reg.mapf(op->rs2), d0, optp, false); - break; + case SZ_32I: + if (op->flags2!=0x1337) + STR(rs2, r1, r8, Offset, true); + else + { + emit_Skip(-4); + AND(r1,raddr,0x3F); + ADD(r1,r1,r8); + STR(rs2, r1, sq_offs); + } + break; - case SZ_64F: - vmem_slowpath(raddr, r0, f0, d0, optp, false); - break; + case SZ_32F: + if (op->flags2!=0x1337) + { + ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ + VSTR(rs2f, r1, 0); + } + else + { + emit_Skip(-4); + AND(r1,raddr,0x3F); + ADD(r1,r1,r8); + VSTR(rs2f, r1, sq_offs / 4); + } + break; + + case SZ_64F: + if (op->flags2!=0x1337) + { + ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ + VSTR(d0,r1,0); //TODO: use reg alloc + } + else + { + emit_Skip(-4); + AND(r1,raddr,0x3F); + ADD(r1,r1,r8); + VSTR(d0,r1,sq_offs/4); + } + break; + } + } else { + switch(optp) + { + case SZ_8: + vmem_slowpath(raddr, rs2, f0, d0, optp, false); + break; + + case SZ_16: + vmem_slowpath(raddr, rs2, f0, d0, optp, false); + break; + + case SZ_32I: + vmem_slowpath(raddr, rs2, f0, d0, optp, false); + break; + + case SZ_32F: + vmem_slowpath(raddr, r0, rs2f, d0, optp, false); + break; + + case SZ_64F: + vmem_slowpath(raddr, r0, f0, d0, optp, false); + break; + } } } } @@ -1341,7 +1424,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_jdyn: { //ReadReg rs1(r4,op->rs1); - reg.writeback_gpr--; verify(op->rd.is_reg() && op->rd._reg==reg_pc_dyn); if (op->rs2.is_imm()) { @@ -1367,7 +1449,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, } else { - verify(op->rs1._imm==0 || op->rs1._imm==0x3F800000); if (op->rs1._imm==0) { //VEOR(reg.mapf(op->rd),reg.mapf(op->rd),reg.mapf(op->rd)); @@ -1384,8 +1465,13 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, VSUB_VFP(reg.mapfs(op->rd),reg.mapfs(op->rd),reg.mapfs(op->rd)); #endif } + else if (op->rs1._imm == 0x3F800000) + VMOV(reg.mapfs(op->rd), fpu_imm_1); else - VMOV(reg.mapfs(op->rd),fpu_imm_1); + { + MOV32(r0, op->rs1._imm); + VMOV(reg.mapfs(op->rd), r0); + } } } else if (op->rs1.is_r32()) @@ -1495,27 +1581,33 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, ADD(reg.mapg(op->rd),r0,reg.mapg(op->rs3),true); ADC(reg.mapg(op->rd2),r1,0); #else + eReg rs1 = GetParam(op->rs1, r1); + eReg rs2 = GetParam(op->rs2, r2); + eReg rs3 = GetParam(op->rs3, r3); - LSR(r0,reg.mapg(op->rs3),1,true); //C=rs3, r0=0 - ADC(reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2),true); //(C,rd)=rs1+rs2+rs3(C) - ADC(reg.mapg(op->rd2),r0,0); //rd2=C, (or MOVCS rd2, 1) + LSR(r0, rs3, 1, true); //C=rs3, r0=0 + ADC(reg.mapg(op->rd), rs1, rs2, true); //(C,rd)=rs1+rs2+rs3(C) + ADC(reg.mapg(op->rd2), r0, 0); //rd2=C, (or MOVCS rd2, 1) #endif } break; case shop_rocr: { - - if (reg.mapg(op->rd2)!=reg.mapg(op->rs1)) { - LSR(reg.mapg(op->rd2),reg.mapg(op->rs2),1,true); //C=rs2, rd2=0 - AND(reg.mapg(op->rd2),reg.mapg(op->rs1),1); //get new carry + eReg rd2 = reg.mapg(op->rd2); + eReg rs1 = GetParam(op->rs1, r1); + eReg rs2 = GetParam(op->rs2, r2); + if (rd2 != rs1) { + verify(rd2 != rs1); + LSR(rd2, rs2, 1, true); //C=rs2, rd2=0 + AND(rd2, rs1, 1); //get new carry } else { - LSR(r0,reg.mapg(op->rs2),1,true); //C=rs2, rd2=0 - ADD(r0, reg.mapg(op->rs1),1); + LSR(r0, rs2, 1, true); //C=rs2, rd2=0 + ADD(r0, rs1, 1); } - RRX(reg.mapg(op->rd),reg.mapg(op->rs1)); //RRX w/ carry :) - if (reg.mapg(op->rd2)==reg.mapg(op->rs1)) - MOV(reg.mapg(op->rd2), r0); + RRX(reg.mapg(op->rd), rs1); //RRX w/ carry :) + if (rd2 == rs1) + MOV(rd2, r0); } break; @@ -1523,30 +1615,64 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_rocl: { //ADD(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),1,true); //(C,rd)= rs1<<1 + (|) rs2 - ORR(reg.mapg(op->rd),reg.mapg(op->rs2),reg.mapg(op->rs1),true, S_LSL, 1); //(C,rd)= rs1<<1 + (|) rs2 - MOVW(reg.mapg(op->rd2),0); //clear rd2 (for ADC/MOVCS) - ADC(reg.mapg(op->rd2),reg.mapg(op->rd2),0); //rd2=C (or MOVCS rd2, 1) + eReg rs1 = GetParam(op->rs1, r1); + eReg rs2 = GetParam(op->rs2, r2); + ORR(reg.mapg(op->rd), rs2, rs1, true, S_LSL, 1); //(C,rd)= rs1<<1 + (|) rs2 + MOVW(reg.mapg(op->rd2), 0); //clear rd2 (for ADC/MOVCS) + ADC(reg.mapg(op->rd2), reg.mapg(op->rd2), 0); //rd2=C (or MOVCS rd2, 1) } break; case shop_sbc: //printf("sbc: r%d r%d r%d r%d r%d\n",reg.mapg(op->rd),reg.mapg(op->rd2),reg.mapg(op->rs1),reg.mapg(op->rs2), reg.mapg(op->rs3)); { - EOR(reg.mapg(op->rd2),reg.mapg(op->rs3),1); - LSR(reg.mapg(op->rd2),reg.mapg(op->rd2),1,true); //C=rs3, rd2=0 - SBC(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2), true); - MOV(reg.mapg(op->rd2), 1, CC_CC); + eReg rd2 = reg.mapg(op->rd2); + eReg rs1 = GetParam(op->rs1, r1); + if (rs1 == rd2) + { + MOV(r1, rs1); + rs1 = r1; + } + eReg rs2 = GetParam(op->rs2, r2); + if (rs2 == rd2) + { + MOV(r2, rs2); + rs2 = r2; + } + eReg rs3 = GetParam(op->rs3, r3); + EOR(rd2, rs3, 1); + LSR(rd2, rd2, 1, true); //C=rs3, rd2=0 + SBC(reg.mapg(op->rd), rs1, rs2, true); + MOV(rd2, 1, CC_CC); } break; + case shop_negc: + { + eReg rd2 = reg.mapg(op->rd2); + eReg rs1 = GetParam(op->rs1, r1); + if (rs1 == rd2) + { + MOV(r1, rs1); + rs1 = r1; + } + eReg rs2 = GetParam(op->rs2, r2); + EOR(rd2, rs2, 1); + LSR(rd2, rd2, 1, true); //C=rs3, rd2=0 + SBC(reg.mapg(op->rd), rd2, rs1, true); // rd2 == 0 + MOV(rd2, 1, CC_CC); + } + break; + case shop_shld: //printf("shld: r%d r%d r%d\n",reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); { verify(!op->rs2.is_imm()); AND(r0, reg.mapg(op->rs2), 0x8000001F, true); RSB(r0, r0, 0x80000020, CC_MI); - LSR(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_MI); - LSL(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_PL); + eReg rs1 = GetParam(op->rs1, r1); + LSR(reg.mapg(op->rd), rs1, r0, CC_MI); + LSL(reg.mapg(op->rd), rs1, r0, CC_PL); //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSL, r0, CC_PL); //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSR, r0, CC_MI); } @@ -1558,8 +1684,9 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, verify(!op->rs2.is_imm()); AND(r0, reg.mapg(op->rs2), 0x8000001F, true); RSB(r0, r0, 0x80000020, CC_MI); - ASR(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_MI); - LSL(reg.mapg(op->rd), reg.mapg(op->rs1), r0, CC_PL); + eReg rs1 = GetParam(op->rs1, r1); + ASR(reg.mapg(op->rd), rs1, r0, CC_MI); + LSL(reg.mapg(op->rd), rs1, r0, CC_PL); //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_LSL, r0, CC_PL); //MOV(reg.mapg(op->rd), reg.mapg(op->rs1), S_ASR, r0, CC_MI); } @@ -1574,11 +1701,8 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_div32p2: { - if (reg.mapg(op->rs1)!=reg.mapg(op->rd)) - MOV(reg.mapg(op->rd),reg.mapg(op->rs1)); - - CMP(reg.mapg(op->rs3),0); - SUB(reg.mapg(op->rd),reg.mapg(op->rd),reg.mapg(op->rs2),CC_EQ); + CMP(reg.mapg(op->rs3), 0); + SUB(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2), CC_EQ); } break; @@ -1589,25 +1713,22 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_setae: case shop_setab: { - verify(op->rd._reg!=op->rs1._reg); - verify(op->rs2.is_imm() || op->rd._reg!=op->rs2._reg); + eReg rd = reg.mapg(op->rd); + eReg rs1 = GetParam(op->rs1, r0); - //rd is always NOT a source ! - MOVW(reg.mapg(op->rd),0); - - eReg rs2=r0; - bool is_imm=false; + eReg rs2 = r1; + bool is_imm = false; if (op->rs2.is_imm()) { if (!is_i8r4(op->rs2._imm)) MOV32(rs2,(u32)op->rs2._imm); else - is_imm=true; + is_imm = true; } else if (op->rs2.is_r32i()) { - rs2=reg.mapg(op->rs2); + rs2 = reg.mapg(op->rs2); } else { @@ -1615,31 +1736,33 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, verify(false); } - if (op->op==shop_test) + if (op->op == shop_test) { if (is_imm) - TST(reg.mapg(op->rs1),op->rs2._imm); + TST(rs1, op->rs2._imm); else - TST(reg.mapg(op->rs1),rs2); + TST(rs1, rs2); } else { if (is_imm) - CMP(reg.mapg(op->rs1),op->rs2._imm); + CMP(rs1, op->rs2._imm); else - CMP(reg.mapg(op->rs1),rs2); + CMP(rs1, rs2); } - eCC opcls2[]={CC_EQ,CC_EQ,CC_GE,CC_GT,CC_HS,CC_HI }; - MOVW(reg.mapg(op->rd),1,opcls2[op->op-shop_test]); + MOVW(rd, 0); + MOVW(rd, 1, opcls2[op->op-shop_test]); break; } case shop_setpeq: { - EOR(r1, reg.mapg(op->rs1), reg.mapg(op->rs2)); + eReg rs1 = GetParam(op->rs1, r1); + eReg rs2 = GetParam(op->rs2, r2); + EOR(r1, rs1, rs2); MOVW(reg.mapg(op->rd), 0); TST(r1, 0xFF000000); @@ -1654,25 +1777,28 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_mul_u16: { + eReg rs2 = GetParam(op->rs2, r2); UXTH(r1, reg.mapg(op->rs1)); - UXTH(r2, reg.mapg(op->rs2)); - MUL(reg.mapg(op->rd),r1,r2); + UXTH(r2, rs2); + MUL(reg.mapg(op->rd), r1, r2); } break; case shop_mul_s16: { + eReg rs2 = GetParam(op->rs2, r2); SXTH(r1, reg.mapg(op->rs1)); - SXTH(r2, reg.mapg(op->rs2)); - MUL(reg.mapg(op->rd),r1,r2); + SXTH(r2, rs2); + MUL(reg.mapg(op->rd), r1, r2); } break; case shop_mul_i32: { + eReg rs2 = GetParam(op->rs2, r2); //x86_opcode_class opdt[]={op_movzx16to32,op_movsx16to32,op_mov32,op_mov32,op_mov32}; //x86_opcode_class opmt[]={op_mul32,op_mul32,op_mul32,op_mul32,op_imul32}; //only the top 32 bits are different on signed vs unsigned - MUL(reg.mapg(op->rd),reg.mapg(op->rs1),reg.mapg(op->rs2)); + MUL(reg.mapg(op->rd), reg.mapg(op->rs1), rs2); } break; case shop_mul_u64: @@ -1744,14 +1870,20 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_pref: { - if (op->flags != 0x1337) + ConditionCode cc = CC_EQ; + if (op->flags != 0x1337 && !op->rs1.is_imm()) { LSR(r1,reg.mapg(op->rs1),26); MOV(r0,reg.mapg(op->rs1)); CMP(r1,0x38); } else + { + // The decoder or SSA pass has already checked that the + // destination is a store queue so no need to check MOV(r0,reg.mapg(op->rs1)); + cc = CC_AL; + } if (CCN_MMUCR.AT) { @@ -1761,7 +1893,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, { LDR(r2,r8,rcb_noffs(&do_sqw_nommu)); SUB(r1,r8,-rcb_noffs(sq_both)); - BLX(r2,op->flags==0x1337?CC_AL:CC_EQ); + BLX(r2, cc); } } break; @@ -1815,8 +1947,48 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_fmac: { - verify(reg.mapfs(op->rd)==reg.mapfs(op->rs1)); - VMLA_VFP(reg.mapfs(op->rs1),reg.mapfs(op->rs2),reg.mapfs(op->rs3)); + eFSReg rd = reg.mapf(op->rd); + eFSReg rs1 = f1; + if (op->rs1.is_imm()) + { + MOV32(r0, op->rs1.imm_value()); + VMOV(rs1, r0); + } + else + rs1 = reg.mapf(op->rs1); + eFSReg rs2 = f2; + if (op->rs2.is_imm()) + { + MOV32(r1, op->rs2.imm_value()); + VMOV(rs2, r1); + } + else + { + rs2 = reg.mapf(op->rs2); + if (rs2 == rd) + { + VMOV(f2, rs2); + rs2 = f2; + } + } + eFSReg rs3 = f3; + if (op->rs3.is_imm()) + { + MOV32(r2, op->rs3.imm_value()); + VMOV(rs3, r2); + } + else + { + rs3 = reg.mapf(op->rs3); + if (rs3 == rd) + { + VMOV(f3, rs3); + rs3 = f3; + } + } + if (rd != rs1) + VMOV(rd, rs1); + VMLA_VFP(rd, rs2, rs3); } break; @@ -1836,7 +2008,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, #if 1 { - //this is aparently much faster (tested on A9) + //this is apparently much faster (tested on A9) MOVW(reg.mapg(op->rd),0); VCMP_F32(reg.mapfs(op->rs1),reg.mapfs(op->rs2)); @@ -1868,8 +2040,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_fsca: { - reg.writeback_fpu+=2; - //r1: base ptr MOVW(r1,((unat)sin_table)&0xFFFF); UXTH(r0,reg.mapg(op->rs1)); @@ -1901,12 +2071,10 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, SUB(r0,r8,op->rs1.reg_aofs()); if (op->rs2.reg_aofs()==op->rs1.reg_aofs()) { - reg.preload_fpu+=4; VLDM(d0,r0,2); } else { - reg.preload_fpu+=8; SUB(r1,r8,op->rs2.reg_aofs()); VLDM(d0,r0,2); VLDM(d2,r1,2); @@ -1931,9 +2099,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_ftrv: { - reg.preload_fpu+=4; - reg.writeback_fpu+=4; - eReg rdp=r1; SUB(r2,r8,op->rs2.reg_aofs()); SUB(r1,r8,op->rs1.reg_aofs()); @@ -2027,9 +2192,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_frswap: { - reg.preload_fpu+=16; - reg.writeback_fpu+=16; - verify(op->rd._reg==op->rs2._reg); verify(op->rd2._reg==op->rs1._reg); @@ -2110,7 +2272,8 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, STR(r1,r0); } //pre-load the first reg alloc operations, for better efficiency .. - reg.OpBegin(&block->oplist[0],0); + if (!block->oplist.empty()) + reg.OpBegin(&block->oplist[0],0); //scheduler switch (smc_checks) { @@ -2205,7 +2368,21 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, reg.OpEnd(op); } - + if (block->BlockType == BET_Cond_0 || block->BlockType == BET_Cond_1) + { + // Store the arm reg containing sr.T in the block + // This will be used when the block in (re)linked + const shil_param param = shil_param(reg_sr_T); + if (reg.IsAllocg(param)) + { + ((DynaRBI *)block)->T_reg = reg.mapg(param); + } + else + { + ((DynaRBI *)block)->T_reg = (eReg)-1; + } + } + reg.Cleanup(); /* extern u32 ralst[4]; @@ -2340,7 +2517,7 @@ void ngen_init() MOV(r0,(eReg)i); ADD(r3,r3,r8); CMP(r2,0x38); - JUMP((unat)&WriteMem32,CC_NE); + JUMP((unat)&_vmem_WriteMem32,CC_NE); STR(r1,r3,rcb_noffs(sq_both)); BX(LR); } From de86aae73e61febc410a20df693af09debdbd206 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 12 Jun 2019 17:46:53 +0200 Subject: [PATCH 066/158] rec-arm: XTRCT implementation --- core/rec-ARM/rec_arm.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index ba6cc1983..da67d245b 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -1898,16 +1898,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, } break; -/* - case shop_cvt_i2f_z: - case shop_cvt_i2f_n: - - break; -*/ - - //shop_cvt_f2i_t - //shop_cvt_i2f_n - //shop_cvt_i2f_z case shop_ext_s8: case shop_ext_s16: { @@ -1918,8 +1908,19 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, } break; + case shop_xtrct: + { + eReg rd = reg.mapg(op->rd); + LSR(rd, reg.mapg(op->rs1), 16); + LSL(r0, reg.mapg(op->rs2), 16); + ORR(rd, rd, r0); + } + break; + + // + // FPU + // - //fpu case shop_fadd: case shop_fsub: case shop_fmul: From e0949fb9aa960416528d81ab9969e8bb09457b7d Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 13 Jun 2019 18:27:21 +0200 Subject: [PATCH 067/158] Fix div matching: support 64-bit div and correct handling of negative Some games do 64-bit / 32-bit division (Pro Pinball Trilogy) DIV0s/1 use and output 1's complement numbers The final reminder fixup wasn't correct for negative dividend --- core/hw/sh4/dyna/decoder.cpp | 24 +++++++------- core/hw/sh4/dyna/shil_canonical.h | 54 ++++++++++++++++++++++++------- core/hw/sh4/dyna/ssa.cpp | 2 +- core/nullDC.cpp | 16 ++------- core/rec-ARM/rec_arm.cpp | 3 +- core/rec-x86/rec_x86_il.cpp | 3 +- 6 files changed, 63 insertions(+), 39 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 25b52a3b8..bb0c1b441 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -907,16 +907,16 @@ bool dec_generic(u32 op) { verify(!state.cpu.is_delayslot); //div32u - Emit(shop_div32u,mk_reg(div_som_reg1),mk_reg(div_som_reg1),mk_reg(div_som_reg2),0,shil_param(),mk_reg(div_som_reg3)); + Emit(shop_div32u, mk_reg(div_som_reg1), mk_reg(div_som_reg1), mk_reg(div_som_reg2), 0, mk_reg(div_som_reg3), mk_reg(div_som_reg3)); - Emit(shop_and,mk_reg(reg_sr_T),mk_reg(div_som_reg1),mk_imm(1)); - Emit(shop_shr,mk_reg(div_som_reg1),mk_reg(div_som_reg1),mk_imm(1)); + Emit(shop_and, mk_reg(reg_sr_T), mk_reg(div_som_reg1), mk_imm(1)); + Emit(shop_shr, mk_reg(div_som_reg1), mk_reg(div_som_reg1), mk_imm(1)); - Emit(shop_div32p2,mk_reg(div_som_reg3),mk_reg(div_som_reg3),mk_reg(div_som_reg2),0,shil_param(reg_sr_T)); + Emit(shop_div32p2, mk_reg(div_som_reg3), mk_reg(div_som_reg3), mk_reg(div_som_reg2), 0, mk_reg(reg_sr_T)); //skip the aggregated opcodes - state.cpu.rpc+=128; - blk->guest_cycles+=CPU_RATIO*64; + state.cpu.rpc += 128; + blk->guest_cycles += CPU_RATIO*64; } else { @@ -933,16 +933,18 @@ bool dec_generic(u32 op) { verify(!state.cpu.is_delayslot); //div32s - Emit(shop_div32s,mk_reg(div_som_reg1),mk_reg(div_som_reg1),mk_reg(div_som_reg2),0,shil_param(),mk_reg(div_som_reg3)); + Emit(shop_div32s, mk_reg(div_som_reg1), mk_reg(div_som_reg1), mk_reg(div_som_reg2), 0, mk_reg(div_som_reg3), mk_reg(div_som_reg3)); - Emit(shop_and,mk_reg(reg_sr_T),mk_reg(div_som_reg1),mk_imm(1)); - Emit(shop_sar,mk_reg(div_som_reg1),mk_reg(div_som_reg1),mk_imm(1)); + Emit(shop_and, mk_reg(reg_sr_T), mk_reg(div_som_reg1), mk_imm((1 << 31) | 1)); // set lsb and sign of quotient in T + Emit(shop_sar, mk_reg(div_som_reg1), mk_reg(div_som_reg1), mk_imm(1)); // shift quotient right - Emit(shop_div32p2,mk_reg(div_som_reg3),mk_reg(div_som_reg3),mk_reg(div_som_reg2),0,shil_param(reg_sr_T)); + Emit(shop_div32p2, mk_reg(div_som_reg3), mk_reg(div_som_reg3), mk_reg(div_som_reg2), 0, mk_reg(reg_sr_T)); + Emit(shop_and, mk_reg(reg_sr_T), mk_reg(reg_sr_T), mk_imm(1)); // clean up T + //skip the aggregated opcodes state.cpu.rpc+=128; - blk->guest_cycles+=CPU_RATIO*64; + blk->guest_cycles += CPU_RATIO * 64; } else { diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index dc8a6f7a0..a91a01384 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -583,9 +583,10 @@ shil_opc_end() shil_opc(div32u) shil_canonical ( -u64,f1,(u32 r1,u32 r2), - u32 quo=r1/r2; - u32 rem=r1%r2; +u64,f1,(u32 r1, u32 r2, u32 r3), + u64 dividend = ((u64)r3 << 32) | r1; + u32 quo = dividend / r2; + u32 rem = dividend % r2; u64 rv; ((u32*)&rv)[0]=quo; @@ -595,6 +596,7 @@ u64,f1,(u32 r1,u32 r2), shil_compile ( + shil_cf_arg_u32(rs3); shil_cf_arg_u32(rs2); shil_cf_arg_u32(rs1); shil_cf(f1); @@ -607,9 +609,29 @@ shil_opc_end() shil_opc(div32s) shil_canonical ( -u64,f1,(s32 r1,s32 r2), - u32 quo=r1/r2; - u32 rem=r1%r2; +u64,f1,(u32 r1, u32 r2, s32 r3), + s64 dividend = ((s64)r3 << 32) | r1; + bool negative; + if (dividend < 0) + { + // 1's complement -> 2's complement + dividend++; + negative = true; + } + else + { + negative = false; + } + s32 quo = dividend / r2; + s32 rem = dividend % r2; + // 2's complement -> 1's complement + if (negative) + { + if (quo <= 0) + quo--; + if (rem <= 0) + rem--; + } u64 rv; ((u32*)&rv)[0]=quo; @@ -619,6 +641,7 @@ u64,f1,(s32 r1,s32 r2), shil_compile ( + shil_cf_arg_u32(rs3); shil_cf_arg_u32(rs2); shil_cf_arg_u32(rs1); shil_cf(f1); @@ -631,11 +654,20 @@ shil_opc_end() shil_opc(div32p2) shil_canonical ( -u32,f1,(s32 a,s32 b,s32 T), - if (!T) - { - a-=b; - } +u32,f1,(s32 a,s32 b,u32 T), + a += b * (((T >> 31) ^ ~T) & 1) * (2 * (T & 1) - 1); + // This is equivalent to this: + // (the sign of the quotient is stored in bit 31 of T) + // if (quo >= 0) + // { + // if (!T) + // rem -= divisor; + // } + // else + // { + // if (T) + // rem += divisor; + // } return a; ) diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp index b40e9f2fd..1689165d5 100644 --- a/core/hw/sh4/dyna/ssa.cpp +++ b/core/hw/sh4/dyna/ssa.cpp @@ -205,7 +205,7 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_div32u: case shop_div32s: { - u64 res = op.op == shop_div32u ? shil_opcl_div32u::f1::impl(rs1, rs2) : shil_opcl_div32s::f1::impl(rs1, rs2); + u64 res = op.op == shop_div32u ? shil_opcl_div32u::f1::impl(rs1, rs2, rs3) : shil_opcl_div32s::f1::impl(rs1, rs2, rs3); rd = (u32)res; constprop_values[RegValue(op.rd, 1)] = res >> 32; diff --git a/core/nullDC.cpp b/core/nullDC.cpp index b97a9cd59..07a847890 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -169,20 +169,8 @@ void LoadSpecialSettings() settings.rend.TranslucentPolygonDepthMask = 1; tr_poly_depth_mask_game = true; } - // Pro Pinball Trilogy - if (!strncmp("T30701D", reios_product_number, 7) - // Demolition Racer - || !strncmp("T15112N", reios_product_number, 7) - // Star Wars - Episode I - Racer (United Kingdom) - || !strncmp("T23001D", reios_product_number, 7) - // Star Wars - Episode I - Racer (USA) - || !strncmp("T23001N", reios_product_number, 7) - // Record of Lodoss War (EU) - || !strncmp("T7012D", reios_product_number, 6) - // Record of Lodoss War (USA) - || !strncmp("T40218N", reios_product_number, 7) - // Surf Rocket Racers - || !strncmp("T40216N", reios_product_number, 7)) + // Demolition Racer + if (!strncmp("T15112N", reios_product_number, 7)) { printf("Enabling Dynarec safe mode for game %s\n", reios_product_number); settings.dynarec.safemode = 1; diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index da67d245b..76abd8706 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -1698,13 +1698,14 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, CALL((u32)UpdateSR); break; } - + /* TODO Update this to use quotient sign as well case shop_div32p2: { CMP(reg.mapg(op->rs3), 0); SUB(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2), CC_EQ); } break; + */ case shop_test: case shop_seteq: diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp index ca2d6f9e4..f24e4f081 100644 --- a/core/rec-x86/rec_x86_il.cpp +++ b/core/rec-x86/rec_x86_il.cpp @@ -1492,6 +1492,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool } break; + /* TODO Update this according to new canonical implementation case shop_div32s: case shop_div32u: { @@ -1519,7 +1520,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool x86e->Emit(op_sub32,reg.mapg(op->rd),EAX); } break; - + */ #endif From 7120512205c633ad3263c9df2ff7db0da87ba0af Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 13 Jun 2019 18:36:08 +0200 Subject: [PATCH 068/158] wince: use exceptions in dyna/decoder.cpp and catch them in driver.cpp --- core/hw/sh4/dyna/decoder.cpp | 14 ++------------ core/hw/sh4/dyna/driver.cpp | 12 +++++++++++- core/hw/sh4/modules/mmu.cpp | 17 ----------------- core/hw/sh4/modules/mmu.h | 2 -- 4 files changed, 13 insertions(+), 32 deletions(-) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index bb0c1b441..c1763a2cb 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1059,18 +1059,8 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) } */ - u32 op; - if (!mmu_enabled()) - op = IReadMem16(state.cpu.rpc); -#ifndef NO_MMU - else - { - u32 exception_occurred; - op = mmu_IReadMem16NoEx(state.cpu.rpc, &exception_occurred); - if (exception_occurred) - return false; - } -#endif + u32 op = IReadMem16(state.cpu.rpc); + if (op==0 && state.cpu.is_delayslot) { printf("Delayslot 0 hack!\n"); diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 77d75bce1..db0e3086b 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -261,8 +261,18 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) oplist.clear(); - if (!dec_DecodeBlock(this, SH4_TIMESLICE / 2)) +#if !defined(NO_MMU) + try { +#endif + if (!dec_DecodeBlock(this, SH4_TIMESLICE / 2)) + return false; +#if !defined(NO_MMU) + } + catch (SH4ThrownException& ex) { + Do_Exception(rpc, ex.expEvn, ex.callVect); return false; + } +#endif AnalyseBlock(this); diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 312ddcb3b..83981dde3 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -756,23 +756,6 @@ void DYNACALL mmu_WriteMem(u32 adr, T data) _vmem_writet(addr, data); } -u16 DYNACALL mmu_IReadMem16NoEx(u32 vaddr, u32 *exception_occurred) -{ - u32 addr; - u32 rv = mmu_instruction_translation(vaddr, addr); - if (rv != MMU_ERROR_NONE) - { - DoMMUException(vaddr, rv, MMU_TT_IREAD); - *exception_occurred = 1; - return 0; - } - else - { - *exception_occurred = 0; - return _vmem_ReadMem16(addr); - } -} - bool mmu_TranslateSQW(u32 adr, u32* out) { if (!settings.dreamcast.FullMMU) diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index a03195e6a..c9419321a 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -95,8 +95,6 @@ void DoMMUException(u32 addr, u32 error_code, u32 access_type); bool mmu_TranslateSQW(u32 addr, u32* mapped); - u16 DYNACALL mmu_IReadMem16NoEx(u32 adr, u32 *exception_occurred); - template T DYNACALL mmu_ReadMemNoEx(u32 adr, u32 *exception_occurred) { From 850635544774c04a6d31a56ebae324c4c831e23e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 13 Jun 2019 21:58:09 +0200 Subject: [PATCH 069/158] wrap aica ram to 8MB instead of only 2MB (dc) fix crash with GuruGuru Onsen 2 and HeadHunter --- core/hw/mem/_vmem.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index a1f42ff2b..6b86d421e 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -493,13 +493,13 @@ static void _vmem_set_p0_mappings() const vmem_mapping mem_mappings[] = { // P0/U0 {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused - {0x00800000, 0x00800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica - {0x00800000 + ARAM_SIZE, 0x02800000, 0, 0, false}, // unused - {0x02800000, 0x02800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror - {0x02800000 + ARAM_SIZE, 0x04000000, 0, 0, false}, // unused - {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) + {0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica + {0x01000000, 0x02800000, 0, 0, false}, // unused + {0x02800000, 0x03000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror + {0x03000000, 0x04000000, 0, 0, false}, // unused + {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) - {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror + {0x06000000, 0x07000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror {0x07000000, 0x08000000, 0, 0, false}, // 32 bit path (unused) mirror {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) @@ -570,10 +570,10 @@ bool _vmem_reserve() { const vmem_mapping mem_mappings[] = { // P1 {0x80000000, 0x80800000, 0, 0, false}, // Area 0 -> unused - {0x80800000, 0x80800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica - {0x80800000 + ARAM_SIZE, 0x82800000, 0, 0, false}, // unused - {0x82800000, 0x82800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror - {0x82800000 + ARAM_SIZE, 0x84000000, 0, 0, false}, // unused + {0x80800000, 0x81000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica + {0x81000000, 0x82800000, 0, 0, false}, // unused + {0x82800000, 0x83000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror + {0x83000000, 0x84000000, 0, 0, false}, // unused {0x84000000, 0x85000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0x85000000, 0x86000000, 0, 0, false}, // 32 bit path (unused) {0x86000000, 0x87000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror @@ -583,10 +583,10 @@ bool _vmem_reserve() { {0x90000000, 0xA0000000, 0, 0, false}, // Area 4-7 (unused) // P2 {0xA0000000, 0xA0800000, 0, 0, false}, // Area 0 -> unused - {0xA0800000, 0xA0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica - {0xA0800000 + ARAM_SIZE, 0xA2800000, 0, 0, false}, // unused - {0xA2800000, 0xA2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror - {0xA2800000 + ARAM_SIZE, 0xA4000000, 0, 0, false}, // unused + {0xA0800000, 0xA1000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica + {0xA1000000, 0xA2800000, 0, 0, false}, // unused + {0xA2800000, 0xA3000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror + {0xA3000000, 0xA4000000, 0, 0, false}, // unused {0xA4000000, 0xA5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0xA5000000, 0xA6000000, 0, 0, false}, // 32 bit path (unused) {0xA6000000, 0xA7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror @@ -596,10 +596,10 @@ bool _vmem_reserve() { {0xB0000000, 0xC0000000, 0, 0, false}, // Area 4-7 (unused) // P3 {0xC0000000, 0xC0800000, 0, 0, false}, // Area 0 -> unused - {0xC0800000, 0xC0800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica - {0xC0800000 + ARAM_SIZE, 0xC2800000, 0, 0, false}, // unused - {0xC2800000, 0xC2800000 + ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror - {0xC2800000 + ARAM_SIZE, 0xC4000000, 0, 0, false}, // unused + {0xC0800000, 0xC1000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica + {0xC1000000, 0xC2800000, 0, 0, false}, // unused + {0xC2800000, 0xC3000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // Aica mirror + {0xC3000000, 0xC4000000, 0, 0, false}, // unused {0xC4000000, 0xC5000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0xC5000000, 0xC6000000, 0, 0, false}, // 32 bit path (unused) {0xC6000000, 0xC7000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // VRAM mirror From 419370084ef766cc2ef68ab7e2bc748e486d0bda Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 14 Jun 2019 23:34:18 +0200 Subject: [PATCH 070/158] rec-x86: ssa support --- core/rec-x86/rec_x86_driver.cpp | 32 +- core/rec-x86/rec_x86_il.cpp | 591 ++++++++++---------------------- 2 files changed, 201 insertions(+), 422 deletions(-) diff --git a/core/rec-x86/rec_x86_driver.cpp b/core/rec-x86/rec_x86_driver.cpp index 727cf4eee..3ddc6832b 100644 --- a/core/rec-x86/rec_x86_driver.cpp +++ b/core/rec-x86/rec_x86_driver.cpp @@ -613,13 +613,31 @@ enum mem_op_type SZ_64F, }; +static DYNACALL s32 ReadMem8SX32(u32 addr) +{ + return (s32)(s8)ReadMem8(addr); +} + +static DYNACALL s32 ReadMem16SX32(u32 addr) +{ + return (s32)(s16)ReadMem16(addr); +} + void gen_hande(u32 w, u32 sz, u32 mode) { +#ifdef NO_MMU static const x86_ptr_imm rwm[2][5]= { - {x86_ptr_imm(&_vmem_ReadMem8SX32),x86_ptr_imm(&_vmem_ReadMem16SX32),x86_ptr_imm(&ReadMem32),x86_ptr_imm(&ReadMem32),x86_ptr_imm(&ReadMem64),}, - {x86_ptr_imm(&WriteMem8),x86_ptr_imm(&WriteMem16),x86_ptr_imm(&WriteMem32),x86_ptr_imm(&WriteMem32),x86_ptr_imm(&WriteMem64),} + {x86_ptr_imm(&_vmem_ReadMem8SX32),x86_ptr_imm(&_vmem_ReadMem16SX32),x86_ptr_imm(&_vmem_ReadMem32),x86_ptr_imm(&_vmem_ReadMem32),x86_ptr_imm(&_vmem_ReadMem64),}, + {x86_ptr_imm(&_vmem_WriteMem8),x86_ptr_imm(&_vmem_WriteMem16),x86_ptr_imm(&_vmem_WriteMem32),x86_ptr_imm(&_vmem_WriteMem32),x86_ptr_imm(&_vmem_WriteMem64),} }; +#else + x86_ptr_imm rwm[2][5]= + { + {x86_ptr_imm(&ReadMem8SX32),x86_ptr_imm(&ReadMem16SX32),x86_ptr_imm(ReadMem32),x86_ptr_imm(ReadMem32),x86_ptr_imm(ReadMem64),}, + {x86_ptr_imm(WriteMem8),x86_ptr_imm(WriteMem16),x86_ptr_imm(WriteMem32),x86_ptr_imm(WriteMem32),x86_ptr_imm(WriteMem64),} + }; +#endif static const x86_opcode_class opcl_i[2][3]= { @@ -746,6 +764,12 @@ void* mem_code[3][2][5]; void ngen_init() { ngen_FailedToFindBlock = &ngen_FailedToFindBlock_; +} + +static void gen_handles() +{ + if (mem_code_end != 0) + return; //Setup emitter x86e = new x86_block(); @@ -777,12 +801,11 @@ void ngen_init() x86e->Generate(); delete x86e; - - emit_SetBaseAddr(); } void ngen_ResetBlocks() { + mem_code_end = 0; } void ngen_GetFeatures(ngen_features* dst) @@ -794,6 +817,7 @@ void ngen_GetFeatures(ngen_features* dst) RuntimeBlockInfo* ngen_AllocateBlock() { + gen_handles(); return new DynaRBI(); } diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp index f24e4f081..3778baf37 100644 --- a/core/rec-x86/rec_x86_il.cpp +++ b/core/rec-x86/rec_x86_il.cpp @@ -12,20 +12,31 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ verify(reg.IsAllocg(op->rs1._reg)); verify(reg.IsAllocg(op->rd._reg)); - if (has_wb && reg.mapg(op->rs1)!=reg.mapg(op->rd)) + x86_reg rs2; + if (op->rs2.is_r32i()) { - x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + if (has_wb && reg.mapg(op->rs2) == reg.mapg(op->rd)) + { + x86e->Emit(op_mov32, EAX, reg.mapg(op->rs2)); + rs2 = EAX; + } + else + { + rs2 = reg.mapg(op->rs2); + } + } + if (has_wb && reg.mapg(op->rs1) != reg.mapg(op->rd)) + { + x86e->Emit(op_mov32, reg.mapg(op->rd), reg.mapg(op->rs1)); } if (has_imm && op->rs2.is_imm()) { - x86e->Emit(natop,has_wb?reg.mapg(op->rd):reg.mapg(op->rs1),op->rs2._imm); + x86e->Emit(natop, has_wb ? reg.mapg(op->rd) : reg.mapg(op->rs1), op->rs2._imm); } else if (op->rs2.is_r32i()) { - verify(reg.IsAllocg(op->rs2._reg)); - - x86e->Emit(natop,has_wb?reg.mapg(op->rd):reg.mapg(op->rs1),reg.mapg(op->rs2)); + x86e->Emit(natop, has_wb ? reg.mapg(op->rd) : reg.mapg(op->rs1), rs2); } else { @@ -37,21 +48,37 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ void ngen_fp_bin(shil_opcode* op,x86_opcode_class natop) { verify(reg.IsAllocf(op->rs1)); - verify(reg.IsAllocf(op->rs2)); verify(reg.IsAllocf(op->rd)); - if (op->rd._reg!=op->rs1._reg) - x86e->Emit(op_movss,reg.mapf(op->rd),reg.mapf(op->rs1)); - + x86_reg rs2; if (op->rs2.is_r32f()) { - x86e->Emit(natop,reg.mapf(op->rd),reg.mapf(op->rs2)); + if (reg.mapf(op->rs2) == reg.mapf(op->rd)) + { + x86e->Emit(op_movss, XMM0, reg.mapf(op->rs2)); + rs2 = XMM0; + } + else + { + rs2 = reg.mapf(op->rs2); + } + } + else if (op->rs2.is_imm()) + { + //x86e->Emit(op_movss, XMM0, x86_ptr(&reinterpret_cast(op->rs2._imm))); + x86e->Emit(op_mov32, EAX, op->rs2._imm); + x86e->Emit(op_movd_xmm_from_r32, XMM0, EAX); + rs2 = XMM0; } else { printf("%d \n",op->rs2.type); verify(false); } + if (op->rd._reg != op->rs1._reg) + x86e->Emit(op_movss, reg.mapf(op->rd), reg.mapf(op->rs1)); + + x86e->Emit(natop, reg.mapf(op->rd), rs2); // verify(has_wb); //x86e->Emit(op_movss,op->rd.reg_ptr(),XMM0); } @@ -106,7 +133,7 @@ void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp) verify(par->is_reg()); x86e->Emit(op_push,(unat)par->reg_ptr()); - +/* FIXME wtf is this? for (u32 ri=0; ri<(*par).count(); ri++) { if (reg.IsAllocf(*par,ri)) @@ -119,7 +146,7 @@ void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp) verify(!reg.IsAllocAny((Sh4RegType)(par->_reg+ri))); } } - +*/ ngen_CC_BytesPushed+=4; break; @@ -224,36 +251,37 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool { case shop_readm: { - void* fuct=0; - bool isram=false; + void* fuct = 0; + bool isram = false; verify(op->rs1.is_imm() || op->rs1.is_r32i()); verify(op->rs1.is_imm() || reg.IsAllocg(op->rs1)); verify(op->rs3.is_null() || op->rs3.is_imm() || reg.IsAllocg(op->rs3)); - for (u32 i=0;ird.count();i++) + for (u32 i = 0; i < op->rd.count(); i++) { - verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg+i))); + verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg + i))); } - u32 size=op->flags&0x7f; + u32 size = op->flags & 0x7f; if (op->rs1.is_imm()) { - if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_const,1); - void* ptr=_vmem_read_const(op->rs1._imm,isram,size); + if (prof.enable) x86e->Emit(op_add32, &prof.counters.shil.readm_const, 1); + void* ptr = _vmem_read_const(op->rs1._imm, isram, size); if (isram) { #ifdef PROF2 - x86e->Emit(op_add32,&srmlu,1); + x86e->Emit(op_add32, &srmlu, 1); #endif - if (size==1) - x86e->Emit(op_movsx8to32,EAX,ptr); - else if (size==2) - x86e->Emit(op_movsx16to32,EAX,ptr); - else if (size==4) + if (size == 1) + x86e->Emit(op_movsx8to32, EAX, ptr); + else if (size == 2) + x86e->Emit(op_movsx16to32, EAX, ptr); + else if (size == 4) { - x86e->Emit(op_mov32,EAX,ptr); + x86e->Emit(op_mov32, EAX, ptr); +#if 0 //this is a pretty good sieve, but its not perfect. //whitelisting is much better, but requires side channel data //Page locking w/ invalidation is another strategy we can try (leads to 'excessive' @@ -282,6 +310,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool #endif } } +#endif } else if (size==8) { @@ -321,146 +350,6 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool } else if (prof.enable) x86e->Emit(op_add32,&prof.counters.shil.readm_reg,1); -#if 0 - if (op->flags==0x431 || op->flags==0x440) - { - verify(!reg.IsAllocAny(op->rd)); - verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+1))); - verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+2))); - verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+3))); - - x86e->Emit(op_add32,&vrml_431,1); - x86e->Emit(op_mov32,EDX,ECX); - x86e->Emit(op_and32,EDX,0x1FFFFFFF); - x86e->Emit(op_movups,XMM0,x86_mrm(EDX,x86_ptr(virt_ram_base))); - x86e->Emit(op_movaps,op->rd.reg_ptr(),XMM0); - - if (op->flags==0x431) - x86e->Emit(op_mov32,op->rd.reg_ptr()+3,0x3f800000); - else if (op->flags==0x430) - x86e->Emit(op_mov32,op->rd.reg_ptr()+3,0); - - break; - } - - bool vect=op->flags&0x80; - - if (vect) - { - u32 sz=size; - //x86e->Emit(op_add32,&cvld,sz/(op->flags&0x100?8:4)); - x86e->Emit(op_add32,&vrml_431,sz/(op->flags&0x100?8:4)*2); - verify(sz==8 || sz==12 || sz==16 || sz==32 || sz==64); - - void** vmap,** funct; - _vmem_get_ptrs(4,false,&vmap,&funct); - x86e->Emit(op_mov32,EAX,ECX); - x86e->Emit(op_shr32,EAX,24); - x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); - - x86e->Emit(op_test32,EAX,~0x7F); - x86e->Emit(op_jz,x86_ptr_imm::create(op->flags)); - x86e->Emit(op_xchg32,ECX,EAX); - x86e->Emit(op_shl32,EAX,ECX); - x86e->Emit(op_shr32,EAX,ECX); - x86e->Emit(op_and32,ECX,~0x7F); - - int i=0; - for (i=0;(i+16)<=sz;i+=16) - { - x86e->Emit(op_movups,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); - if (op->rd._reg&3) - x86e->Emit(op_movups,op->rd.reg_ptr()+i/4,XMM0); - else - x86e->Emit(op_movaps,op->rd.reg_ptr()+i/4,XMM0); - } - for (;(i+8)<=sz;i+=8) - { - x86e->Emit(op_movlps,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); - x86e->Emit(op_movlps,op->rd.reg_ptr()+i/4,XMM0); - } - for (;(i+4)<=sz;i+=4) - { - x86e->Emit(op_movss,XMM0,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i))); - x86e->Emit(op_movss,op->rd.reg_ptr()+i/4,XMM0); - } - - verify(i==sz); - - break; - - } - - if (optimise) - { - if (staging || op->flags&0x80000000) - { - - //opt disabled for now - op->flags|=0x80000000; - - x86_Label* _ram=x86e->CreateLabel(false,8); - void** vmap,** funct; - _vmem_get_ptrs(4,false,&vmap,&funct); - x86e->Emit(op_mov32,EAX,ECX); - x86e->Emit(op_shr32,EAX,24); - x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); - - x86e->Emit(op_test32,EAX,~0x7F); - x86e->Emit(op_jnz,_ram); - - if (staging) - { - x86e->Emit(op_and32,&op->flags,~0x80000000); - } - else - { - //x86e->Emit(op_int3); - } - - x86e->MarkLabel(_ram); - } - - if ( !staging) - { - if (op->flags & 0x80000000) - { -#ifdef PROF2 - x86e->Emit(op_add32,&rmlu,1); -#endif - if (true) - { - u32 sz=op->flags&0x7f; - if (sz!=8) - { - x86e->Emit(op_mov32,EDX,ECX); - x86e->Emit(op_and32,EDX,0x1FFFFFFF); - if (sz==1) - { - x86e->Emit(op_movsx8to32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); - } - else if (sz==2) - { - x86e->Emit(op_movsx16to32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); - } - else if (sz==4) - { - x86e->Emit(op_mov32,EAX,x86_mrm(EDX,x86_ptr(virt_ram_base))); - } - isram=true; - } - } - - } -#ifdef PROF2 - else - { - x86e->Emit(op_add32,&rmls,1); - } -#endif - } - } -#endif #if 1 //new code ... //yay ... @@ -514,21 +403,21 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool switch(size) { case 1: - if (!fuct) fuct=reinterpret_cast(&ReadMem8); + if (!fuct) fuct=reinterpret_cast(ReadMem8); x86e->Emit(op_call,x86_ptr_imm(fuct)); x86e->Emit(op_movsx8to32,EAX,EAX); break; case 2: - if (!fuct) fuct=reinterpret_cast(&ReadMem16); + if (!fuct) fuct=reinterpret_cast(ReadMem16); x86e->Emit(op_call,x86_ptr_imm(fuct)); x86e->Emit(op_movsx16to32,EAX,EAX); break; case 4: - if (!fuct) fuct=reinterpret_cast(&ReadMem32); + if (!fuct) fuct=reinterpret_cast(ReadMem32); x86e->Emit(op_call,x86_ptr_imm(fuct)); break; case 8: - if (!fuct) fuct=reinterpret_cast(&ReadMem64); + if (!fuct) fuct=reinterpret_cast(ReadMem64); x86e->Emit(op_call,x86_ptr_imm(fuct)); break; default: @@ -563,7 +452,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool u32 size=op->flags&0x7f; verify(reg.IsAllocg(op->rs1) || op->rs1.is_imm()); - verify(op->rs2.is_r32() || (op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1))); + verify(op->rs2.is_imm() || op->rs2.is_r32() || (op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1))); if (op->rs1.is_imm() && size<=4) { @@ -572,21 +461,25 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool void* ptr=_vmem_read_const(op->rs1._imm,isram,size); if (isram) { - if (size<=2) - x86e->Emit(op_mov32,EAX,reg.mapg(op->rs2)); - if (size==1) - x86e->Emit(op_mov8,ptr,EAX); - else if (size==2) - x86e->Emit(op_mov16,ptr,EAX); - else if (size==4) + if (op->rs2.is_imm()) + x86e->Emit(op_mov32, EAX, op->rs2._imm); + else if (size <= 2) + x86e->Emit(op_mov32, EAX, reg.mapg(op->rs2)); + if (size == 1) + x86e->Emit(op_mov8, ptr, EAX); + else if (size == 2) + x86e->Emit(op_mov16, ptr, EAX); + else if (op->rs2.is_imm()) + x86e->Emit(op_mov32, ptr, EAX); + else if (size == 4) { if (op->rs2.is_r32i()) - x86e->Emit(op_mov32,ptr,reg.mapg(op->rs2)); + x86e->Emit(op_mov32, ptr, reg.mapg(op->rs2)); else - x86e->Emit(op_movss,ptr,reg.mapf(op->rs2)); + x86e->Emit(op_movss, ptr, reg.mapf(op->rs2)); } - else if (size==8) + else if (size == 8) { die("A"); } @@ -622,211 +515,33 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool //new code ... //yay ... - int Lsz=0; - int sz=size; - if (sz==2) Lsz=1; - if (sz==4 && op->rs2.is_r32i()) Lsz=2; - if (sz==4 && op->rs2.is_r32f()) Lsz=3; - if (sz==8) Lsz=4; + int Lsz = 0; + int sz = size; + if (sz == 2) Lsz = 1; + if (sz == 4 && (op->rs2.is_r32i() || op->rs2.is_imm())) Lsz = 2; + if (sz == 4 && op->rs2.is_r32f()) Lsz = 3; + if (sz == 8) Lsz = 4; //x86e->Emit(op_int3); //if (Lsz==0) { - - if (Lsz<=2) - x86e->Emit(op_mov32,EDX,reg.mapg(op->rs2)); + if (op->rs2.is_imm()) + x86e->Emit(op_mov32, EDX, op->rs2._imm); + else if (Lsz <= 2) + x86e->Emit(op_mov32, EDX, reg.mapg(op->rs2)); else { - x86e->Emit(op_movss,XMM0,reg.mapfv(op->rs2,0)); - if (Lsz==4) - x86e->Emit(op_movss,XMM1,reg.mapfv(op->rs2,1)); + x86e->Emit(op_movss, XMM0, reg.mapfv(op->rs2, 0)); + if (Lsz == 4) + x86e->Emit(op_movss, XMM1, reg.mapfv(op->rs2, 1)); } reg.FreezeXMM(); - x86e->Emit(op_call,x86_ptr_imm(mem_code[2][1][Lsz])); + x86e->Emit(op_call, x86_ptr_imm(mem_code[2][1][Lsz])); reg.ThawXMM(); break; } -#endif -#ifdef OPTIMIZATION_GRAVEYARD - die("woohoo"); - /* - if (size==8 && optimise) - { - verify(!reg.IsAllocAny(op->rd)); - verify(!reg.IsAllocAny((Sh4RegType)(op->rd._reg+1))); - - x86e->Emit(op_mov32,EDX,ECX); - x86e->Emit(op_and32,EDX,0x1FFFFFFF); - x86e->Emit(op_movlps,XMM0,op->rs2.reg_ptr()); - x86e->Emit(op_movlps,x86_mrm(EDX,x86_ptr(virt_ram_base)),XMM0); - break; - }*/ - - bool vect=op->flags&0x80; - - if (!vect && size<=8) - { - if (size!=8) - { - if (reg.IsAllocg(op->rs2)) - { - x86e->Emit(op_mov32,EDX,reg.mapg(op->rs2)); - } - else if (reg.IsAllocf(op->rs2)) - { - x86e->Emit(op_movd_xmm_to_r32,EDX,reg.mapf(op->rs2)); - } - else - { - die("Must not happen\n"); - } - } - else - { - verify(op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1)); - - x86e->Emit(op_sub32,ESP,8); - //[ESP+4]=rs2[1]//-4 +8= +4 - //[ESP+0]=rs2[0]//-8 +8 = 0 - x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(+4)),reg.mapfv(op->rs2,1)); - x86e->Emit(op_movss,x86_mrm(ESP,x86_ptr::create(-0)),reg.mapfv(op->rs2,0)); - } - - - - if (optimise) - { - if (staging || op->flags&0x80000000) - { - - //opt disabled for now - op->flags|=0x80000000; - x86_Label* _ram=x86e->CreateLabel(false,8); - void** vmap,** funct; - _vmem_get_ptrs(4,false,&vmap,&funct); - x86e->Emit(op_mov32,EAX,ECX); - x86e->Emit(op_shr32,EAX,24); - x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); - - x86e->Emit(op_test32,EAX,~0x7F); - x86e->Emit(op_jnz,_ram); - - if (staging) - { - x86e->Emit(op_and32,&op->flags,~0x80000000); - } - else - { - //x86e->Emit(op_int3); - } - - x86e->MarkLabel(_ram); - } - - - if (!staging) - { - if (op->flags & 0x80000000) - { -#ifdef PROF2 - x86e->Emit(op_add32,&wmlu,1); -#endif - if (false && size<4) - { - x86e->Emit(op_mov32,EAX,ECX); - x86e->Emit(op_and32,EAX,0x1FFFFFFF); - - if (size==1) - { - x86e->Emit(op_mov8,x86_mrm(EAX,x86_ptr(virt_ram_base)),EDX); - } - else if (size==2) - { - x86e->Emit(op_mov16,x86_mrm(EAX,x86_ptr(virt_ram_base)),EDX); - } - else if (size==4) - { - x86e->Emit(op_mov32,x86_mrm(EAX,x86_ptr(virt_ram_base)),EAX); - } - break; - } - - } -#ifdef PROF2 - else - x86e->Emit(op_add32,&wmls,1); -#endif - } - } - } - - if (vect) - { - u32 sz=op->flags&0x7f; - x86e->Emit(op_add32,&vrml_431,sz/(op->flags&0x100?8:4)*5); - verify(sz==8 || sz==12 || sz==16 || sz==32 || sz==64); - - void** vmap,** funct; - _vmem_get_ptrs(4,false,&vmap,&funct); - x86e->Emit(op_mov32,EAX,ECX); - x86e->Emit(op_shr32,EAX,24); - x86e->Emit(op_mov32,EAX,x86_mrm(EAX,sib_scale_4,vmap)); - - x86e->Emit(op_test32,EAX,~0x7F); - x86e->Emit(op_jz,x86_ptr_imm::create(op->flags)); - x86e->Emit(op_xchg32,ECX,EAX); - x86e->Emit(op_shl32,EAX,ECX); - x86e->Emit(op_shr32,EAX,ECX); - x86e->Emit(op_and32,ECX,~0x7F); - - u32 i=0; - for (; (i+16)<=sz; i+=16) - { - if (op->rs2._reg&3) - x86e->Emit(op_movups,XMM0,op->rs2.reg_ptr()+i/4); - else - x86e->Emit(op_movaps,XMM0,op->rs2.reg_ptr()+i/4); - - x86e->Emit(op_movups,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); - } - for (; (i+8)<=sz; i+=8) - { - x86e->Emit(op_movlps,XMM0,op->rs2.reg_ptr()+i/4); - x86e->Emit(op_movlps,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); - } - for (; (i+4)<=sz; i+=4) - { - x86e->Emit(op_movss,XMM0,op->rs2.reg_ptr()+i/4); - x86e->Emit(op_movss,x86_mrm(EAX,ECX,sib_scale_1,x86_ptr::create(i)),XMM0); - } - - verify(i==sz); - } - else - { - - reg.FreezeXMM(); - switch(size) - { - case 1: - x86e->Emit(op_call,x86_ptr_imm(&WriteMem8)); - break; - case 2: - x86e->Emit(op_call,x86_ptr_imm(&WriteMem16)); - break; - case 4: - x86e->Emit(op_call,x86_ptr_imm(&WriteMem32)); - break; - case 8: - x86e->Emit(op_call,x86_ptr_imm(&WriteMem64)); - break; - default: - verify(false); - } - reg.ThawXMM(); - } #endif } done_writem: @@ -903,14 +618,12 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool if (op->rd.is_r32i()) { x86e->Emit(op_mov32,reg.mapg(op->rd),op->rs1._imm); - // x86e->Emit(op_add32,&rdmt[4],1); } else { //verify(!reg.IsAllocAny(op->rd)); x86e->Emit(op_mov32,EAX,op->rs1._imm); x86e->Emit(op_movd_xmm_from_r32,reg.mapf(op->rd),EAX); - // x86e->Emit(op_add32,&rdmt[5],1); } } else if (op->rs1.is_r32()) @@ -922,7 +635,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool if (reg.IsAllocf(op->rs1)) type|=2; - // x86e->Emit(op_add32,&rdmt[type],1); + switch(type) { case 0: //reg=reg @@ -964,7 +677,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool case shop_xor: ngen_Bin(op,op_xor32); break; case shop_add: ngen_Bin(op,op_add32); break; case shop_sub: ngen_Bin(op,op_sub32); break; - case shop_ror: ngen_Bin(op,op_ror32); break; + case shop_ror: ngen_Bin(op,op_ror32); break; case shop_shl: case shop_shr: @@ -978,9 +691,13 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool case shop_rocr: case shop_rocl: { - x86e->Emit(op_sar32,reg.mapg(op->rs2),1); - x86e->Emit(op->op==shop_rocr?op_rcr32:op_rcl32,reg.mapg(op->rd),1); - x86e->Emit(op_rcl32,reg.mapg(op->rd2),1); + x86e->Emit(op_mov32, EAX, reg.mapg(op->rs2)); + x86e->Emit(op_sar32, EAX, 1); + if (reg.mapg(op->rd) != reg.mapg(op->rs1)) + x86e->Emit(op_mov32, reg.mapg(op->rd), reg.mapg(op->rs1)); + x86e->Emit(op->op == shop_rocr ? op_rcr32 : op_rcl32, reg.mapg(op->rd), 1); + x86e->Emit(op_mov32, reg.mapg(op->rd2), 0); + x86e->Emit(op_rcl32, reg.mapg(op->rd2), 1); } break; @@ -1001,11 +718,43 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool case shop_adc: { - x86e->Emit(op_sar32,reg.mapg(op->rs3),1); - if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) - x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); - x86e->Emit(op_adc32,reg.mapg(op->rd),reg.mapg(op->rs2)); - x86e->Emit(op_rcl32,reg.mapg(op->rd2),1); + x86e->Emit(op_mov32, EAX, reg.mapg(op->rs3)); + x86e->Emit(op_sar32, EAX, 1); + x86_reg rs1; + if (op->rs1.is_imm()) + { + rs1 = ECX; + x86e->Emit(op_mov32, ECX, op->rs1._imm); + } + else + { + rs1 = reg.mapg(op->rs1); + } + x86_reg rs2; + if (op->rs2.is_imm()) + { + rs2 = EDX; + x86e->Emit(op_mov32, EDX, op->rs2._imm); + } + else + { + rs2 = reg.mapg(op->rs2); + } + if (reg.mapg(op->rd) != rs1) + { + if (reg.mapg(op->rd) == rs2) + { + // Invert the operands + rs2 = rs1; + } + else + { + x86e->Emit(op_mov32, reg.mapg(op->rd), rs1); + } + } + x86e->Emit(op_adc32, reg.mapg(op->rd), rs2); + x86e->Emit(op_mov32, reg.mapg(op->rd2), 0); + x86e->Emit(op_rcl32, reg.mapg(op->rd2), 1); } break; @@ -1013,15 +762,19 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool case shop_shad: case shop_shld: { - verify(reg.IsAllocg(op->rs1)); verify(op->rs2.is_imm() || reg.IsAllocg(op->rs2)); verify(reg.IsAllocg(op->rd)); - x86_opcode_class sl32=op->op==shop_shad?op_sal32:op_shl32; - x86_opcode_class sr32=op->op==shop_shad?op_sar32:op_shr32; + x86_opcode_class sl32 = op->op == shop_shad ? op_sal32 : op_shl32; + x86_opcode_class sr32 = op->op == shop_shad ? op_sar32 : op_shr32; - if (reg.mapg(op->rd)!=reg.mapg(op->rs1)) - x86e->Emit(op_mov32,reg.mapg(op->rd),reg.mapg(op->rs1)); + if (op->rs1.is_imm()) + x86e->Emit(op_mov32, reg.mapg(op->rd), op->rs1._imm); + else if (reg.mapg(op->rd) != reg.mapg(op->rs1)) + { + verify(reg.mapg(op->rs2) != reg.mapg(op->rd)); + x86e->Emit(op_mov32, reg.mapg(op->rd), reg.mapg(op->rs1)); + } if (op->rs2.is_imm()) { @@ -1080,7 +833,6 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool } break; - case shop_neg: ngen_Unary(op,op_neg32); break; case shop_not: ngen_Unary(op,op_not32); break; @@ -1120,7 +872,6 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool } break; - case shop_mul_u16: case shop_mul_s16: case shop_mul_i32: @@ -1128,7 +879,6 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool case shop_mul_s64: { verify(reg.IsAllocg(op->rs1)); - verify(reg.IsAllocg(op->rs2)); verify(reg.IsAllocg(op->rd)); x86_opcode_class opdt[]={op_movzx16to32,op_movsx16to32,op_mov32,op_mov32,op_mov32}; @@ -1138,7 +888,21 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool u32 opofs=op->op-shop_mul_u16; x86e->Emit(opdt[opofs],EAX,reg.mapg(op->rs1)); - x86e->Emit(opdt[opofs],EDX,reg.mapg(op->rs2)); + if (op->rs2.is_reg()) + x86e->Emit(opdt[opofs], EDX, reg.mapg(op->rs2)); + else + { + verify(op->rs2.is_imm()); + if (opofs <= 2) + { + x86e->Emit(op_mov32, EDX, op->rs2._imm); + x86e->Emit(opdt[opofs], EDX, EDX); + } + else + { + x86e->Emit(opdt[opofs], EDX, op->rs2._imm); + } + } x86e->Emit(opmt[opofs],EDX); x86e->Emit(op_mov32,reg.mapg(op->rd),EAX); @@ -1148,17 +912,12 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool } break; - //fpu case shop_fadd: case shop_fsub: case shop_fmul: case shop_fdiv: { - verify(reg.IsAllocf(op->rs1)); - verify(reg.IsAllocf(op->rs2)); - verify(reg.IsAllocf(op->rd)); - const x86_opcode_class opcds[]= { op_addss, op_subss, op_mulss, op_divss }; ngen_fp_bin(op,opcds[op->op-shop_fadd]); } @@ -1171,8 +930,9 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool static DECL_ALIGN(16) u32 AND_ABS_MASK[4] = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; - verify(op->rd._reg==op->rs1._reg); - x86e->Emit(op_pand,reg.mapf(op->rd),AND_ABS_MASK); + if (op->rd._reg != op->rs1._reg) + x86e->Emit(op_movss, reg.mapf(op->rd), reg.mapf(op->rs1)); + x86e->Emit(op_pand, reg.mapf(op->rd), AND_ABS_MASK); } break; @@ -1183,12 +943,13 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool static DECL_ALIGN(16) u32 XOR_NEG_MASK[4] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; - verify(op->rd._reg==op->rs1._reg); - x86e->Emit(op_pxor,reg.mapf(op->rd),XOR_NEG_MASK); + if (op->rd._reg != op->rs1._reg) + x86e->Emit(op_movss, reg.mapf(op->rd), reg.mapf(op->rs1)); + x86e->Emit(op_pxor, reg.mapf(op->rd), XOR_NEG_MASK); } break; - case shop_fsca: + case shop_fsca: // FIXME the canonical version doesn't work because components of the resulting vector are allocated (mapfv) { verify(op->rs1.is_r32i()); @@ -1250,7 +1011,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool //x86e->Emit(op_movss ,op->rd.reg_ptr(),XMM0); } break; - + case shop_ftrv: { #ifdef PROF2 @@ -1339,7 +1100,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool #endif } break; - + case shop_fmac: { verify(reg.IsAllocf(op->rs1)); @@ -1453,10 +1214,11 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(op->rs1.is_r32f()); verify(reg.IsAllocg(op->rd)); verify(reg.IsAllocf(op->rs1)); - static f32 sse_ftrc_saturate = 2147483520.0f; // IEEE 754: 0x4effffff - x86e->Emit(op_movaps, XMM0, reg.mapf(op->rs1)); - x86e->Emit(op_minss, XMM0, &sse_ftrc_saturate); - x86e->Emit(op_cvttss2si, reg.mapg(op->rd), XMM0); + + x86e->Emit(op_cvttss2si, reg.mapg(op->rd), reg.mapf(op->rs1)); + x86e->Emit(op_mov32, EAX, 0x7fffffff); + x86e->Emit(op_cmp32, reg.mapg(op->rd), 0x7fffff80); // 2147483520.0f + x86e->Emit(op_cmovge32, reg.mapg(op->rd), EAX); } break; @@ -1525,15 +1287,8 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool #endif default: -#if 1 || CANONICAL_TEST shil_chf[op->op](op); break; -#endif - - -defaulty: - printf("OH CRAP %d\n",op->op); - verify(false); } } From 3d8b0df7898022d437ce69eba668ce3c0e120b62 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 18 Jun 2019 13:16:42 +0200 Subject: [PATCH 071/158] rec-x64: setpeq native impl. Fix imm mem write for byte and short Optimize fneg, fabs and sub Fix cvt_f2i Fix fsca with imm arg --- core/rec-x64/rec_x64.cpp | 111 +++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 40 deletions(-) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 21a207d52..4f924cc39 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -418,11 +418,26 @@ public: case shop_jdyn: { Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); - Xbyak::Reg32 rs1 = regalloc.MapRegister(op.rs1); - if (rd != rs1) - mov(rd, rs1); - if (op.rs2.is_imm()) - add(rd, op.rs2._imm); + // This shouldn't happen since the block type would have been changed to static. + // But it doesn't hurt and is handy when partially disabling ssa for testing + if (op.rs1.is_imm()) + { + if (op.rs2.is_imm()) + mov(rd, op.rs1._imm + op.rs2._imm); + else + { + mov(rd, op.rs1._imm); + verify(op.rs2.is_null()); + } + } + else + { + Xbyak::Reg32 rs1 = regalloc.MapRegister(op.rs1); + if (rd != rs1) + mov(rd, rs1); + if (op.rs2.is_imm()) + add(rd, op.rs2._imm); + } } break; @@ -776,11 +791,31 @@ public: movzx(regalloc.MapRegister(op.rd), al); } break; -/* + case shop_setpeq: - // TODO + { + Xbyak::Label end; + mov(ecx, regalloc.MapRegister(op.rs1)); + if (op.rs2.is_r32i()) + xor_(ecx, regalloc.MapRegister(op.rs2)); + else + xor_(ecx, op.rs2._imm); + + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + mov(rd, 1); + test(ecx, 0xFF000000); + je(end); + test(ecx, 0x00FF0000); + je(end); + test(ecx, 0x0000FF00); + je(end); + xor_(rd, rd); + test(cl, cl); + sete(rd.cvt8()); + L(end); + } break; -*/ + case shop_mul_u16: movzx(eax, regalloc.MapRegister(op.rs1).cvt16()); if (op.rs2.is_reg()) @@ -952,18 +987,14 @@ public: break; case shop_fabs: - if (regalloc.mapf(op.rd) != regalloc.mapf(op.rs1)) - movss(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs1)); - mov(rcx, (size_t)&float_abs_mask); - movss(xmm0, dword[rcx]); - pand(regalloc.MapXRegister(op.rd), xmm0); + movd(eax, regalloc.MapXRegister(op.rs1)); + and_(eax, 0x7FFFFFFF); + movd(regalloc.MapXRegister(op.rd), eax); break; case shop_fneg: - if (regalloc.mapf(op.rd) != regalloc.mapf(op.rs1)) - movss(regalloc.MapXRegister(op.rd), regalloc.MapXRegister(op.rs1)); - mov(rcx, (size_t)&float_sign_mask); - movss(xmm0, dword[rcx]); - pxor(regalloc.MapXRegister(op.rd), xmm0); + movd(eax, regalloc.MapXRegister(op.rs1)); + xor_(eax, 0x80000000); + movd(regalloc.MapXRegister(op.rd), eax); break; case shop_fsqrt: @@ -1033,7 +1064,10 @@ public: break; case shop_fsca: - movzx(rax, regalloc.MapRegister(op.rs1).cvt16()); + if (op.rs1.is_imm()) + mov(rax, op.rs1._imm & 0xFFFF); + else + movzx(rax, regalloc.MapRegister(op.rs1).cvt16()); mov(rcx, (uintptr_t)&sin_table); #ifdef EXPLODE_SPANS movss(regalloc.MapXRegister(op.rd, 0), dword[rcx + rax * 8]); @@ -1149,10 +1183,13 @@ public: break; case shop_cvt_f2i_t: - mov(rcx, (uintptr_t)&cvtf2i_pos_saturation); - movss(xmm0, dword[rcx]); - minss(xmm0, regalloc.MapXRegister(op.rs1)); - cvttss2si(regalloc.MapRegister(op.rd), xmm0); + { + Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); + cvttss2si(rd, regalloc.MapXRegister(op.rs1)); + mov(eax, 0x7fffffff); + cmp(rd, 0x7fffff80); // 2147483520.0f + cmovge(rd, eax); + } break; case shop_cvt_i2f_n: case shop_cvt_i2f_z: @@ -1623,27 +1660,27 @@ private: { case 1: if (regalloc.IsAllocg(op.rs2)) - mov(byte[rax], regalloc.MapRegister(op.rs2)); + mov(byte[rax], regalloc.MapRegister(op.rs2).cvt8()); else if (op.rs2.is_imm()) - mov(byte[rax], op.rs2._imm); + mov(byte[rax], (u8)op.rs2._imm); else { mov(rcx, (uintptr_t)op.rs2.reg_ptr()); - mov(ecx, dword[rcx]); - mov(byte[rax], ecx); + mov(cl, byte[rcx]); + mov(byte[rax], cl); } break; case 2: if (regalloc.IsAllocg(op.rs2)) - mov(word[rax], regalloc.MapRegister(op.rs2)); + mov(word[rax], regalloc.MapRegister(op.rs2).cvt16()); else if (op.rs2.is_imm()) - mov(word[rax], op.rs2._imm); + mov(word[rax], (u16)op.rs2._imm); else { mov(rcx, (uintptr_t)op.rs2.reg_ptr()); - mov(ecx, dword[rcx]); - mov(word[rax], ecx); + mov(cx, word[rcx]); + mov(word[rax], cx); } break; @@ -1678,6 +1715,7 @@ private: mov(rcx, qword[rcx]); mov(qword[rax], rcx); } + break; default: die("Invalid immediate size"); @@ -1879,9 +1917,8 @@ private: if (op.op == shop_sub) { // This op isn't commutative - mov(ecx, regalloc.MapRegister(op.rs2)); - mov(rd, regalloc.MapRegister(op.rs1)); - (this->*natop)(rd, ecx); + neg(rd); + add(rd, regalloc.MapRegister(op.rs1)); return; } @@ -2102,18 +2139,12 @@ private: Xbyak::util::Cpu cpu; size_t current_opid; Xbyak::Label exit_block; - static const u32 float_sign_mask; - static const u32 float_abs_mask; - static const f32 cvtf2i_pos_saturation; static const u32 read_mem_op_size; static const u32 write_mem_op_size; public: static u32 mem_access_offset; }; -const u32 BlockCompiler::float_sign_mask = 0x80000000; -const u32 BlockCompiler::float_abs_mask = 0x7fffffff; -const f32 BlockCompiler::cvtf2i_pos_saturation = 2147483520.0f; // IEEE 754: 0x4effffff; const u32 BlockCompiler::read_mem_op_size = 30; const u32 BlockCompiler::write_mem_op_size = 30; u32 BlockCompiler::mem_access_offset = 0; From 8d8e694e23aff7b5651b98d756dcbb9ce34f736f Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 18 Jun 2019 13:25:43 +0200 Subject: [PATCH 072/158] swap setpeq args in ssa if first is imm --- core/hw/sh4/dyna/ssa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index e322af7b8..78299811a 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -191,7 +191,7 @@ private: } else if (op.op == shop_and || op.op == shop_or || op.op == shop_xor || op.op == shop_add || op.op == shop_mul_s16 || op.op == shop_mul_u16 || op.op == shop_mul_i32 || op.op == shop_test || op.op == shop_seteq || op.op == shop_fseteq || op.op == shop_fadd || op.op == shop_fmul - || op.op == shop_mul_u64 || op.op == shop_mul_s64 || op.op == shop_adc) + || op.op == shop_mul_u64 || op.op == shop_mul_s64 || op.op == shop_adc || op.op == shop_setpeq) { if (op.rs1.is_imm() && op.rs2.is_reg()) { From 0b8a312feaf7430b56de95a68afa265f2c69f482 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 18 Jun 2019 15:07:32 +0200 Subject: [PATCH 073/158] rec-arm64: simplify read/write mem rewrite logic pass exception pc in x2 reg for both slow/fast paths infer the op type and size from the armv8 op encoding rewrite doesn't need access to the block anymore add support for some imm args --- core/linux/common.cpp | 3 +- core/linux/context.cpp | 2 +- core/linux/context.h | 2 +- core/rec-ARM64/rec_arm64.cpp | 306 ++++++++++++++++------------------- 4 files changed, 146 insertions(+), 167 deletions(-) diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 9d12aae26..1195dbd11 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -55,7 +55,6 @@ void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) { void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) { rei_host_context_t ctx; - context_from_segfault(&ctx, segfault_ctx); bool dyna_cde = ((unat)CC_RX2RW(ctx.pc) > (unat)CodeCache) && ((unat)CC_RX2RW(ctx.pc) < (unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); @@ -64,7 +63,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) #if HOST_CPU == CPU_ARM64 u32 op = *(u32*)ctx.pc; bool write = (op & 0x00400000) == 0; - u32 exception_pc = ctx.x27; + u32 exception_pc = ctx.x2; #elif HOST_CPU == CPU_X64 bool write = false; // TODO? u32 exception_pc = 0; diff --git a/core/linux/context.cpp b/core/linux/context.cpp index ca63b6e47..c39fa72d5 100644 --- a/core/linux/context.cpp +++ b/core/linux/context.cpp @@ -53,7 +53,7 @@ void context_segfault(rei_host_context_t* reictx, void* segfault_ctx, bool to_se #endif #elif HOST_CPU == CPU_ARM64 bicopy(reictx->pc, MCTX(.pc), to_segfault); - bicopy(reictx->x27, MCTX(.regs[27]), to_segfault); + bicopy(reictx->x2, MCTX(.regs[2]), to_segfault); #elif HOST_CPU == CPU_X86 #if defined(__FreeBSD__) bicopy(reictx->pc, MCTX(.mc_eip), to_segfault); diff --git a/core/linux/context.h b/core/linux/context.h index 30c5b0bb8..bcfceaa90 100644 --- a/core/linux/context.h +++ b/core/linux/context.h @@ -15,7 +15,7 @@ struct rei_host_context_t { #elif HOST_CPU == CPU_ARM u32 r[15]; #elif HOST_CPU == CPU_ARM64 - u64 x27; + u64 x2; #endif }; diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index e051359e1..dd3fbbe1b 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -29,6 +29,7 @@ using namespace vixl::aarch64; //#define EXPLODE_SPANS +//#define NO_BLOCK_LINKING #include "hw/sh4/sh4_opcode_list.h" @@ -154,7 +155,7 @@ void ngen_mainloop(void* v_cntx) void ngen_init() { - printf("Initializing the ARM64 dynarec\n"); + LOGI("Initializing the ARM64 dynarec\n"); ngen_FailedToFindBlock = &ngen_FailedToFindBlock_nommu; } @@ -180,17 +181,14 @@ void ngen_GetFeatures(ngen_features* dst) } template -static T ReadMemNoEx(u32 addr, u32 pc) +static T ReadMemNoEx(u32 addr, u32, u32 pc) { #ifndef NO_MMU u32 ex; T rv = mmu_ReadMemNoEx(addr, &ex); if (ex) { - if (pc & 1) - spc = pc - 1; - else - spc = pc; + spc = pc; longjmp(jmp_env, 1); } return rv; @@ -206,10 +204,7 @@ static void WriteMemNoEx(u32 addr, T data, u32 pc) u32 ex = mmu_WriteMemNoEx(addr, data); if (ex) { - if (pc & 1) - spc = pc - 1; - else - spc = pc; + spc = pc; longjmp(jmp_env, 1); } #endif @@ -868,11 +863,21 @@ public: case shop_mul_u64: case shop_mul_s64: { + Register reg2; + if (op.rs2.is_imm()) + { + Mov(w0, op.rs2.imm_value()); + reg2 = w0; + } + else + { + reg2 = regalloc.MapRegister(op.rs2); + } const Register& rd_xreg = Register::GetXRegFromCode(regalloc.MapRegister(op.rd).GetCode()); if (op.op == shop_mul_u64) - Umull(rd_xreg, regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + Umull(rd_xreg, regalloc.MapRegister(op.rs1), reg2); else - Smull(rd_xreg, regalloc.MapRegister(op.rs1), regalloc.MapRegister(op.rs2)); + Smull(rd_xreg, regalloc.MapRegister(op.rs1), reg2); const Register& rd2_xreg = Register::GetXRegFromCode(regalloc.MapRegister(op.rd2).GetCode()); Lsr(rd2_xreg, rd_xreg, 32); } @@ -983,7 +988,10 @@ public: case shop_fsca: Mov(x1, reinterpret_cast(&sin_table)); - Add(x1, x1, Operand(regalloc.MapRegister(op.rs1), UXTH, 3)); + if (op.rs1.is_reg()) + Add(x1, x1, Operand(regalloc.MapRegister(op.rs1), UXTH, 3)); + else + Add(x1, x1, Operand(op.rs1.imm_value() << 3)); #ifdef EXPLODE_SPANS Ldr(regalloc.MapVRegister(op.rd, 0), MemOperand(x1, 4, PostIndex)); Ldr(regalloc.MapVRegister(op.rd, 1), MemOperand(x1)); @@ -1145,13 +1153,9 @@ public: return MemOperand(x28, offset); } - void GenReadMemorySlow(const shil_opcode& op) + void GenReadMemorySlow(u32 size) { Instruction *start_instruction = GetCursorAddress(); - u32 size = op.flags & 0x7f; - - if (mmu_enabled()) - Mov(*call_regs[1], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc switch (size) { @@ -1189,30 +1193,13 @@ public: die("1..8 bytes"); break; } - - if (size != 8) - host_reg_to_shil_param(op.rd, w0); - else - { -#ifdef EXPLODE_SPANS - verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); - Fmov(regalloc.MapVRegister(op.rd, 0), w0); - Lsr(x0, x0, 32); - Fmov(regalloc.MapVRegister(op.rd, 1), w0); -#else - host_reg_to_shil_param(op.rd, x0); -#endif - } EnsureCodeSize(start_instruction, read_memory_rewrite_size); } - void GenWriteMemorySlow(const shil_opcode& op) + void GenWriteMemorySlow(u32 size) { Instruction *start_instruction = GetCursorAddress(); - if (mmu_enabled()) - Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 1 : 0)); // pc - u32 size = op.flags & 0x7f; switch (size) { case 1: @@ -1250,17 +1237,6 @@ public: EnsureCodeSize(start_instruction, write_memory_rewrite_size); } - void InitializeRewrite(RuntimeBlockInfo *block, size_t opid) - { - this->block = block; - // writem rewrite doesn't use regalloc - if (block->oplist[opid].op == shop_readm) - { - regalloc.DoAlloc(block); - regalloc.SetOpnum(opid); - } - } - u32 RelinkBlock(RuntimeBlockInfo *block) { ptrdiff_t start_offset = GetBuffer()->GetCursorOffset(); @@ -1271,19 +1247,23 @@ public: case BET_StaticJump: case BET_StaticCall: // next_pc = block->BranchBlock; - if (block->pBranchBlock == NULL) +#ifndef NO_BLOCK_LINKING + if (block->pBranchBlock != NULL) + GenBranch(block->pBranchBlock->code); + else { if (!mmu_enabled()) GenCallRuntime(ngen_LinkBlock_Generic_stub); else +#else + { +#endif { Mov(w29, block->BranchBlock); Str(w29, sh4_context_mem_operand(&next_pc)); GenBranch(*arm64_no_update); } } - else - GenBranch(block->pBranchBlock->code); break; case BET_Cond_0: @@ -1303,6 +1283,7 @@ public: Label branch_not_taken; B(ne, &branch_not_taken); +#ifndef NO_BLOCK_LINKING if (block->pBranchBlock != NULL) GenBranch(block->pBranchBlock->code); else @@ -1310,6 +1291,9 @@ public: if (!mmu_enabled()) GenCallRuntime(ngen_LinkBlock_cond_Branch_stub); else +#else + { +#endif { Mov(w29, block->BranchBlock); Str(w29, sh4_context_mem_operand(&next_pc)); @@ -1319,6 +1303,7 @@ public: Bind(&branch_not_taken); +#ifndef NO_BLOCK_LINKING if (block->pNextBlock != NULL) GenBranch(block->pNextBlock->code); else @@ -1326,6 +1311,9 @@ public: if (!mmu_enabled()) GenCallRuntime(ngen_LinkBlock_cond_Next_stub); else +#else + { +#endif { Mov(w29, block->NextBlock); Str(w29, sh4_context_mem_operand(&next_pc)); @@ -1408,6 +1396,7 @@ public: #if 0 if (rewrite && block != NULL) { + LOGI("BLOCK %08x\n", block->vaddr); Instruction* instr_start = (Instruction*)block->code; // Instruction* instr_end = GetLabelAddress(&code_end); Instruction* instr_end = (Instruction*)((u8 *)block->code + block->host_code_size); @@ -1417,7 +1406,7 @@ public: Instruction* instr; for (instr = instr_start; instr < instr_end; instr += kInstructionSize) { decoder.Decode(instr); - printf("VIXL\t %p:\t%s\n", + LOGI("VIXL\t %p:\t%s\n", reinterpret_cast(instr), disasm.GetOutput()); } @@ -1614,11 +1603,26 @@ private: return; GenMemAddr(op, call_regs[0]); + if (mmu_enabled()) + Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); // pc - if (optimise && GenReadMemoryFast(op, opid)) - return; + u32 size = op.flags & 0x7f; + if (!optimise || !GenReadMemoryFast(op, opid)) + GenReadMemorySlow(size); - GenReadMemorySlow(op); + if (size < 8) + host_reg_to_shil_param(op.rd, w0); + else + { +#ifdef EXPLODE_SPANS + verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); + Fmov(regalloc.MapVRegister(op.rd, 0), w0); + Lsr(x0, x0, 32); + Fmov(regalloc.MapVRegister(op.rd, 1), w0); +#else + Str(x0, sh4_context_mem_operand(op.rd.reg_ptr())); +#endif + } } bool GenReadMemoryImmediate(const shil_opcode& op) @@ -1650,7 +1654,7 @@ private: if (isram) { - Ldr(x1, reinterpret_cast(ptr)); + Ldr(x1, reinterpret_cast(ptr)); // faster than Mov if (regalloc.IsAllocAny(op.rd)) { switch (size) @@ -1752,7 +1756,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) + // WARNING: the rewrite code relies on having 1 or 2 ops before the memory access // Update ngen_Rewrite (and perhaps read_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1762,78 +1766,26 @@ private: else { Add(x1, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); - if (mmu_enabled()) - { - u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - Mov(w27, exception_pc & 0xFFFF); - Movk(w27, exception_pc >> 16, 16); - } } - //printf("direct read memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); - this->block->memory_accesses[GetCursorAddress()] = (u32)opid; - u32 size = op.flags & 0x7f; - if (regalloc.IsAllocAny(op.rd)) + switch(size) { - switch(size) - { - case 1: - Ldrsb(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); - break; + case 1: + Ldrsb(w0, MemOperand(x28, x1)); + break; - case 2: - Ldrsh(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); - break; + case 2: + Ldrsh(w0, MemOperand(x28, x1)); + break; - case 4: - if (!op.rd.is_r32f()) - Ldr(regalloc.MapRegister(op.rd), MemOperand(x28, x1)); - else - Ldr(regalloc.MapVRegister(op.rd), MemOperand(x28, x1)); - break; + case 4: + Ldr(w0, MemOperand(x28, x1)); + break; - case 8: - Ldr(x1, MemOperand(x28, x1)); - break; - } - - if (size == 8) - { -#ifdef EXPLODE_SPANS - verify(op.rd.count() == 2 && regalloc.IsAllocf(op.rd, 0) && regalloc.IsAllocf(op.rd, 1)); - Fmov(regalloc.MapVRegister(op.rd, 0), w1); - Lsr(x1, x1, 32); - Fmov(regalloc.MapVRegister(op.rd, 1), w1); -#else - die("GenReadMemoryFast: size == 8 and !explode_spans"); -#endif - } - } - else - { - switch(size) - { - case 1: - Ldrsb(w1, MemOperand(x28, x1)); - break; - - case 2: - Ldrsh(w1, MemOperand(x28, x1)); - break; - - case 4: - Ldr(w1, MemOperand(x28, x1)); - break; - - case 8: - Ldr(x1, MemOperand(x28, x1)); - break; - } - if (size == 8) - Str(x1, sh4_context_mem_operand(op.rd.reg_ptr())); - else - Str(w1, sh4_context_mem_operand(op.rd.reg_ptr())); + case 8: + Ldr(x0, MemOperand(x28, x1)); + break; } EnsureCodeSize(start_instruction, read_memory_rewrite_size); @@ -1846,6 +1798,8 @@ private: return; GenMemAddr(op, call_regs[0]); + if (mmu_enabled()) + Mov(*call_regs[2], block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0)); // pc u32 size = op.flags & 0x7f; if (size != 8) @@ -1865,7 +1819,7 @@ private: if (optimise && GenWriteMemoryFast(op, opid)) return; - GenWriteMemorySlow(op); + GenWriteMemorySlow(size); } bool GenWriteMemoryImmediate(const shil_opcode& op) @@ -1877,7 +1831,7 @@ private: u32 addr = op.rs1._imm; if (mmu_enabled()) { - if ((addr >> 12) != (block->vaddr >> 12)) + if ((addr >> 12) != (block->vaddr >> 12) && ((addr >> 12) != ((block->vaddr + block->guest_opcodes * 2 - 1) >> 12))) // When full mmu is on, only consider addresses in the same 4k page return false; u32 paddr; @@ -1933,10 +1887,7 @@ private: break; case 4: - if (op.rs2.is_r32f()) - Str(reg2, MemOperand(x1)); - else - Str(reg2, MemOperand(x1)); + Str(reg2, MemOperand(x1)); break; default: @@ -1982,7 +1933,7 @@ private: Instruction *start_instruction = GetCursorAddress(); - // WARNING: the rewrite code relies on having 1-2 ops before the memory access (3 when mmu is enabled) + // WARNING: the rewrite code relies on having 1 or 2 ops before the memory access // Update ngen_Rewrite (and perhaps write_memory_rewrite_size) if adding or removing code if (!_nvmem_4gb_space()) { @@ -1992,17 +1943,8 @@ private: else { Add(x7, *call_regs64[0], sizeof(Sh4Context), LeaveFlags); - if (mmu_enabled()) - { - u32 exception_pc = block->vaddr + op.guest_offs - (op.delay_slot ? 2 : 0); - Mov(w27, exception_pc & 0xFFFF); - Movk(w27, exception_pc >> 16, 16); - } } - //printf("direct write memory access opid %d pc %p code addr %08x\n", opid, GetCursorAddress(), this->block->addr); - this->block->memory_accesses[GetCursorAddress()] = (u32)opid; - u32 size = op.flags & 0x7f; switch(size) { @@ -2050,7 +1992,10 @@ private: switch (smc_checks) { case NoCheck: - return; + if (!mmu_enabled()) + return; + B(&blockcheck_success); + break; case FastCheck: { u8* ptr = GetMemPtr(block->addr, 4); @@ -2200,9 +2145,8 @@ private: std::vector call_fregs; Arm64RegAlloc regalloc; RuntimeBlockInfo* block = NULL; - const int read_memory_rewrite_size = 5; // worst case for u64/mmu: add, mov, movk, ldr, str - // FIXME rewrite size per read/write size? - const int write_memory_rewrite_size = 4; // TODO only 2 if !mmu & 4gb + const int read_memory_rewrite_size = 3; // ubfx, add, ldr + const int write_memory_rewrite_size = 3; // ubfx, add, str }; static Arm64Assembler* compiler; @@ -2239,39 +2183,71 @@ void ngen_CC_Finish(shil_opcode* op) } +#define STR_LDR_MASK 0xFFE0EC00 + +static const u32 armv8_mem_ops[] = { + 0x38E06800, // Ldrsb + 0x78E06800, // Ldrsh + 0xB8606800, // Ldr w + 0xF8606800, // Ldr x + 0x38206800, // Strb + 0x78206800, // Strh + 0xB8206800, // Str w + 0xF8206800, // Str x +}; +static const bool read_ops[] = { + true, + true, + true, + true, + false, + false, + false, + false, +}; +static const u32 op_sizes[] = { + 1, + 2, + 4, + 8, + 1, + 2, + 4, + 8, +}; bool ngen_Rewrite(unat& host_pc, unat, unat) { - //printf("ngen_Rewrite pc %p\n", host_pc); - void *host_pc_rw = (void*)CC_RX2RW(host_pc); - RuntimeBlockInfo *block = bm_GetBlock((void*)host_pc); - if (block == NULL) + //LOGI("ngen_Rewrite pc %zx\n", host_pc); + u32 *code_ptr = (u32 *)CC_RX2RW(host_pc); + u32 armv8_op = *code_ptr; + bool is_read; + u32 size; + bool found = false; + u32 masked = armv8_op & STR_LDR_MASK; + for (int i = 0; i < ARRAY_SIZE(armv8_mem_ops); i++) { - printf("ngen_Rewrite: Block at %p not found\n", (void *)host_pc); - return false; + if (masked == armv8_mem_ops[i]) + { + size = op_sizes[i]; + is_read = read_ops[i]; + found = true; + break; + } } - u32 *code_ptr = (u32*)host_pc_rw; - auto it = block->memory_accesses.find(code_ptr); - if (it == block->memory_accesses.end()) - { - printf("ngen_Rewrite: memory access at %p not found (%lu entries)\n", code_ptr, block->memory_accesses.size()); - return false; - } - u32 opid = it->second; - verify(opid < block->oplist.size()); - const shil_opcode& op = block->oplist[opid]; - // Skip the preceding ops (add, bic, ...) - u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0) - (mmu_enabled() ? 2 : 0); + verify(found); + + // Skip the preceding ops (add, ubfx) + u32 *code_rewrite = code_ptr - 1 - (!_nvmem_4gb_space() ? 1 : 0); Arm64Assembler *assembler = new Arm64Assembler(code_rewrite); - assembler->InitializeRewrite(block, opid); - if (op.op == shop_readm) + if (is_read) { mem_rewrites_r++; - assembler->GenReadMemorySlow(op); + assembler->GenReadMemorySlow(size); } else { mem_rewrites_w++; - assembler->GenWriteMemorySlow(op); + assembler->GenWriteMemorySlow(size); } assembler->Finalize(true); delete assembler; @@ -2305,6 +2281,7 @@ void ngen_HandleException() u32 DynaRBI::Relink() { +#ifndef NO_BLOCK_LINKING //printf("DynaRBI::Relink %08x\n", this->addr); Arm64Assembler *compiler = new Arm64Assembler((u8 *)this->code + this->relink_offset); @@ -2313,6 +2290,9 @@ u32 DynaRBI::Relink() delete compiler; return code_size; +#else + return 0; +#endif } void Arm64RegAlloc::Preload(u32 reg, eReg nreg) From 318852e261b9f472276839b272730c87016dfb71 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 11:01:33 +0200 Subject: [PATCH 074/158] dynarec: use mprotect to protect code areas All ram pages containing code are write protected. In that case, no need for block checks. Memory reads in the same block(s) can also be executed at compile time and the results propagated as constants. When a write is detected in a protected area, the corresponding blocks are discarded and recompiled using traditional (slow) block checks. Backported the blkmap code finding change from upstream. Use smart pointers for block management to avoid reference issues. Added WriteAfterWrite ssa pass Fixed crash in ssa ConstProp pass when op list is modified --- core/hw/mem/vmem32.cpp | 48 +++- core/hw/sh4/dyna/blockmanager.cpp | 421 +++++++++++++++++++----------- core/hw/sh4/dyna/blockmanager.h | 34 ++- core/hw/sh4/dyna/driver.cpp | 87 +++--- core/hw/sh4/dyna/ssa.cpp | 76 +++--- core/hw/sh4/dyna/ssa.h | 87 +++++- core/linux/common.cpp | 2 + core/nullDC.cpp | 10 +- core/rec-x64/rec_x64.cpp | 8 +- core/windows/winmain.cpp | 7 +- 10 files changed, 517 insertions(+), 263 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 21056982a..8316de45a 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -1,8 +1,22 @@ /* - * vmem32.cpp - * - * Created on: Apr 11, 2019 - * Author: Flyinghead + Created on: Apr 11, 2019 + + Copyright 2019 flyinghead + + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . */ #include #include "build.h" @@ -49,6 +63,7 @@ static const u64 AREA7_ADDRESS = 0x7C000000L; static std::unordered_set vram_mapped_pages; static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +static u8 sram_mapped_pages[KERNEL_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped bool vmem32_inited; @@ -258,9 +273,30 @@ static u32 vmem32_map_mmu(u32 address, bool write) } } vramlist_lock.Unlock(); + + } + else if (offset >= MAP_VRAM_START_OFFSET && offset < MAP_VRAM_START_OFFSET + VRAM_SIZE) + { + // Check system RAM protected pages + if (bm_IsRamPageProtected(ppn)) + { + if (sram_mapped_pages[ppn >> 15] & (1 << ((ppn >> 12) & 7))) + { + // Already mapped => write access + vmem32_unprotect_buffer(address & ~PAGE_MASK, PAGE_SIZE); + bm_RamWriteAccess(ppn); + } + else + { + sram_mapped_pages[ppn >> 15] |= (1 << ((ppn >> 12) & 7)); + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, false) != NULL); + } + } + else + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); } else - // Not vram + // Not vram or system ram verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); return MMU_ERROR_NONE; @@ -322,6 +358,7 @@ void vmem32_flush_mmu() { //vmem32_flush++; vram_mapped_pages.clear(); + memset(sram_mapped_pages, 0, sizeof(sram_mapped_pages)); vmem32_unmap_buffer(0, KERNEL_SPACE); // TODO flush P3? } @@ -333,7 +370,6 @@ bool vmem32_init() #else if (settings.dynarec.disable_vmem32 || !_nvmem_4gb_space()) return false; - vmem32_inited = true; return true; #endif diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index b39031ce0..dc32785f1 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -4,19 +4,12 @@ */ #include +#include +#include #include "blockmanager.h" #include "ngen.h" -#include "../sh4_interpreter.h" -#include "../sh4_opcode_list.h" #include "../sh4_core.h" -#include "../sh4_if.h" -#include "hw/pvr/pvr_mem.h" -#include "hw/aica/aica_if.h" -//#include "../dmac.h" -#include "hw/gdrom/gdrom_if.h" -//#include "../intc.h" -//#include "../tmu.h" #include "hw/sh4/sh4_mem.h" #include "hw/sh4/sh4_sched.h" @@ -29,62 +22,21 @@ op_agent_t oprofHandle; #if FEAT_SHREC != DYNAREC_NONE -typedef vector bm_List; +typedef std::vector bm_List; +typedef std::set bm_Set; +typedef std::map bm_Map; -bm_List all_blocks; -bm_List all_temp_blocks; +bm_Set all_temp_blocks; bm_List del_blocks; -#include -struct BlockMapCMP -{ - static bool is_code(RuntimeBlockInfo* blk) - { - if ((unat)((u8*)blk-CodeCache) blocks_per_page[RAM_SIZE_MAX/PAGE_SIZE]; - static unat get_blkstart(RuntimeBlockInfo* blk) - { - if (is_code(blk)) - return (unat)blk; - else - return (unat)blk->code; - } - - static unat get_blkend(RuntimeBlockInfo* blk) - { - if (is_code(blk)) - return (unat)blk; - else - return (unat)blk->code+blk->host_code_size-1; - } - - //return true if blkl > blkr - bool operator()(RuntimeBlockInfo* blkl, RuntimeBlockInfo* blkr) const - { - if (!is_code(blkl) && !is_code(blkr)) - return (unat)blkl->code<(unat)blkr->code; - - unat blkr_start=get_blkstart(blkr),blkl_end=get_blkend(blkl); - - if (blkl_end blkmap_t; -blkmap_t blkmap; +bm_Map blkmap; u32 bm_gc_luc,bm_gcf_luc; - +// Stats +u32 protected_blocks; +u32 unprotected_blocks; #define FPCA(x) ((DynarecCodeEntryPtr&)sh4rcb.fpcb[(x>>1)&FPCB_MASK]) @@ -158,70 +110,81 @@ DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) // addr must be a physical address // This returns an executable address -RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr) +RuntimeBlockInfoPtr DYNACALL bm_GetBlock(u32 addr) { DynarecCodeEntryPtr cde = bm_GetCode(addr); // Returns RX ptr if (cde == ngen_FailedToFindBlock) - return 0; + return NULL; else return bm_GetBlock((void*)cde); // Returns RX pointer } // This takes a RX address and returns the info block ptr (RW space) -RuntimeBlockInfo* bm_GetBlock(void* dynarec_code) +RuntimeBlockInfoPtr bm_GetBlock(void* dynarec_code) { + if (blkmap.empty()) + return NULL; + void *dynarecrw = CC_RX2RW(dynarec_code); - blkmap_t::iterator iter = blkmap.find((RuntimeBlockInfo*)dynarecrw); - if (iter != blkmap.end()) - { - verify((*iter)->contains_code((u8*)dynarecrw)); - return *iter; - } - else - { - printf("bm_GetBlock(%p) failed ..\n", dynarec_code); - return 0; - } + // Returns a block who's code addr is bigger than dynarec_code (or end) + auto iter = blkmap.upper_bound(dynarecrw); + iter--; // Need to go back to find the potential candidate + + // However it might be out of bounds, check for that + if ((u8*)iter->second->code + iter->second->host_code_size < dynarec_code) + return NULL; + + verify(iter->second->contains_code((u8*)dynarecrw)); + return iter->second; +} + +void bm_CleanupDeletedBlocks() +{ + del_blocks.clear(); } // Takes RX pointer and returns a RW pointer -RuntimeBlockInfo* bm_GetStaleBlock(void* dynarec_code) +RuntimeBlockInfoPtr bm_GetStaleBlock(void* dynarec_code) { void *dynarecrw = CC_RX2RW(dynarec_code); - for(u32 i=0;icontains_code((u8*)dynarecrw)) - return del_blocks[i]; - } + it--; + if ((*it)->contains_code((u8*)dynarecrw)) + return *it; + } while (it != del_blocks.begin()); - return 0; + return NULL; } void bm_AddBlock(RuntimeBlockInfo* blk) { - if (!blk->temp_block) - all_blocks.push_back(blk); - else - all_temp_blocks.push_back(blk); - if (blkmap.find(blk)!=blkmap.end()) - { - printf("DUP: %08X %p %08X %p\n", (*blkmap.find(blk))->addr,(*blkmap.find(blk))->code,blk->addr,blk->code); + RuntimeBlockInfoPtr block(blk); + if (block->temp_block) + all_temp_blocks.insert(block); + auto iter = blkmap.find((void*)blk->code); + if (iter != blkmap.end()) { + printf("DUP: %08X %p %08X %p\n", iter->second->addr, iter->second->code, block->addr, block->code); verify(false); } - blkmap.insert(blk); + blkmap[(void*)block->code] = block; - verify((void*)bm_GetCode(blk->addr)==(void*)ngen_FailedToFindBlock); - FPCA(blk->addr) = (DynarecCodeEntryPtr)CC_RW2RX(blk->code); + verify((void*)bm_GetCode(block->addr) == (void*)ngen_FailedToFindBlock); + FPCA(block->addr) = (DynarecCodeEntryPtr)CC_RW2RX(block->code); #ifdef DYNA_OPROF if (oprofHandle) { char fname[512]; - sprintf(fname,"sh4:%08X,c:%d,s:%d,h:%d",blk->addr,blk->guest_cycles,blk->guest_opcodes,blk->host_opcodes); + sprintf(fname,"sh4:%08X,c:%d,s:%d,h:%d", block->addr, block->guest_cycles, block->guest_opcodes, block->host_opcodes); - if (op_write_native_code(oprofHandle, fname, (uint64_t)blk->code, (void*)blk->code, blk->host_code_size) != 0) + if (op_write_native_code(oprofHandle, fname, (uint64_t)block->code, (void*)block->code, block->host_code_size) != 0) { printf("op_write_native_code error\n"); } @@ -230,35 +193,31 @@ void bm_AddBlock(RuntimeBlockInfo* blk) } -void bm_RemoveBlock(RuntimeBlockInfo* block) +void bm_DiscardBlock(RuntimeBlockInfo* block) { - verify((void*)bm_GetCode(block->addr) != (void*)ngen_FailedToFindBlock); - FPCA(block->addr) = ngen_FailedToFindBlock; - auto it = blkmap.find(block); - if (it != blkmap.end()) - blkmap.erase(it); - if (!block->temp_block) - { - for (auto it = all_blocks.begin(); it != all_blocks.end(); it++) - if (*it == block) - { - all_blocks.erase(it); - break; - } - } - else - { - for (auto it = all_temp_blocks.begin(); it != all_temp_blocks.end(); it++) - if (*it == block) - { - all_temp_blocks.erase(it); - break; - } - } - // FIXME need to remove refs - del_blocks.push_back(block); + // Remove from block map + auto it = blkmap.find((void*)block->code); + verify(it != blkmap.end()); + RuntimeBlockInfoPtr block_ptr = it->second; + + blkmap.erase(it); + + block_ptr->pNextBlock = NULL; + block_ptr->pBranchBlock = NULL; + block_ptr->Relink(); + + // Remove from jump table + verify((void*)bm_GetCode(block_ptr->addr) == (void*)block_ptr->code); + FPCA(block_ptr->addr) = ngen_FailedToFindBlock; + + if (block_ptr->temp_block) + all_temp_blocks.erase(block_ptr); + + del_blocks.push_back(block_ptr); + block_ptr->Discard(); } +#if 0 bool UDgreaterX ( RuntimeBlockInfo* elem1, RuntimeBlockInfo* elem2 ) { return elem1->runs > elem2->runs; @@ -330,15 +289,12 @@ void FindPath(u32 start) } rbi->runs=0; } +#endif -#include u32 rebuild_counter=20; void bm_Periodical_1s() { - for (u32 i=0;i0) rebuild_counter--; #if HOST_OS==OS_WINDOWS && 0 @@ -393,6 +349,7 @@ void bm_Periodical_1s() #endif } +#if 0 void constprop(RuntimeBlockInfo* blk); void bm_Rebuild() { @@ -432,6 +389,7 @@ void bm_Rebuild() rebuild_counter=30; } +#endif void bm_vmem_pagefill(void** ptr, u32 size_bytes) { @@ -442,22 +400,73 @@ void bm_vmem_pagefill(void** ptr, u32 size_bytes) } void bm_Reset() +{ + bm_ResetCache(); + bm_CleanupDeletedBlocks(); + protected_blocks = 0; + unprotected_blocks = 0; + + mem_region_unlock(virt_ram_base + 0x0C000000, 0x10000000 - 0x0C000000); + if (_nvmem_4gb_space()) + { + mem_region_unlock(virt_ram_base + 0x8C000000, 0x90000000 - 0x8C000000); + mem_region_unlock(virt_ram_base + 0xAC000000, 0xB0000000 - 0xAC000000); + } +} + +static void bm_LockPage(u32 addr) +{ + addr = addr & (RAM_MASK - PAGE_MASK); + if (!mmu_enabled()) + mem_region_lock(virt_ram_base + 0x0C000000 + addr, PAGE_SIZE); + if (_nvmem_4gb_space()) + { + mem_region_lock(virt_ram_base + 0x8C000000 + addr, PAGE_SIZE); + mem_region_lock(virt_ram_base + 0xAC000000 + addr, PAGE_SIZE); + // TODO wraps + } +} + +static void bm_UnlockPage(u32 addr) +{ + addr = addr & (RAM_MASK - PAGE_MASK); + if (!mmu_enabled()) + mem_region_unlock(virt_ram_base + 0x0C000000 + addr, PAGE_SIZE); + if (_nvmem_4gb_space()) + { + mem_region_unlock(virt_ram_base + 0x8C000000 + addr, PAGE_SIZE); + mem_region_unlock(virt_ram_base + 0xAC000000 + addr, PAGE_SIZE); + // TODO wraps + } +} + +void bm_ResetCache() { ngen_ResetBlocks(); _vmem_bm_reset(); - for (size_t i=0; irelink_data=0; - all_blocks[i]->pNextBlock=0; - all_blocks[i]->pBranchBlock=0; - all_blocks[i]->Relink(); + RuntimeBlockInfoPtr block = it.second; + block->relink_data = 0; + block->pNextBlock = 0; + block->pBranchBlock = 0; + // needed for the transition to full mmu. Could perhaps limit it to the current block. + block->Relink(); + // Avoid circular references + block->Discard(); + del_blocks.push_back(block); } - del_blocks.insert(del_blocks.begin(),all_blocks.begin(),all_blocks.end()); - - all_blocks.clear(); blkmap.clear(); + // blkmap includes temp blocks as well + all_temp_blocks.clear(); + + for (auto& block_list : blocks_per_page) + block_list.clear(); + + // FIXME Grandia II doesn't like it. intermittent reset when pressing start (except if disabling SSA?? TBC) + memset(unprotected_pages, 0, sizeof(unprotected_pages)); #ifdef DYNA_OPROF if (oprofHandle) @@ -480,9 +489,7 @@ void bm_ResetTempCache(bool full) for (auto& block : all_temp_blocks) { FPCA(block->addr) = ngen_FailedToFindBlock; - auto it = blkmap.find(block); - if (it != blkmap.end()) - blkmap.erase(it); + blkmap.erase((void*)block->code); } } del_blocks.insert(del_blocks.begin(),all_temp_blocks.begin(),all_temp_blocks.end()); @@ -499,6 +506,7 @@ void bm_Init() else printf("bm: Oprofile integration enabled !\n"); #endif + bm_Reset(); } void bm_Term() @@ -509,9 +517,6 @@ void bm_Term() oprofHandle=0; #endif bm_Reset(); - for (int i = 0; i < del_blocks.size(); i++) - delete del_blocks[i]; - del_blocks.clear(); } void bm_WriteBlockMap(const string& file) @@ -520,11 +525,12 @@ void bm_WriteBlockMap(const string& file) if (f) { printf("Writing block map !\n"); - for (size_t i=0; iBlockType,all_blocks[i]->addr,all_blocks[i]->code,all_blocks[i]->host_code_size,all_blocks[i]->guest_cycles,all_blocks[i]->guest_opcodes); - for(size_t j=0;joplist.size();j++) - fprintf(f,"\top: %zd:%d:%s\n",j,all_blocks[i]->oplist[j].guest_offs,all_blocks[i]->oplist[j].dissasm().c_str()); + RuntimeBlockInfoPtr& block = it.second; + fprintf(f, "block: %d:%08X:%p:%d:%d:%d\n", block->BlockType, block->addr, block->code, block->host_code_size, block->guest_cycles, block->guest_opcodes); + for(size_t j = 0; j < block->oplist.size(); j++) + fprintf(f,"\top: %zd:%d:%s\n", j, block->oplist[j].guest_offs, block->oplist[j].dissasm().c_str()); } fclose(f); printf("Finished writing block map\n"); @@ -553,12 +559,13 @@ bool UDgreater3 ( RuntimeBlockInfo* elem1, RuntimeBlockInfo* elem2 ) void sh4_jitsym(FILE* out) { - for (size_t i=0; icode,all_blocks[i]->host_code_size,all_blocks[i]->addr); + RuntimeBlockInfoPtr& block = it.second; + fprintf(out, "%p %d %08X\n", block->code, block->host_code_size, block->addr); } } - +#if 0 void bm_PrintTopBlocks() { double total_lups=0; @@ -642,27 +649,129 @@ void bm_Sort() all_blocks[i]->runs=0; } } - - +#endif RuntimeBlockInfo::~RuntimeBlockInfo() { - + if (read_only) + protected_blocks--; + else + unprotected_blocks--; } -#include -void RuntimeBlockInfo::AddRef(RuntimeBlockInfo* other) +void RuntimeBlockInfo::AddRef(RuntimeBlockInfoPtr other) { pre_refs.push_back(other); } -void RuntimeBlockInfo::RemRef(RuntimeBlockInfo* other) +void RuntimeBlockInfo::RemRef(RuntimeBlockInfoPtr other) { - pre_refs.erase(find(pre_refs.begin(),pre_refs.end(),other)); + bm_List::iterator it = std::find(pre_refs.begin(), pre_refs.end(), other); + if (it != pre_refs.end()) + pre_refs.erase(it); +} + +void RuntimeBlockInfo::Discard() +{ + // Update references + for (RuntimeBlockInfoPtr& ref : pre_refs) + { + if (ref->NextBlock == vaddr) + ref->pNextBlock = NULL; + if (ref->BranchBlock == vaddr) + ref->pBranchBlock = NULL; + ref->relink_data = 0; + ref->Relink(); + } + pre_refs.clear(); + + if (read_only) + { + // Remove this block from the per-page block lists + for (u32 addr = this->addr & ~PAGE_MASK; addr < this->addr + this->sh4_code_size; addr += PAGE_SIZE) + { + set& block_list = blocks_per_page[(addr & RAM_MASK) / PAGE_SIZE]; + block_list.erase(this); + } + } +} + +void RuntimeBlockInfo::SetProtectedFlags() +{ + // Don't write protect rom + // TODO Enable this for wince. hangs 4x4 EVO + if (mmu_enabled() || (!IsOnRam(addr) /*|| (vaddr & 0x1FFF0000) == 0x0C000000 */)) + { + this->read_only = false; + unprotected_blocks++; + return; + } + for (u32 addr = this->addr & ~PAGE_MASK; addr < this->addr + sh4_code_size; addr += PAGE_SIZE) + { + if (unprotected_pages[(addr & RAM_MASK) / PAGE_SIZE]) + { + this->read_only = false; + unprotected_blocks++; + return; + } + } + this->read_only = true; + protected_blocks++; + for (u32 addr = this->addr & ~PAGE_MASK; addr < this->addr + sh4_code_size; addr += PAGE_SIZE) + { + blocks_per_page[(addr & RAM_MASK) / PAGE_SIZE].insert(this); + bm_LockPage(addr); + } +} + +void bm_RamWriteAccess(u32 addr) +{ + addr &= RAM_MASK; + if (unprotected_pages[addr / PAGE_SIZE]) + { + printf("Page %08x already unprotected\n", addr); + die("Fatal error"); + } + unprotected_pages[addr / PAGE_SIZE] = true; + bm_UnlockPage(addr); + set& block_list = blocks_per_page[addr / PAGE_SIZE]; + vector list_copy; + list_copy.insert(list_copy.begin(), block_list.begin(), block_list.end()); + //if (!list_copy.empty()) + // printf("bm_RamWriteAccess write access to %08x\n", addr); + for (auto& block : list_copy) + { + bm_DiscardBlock(block); + } + verify(block_list.empty()); +} + +bool bm_RamWriteAccess(void *p, unat pc) +{ + if (_nvmem_4gb_space()) + { + if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x100000000L) + return false; + } + else + { + if ((u8 *)p < virt_ram_base || (u8 *)p >= virt_ram_base + 0x20000000) + return false; + } + u32 addr = (u8*)p - virt_ram_base; + if (mmu_enabled() && (addr & 0x80000000) == 0) + // If mmu enabled, let vmem32 manage user space + // shouldn't be necessary since it's called first + return false; + if (!IsOnRam(addr) || ((addr >> 29) > 0 && (addr >> 29) < 4)) // system RAM is not mapped to 20, 40 and 60 because of laziness + return false; + bm_RamWriteAccess(addr); + + return true; } bool print_stats; - +#if 0 void fprint_hex(FILE* d,const char* init,u8* ptr, u32& ofs, u32 limit) { int base=ofs; @@ -698,9 +807,8 @@ void print_blocks() printf("Writing blocks to %p\n",f); } - for (size_t i=0;ioplist.size();j++) { - shil_opcode* op=&all_blocks[i]->oplist[j]; + shil_opcode* op = &blk->oplist[j]; fprint_hex(f,"//h:",pucode,hcode,op->host_offs); if (gcode!=op->guest_offs) @@ -762,10 +870,11 @@ void print_blocks() fprintf(f,"}\n"); } - all_blocks[i]->runs=0; + blk->runs=0; } if (f) fclose(f); } #endif +#endif diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index 375fba25c..0d135a117 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -1,11 +1,13 @@ /* In case you wonder, the extern "C" stuff are for the assembly code on beagleboard/pandora */ +#include #include "types.h" #include "decoder.h" #pragma once typedef void (*DynarecCodeEntryPtr)(); +typedef std::shared_ptr RuntimeBlockInfoPtr; struct RuntimeBlockInfo_Core { @@ -65,22 +67,19 @@ struct RuntimeBlockInfo: RuntimeBlockInfo_Core virtual void Relocate(void* dst)=0; //predecessors references - vector pre_refs; + vector pre_refs; - void AddRef(RuntimeBlockInfo* other); - void RemRef(RuntimeBlockInfo* other); + void AddRef(RuntimeBlockInfoPtr other); + void RemRef(RuntimeBlockInfoPtr other); void Discard(); void UpdateRefs(); + void SetProtectedFlags(); u32 memops; u32 linkedmemops; std::map memory_accesses; // key is host pc when access is made, value is opcode id -}; - -struct CachedBlockInfo: RuntimeBlockInfo_Core -{ - RuntimeBlockInfo* block; + bool read_only; }; void bm_WriteBlockMap(const string& file); @@ -92,19 +91,26 @@ extern "C" { ATTR_USED DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr); } -RuntimeBlockInfo* bm_GetBlock(void* dynarec_code); -RuntimeBlockInfo* bm_GetStaleBlock(void* dynarec_code); -RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr); +RuntimeBlockInfoPtr bm_GetBlock(void* dynarec_code); +RuntimeBlockInfoPtr bm_GetStaleBlock(void* dynarec_code); +RuntimeBlockInfoPtr DYNACALL bm_GetBlock(u32 addr); void bm_AddBlock(RuntimeBlockInfo* blk); -void bm_RemoveBlock(RuntimeBlockInfo* block); +void bm_DiscardBlock(RuntimeBlockInfo* block); void bm_Reset(); +void bm_ResetCache(); void bm_ResetTempCache(bool full); void bm_Periodical_1s(); -void bm_Periodical_14k(); -void bm_Sort(); void bm_Init(); void bm_Term(); void bm_vmem_pagefill(void** ptr,u32 PAGE_SZ); +bool bm_RamWriteAccess(void *p, unat pc); +void bm_RamWriteAccess(u32 addr); +static inline bool bm_IsRamPageProtected(u32 addr) +{ + extern bool unprotected_pages[RAM_SIZE_MAX/PAGE_SIZE]; + addr &= RAM_MASK; + return !unprotected_pages[addr / PAGE_SIZE]; +} diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index db0e3086b..a9633c659 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -82,7 +82,7 @@ void recSh4_ClearCache() { printf("recSh4:Dynarec Cache clear at %08X free space %d\n", next_pc, emit_FreeSpace()); LastAddr=LastAddr_min; - bm_Reset(); + bm_ResetCache(); smc_hotspots.clear(); clear_temp_cache(true); } @@ -200,7 +200,7 @@ const char* RuntimeBlockInfo::hash(bool full, bool relocable) sha1_ctx ctx; sha1_init(&ctx); - u8* ptr = GetMemPtr(this->addr,this->guest_opcodes*2); + u8* ptr = GetMemPtr(this->addr, this->sh4_code_size); if (ptr) { @@ -218,7 +218,7 @@ const char* RuntimeBlockInfo::hash(bool full, bool relocable) } else { - sha1_update(&ctx,this->guest_opcodes*2,ptr); + sha1_update(&ctx, this->sh4_code_size, ptr); } } @@ -273,6 +273,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) return false; } #endif + SetProtectedFlags(); AnalyseBlock(this); @@ -301,10 +302,17 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) emit_ptr = (u32 *)(TempCodeCache + TempLastAddr); emit_ptr_limit = (u32 *)(TempCodeCache + TEMP_CODE_SIZE); rbi->temp_block = true; + if (rbi->read_only) + printf("WARNING: temp block %x (%x) is protected!\n", rbi->vaddr, rbi->addr); } bool do_opts = !rbi->temp_block; rbi->staging_runs=do_opts?100:-100; - ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts); + SmcCheckEnum block_check; + if (rbi->read_only) + block_check = NoCheck; + else + block_check = DoCheck(rbi->addr); + ngen_Compile(rbi, block_check, (pc & 0xFFFFFF) == 0x08300 || (pc & 0xFFFFFF) == 0x10000, false, do_opts); verify(rbi->code!=0); bm_AddBlock(rbi); @@ -362,7 +370,7 @@ u32 DYNACALL rdv_DoInterrupts_pc(u32 pc) { u32 DYNACALL rdv_DoInterrupts(void* block_cpde) { - RuntimeBlockInfo* rbi = bm_GetBlock(block_cpde); + RuntimeBlockInfoPtr rbi = bm_GetBlock(block_cpde); return rdv_DoInterrupts_pc(rbi->vaddr); } @@ -372,7 +380,7 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) u32 blockcheck_failures = 0; if (mmu_enabled()) { - RuntimeBlockInfo *block = bm_GetBlock(addr); + RuntimeBlockInfoPtr block = bm_GetBlock(addr); blockcheck_failures = block->blockcheck_failures + 1; if (blockcheck_failures > 5) { @@ -380,7 +388,7 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) //if (inserted) // printf("rdv_BlockCheckFail SMC hotspot @ %08x fails %d\n", addr, blockcheck_failures); } - bm_RemoveBlock(block); + bm_DiscardBlock(block.get()); } else { @@ -402,74 +410,75 @@ DynarecCodeEntryPtr rdv_FindOrCompile() void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc) { // code is the RX addr to return after, however bm_GetBlock returns RW - RuntimeBlockInfo* rbi = bm_GetBlock(code); - + RuntimeBlockInfoPtr rbi = bm_GetBlock(code); + bool stale_block = false; if (!rbi) { - printf("Stale block .."); + stale_block = true; rbi = bm_GetStaleBlock(code); } verify(rbi != NULL); - u32 bcls=BET_GET_CLS(rbi->BlockType); + u32 bcls = BET_GET_CLS(rbi->BlockType); - if (bcls==BET_CLS_Static) + if (bcls == BET_CLS_Static) { - next_pc=rbi->BranchBlock; + if (rbi->BlockType == BET_StaticIntr) + next_pc = rbi->NextBlock; + else + next_pc = rbi->BranchBlock; } - else if (bcls==BET_CLS_Dynamic) + else if (bcls == BET_CLS_Dynamic) { - next_pc=dpc; + next_pc = dpc; } - else if (bcls==BET_CLS_COND) + else if (bcls == BET_CLS_COND) { if (dpc) - next_pc=rbi->BranchBlock; + next_pc = rbi->BranchBlock; else - next_pc=rbi->NextBlock; + next_pc = rbi->NextBlock; } DynarecCodeEntryPtr rv = rdv_FindOrCompile(); // Returns rx ptr - bool do_link = !mmu_enabled() && bm_GetBlock(code) == rbi; - - if (do_link) + if (!mmu_enabled() && !stale_block) { - if (bcls==BET_CLS_Dynamic) + if (bcls == BET_CLS_Dynamic) { - verify(rbi->relink_data==0 || rbi->pBranchBlock==0); + verify(rbi->relink_data == 0 || rbi->pBranchBlock == NULL); - if (rbi->pBranchBlock!=0) + if (rbi->pBranchBlock != NULL) { rbi->pBranchBlock->RemRef(rbi); - rbi->pBranchBlock=0; - rbi->relink_data=1; + rbi->pBranchBlock = NULL; + rbi->relink_data = 1; } - else if (rbi->relink_data==0) + else if (rbi->relink_data == 0) { - rbi->pBranchBlock=bm_GetBlock(next_pc); + rbi->pBranchBlock = bm_GetBlock(next_pc).get(); rbi->pBranchBlock->AddRef(rbi); } } else { - RuntimeBlockInfo* nxt=bm_GetBlock(next_pc); + RuntimeBlockInfo* nxt = bm_GetBlock(next_pc).get(); - if (rbi->BranchBlock==next_pc) - rbi->pBranchBlock=nxt; - if (rbi->NextBlock==next_pc) - rbi->pNextBlock=nxt; + if (rbi->BranchBlock == next_pc) + rbi->pBranchBlock = nxt; + if (rbi->NextBlock == next_pc) + rbi->pNextBlock = nxt; nxt->AddRef(rbi); } - u32 ncs=rbi->relink_offset+rbi->Relink(); - verify(rbi->host_code_size>=ncs); - rbi->host_code_size=ncs; + u32 ncs = rbi->relink_offset + rbi->Relink(); + verify(rbi->host_code_size >= ncs); + rbi->host_code_size = ncs; } else { - printf(" .. null RBI: %08X -- unlinked stale block\n",next_pc); + printf(" .. null RBI: from %08X to %08X -- unlinked stale block -- code %p next %p\n", rbi->vaddr, next_pc, code, rv); } return (void*)rv; @@ -498,6 +507,7 @@ void recSh4_Reset(bool Manual) { Sh4_int_Reset(Manual); recSh4_ClearCache(); + bm_Reset(); } void recSh4_Init() @@ -505,7 +515,6 @@ void recSh4_Init() printf("recSh4 Init\n"); Sh4_int_Init(); bm_Init(); - bm_Reset(); verify(rcb_noffs(p_sh4rcb->fpcb) == FPCB_OFFSET); @@ -541,7 +550,7 @@ void recSh4_Init() memset(CodeCache, 0xFF, CODE_SIZE + TEMP_CODE_SIZE); TempCodeCache = CodeCache + CODE_SIZE; ngen_init(); - bm_Reset(); + bm_ResetCache(); } void recSh4_Term() diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp index 1689165d5..a27bc6fa4 100644 --- a/core/hw/sh4/dyna/ssa.cpp +++ b/core/hw/sh4/dyna/ssa.cpp @@ -39,21 +39,21 @@ void SSAOptimizer::InsertMov32Op(const shil_param& rd, const shil_param& rs) } -bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) +bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) { - if (!op.rs1.is_reg() && !op.rs2.is_reg() && !op.rs3.is_reg() - && (op.rs1.is_imm() || op.rs2.is_imm() || op.rs3.is_imm()) - && op.rd.is_reg()) + if (!op->rs1.is_reg() && !op->rs2.is_reg() && !op->rs3.is_reg() + && (op->rs1.is_imm() || op->rs2.is_imm() || op->rs3.is_imm()) + && op->rd.is_reg()) { // Only immediate operands -> execute the op at compile time - u32 rs1 = op.rs1.is_imm() ? op.rs1.imm_value() : 0; - u32 rs2 = op.rs2.is_imm() ? op.rs2.imm_value() : 0; - u32 rs3 = op.rs3.is_imm() ? op.rs3.imm_value() : 0; + u32 rs1 = op->rs1.is_imm() ? op->rs1.imm_value() : 0; + u32 rs2 = op->rs2.is_imm() ? op->rs2.imm_value() : 0; + u32 rs3 = op->rs3.is_imm() ? op->rs3.imm_value() : 0; u32 rd; u32 rd2; - switch (op.op) + switch (op->op) { case shop_mov32: rd = rs1; @@ -71,24 +71,26 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_rocr: { u64 v; - if (op.op == shop_adc) + if (op->op == shop_adc) v = shil_opcl_adc::f1::impl(rs1, rs2, rs3); - else if (op.op == shop_sbc) + else if (op->op == shop_sbc) v = shil_opcl_sbc::f1::impl(rs1, rs2, rs3); - else if (op.op == shop_rocl) + else if (op->op == shop_rocl) v = shil_opcl_rocl::f1::impl(rs1, rs2); - else if (op.op == shop_rocr) + else if (op->op == shop_rocr) v = shil_opcl_rocr::f1::impl(rs1, rs2); else v = shil_opcl_negc::f1::impl(rs1, rs2); rd = (u32)v; rd2 = (u32)(v >> 32); - shil_param op2_rd = shil_param(op.rd2._reg); - op2_rd.version[0] = op.rd2.version[0]; + shil_param op2_rd = shil_param(op->rd2._reg); + op2_rd.version[0] = op->rd2.version[0]; InsertMov32Op(op2_rd, shil_param(FMT_IMM, (u32)(v >> 32))); - op.rd2 = shil_param(); + // the previous insert might have invalidated our reference + op = &block->oplist[opnum - 1]; + op->rd2 = shil_param(); } break; case shop_shl: @@ -141,18 +143,20 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_mul_s64: { u64 v; - if (op.op == shop_mul_u64) + if (op->op == shop_mul_u64) v = shil_opcl_mul_u64::f1::impl(rs1, rs2); else v = shil_opcl_mul_s64::f1::impl(rs1, rs2); rd = (u32)v; rd2 = (u32)(v >> 32); - shil_param op2_rd = shil_param(op.rd2._reg); - op2_rd.version[0] = op.rd2.version[0]; + shil_param op2_rd = shil_param(op->rd2._reg); + op2_rd.version[0] = op->rd2.version[0]; InsertMov32Op(op2_rd, shil_param(FMT_IMM, rd2)); - op.rd2 = shil_param(); + // the previous insert might have invalidated our reference + op = &block->oplist[opnum - 1]; + op->rd2 = shil_param(); } break; case shop_test: @@ -173,7 +177,7 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_setab: case shop_setae: { - switch (op.op) + switch (op->op) { case shop_seteq: rd = rs1 == rs2; @@ -205,13 +209,16 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_div32u: case shop_div32s: { - u64 res = op.op == shop_div32u ? shil_opcl_div32u::f1::impl(rs1, rs2, rs3) : shil_opcl_div32s::f1::impl(rs1, rs2, rs3); + u64 res = op->op == shop_div32u ? shil_opcl_div32u::f1::impl(rs1, rs2, rs3) : shil_opcl_div32s::f1::impl(rs1, rs2, rs3); rd = (u32)res; - constprop_values[RegValue(op.rd, 1)] = res >> 32; + constprop_values[RegValue(op->rd, 1)] = res >> 32; - shil_param op2_rd = shil_param((Sh4RegType)(op.rd._reg + 1)); - op2_rd.version[0] = op.rd.version[1]; + shil_param op2_rd = shil_param((Sh4RegType)(op->rd._reg + 1)); + op2_rd.version[0] = op->rd.version[1]; InsertMov32Op(op2_rd, shil_param(FMT_IMM, res >> 32)); + + // the previous insert might have invalidated our reference + op = &block->oplist[opnum - 1]; } break; case shop_div32p2: @@ -221,6 +228,7 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) case shop_jdyn: { verify(BET_GET_CLS(block->BlockType) == BET_CLS_Dynamic); + rs1 += rs2; switch ((block->BlockType >> 1) & 3) { case BET_SCL_Jump: @@ -322,13 +330,15 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) shil_opcl_fsca::fsca_table::impl(tmp, rs1); rd = reinterpret_cast(tmp[0]); u32 rd_1 = reinterpret_cast(tmp[1]); - constprop_values[RegValue(op.rd, 1)] = rd_1; + constprop_values[RegValue(op->rd, 1)] = rd_1; - shil_param op2_rd = shil_param((Sh4RegType)(op.rd._reg + 1)); - op2_rd.version[0] = op.rd.version[1]; + shil_param op2_rd = shil_param((Sh4RegType)(op->rd._reg + 1)); + op2_rd.version[0] = op->rd.version[1]; InsertMov32Op(op2_rd, shil_param(FMT_IMM, rd_1)); - op.rd.type = FMT_F32; + // the previous insert might have invalidated our reference + op = &block->oplist[opnum - 1]; + op->rd.type = FMT_F32; } break; case shop_fabs: @@ -351,15 +361,15 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode& op) break; default: - printf("unhandled constant op %d\n", op.op); + printf("unhandled constant op %d\n", op->op); die("unhandled constant op"); break; } - constprop_values[RegValue(op.rd)] = rd; - if (op.rd2.is_r32()) - constprop_values[RegValue(op.rd2)] = rd2; - ReplaceByMov32(op, rd); + constprop_values[RegValue(op->rd)] = rd; + if (op->rd2.is_r32()) + constprop_values[RegValue(op->rd2)] = rd2; + ReplaceByMov32(*op, rd); return true; } diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 78299811a..0252c956a 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -26,6 +26,7 @@ #include "types.h" #include "decoder.h" #include "hw/sh4/modules/mmu.h" +#include "hw/sh4/sh4_mem.h" class SSAOptimizer { @@ -36,11 +37,12 @@ public: { AddVersionPass(); #if DEBUG - printf("BEFORE\n"); - PrintBlock(); + printf("BEFORE\n"); + PrintBlock(); #endif ConstPropPass(); + WriteAfterWritePass(); DeadCodeRemovalPass(); SimplifyExpressionPass(); CombineShiftsPass(); @@ -49,13 +51,13 @@ public: #if DEBUG if (stats.prop_constants > 0 || stats.dead_code_ops > 0 || stats.constant_ops_replaced > 0 - || stats.dead_registers > 0 || stats.dyn_to_stat_blocks > 0) + || stats.dead_registers > 0 || stats.dyn_to_stat_blocks > 0 || stats.waw_blocks > 0 || stats.combined_shifts > 0) { //printf("AFTER %08x\n", block->vaddr); //PrintBlock(); - printf("STATS: %08x ops %zd constants %d constops replaced %d dead code %d dead regs %d dyn2stat blks %d\n", block->vaddr, block->oplist.size(), + printf("STATS: %08x ops %zd constants %d constops replaced %d dead code %d dead regs %d dyn2stat blks %d waw %d shifts %d\n", block->vaddr, block->oplist.size(), stats.prop_constants, stats.constant_ops_replaced, - stats.dead_code_ops, stats.dead_registers, stats.dyn_to_stat_blocks); + stats.dead_code_ops, stats.dead_registers, stats.dyn_to_stat_blocks, stats.waw_blocks, stats.combined_shifts); } #endif } @@ -151,7 +153,7 @@ private: } } - bool ExecuteConstOp(shil_opcode& op); + bool ExecuteConstOp(shil_opcode* op); void ConstPropPass() { @@ -159,6 +161,7 @@ private: { shil_opcode& op = block->oplist[opnum]; + // TODO do shop_sub and others if (op.op != shop_setab && op.op != shop_setae && op.op != shop_setgt && op.op != shop_setge && op.op != shop_sub && op.op != shop_fsetgt && op.op != shop_fseteq && op.op != shop_fdiv && op.op != shop_fsub && op.op != shop_fmac) ConstPropOperand(op.rs1); @@ -184,9 +187,52 @@ private: op.rs1 = op.rs3; op.rs3 = t; } + + // If we know the address to read and it's in the same memory page(s) as the block + // and if those pages are read-only, then we can directly read the memory at compile time + // and propagate the read value as a constant. + if (op.rs1.is_imm() && op.op == shop_readm && block->read_only + && (op.rs1._imm >> 12) >= (block->vaddr >> 12) + && (op.rs1._imm >> 12) <= ((block->vaddr + block->sh4_code_size - 1) >> 12) + && (op.flags & 0x7f) <= 4) + { + bool doit = false; + if (mmu_enabled()) + { + // Only for user space addresses + if ((op.rs1._imm & 0x80000000) == 0) + doit = true; + else + // And kernel RAM addresses + doit = IsOnRam(op.rs1._imm); + } + else + doit = IsOnRam(op.rs1._imm); + if (doit) + { + u32 v; + switch (op.flags & 0x7f) + { + case 1: + v = (s32)(::s8)ReadMem8(op.rs1._imm); + break; + case 2: + v = (s32)(::s16)ReadMem16(op.rs1._imm); + break; + case 4: + v = ReadMem32(op.rs1._imm); + break; + default: + die("invalid size"); + break; + } + ReplaceByMov32(op, v); + constprop_values[RegValue(op.rd)] = v; + } + } } } - else if (ExecuteConstOp(op)) + else if (ExecuteConstOp(&op)) { } else if (op.op == shop_and || op.op == shop_or || op.op == shop_xor || op.op == shop_add || op.op == shop_mul_s16 || op.op == shop_mul_u16 @@ -598,11 +644,36 @@ private: next_op.rs2._imm += op.rs2._imm; //printf("%08x SHFT %s -> %d\n", block->vaddr + op.guest_offs, op.dissasm().c_str(), next_op.rs2._imm); ReplaceByMov32(op); + stats.combined_shifts++; } } } } + void WriteAfterWritePass() + { + for (int opnum = 0; opnum < (int)block->oplist.size() - 1; opnum++) + { + shil_opcode& op = block->oplist[opnum]; + shil_opcode& next_op = block->oplist[opnum + 1]; + if (op.op == next_op.op && op.op == shop_writem + && op.rs1.type == next_op.rs1.type + && op.rs1._imm == next_op.rs1._imm + && op.rs1.version[0] == next_op.rs1.version[0] + && op.rs3.type == next_op.rs3.type + && op.rs3._imm == next_op.rs3._imm + && op.rs3.version[0] == next_op.rs3.version[0] + && op.rs2.count() == next_op.rs2.count()) + { + //printf("%08x DEAD %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + block->oplist.erase(block->oplist.begin() + opnum); + opnum--; + stats.dead_code_ops++; + stats.waw_blocks++; + } + } + } + RuntimeBlockInfo* block; std::set writeback_values; @@ -612,6 +683,8 @@ private: u32 dead_code_ops = 0; u32 dead_registers = 0; u32 dyn_to_stat_blocks = 0; + u32 waw_blocks = 0; + u32 combined_shifts = 0; } stats; // transient vars diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 1195dbd11..3a3b6df9a 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -71,6 +71,8 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) if (vmem32_handle_signal(si->si_addr, write, exception_pc)) return; #endif + if (bm_RamWriteAccess(si->si_addr, ctx.pc)) + return; if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) return; #if FEAT_SHREC == DYNAREC_JIT diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 07a847890..f7c616b6f 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -23,6 +23,7 @@ #include "rend/gui.h" #include "profiler/profiler.h" #include "input/gamepad_device.h" +#include "hw/sh4/dyna/blockmanager.h" void FlushCache(); void LoadCustom(); @@ -170,7 +171,11 @@ void LoadSpecialSettings() tr_poly_depth_mask_game = true; } // Demolition Racer - if (!strncmp("T15112N", reios_product_number, 7)) + if (!strncmp("T15112N", reios_product_number, 7) + // Ducati World - Racing Challenge (NTSC) + || !strncmp("T-8113N", reios_product_number, 7) + // Ducati World (PAL) + || !strncmp("T-8121D-50", reios_product_number, 10)) { printf("Enabling Dynarec safe mode for game %s\n", reios_product_number); settings.dynarec.safemode = 1; @@ -324,6 +329,7 @@ int dc_start_game(const char *path) if (init_done) { InitSettings(); + dc_reset(); LoadSettings(false); #if DC_PLATFORM == DC_PLATFORM_DREAMCAST if (!settings.bios.UseReios) @@ -354,7 +360,6 @@ int dc_start_game(const char *path) mcfg_CreateAtomisWaveControllers(); #endif #endif - dc_reset(); game_started = true; dc_resume(); @@ -951,6 +956,7 @@ void dc_loadstate() } mmu_set_state(); + bm_Reset(); sh4_cpu.ResetCache(); dsp.dyndirty = true; sh4_sched_ffts(); diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 4f924cc39..59349d5f2 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -2204,7 +2204,7 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) return false; //printf("ngen_Rewrite pc %p\n", host_pc); - RuntimeBlockInfo *block = bm_GetBlock((void *)host_pc); + RuntimeBlockInfoPtr block = bm_GetBlock((void *)host_pc); if (block == NULL) { printf("ngen_Rewrite: Block at %p not found\n", (void *)host_pc); @@ -2222,16 +2222,16 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) const shil_opcode& op = block->oplist[opid]; BlockCompiler *assembler = new BlockCompiler(code_ptr - BlockCompiler::mem_access_offset); - assembler->InitializeRewrite(block, opid); + assembler->InitializeRewrite(block.get(), opid); if (op.op == shop_readm) { mem_rewrites_r++; - assembler->GenReadMemorySlow(op, block); + assembler->GenReadMemorySlow(op, block.get()); } else { mem_rewrites_w++; - assembler->GenWriteMemorySlow(op, block); + assembler->GenWriteMemorySlow(op, block.get()); } assembler->FinalizeRewrite(); verify(block->host_code_size >= assembler->getSize()); diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 4418f0523..d36024eb5 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -149,8 +149,11 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) if (vmem32_handle_signal(address, write, 0)) return EXCEPTION_CONTINUE_EXECUTION; #endif - - if (VramLockedWrite(address)) + if (bm_RamWriteAccess(address, 0)) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + else if (VramLockedWrite(address)) { return EXCEPTION_CONTINUE_EXECUTION; } From 13a2f8bc612fca47e08132ec4f9eb84636f9360c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 11:14:12 +0200 Subject: [PATCH 075/158] win32: build fix --- core/windows/winmain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index d36024eb5..7a9a2d39b 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -6,6 +6,7 @@ #include "cfg/cfg.h" #include "xinput_gamepad.h" #include "win_keyboard.h" +#include "hw/sh4/dyna/blockmanager.h" #define _WIN32_WINNT 0x0500 #include From ad5ab6240b45e1c41402b8ad902cf0a9f5441944 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 14:49:14 +0200 Subject: [PATCH 076/158] refactor vram lock/unlock code into new vmem.cpp functions --- core/hw/mem/_vmem.cpp | 98 +++++++++++++++++++++++++++++++++++++ core/hw/mem/_vmem.h | 4 ++ core/hw/mem/vmem32.cpp | 38 ++++++++------ core/hw/mem/vmem32.h | 4 +- core/hw/pvr/Renderer_if.cpp | 3 +- core/rend/TexCache.cpp | 64 +++--------------------- core/rend/gles/gltex.cpp | 12 ++--- 7 files changed, 138 insertions(+), 85 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 6b86d421e..a3af713c3 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -659,3 +659,101 @@ void _vmem_enable_mmu(bool enable) _vmem_set_p0_mappings(); } } + +void _vmem_protect_vram(u32 addr, u32 size) +{ + addr &= VRAM_MASK; + if (!mmu_enabled()) + { + mem_region_lock(virt_ram_base + 0x04000000 + addr, size); // P0 + //mem_region_lock(virt_ram_base + 0x06000000 + addr, size); // P0 - mirror + if (VRAM_SIZE == 0x800000) + { + // wraps when only 8MB VRAM + mem_region_lock(virt_ram_base + 0x04000000 + addr + VRAM_SIZE, size); + //mem_region_lock(virt_ram_base + 0x06000000 + addr + VRAM_SIZE, size); + } + } + if (_nvmem_4gb_space()) + { + mem_region_lock(virt_ram_base + 0x84000000 + addr, size); // P1 + //mem_region_lock(virt_ram_base + 0x86000000 + addr, size); // P1 - mirror + // We should also lock P2 and P3, and the mirrors, but they don't seem to be used... + //mem_region_lock(virt_ram_base + 0xA4000000 + addr, size); // P2 + //mem_region_lock(virt_ram_base + 0xA6000000 + addr, size); // P2 - mirror + //mem_region_lock(virt_ram_base + 0xC4000000 + addr, size); // P3 + //mem_region_lock(virt_ram_base + 0xC6000000 + addr, size); // P3 - mirror + if (VRAM_SIZE == 0x800000) + { + mem_region_lock(virt_ram_base + 0x84000000 + addr + VRAM_SIZE, size); + //mem_region_lock(virt_ram_base + 0x86000000 + addr + VRAM_SIZE, size); + //mem_region_lock(virt_ram_base + 0xA4000000 + addr + VRAM_SIZE, size); + //mem_region_lock(virt_ram_base + 0xC4000000 + addr + VRAM_SIZE, size); + } + vmem32_protect_vram(addr, size); + } +} + +void _vmem_unprotect_vram(u32 addr, u32 size) +{ + addr &= VRAM_MASK; + if (!mmu_enabled()) + { + mem_region_unlock(virt_ram_base + 0x04000000 + addr, size); // P0 + //mem_region_unlock(virt_ram_base + 0x06000000 + addr, size); // P0 - mirror + if (VRAM_SIZE == 0x800000) + { + // wraps when only 8MB VRAM + mem_region_unlock(virt_ram_base + 0x04000000 + addr + VRAM_SIZE, size); + //mem_region_unlock(virt_ram_base + 0x06000000 + addr + VRAM_SIZE, size); + } + } + if (_nvmem_4gb_space()) + { + mem_region_unlock(virt_ram_base + 0x84000000 + addr, size); // P1 + //mem_region_unlock(virt_ram_base + 0x86000000 + addr, size); // P1 - mirror + // We should also lock P2 and P3, and the mirrors, but they don't seem to be used... + //mem_region_unlock(virt_ram_base + 0xA4000000 + addr, size); // P2 + //mem_region_unlock(virt_ram_base + 0xA6000000 + addr, size); // P2 - mirror + //mem_region_unlock(virt_ram_base + 0xC4000000 + addr, size); // P3 + //mem_region_unlock(virt_ram_base + 0xC6000000 + addr, size); // P3 - mirror + if (VRAM_SIZE == 0x800000) + { + mem_region_unlock(virt_ram_base + 0x84000000 + addr + VRAM_SIZE, size); + //mem_region_unlock(virt_ram_base + 0x86000000 + addr + VRAM_SIZE, size); + //mem_region_unlock(virt_ram_base + 0xA4000000 + addr + VRAM_SIZE, size); + //mem_region_unlock(virt_ram_base + 0xC4000000 + addr + VRAM_SIZE, size); + } + vmem32_unprotect_vram(addr, size); + } +} + +u32 _vmem_get_vram_offset(void *addr) +{ + ptrdiff_t offset = (u8*)addr - virt_ram_base; + if (_nvmem_4gb_space()) + { + if (mmu_enabled()) + { + // Only kernel mirrors + if (offset < 0x80000000 || offset >= 0xE0000000) + return -1; + } + else + { + if (offset < 0 || offset >= 0xE0000000) + return -1; + } + offset &= 0x1FFFFFFF; + } + else + { + if (offset < 0 || offset >= 0x20000000) + return -1; + } + if ((offset >> 24) != 4) + return -1; + verify((((u8*)addr - virt_ram_base) >> 29) == 0 || (((u8*)addr - virt_ram_base) >> 29) == 4); // others areas aren't mapped atm + + return offset & VRAM_MASK; +} diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index f93d4842b..dc31d93c4 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -117,3 +117,7 @@ void _vmem_enable_mmu(bool enable); #define MAP_RAM_START_OFFSET 0 #define MAP_VRAM_START_OFFSET (MAP_RAM_START_OFFSET+RAM_SIZE) #define MAP_ARAM_START_OFFSET (MAP_VRAM_START_OFFSET+VRAM_SIZE) + +void _vmem_protect_vram(u32 addr, u32 size); +void _vmem_unprotect_vram(u32 addr, u32 size); +u32 _vmem_get_vram_offset(void *addr); diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 8316de45a..fab4a29ca 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -62,7 +62,11 @@ static const u64 AREA7_ADDRESS = 0x7C000000L; #define VRAM_PROT_SEGMENT (1024 * 1024) // vram protection regions are grouped by 1MB segment static std::unordered_set vram_mapped_pages; -static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +struct vram_lock { + u32 start; + u32 end; +}; +static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; static u8 sram_mapped_pages[KERNEL_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped bool vmem32_inited; @@ -144,27 +148,29 @@ static void vmem32_unprotect_buffer(u32 start, u32 size) #endif } -void vmem32_protect_vram(vram_block *block) +void vmem32_protect_vram(u32 addr, u32 size) { if (!vmem32_inited) return; - for (int i = block->start / VRAM_PROT_SEGMENT; i <= block->end / VRAM_PROT_SEGMENT; i++) + for (int page = (addr & VRAM_MASK) / VRAM_PROT_SEGMENT; page <= ((addr & VRAM_MASK) + size - 1) / VRAM_PROT_SEGMENT; page++) { - vram_blocks[i].push_back(block); + vram_blocks[page].push_back({ addr, addr + size - 1 }); } } -void vmem32_unprotect_vram(vram_block *block) +void vmem32_unprotect_vram(u32 addr, u32 size) { if (!vmem32_inited) return; - for (int page = block->start / VRAM_PROT_SEGMENT; page <= block->end / VRAM_PROT_SEGMENT; page++) + for (int page = (addr & VRAM_MASK) / VRAM_PROT_SEGMENT; page <= ((addr & VRAM_MASK) + size - 1) / VRAM_PROT_SEGMENT; page++) { - for (int i = 0; i < vram_blocks[page].size(); i++) - if (vram_blocks[page][i] == block) - { - vram_blocks[page].erase(vram_blocks[page].begin() + i); - break; - } + std::vector& block_list = vram_blocks[page]; + for (auto it = block_list.begin(); it != block_list.end(); ) + { + if (it->start >= addr && it->end < addr + size) + it = block_list.erase(it); + else + it++; + } } } @@ -258,15 +264,15 @@ static u32 vmem32_map_mmu(u32 address, bool write) } verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); u32 end = start + page_size; - const vector& blocks = vram_blocks[start / VRAM_PROT_SEGMENT]; + const vector& blocks = vram_blocks[start / VRAM_PROT_SEGMENT]; vramlist_lock.Lock(); for (int i = blocks.size() - 1; i >= 0; i--) { - if (blocks[i]->start < end && blocks[i]->end >= start) + if (blocks[i].start < end && blocks[i].end >= start) { - u32 prot_start = max(start, blocks[i]->start); - u32 prot_size = min(end, blocks[i]->end + 1) - prot_start; + u32 prot_start = max(start, blocks[i].start); + u32 prot_size = min(end, blocks[i].end + 1) - prot_start; prot_size += prot_start % PAGE_SIZE; prot_start &= ~PAGE_MASK; vmem32_protect_buffer(vpn + (prot_start & (page_size - 1)), prot_size); diff --git a/core/hw/mem/vmem32.h b/core/hw/mem/vmem32.h index 60e20a7b8..868c2f0bc 100644 --- a/core/hw/mem/vmem32.h +++ b/core/hw/mem/vmem32.h @@ -24,8 +24,8 @@ bool vmem32_init(); void vmem32_term(); bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc); void vmem32_flush_mmu(); -void vmem32_protect_vram(vram_block *block); -void vmem32_unprotect_vram(vram_block *block); +void vmem32_protect_vram(u32 addr, u32 size); +void vmem32_unprotect_vram(u32 addr, u32 size); extern bool vmem32_inited; static inline bool vmem32_enabled() { diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 52fff6364..254cccb76 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -3,6 +3,7 @@ #include "hw/pvr/pvr_mem.h" #include "rend/TexCache.h" #include "rend/gui.h" +#include "hw/mem/_vmem.h" #include "deps/zlib/zlib.h" @@ -205,7 +206,7 @@ TA_context* read_frame(const char* file, u8* vram_ref = NULL) { fread(&t, 1, sizeof(t), fw); verify(t == VRAM_SIZE); - vram.UnLockRegion(0, VRAM_SIZE); + _vmem_unprotect_vram(0, VRAM_SIZE); uLongf compressed_size; diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index 25ef5c03c..8ed8e3219 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -208,34 +208,7 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user { vramlist_lock.Lock(); - vram.LockRegion(block->start, block->len); - - //TODO: Fix this for 32M wrap as well - if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { - vram.LockRegion(block->start + VRAM_SIZE, block->len); - } - if (!mmu_enabled()) - { - if (_nvmem_4gb_space()) - { - // In 4GB mode, vram.LockRegion() locks in the P1 area only so we also need to lock P0 - // We should also lock P2 and P3 but they don't seem to be used... - mem_region_lock(virt_ram_base + 0x04000000 + block->start, block->len); - //mem_region_lock(virt_ram_base + 0xA4000000 + block->start, block->len); - //mem_region_lock(virt_ram_base + 0xC4000000 + block->start, block->len); - if (VRAM_SIZE == 0x800000) - { - mem_region_lock(virt_ram_base + 0x04000000 + block->start + VRAM_SIZE, block->len); - //mem_region_lock(virt_ram_base + 0xA4000000 + block->start + VRAM_SIZE, block->len); - //mem_region_lock(virt_ram_base + 0xC4000000 + block->start + VRAM_SIZE, block->len); - } - } - } - else - { - vmem32_protect_vram(block); - } - + _vmem_protect_vram(block->start, block->len); vramlock_list_add(block); vramlist_lock.Unlock(); @@ -271,19 +244,7 @@ bool VramLockedWriteOffset(size_t offset) } list->clear(); - u32 aligned_offset = (u32)offset & ~(PAGE_SIZE - 1); - vram.UnLockRegion(aligned_offset, PAGE_SIZE); - - //TODO: Fix this for 32M wrap as well - if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { - vram.UnLockRegion(aligned_offset + VRAM_SIZE, PAGE_SIZE); - } - if (_nvmem_4gb_space() && !mmu_enabled()) - { - mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset, PAGE_SIZE); - if (VRAM_SIZE == 0x800000) - mem_region_unlock(virt_ram_base + 0x04000000 + aligned_offset + VRAM_SIZE, PAGE_SIZE); - } + _vmem_unprotect_vram((u32)offset, PAGE_SIZE); vramlist_lock.Unlock(); } @@ -296,20 +257,10 @@ bool VramLockedWriteOffset(size_t offset) bool VramLockedWrite(u8* address) { - size_t offset=address-vram.data; - - if (offset < 0x01000000) - return VramLockedWriteOffset(offset & (VRAM_SIZE - 1)); - if (_nvmem_4gb_space() && !mmu_enabled()) - { - offset = address - virt_ram_base; - if (offset >= 0x04000000 && offset < 0x05000000) - return VramLockedWriteOffset((offset - 0x04000000) & (VRAM_SIZE - 1)); - // 32MB wrap not set yet - //if (offset >= 0x06000000 && offset < 0x070000000) - // return VramLockedWriteOffset((offset - 0x06000000) & (VRAM_SIZE - 1)); - } - return false; + u32 offset = _vmem_get_vram_offset(address); + if (offset == -1) + return false; + return VramLockedWriteOffset(offset); } //unlocks mem @@ -328,8 +279,7 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block) msgboxf("Error : block end is after vram , skipping unlock",MBX_OK); else { - if (mmu_enabled()) - vmem32_unprotect_vram(block); + _vmem_unprotect_vram(block->start, block->len); vramlock_list_remove(block); //more work needed free(block); diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index 1a3802fb7..f25779dc2 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -585,7 +585,7 @@ void ReadRTTBuffer() { } } } - vram.UnLockRegion(0, 2 * vram.size); + _vmem_unprotect_vram(0, VRAM_SIZE); glPixelStorei(GL_PACK_ALIGNMENT, 1); u16 *dst = (u16 *)&vram[tex_addr]; @@ -644,14 +644,8 @@ void ReadRTTBuffer() { // Restore VRAM locks for (TexCacheIter i = TexCache.begin(); i != TexCache.end(); i++) { - if (i->second.lock_block != NULL) { - vram.LockRegion(i->second.sa_tex, i->second.sa + i->second.size - i->second.sa_tex); - - //TODO: Fix this for 32M wrap as well - if (_nvmem_enabled() && VRAM_SIZE == 0x800000) { - vram.LockRegion(i->second.sa_tex + VRAM_SIZE, i->second.sa + i->second.size - i->second.sa_tex); - } - } + if (i->second.lock_block != NULL) + _vmem_protect_vram(i->second.sa_tex, i->second.sa + i->second.size - i->second.sa_tex); } } else From becb0a5efe77a8c4c983e7c6a131fb13c85bf4b6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 15:10:28 +0200 Subject: [PATCH 077/158] renderer: when a RTT frame is rendered, swap any pending frame first Fixes Tony Hawks 1 & 2 black screen issue --- core/hw/pvr/Renderer_if.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 254cccb76..eada63387 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -253,6 +253,14 @@ bool rend_frame(TA_context* ctx, bool draw_osd) { dump_frame_switch = false; } bool proc = renderer->Process(ctx); + if ((ctx->rend.isRTT || ctx->rend.isRenderFramebuffer) && swap_pending) + { + // If there a frame swap pending, we want to do it now. + // The current frame "swapping" detection mechanism (using FB_R_SOF1) doesn't work + // if a RTT frame is rendered in between. + renderer->Present(); + swap_pending = false; + } #if !defined(TARGET_NO_THREADS) if (!proc || (!ctx->rend.isRTT && !ctx->rend.isRenderFramebuffer)) // If rendering to texture, continue locking until the frame is rendered From cb338ae106ed9d9526698d7b19d8bd9660d73fb6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 22:52:19 +0200 Subject: [PATCH 078/158] enable NoBatch when FullMMU is on for WinCE games --- core/nullDC.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index f7c616b6f..ef8e2166b 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -601,6 +601,9 @@ void LoadSettings(bool game_specific) settings.dreamcast.broadcast = cfgLoadInt(config_section, "Dreamcast.Broadcast", settings.dreamcast.broadcast); settings.dreamcast.language = cfgLoadInt(config_section, "Dreamcast.Language", settings.dreamcast.language); settings.dreamcast.FullMMU = cfgLoadBool(config_section, "Dreamcast.FullMMU", settings.dreamcast.FullMMU); + if (settings.dreamcast.FullMMU) + // Not really related but full mmu games are usually using Windows CE, which requires NoBatch + settings.aica.NoBatch = true; settings.aica.LimitFPS = (LimitFPSEnum)cfgLoadInt(config_section, "aica.LimitFPS", (int)settings.aica.LimitFPS); settings.aica.DSPEnabled = cfgLoadBool(config_section, "aica.DSPEnabled", settings.aica.DSPEnabled); settings.aica.NoSound = cfgLoadBool(config_section, "aica.NoSound", settings.aica.NoSound); From 6ed098a929c09c31ad79c6992847d57d4a5a640c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 19 Jun 2019 22:55:47 +0200 Subject: [PATCH 079/158] wince: enable code block protection --- core/hw/mem/vmem32.cpp | 17 ++++++++++------- core/hw/pvr/Renderer_if.cpp | 2 +- core/hw/sh4/dyna/blockmanager.cpp | 16 +++++++++------- core/hw/sh4/dyna/blockmanager.h | 2 +- core/hw/sh4/dyna/driver.cpp | 1 + core/linux/common.cpp | 2 +- core/stdclass.h | 18 +----------------- core/windows/winmain.cpp | 2 +- 8 files changed, 25 insertions(+), 35 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index fab4a29ca..d27fa569e 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -249,6 +249,7 @@ static u32 vmem32_map_mmu(u32 address, bool write) if (offset == -1) return VMEM32_ERROR_NOT_MAPPED; + bool allow_write = (entry->Data.PR & 1) != 0; if (offset >= MAP_VRAM_START_OFFSET && offset < MAP_VRAM_START_OFFSET + VRAM_SIZE) { // Check vram protected regions @@ -262,7 +263,7 @@ static u32 vmem32_map_mmu(u32 address, bool write) return MMU_ERROR_NONE; } - verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, allow_write) != NULL); u32 end = start + page_size; const vector& blocks = vram_blocks[start / VRAM_PROT_SEGMENT]; @@ -281,12 +282,14 @@ static u32 vmem32_map_mmu(u32 address, bool write) vramlist_lock.Unlock(); } - else if (offset >= MAP_VRAM_START_OFFSET && offset < MAP_VRAM_START_OFFSET + VRAM_SIZE) + else if (offset >= MAP_RAM_START_OFFSET && offset < MAP_RAM_START_OFFSET + RAM_SIZE) { // Check system RAM protected pages - if (bm_IsRamPageProtected(ppn)) + u32 start = offset - MAP_RAM_START_OFFSET; + + if (bm_IsRamPageProtected(start) && allow_write) { - if (sram_mapped_pages[ppn >> 15] & (1 << ((ppn >> 12) & 7))) + if (sram_mapped_pages[start >> 15] & (1 << ((start >> 12) & 7))) { // Already mapped => write access vmem32_unprotect_buffer(address & ~PAGE_MASK, PAGE_SIZE); @@ -294,16 +297,16 @@ static u32 vmem32_map_mmu(u32 address, bool write) } else { - sram_mapped_pages[ppn >> 15] |= (1 << ((ppn >> 12) & 7)); + sram_mapped_pages[start >> 15] |= (1 << ((start >> 12) & 7)); verify(vmem32_map_buffer(vpn, page_size, offset, page_size, false) != NULL); } } else - verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, allow_write) != NULL); } else // Not vram or system ram - verify(vmem32_map_buffer(vpn, page_size, offset, page_size, (entry->Data.PR & 1) != 0) != NULL); + verify(vmem32_map_buffer(vpn, page_size, offset, page_size, allow_write) != NULL); return MMU_ERROR_NONE; } diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index eada63387..bfa7c94df 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -255,7 +255,7 @@ bool rend_frame(TA_context* ctx, bool draw_osd) { bool proc = renderer->Process(ctx); if ((ctx->rend.isRTT || ctx->rend.isRenderFramebuffer) && swap_pending) { - // If there a frame swap pending, we want to do it now. + // If there is a frame swap pending, we want to do it now. // The current frame "swapping" detection mechanism (using FB_R_SOF1) doesn't work // if a RTT frame is rendered in between. renderer->Present(); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index dc32785f1..a95c4d407 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -653,10 +653,13 @@ void bm_Sort() RuntimeBlockInfo::~RuntimeBlockInfo() { - if (read_only) - protected_blocks--; - else - unprotected_blocks--; + if (sh4_code_size != 0) + { + if (read_only) + protected_blocks--; + else + unprotected_blocks--; + } } void RuntimeBlockInfo::AddRef(RuntimeBlockInfoPtr other) @@ -699,8 +702,7 @@ void RuntimeBlockInfo::Discard() void RuntimeBlockInfo::SetProtectedFlags() { // Don't write protect rom - // TODO Enable this for wince. hangs 4x4 EVO - if (mmu_enabled() || (!IsOnRam(addr) /*|| (vaddr & 0x1FFF0000) == 0x0C000000 */)) + if (!IsOnRam(addr)) { this->read_only = false; unprotected_blocks++; @@ -746,7 +748,7 @@ void bm_RamWriteAccess(u32 addr) verify(block_list.empty()); } -bool bm_RamWriteAccess(void *p, unat pc) +bool bm_RamWriteAccess(void *p) { if (_nvmem_4gb_space()) { diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index 0d135a117..293bd7124 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -106,7 +106,7 @@ void bm_Init(); void bm_Term(); void bm_vmem_pagefill(void** ptr,u32 PAGE_SZ); -bool bm_RamWriteAccess(void *p, unat pc); +bool bm_RamWriteAccess(void *p); void bm_RamWriteAccess(u32 addr); static inline bool bm_IsRamPageProtected(u32 addr) { diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index a9633c659..936d077cb 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -237,6 +237,7 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) { staging_runs=addr=lookups=runs=host_code_size=0; guest_cycles=guest_opcodes=host_opcodes=0; + sh4_code_size = 0; pBranchBlock=pNextBlock=0; code=0; has_jcond=false; diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 3a3b6df9a..879e7c887 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -71,7 +71,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) if (vmem32_handle_signal(si->si_addr, write, exception_pc)) return; #endif - if (bm_RamWriteAccess(si->si_addr, ctx.pc)) + if (bm_RamWriteAccess(si->si_addr)) return; if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr)) return; diff --git a/core/stdclass.h b/core/stdclass.h index 39640f5d8..7b6cd17d0 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -287,7 +287,7 @@ bool mem_region_release(void *start, size_t len); void *mem_region_map_file(void *file_handle, void *dest, size_t len, size_t offset, bool readwrite); bool mem_region_unmap_file(void *start, size_t len); -// Locked memory class, used for texture invalidation purposes. +// Locked memory class, was used for texture invalidation purposes. class VLockedMemory { public: u8* data; @@ -300,23 +300,7 @@ public: void *getPtr() const { return data; } unsigned getSize() const { return size; } - #ifdef TARGET_NO_EXCEPTIONS - void LockRegion(unsigned offset, unsigned size_bytes) {} - void UnLockRegion(unsigned offset, unsigned size_bytes) {} - #else - void LockRegion(unsigned offset, unsigned size_bytes) - { - mem_region_lock(&data[offset], size_bytes); - } - - void UnLockRegion(unsigned offset, unsigned size_bytes) - { - mem_region_unlock(&data[offset], size_bytes); - } - #endif - void Zero() { - UnLockRegion(0, size); memset(data, 0, size); } diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 7a9a2d39b..4caac6764 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -150,7 +150,7 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) if (vmem32_handle_signal(address, write, 0)) return EXCEPTION_CONTINUE_EXECUTION; #endif - if (bm_RamWriteAccess(address, 0)) + if (bm_RamWriteAccess(address)) { return EXCEPTION_CONTINUE_EXECUTION; } From 70ea7c4d769242730f0b9618c1d1c2b8aa26d36a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 20 Jun 2019 19:27:21 +0200 Subject: [PATCH 080/158] ssa: use canonical implementations to compute const ops --- core/hw/sh4/dyna/ssa.cpp | 90 +++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp index a27bc6fa4..3bf32258e 100644 --- a/core/hw/sh4/dyna/ssa.cpp +++ b/core/hw/sh4/dyna/ssa.cpp @@ -59,10 +59,10 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) rd = rs1; break; case shop_add: - rd = rs1 + rs2; + rd = shil_opcl_add::f1::impl(rs1, rs2); break; case shop_sub: - rd = rs1 - rs2; + rd = shil_opcl_sub::f1::impl(rs1, rs2); break; case shop_adc: case shop_sbc: @@ -86,7 +86,7 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) shil_param op2_rd = shil_param(op->rd2._reg); op2_rd.version[0] = op->rd2.version[0]; - InsertMov32Op(op2_rd, shil_param(FMT_IMM, (u32)(v >> 32))); + InsertMov32Op(op2_rd, shil_param(FMT_IMM, rd2)); // the previous insert might have invalidated our reference op = &block->oplist[opnum - 1]; @@ -94,17 +94,16 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) } break; case shop_shl: - rd = rs1 << rs2; + rd = shil_opcl_shl::f1::impl(rs1, rs2); break; case shop_shr: - rd = rs1 >> rs2; + rd = shil_opcl_shr::f1::impl(rs1, rs2); break; case shop_sar: - rd = (s32) rs1 >> rs2; + rd = shil_opcl_sar::f1::impl(rs1, rs2); break; case shop_ror: - rd = (rs1 >> rs2) - | (rs1 << (32 - rs2)); + rd = shil_opcl_ror::f1::impl(rs1, rs2); break; case shop_shld: rd = shil_opcl_shld::f1::impl(rs1, rs2); @@ -113,31 +112,31 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) rd = shil_opcl_shad::f1::impl(rs1, rs2); break; case shop_or: - rd = rs1 | rs2; + rd = shil_opcl_or::f1::impl(rs1, rs2); break; case shop_and: - rd = rs1 & rs2; + rd = shil_opcl_and::f1::impl(rs1, rs2); break; case shop_xor: - rd = rs1 ^ rs2; + rd = shil_opcl_xor::f1::impl(rs1, rs2); break; case shop_not: - rd = ~rs1; + rd = shil_opcl_not::f1::impl(rs1); break; case shop_ext_s16: - rd = (s32)(s16)rs1; + rd = shil_opcl_ext_s16::f1::impl(rs1); break; case shop_ext_s8: - rd = (s32)(s8)rs1; + rd = shil_opcl_ext_s8::f1::impl(rs1); break; case shop_mul_i32: - rd = rs1 * rs2; + rd = shil_opcl_mul_i32::f1::impl(rs1, rs2); break; case shop_mul_u16: - rd = (u16)(rs1 * rs2); + rd = shil_opcl_mul_u16::f1::impl(rs1, rs2); break; case shop_mul_s16: - rd = (s16)(rs1 * rs2); + rd = shil_opcl_mul_s16::f1::impl(rs1, rs2); break; case shop_mul_u64: case shop_mul_s64: @@ -160,10 +159,10 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) } break; case shop_test: - rd = (rs1 & rs2) == 0; + rd = shil_opcl_test::f1::impl(rs1, rs2); break; case shop_neg: - rd = -rs1; + rd = shil_opcl_neg::f1::impl(rs1); break; case shop_swaplb: rd = shil_opcl_swaplb::f1::impl(rs1); @@ -172,32 +171,19 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) rd = shil_opcl_swap::f1::impl(rs1); break; case shop_seteq: + rd = shil_opcl_seteq::f1::impl(rs1, rs2); + break; case shop_setgt: + rd = shil_opcl_setgt::f1::impl(rs1, rs2); + break; case shop_setge: + rd = shil_opcl_setge::f1::impl(rs1, rs2); + break; case shop_setab: + rd = shil_opcl_setab::f1::impl(rs1, rs2); + break; case shop_setae: - { - switch (op->op) - { - case shop_seteq: - rd = rs1 == rs2; - break; - case shop_setge: - rd = (s32)rs1 >= (s32)rs2; - break; - case shop_setgt: - rd = (s32)rs1 > (s32)rs2; - break; - case shop_setab: - rd = rs1 > rs2; - break; - case shop_setae: - rd = rs1 >= rs2; - break; - default: - break; - } - } + rd = shil_opcl_setae::f1::impl(rs1, rs2); break; case shop_setpeq: rd = shil_opcl_setpeq::f1::impl(rs1, rs2); @@ -273,42 +259,50 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) return true; } case shop_fneg: - rd = rs1 ^ 0x80000000; + { + f32 frd = shil_opcl_fneg::f1::impl(reinterpret_cast(rs1)); + rd = reinterpret_cast(frd); + } break; case shop_fadd: { - f32 frd = reinterpret_cast(rs1) + reinterpret_cast(rs2); + f32 frd = shil_opcl_fadd::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); rd = reinterpret_cast(frd); } break; case shop_fsub: { - f32 frd = reinterpret_cast(rs1) - reinterpret_cast(rs2); + f32 frd = shil_opcl_fsub::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); rd = reinterpret_cast(frd); } break; case shop_fmul: { - f32 frd = reinterpret_cast(rs1) * reinterpret_cast(rs2); + f32 frd = shil_opcl_fmul::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); rd = reinterpret_cast(frd); } break; case shop_fdiv: { - f32 frd = reinterpret_cast(rs1) / reinterpret_cast(rs2); + f32 frd = shil_opcl_fdiv::f1::impl(reinterpret_cast(rs1), reinterpret_cast(rs2)); rd = reinterpret_cast(frd); } break; case shop_cvt_i2f_n: + { + f32 frd = shil_opcl_cvt_i2f_n::f1::impl(rs1); + rd = reinterpret_cast(frd); + } + break; case shop_cvt_i2f_z: { - f32 frd = (float)(s32) rs1; + f32 frd = shil_opcl_cvt_i2f_z::f1::impl(rs1); rd = reinterpret_cast(frd); } break; case shop_fsqrt: { - f32 frd = sqrtf(reinterpret_cast(rs1)); + f32 frd = shil_opcl_fsqrt::f1::impl(reinterpret_cast(rs1)); rd = reinterpret_cast(frd); } break; From af2ba55bac896d83a9894b8e461d9f254329cc3c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 20 Jun 2019 19:31:43 +0200 Subject: [PATCH 081/158] rec-arm: fix immediate writem bug. clean up get rid of unused and unstable opts div32p2 implementation (untested) Fixed canonical test mode --- core/arm_emitter/E_DataOp.h | 15 ++- core/arm_emitter/E_LoadStore.h | 4 +- core/rec-ARM/rec_arm.cpp | 226 +++++++++++++-------------------- 3 files changed, 104 insertions(+), 141 deletions(-) diff --git a/core/arm_emitter/E_DataOp.h b/core/arm_emitter/E_DataOp.h index c9d8dafcb..046327ae1 100755 --- a/core/arm_emitter/E_DataOp.h +++ b/core/arm_emitter/E_DataOp.h @@ -591,6 +591,19 @@ ADD.SP.REG 0x008D0000 EMIT_I; } + EAPI SBFX(eReg Rd, eReg Rm, u8 lsb, u8 width, ConditionCode CC=AL) + { + DECL_Id(0x07A00050); + verify(lsb+width<=32); + + SET_CC; + I |= (Rd&15)<<12; + I |= (Rm&15); + I |= (lsb&31)<<7; + I |= ((width-1)&31)<<16; + EMIT_I; + } + EAPI MOV(eReg Rd, eReg Rm, ConditionCode CC=AL) { DECL_Id(0x01A00000); @@ -844,4 +857,4 @@ ADD.SP.REG 0x008D0000 -}; \ No newline at end of file +}; diff --git a/core/arm_emitter/E_LoadStore.h b/core/arm_emitter/E_LoadStore.h index 522ab07ba..f01ada76d 100644 --- a/core/arm_emitter/E_LoadStore.h +++ b/core/arm_emitter/E_LoadStore.h @@ -242,6 +242,8 @@ EAPI LDRH(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x005000B0 EAPI STRH(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000B0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; } EAPI LDRD(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000D0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; } EAPI STRD(eReg Rt, eReg Rn, s32 sImm8, ConditionCode CC=AL) { DECL_Id(0x004000F0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; } +EAPI LDRSB(eReg Rt, eReg Rn, s32 sImm8 = 0, ConditionCode CC = AL) { DECL_Id(0x005000D0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; } +EAPI LDRSH(eReg Rt, eReg Rn, s32 sImm8 = 0, ConditionCode CC = AL) { DECL_Id(0x005000F0); SET_CC; SET_Rtn; SET_P; SET_sImm8; EMIT_I; } EAPI LDRH(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x001000B0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; } EAPI STRH(eReg Rt, eReg Rn, eReg Rm, bool Add=true,ConditionCode CC=AL) { DECL_Id(0x000000B0); SET_CC; SET_Rtnm; SET_P; if (Add) {SET_U;} EMIT_I; } @@ -307,4 +309,4 @@ EAPI POP(u32 RegList, ConditionCode CC=AL) -}; \ No newline at end of file +}; diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index 76abd8706..250bb75bb 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -14,6 +14,8 @@ #define _DEVEL 1 #include "arm_emitter/arm_emitter.h" +//#define CANONICALTEST + /* ARM ABI @@ -303,8 +305,12 @@ u32 DynaRBI::Relink() { //quick opt here: //peek into reg alloc, store actuall sr_T register to relink_data +#ifndef CANONICALTEST bool last_op_sets_flags=!has_jcond && oplist.size() > 0 && oplist[oplist.size()-1].rd._reg==reg_sr_T && ccmap.count(oplist[oplist.size()-1].op); +#else + bool last_op_sets_flags = false; +#endif ConditionCode CC=CC_EQ; @@ -636,33 +642,34 @@ void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp) } } -void ngen_CC_Call(shil_opcode* op,void* function) +void ngen_CC_Call(shil_opcode* op, void* function) { - u32 rd=r0; - u32 fd=f0; + u32 rd = r0; + u32 fd = f0; - for (int i=CC_pars.size();i-->0;) + for (int i = CC_pars.size(); i-- > 0; ) { - if (CC_pars[i].type==CPT_ptr) + CC_PS& param = CC_pars[i]; + if (param.type == CPT_ptr) { - MOV32((eReg)rd, (u32)CC_pars[i].par->reg_ptr()); + MOV32((eReg)rd, (u32)param.par->reg_ptr()); } else { - if (CC_pars[i].par->is_reg()) + if (param.par->is_reg()) { #ifdef ARM_HARDFP - if (CC_pars[i].type == CPT_f32) + if (param.type == CPT_f32) { - if (reg.IsAllocg(*CC_pars[i].par)) + if (reg.IsAllocg(*param.par)) { - //printf("MOV((eReg)rd,reg.map(*CC_pars[i].par)); %d %d\n",rd,reg.map(*CC_pars[i].par)); - VMOV((eFSReg)fd,reg.mapg(*CC_pars[i].par)); + //printf("MOV((eReg)rd,reg.map(*param.par)); %d %d\n",rd,reg.map(*param.par)); + VMOV((eFSReg)fd, reg.mapg(*param.par)); } - else if (reg.IsAllocf(*CC_pars[i].par)) + else if (reg.IsAllocf(*param.par)) { - //printf("LoadSh4Reg_mem((eReg)rd, *CC_pars[i].par); %d\n",rd); - VMOV((eFSReg)fd,reg.mapfs(*CC_pars[i].par)); + //printf("LoadSh4Reg_mem((eReg)rd, *param.par); %d\n",rd); + VMOV((eFSReg)fd, reg.mapfs(*param.par)); } else die("Must not happen!\n"); @@ -670,27 +677,28 @@ void ngen_CC_Call(shil_opcode* op,void* function) } #endif - if (reg.IsAllocg(*CC_pars[i].par)) + if (reg.IsAllocg(*param.par)) { - //printf("MOV((eReg)rd,reg.map(*CC_pars[i].par)); %d %d\n",rd,reg.map(*CC_pars[i].par)); - MOV((eReg)rd,reg.mapg(*CC_pars[i].par)); + //printf("MOV((eReg)rd,reg.map(*param.par)); %d %d\n",rd,reg.map(*param.par)); + MOV((eReg)rd, reg.mapg(*param.par)); } - else if (reg.IsAllocf(*CC_pars[i].par)) + else if (reg.IsAllocf(*param.par)) { - //printf("LoadSh4Reg_mem((eReg)rd, *CC_pars[i].par); %d\n",rd); - VMOV((eReg)rd,reg.mapfs(*CC_pars[i].par)); + //printf("LoadSh4Reg_mem((eReg)rd, *param.par); %d\n",rd); + VMOV((eReg)rd, reg.mapfs(*param.par)); } else die("Must not happen!\n"); } else { - verify(CC_pars[i].type != CPT_f32); - //printf("MOV32((eReg)rd, CC_pars[i].par->_imm); %d\n",rd); - MOV32((eReg)rd, CC_pars[i].par->_imm); + verify(param.par->is_imm()); + //printf("MOV32((eReg)rd, param.par->_imm); %d\n",rd); + MOV32((eReg)rd, param.par->_imm); } } rd++; + fd++; } //printf("used reg r0 to r%d, %d params, calling %08X\n",rd-1,CC_pars.size(),function); CALL((u32)function); @@ -1020,9 +1028,14 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr) return (u32*)ptr; } -EAPI NEG(eReg Rd,eReg Rs) +EAPI NEG(eReg Rd, eReg Rs) { - RSB(Rd,Rs,0); + RSB(Rd, Rs, 0); +} + +EAPI NEG(eReg Rd, eReg Rs, ConditionCode CC) +{ + RSB(Rd, Rs, 0, CC); } eReg GenMemAddr(shil_opcode* op, eReg raddr = r0) @@ -1072,92 +1085,48 @@ bool ngen_readm_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool staging if (isram) { + MOV32(r0, (u32)ptr); switch(optp) { case SZ_8: - { - verify(false); - MOV32(r0, (u32)ptr); - LDRB(rd, r0); - SXTB(rd, rd); - } + LDRSB(rd, r0); break; case SZ_16: - { - LoadImmBase16(rd, (u32)ptr, true); // true for sx - } + LDRSH(rd, r0); break; case SZ_32I: - { - verify(reg.IsAllocg(op->rd)); - { - if (optimise && staging && !is_s8(*(u32*)ptr) && abs((int)op->rs1._imm - (int)block->addr) <= 1024) - { - op->flags |= 0x40000000; - - MOV32(r0, (u32)ptr); - LDR(rd, r0); - MOV32(r1, *(u32*)ptr); - CMP(rd, r1); - //JUMP((unat)EMIT_GET_PTR() + 24, CC_EQ); - MOV32(r1, (u32)&op->flags); - MOV32(r2, ~0x40000000); - LDR(r3, r1); - AND(r3, r3, r2, CC_NE); - STR(r3, r1); - } - else if (optimise && !staging && (op->flags & 0x40000000)) - { - MOV32(rd, *(u32*)ptr); - } - else - { - MOV32(r0, (u32)ptr); - LDR(rd, r0); - } - } - } + LDR(rd, r0); break; case SZ_32F: - { - verify(reg.IsAllocf(op->rd)); - MOV32(r0, (u32)ptr); - VLDR(reg.mapfs(op->rd), r0, 0); - - } + VLDR(reg.mapfs(op->rd), r0, 0); break; case SZ_64F: - { - MOV32(r0, (u32)ptr); - VLDR(d0, r0, 0); - VSTR(d0, r8, op->rd.reg_nofs() / 4); - } + VLDR(d0, r0, 0); + VSTR(d0, r8, op->rd.reg_nofs() / 4); break; } } else { MOV32(r0, op->rs1._imm); + CALL((u32)ptr); switch(optp) { case SZ_8: - CALL((u32)ptr); SXTB(r0, r0); break; case SZ_16: - CALL((u32)ptr); SXTH(r0, r0); break; case SZ_32I: case SZ_32F: - CALL((u32)ptr); break; case SZ_64F: @@ -1169,6 +1138,8 @@ bool ngen_readm_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool staging MOV(rd, r0); else if (reg.IsAllocf(op->rd)) VMOV(reg.mapfs(op->rd), r0); + else + die("Unsupported"); } return true; @@ -1184,20 +1155,14 @@ bool ngen_writemem_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool stag void* ptr = _vmem_write_const(op->rs1._imm, isram, memop_bytes(optp)); eReg rs2 = r1; - eFSReg rs2f = f1; + eFSReg rs2f = f0; if (op->rs2.is_imm()) - { MOV32(rs2, op->rs2._imm); - if (optp == SZ_32F) - VMOV(rs2f, rs2); - } + else if (optp == SZ_32F) + rs2f = reg.mapf(op->rs2); else - { - if (optp == SZ_32F) - rs2f = reg.mapf(op->rs2); - else - rs2 = reg.mapg(op->rs2); - } + rs2 = reg.mapg(op->rs2); + if (isram) { MOV32(r0, (u32)ptr); @@ -1208,7 +1173,7 @@ bool ngen_writemem_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool stag break; case SZ_16: - STRH(rs2, r0); + STRH(rs2, r0, 0); break; case SZ_32I: @@ -1229,7 +1194,9 @@ bool ngen_writemem_immediate(RuntimeBlockInfo* block, shil_opcode* op, bool stag if (optp == SZ_64F) die("SZ_64F not supported"); MOV32(r0, op->rs1._imm); - if (r1 != rs2) + if (optp == SZ_32F) + VMOV(r1, rs2f); + else if (r1 != rs2) MOV(r1, rs2); CALL((u32)ptr); @@ -1351,45 +1318,17 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, break; case SZ_32I: - if (op->flags2!=0x1337) - STR(rs2, r1, r8, Offset, true); - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - STR(rs2, r1, sq_offs); - } + STR(rs2, r1, r8, Offset, true); break; case SZ_32F: - if (op->flags2!=0x1337) - { - ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ - VSTR(rs2f, r1, 0); - } - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - VSTR(rs2f, r1, sq_offs / 4); - } + ADD(r1, r1, r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ + VSTR(rs2f, r1, 0); break; case SZ_64F: - if (op->flags2!=0x1337) - { - ADD(r1,r1,r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ - VSTR(d0,r1,0); //TODO: use reg alloc - } - else - { - emit_Skip(-4); - AND(r1,raddr,0x3F); - ADD(r1,r1,r8); - VSTR(d0,r1,sq_offs/4); - } + ADD(r1, r1, r8); //3 opcodes: there's no [REG+REG] VLDR, also required for SQ + VSTR(d0, r1, 0); //TODO: use reg alloc break; } } else { @@ -1427,8 +1366,8 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, verify(op->rd.is_reg() && op->rd._reg==reg_pc_dyn); if (op->rs2.is_imm()) { - MOV32(r2, (u32)op->rs2._imm); - ADD(r4,reg.mapg(op->rs1),r2); + MOV32(r2, op->rs2.imm_value()); + ADD(r4, reg.mapg(op->rs1), r2); } else //if (r4!=rs1.reg) { @@ -1547,7 +1486,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, break; } -//#define CANONICALTEST #ifndef CANONICALTEST case shop_neg: ngen_Unary(op,NEG); break; case shop_not: ngen_Unary(op,NOT); break; @@ -1564,7 +1502,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_add: ngen_Binary(op,ADD,ADD); break; case shop_sub: ngen_Binary(op,SUB,SUB); break; case shop_ror: ngen_Binary(op,ROR,ROR); break; - case shop_adc: { @@ -1598,7 +1535,6 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, eReg rs1 = GetParam(op->rs1, r1); eReg rs2 = GetParam(op->rs2, r2); if (rd2 != rs1) { - verify(rd2 != rs1); LSR(rd2, rs2, 1, true); //C=rs2, rd2=0 AND(rd2, rs1, 1); //get new carry } else { @@ -1698,14 +1634,24 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, CALL((u32)UpdateSR); break; } - /* TODO Update this to use quotient sign as well + case shop_div32p2: { - CMP(reg.mapg(op->rs3), 0); - SUB(reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2), CC_EQ); + eReg remainder = reg.mapg(op->rs1); + eReg divisor = reg.mapg(op->rs2); + eReg T = reg.mapg(op->rs3); + + LSR(r0, T, 31); + EOR(r0, r0, T); + NOT(r0, r0); + SBFX(r0, r0, 0, 1); + AND(r0, r0, divisor); + TST(T, 1); + NEG(r1, r0, EQ); + MOV(r1, r0, NE); + ADD(reg.mapg(op->rd), remainder, r1); } break; - */ case shop_test: case shop_seteq: @@ -1758,7 +1704,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, MOVW(rd, 1, opcls2[op->op-shop_test]); break; } - + case shop_setpeq: { eReg rs1 = GetParam(op->rs1, r1); @@ -1804,12 +1750,14 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, break; case shop_mul_u64: { - UMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2)); + eReg rs2 = GetParam(op->rs2, r2); + UMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), rs2); } break; case shop_mul_s64: { - SMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), reg.mapg(op->rs2)); + eReg rs2 = GetParam(op->rs2, r2); + SMULL(reg.mapg(op->rd2), reg.mapg(op->rd), reg.mapg(op->rs1), rs2); } break; @@ -1872,7 +1820,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_pref: { ConditionCode cc = CC_EQ; - if (op->flags != 0x1337 && !op->rs1.is_imm()) + if (!op->rs1.is_imm()) { LSR(r1,reg.mapg(op->rs1),26); MOV(r0,reg.mapg(op->rs1)); @@ -1880,15 +1828,15 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, } else { - // The decoder or SSA pass has already checked that the + // The SSA pass has already checked that the // destination is a store queue so no need to check - MOV(r0,reg.mapg(op->rs1)); + MOV32(r0, op->rs1.imm_value()); cc = CC_AL; } if (CCN_MMUCR.AT) { - CALL((unat)&do_sqw_mmu,op->flags==0x1337?CC_AL:CC_EQ); + CALL((unat)&do_sqw_mmu, cc); } else { From 3e8cdc76f32abd76fa2cc5e74206a393bc9e9a41 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 21 Jun 2019 13:17:34 +0200 Subject: [PATCH 082/158] wince: fix load state hanging --- core/hw/mem/vmem32.cpp | 7 ++++--- core/nullDC.cpp | 10 ++++++++-- core/serialize.cpp | 16 ++++++++-------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index d27fa569e..90fb531ad 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -56,7 +56,7 @@ extern int vmem_fd; #define VMEM32_ERROR_NOT_MAPPED 0x100 static const u64 VMEM32_SIZE = 0x100000000L; -static const u64 KERNEL_SPACE = 0x80000000L; +static const u64 USER_SPACE = 0x80000000L; static const u64 AREA7_ADDRESS = 0x7C000000L; #define VRAM_PROT_SEGMENT (1024 * 1024) // vram protection regions are grouped by 1MB segment @@ -67,7 +67,7 @@ struct vram_lock { u32 end; }; static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; -static u8 sram_mapped_pages[KERNEL_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped +static u8 sram_mapped_pages[USER_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped bool vmem32_inited; @@ -368,7 +368,7 @@ void vmem32_flush_mmu() //vmem32_flush++; vram_mapped_pages.clear(); memset(sram_mapped_pages, 0, sizeof(sram_mapped_pages)); - vmem32_unmap_buffer(0, KERNEL_SPACE); + vmem32_unmap_buffer(0, USER_SPACE); // TODO flush P3? } @@ -380,6 +380,7 @@ bool vmem32_init() if (settings.dynarec.disable_vmem32 || !_nvmem_4gb_space()) return false; vmem32_inited = true; + vmem32_flush_mmu(); return true; #endif } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index ef8e2166b..7b7224621 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -455,7 +455,13 @@ void* dc_run(void*) do { reset_requested = false; - sh4_cpu.Run(); + try { + sh4_cpu.Run(); + } catch (const FatalError& error) { + printf("FATAL: %s in %s:%d: %s\n", error.message.c_str(), error.file.c_str(), error.line, error.function.c_str()); + reset_requested = false; + sh4_cpu.Stop(); + } SaveRomFiles(get_writable_data_path("/data/")); if (reset_requested) @@ -949,6 +955,7 @@ void dc_loadstate() #ifndef NO_MMU mmu_flush_table(); #endif + bm_Reset(); if ( ! dc_unserialize(&data_ptr, &total_size) ) { @@ -959,7 +966,6 @@ void dc_loadstate() } mmu_set_state(); - bm_Reset(); sh4_cpu.ResetCache(); dsp.dyndirty = true; sh4_sched_ffts(); diff --git a/core/serialize.cpp b/core/serialize.cpp index 8e8e54b4a..e5f4538eb 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -671,8 +671,8 @@ extern Sh4RegType div_som_reg3; //extern u8 SH4_TCB[CODE_SIZE+4096]; //one time ptr set //extern u8* CodeCache; -extern u32 LastAddr; -extern u32 LastAddr_min; +//extern u32 LastAddr; +//extern u32 LastAddr_min; //temp storage only //extern u32* emit_ptr; extern char block_hash[1024]; @@ -1097,8 +1097,8 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(div_som_reg2); REICAST_S(div_som_reg3); - REICAST_S(LastAddr); - REICAST_S(LastAddr_min); + REICAST_S(i); //LastAddr + REICAST_S(i); //LastAddr_min REICAST_SA(block_hash,1024); REICAST_SA(RegisterWrite,sh4_reg_count); @@ -1492,8 +1492,8 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) //REICAST_USA(CodeCache,CODE_SIZE) ; //REICAST_USA(SH4_TCB,CODE_SIZE+4096); - REICAST_US(LastAddr); - REICAST_US(LastAddr_min); + REICAST_US(i); //LastAddr + REICAST_US(i); //LastAddr_min REICAST_USA(block_hash,1024); @@ -1870,8 +1870,8 @@ bool dc_unserialize(void **data, unsigned int *total_size) //REICAST_USA(CodeCache,CODE_SIZE) ; //REICAST_USA(SH4_TCB,CODE_SIZE+4096); - REICAST_US(LastAddr); - REICAST_US(LastAddr_min); + REICAST_US(i); //LastAddr + REICAST_US(i); //LastAddr_min); REICAST_USA(block_hash,1024); REICAST_USA(RegisterWrite,sh4_reg_count); From 5b2ad02fa25772eded6e76542dfd670087321694 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 21 Jun 2019 13:33:55 +0200 Subject: [PATCH 083/158] this wasn't supposed to be committed --- core/nullDC.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 7b7224621..222ca241e 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -455,13 +455,7 @@ void* dc_run(void*) do { reset_requested = false; - try { - sh4_cpu.Run(); - } catch (const FatalError& error) { - printf("FATAL: %s in %s:%d: %s\n", error.message.c_str(), error.file.c_str(), error.line, error.function.c_str()); - reset_requested = false; - sh4_cpu.Stop(); - } + sh4_cpu.Run(); SaveRomFiles(get_writable_data_path("/data/")); if (reset_requested) From 49b49c52072e66bb1d47eac95d7db12970aae110 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 21 Jun 2019 16:18:34 +0200 Subject: [PATCH 084/158] don't write-protect BIOS and IP.BIN blocks Fixes Grandia II crash at start on arm. Fix bug in bm_GetBlock() --- core/hw/sh4/dyna/blockmanager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index a95c4d407..864a14212 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -129,10 +129,12 @@ RuntimeBlockInfoPtr bm_GetBlock(void* dynarec_code) void *dynarecrw = CC_RX2RW(dynarec_code); // Returns a block who's code addr is bigger than dynarec_code (or end) auto iter = blkmap.upper_bound(dynarecrw); + if (iter == blkmap.begin()) + return NULL; iter--; // Need to go back to find the potential candidate // However it might be out of bounds, check for that - if ((u8*)iter->second->code + iter->second->host_code_size < dynarec_code) + if ((u8*)iter->second->code + iter->second->host_code_size < (u8*)dynarec_code) return NULL; verify(iter->second->contains_code((u8*)dynarecrw)); @@ -701,8 +703,8 @@ void RuntimeBlockInfo::Discard() void RuntimeBlockInfo::SetProtectedFlags() { - // Don't write protect rom - if (!IsOnRam(addr)) + // Don't write protect rom and BIOS/IP.BIN (Grandia II) + if (!IsOnRam(addr) || (vaddr & 0x1FFF0000) == 0x0c000000) { this->read_only = false; unprotected_blocks++; From 862d892e89cfa7f91666d2a4411f36befce16d82 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 21 Jun 2019 23:31:45 +0200 Subject: [PATCH 085/158] texture corruption resulting from misaligned page unprotection --- core/rend/TexCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index 8ed8e3219..e68a28ee2 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -244,7 +244,7 @@ bool VramLockedWriteOffset(size_t offset) } list->clear(); - _vmem_unprotect_vram((u32)offset, PAGE_SIZE); + _vmem_unprotect_vram((u32)(offset & ~PAGE_MASK), PAGE_SIZE); vramlist_lock.Unlock(); } From 112e272075ba454fd30de86e72d550c5b45b604e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 23 Jun 2019 12:17:24 +0200 Subject: [PATCH 086/158] renderer: support non-integer v-scaling factor Fixes missing half-screen in Wacky Races (PAL), Buzz Lightyear of Star Command (PAL), Tom Clancy's Rainbow Six - Rogue Spear + Mission Pack - Urban Operations (PAL), Sega Worldwide Soccer 2000 (PAL) Input record and replay support for test automation --- core/hw/pvr/spg.cpp | 4 ++ core/input/gamepad_device.cpp | 73 +++++++++++++++++++++++++++++++- core/input/gamepad_device.h | 5 +++ core/rend/gl4/gles.cpp | 8 ++-- core/rend/gles/gles.cpp | 78 ++++++++++++++++++++++++++++++++--- shell/linux/Makefile | 4 ++ 6 files changed, 162 insertions(+), 10 deletions(-) diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index a83a482af..053baa5b7 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -4,6 +4,7 @@ #include "hw/holly/holly_intc.h" #include "oslib/oslib.h" #include "hw/sh4/sh4_sched.h" +#include "input/gamepad_device.h" //SPG emulation; Scanline/Raster beam registers & interrupts //Time to emulate that stuff correctly ;) @@ -145,6 +146,9 @@ int spg_line_sched(int tag, int cycl, int jit) vblk_cnt++; //TODO : rend_if_VBlank(); rend_vblank();//notify for vblank :) +#ifdef TEST_AUTOMATION + replay_input(); +#endif if ((os_GetSeconds()-last_fps)>2) { diff --git a/core/input/gamepad_device.cpp b/core/input/gamepad_device.cpp index 82ccefdf8..632eccd30 100644 --- a/core/input/gamepad_device.cpp +++ b/core/input/gamepad_device.cpp @@ -34,6 +34,11 @@ extern s8 joyx[4], joyy[4]; std::vector> GamepadDevice::_gamepads; std::mutex GamepadDevice::_gamepads_mutex; +#ifdef TEST_AUTOMATION +#include "hw/sh4/sh4_sched.h" +static FILE *record_input; +#endif + bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed) { if (_input_detected != NULL && _detecting_button @@ -86,6 +91,10 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed) } else kcode[_maple_port] |= (u16)key; +#ifdef TEST_AUTOMATION + if (record_input != NULL) + fprintf(record_input, "%ld button %x %04x\n", sh4_sched_now64(), _maple_port, kcode[_maple_port]); +#endif } else { @@ -288,13 +297,35 @@ void GamepadDevice::detect_axis_input(input_detected_cb axis_moved) _detection_start_time = os_GetSeconds() + 0.2; } +#ifdef TEST_AUTOMATION +static FILE *get_record_input(bool write) +{ + if (write && !cfgLoadBool("record", "record_input", false)) + return NULL; + if (!write && !cfgLoadBool("record", "replay_input", false)) + return NULL; + string game_dir = cfgLoadStr("config", "image", ""); + size_t slash = game_dir.find_last_of("/"); + size_t dot = game_dir.find_last_of("."); + string input_file = "scripts/" + game_dir.substr(slash + 1, dot - slash) + "input"; + return fopen(input_file.c_str(), write ? "w" : "r"); +} +#endif + void GamepadDevice::Register(std::shared_ptr gamepad) { int maple_port = cfgLoadInt("input", (MAPLE_PORT_CFG_PREFIX + gamepad->unique_id()).c_str(), 12345); if (maple_port != 12345) gamepad->set_maple_port(maple_port); - +#ifdef TEST_AUTOMATION + if (record_input == NULL) + { + record_input = get_record_input(true); + if (record_input != NULL) + setbuf(record_input, NULL); + } +#endif _gamepads_mutex.lock(); _gamepads.push_back(gamepad); _gamepads_mutex.unlock(); @@ -321,3 +352,43 @@ void GamepadDevice::SaveMaplePorts() cfgSaveInt("input", (MAPLE_PORT_CFG_PREFIX + gamepad->unique_id()).c_str(), gamepad->maple_port()); } } + +#ifdef TEST_AUTOMATION +static bool replay_inited; +FILE *replay_file; +u64 next_event; +u32 next_port; +u32 next_kcode; +bool do_screenshot; + +void replay_input() +{ + if (!replay_inited) + { + replay_file = get_record_input(false); + replay_inited = true; + } + if (replay_file == NULL) + { + if (next_event > 0 && sh4_sched_now64() - next_event > SH4_MAIN_CLOCK * 5) + die("Automation time-out after 5 s\n"); + return; + } + u64 now = sh4_sched_now64(); + while (next_event <= now) + { + if (next_event > 0) + kcode[next_port] = next_kcode; + + char action[32]; + if (fscanf(replay_file, "%ld %s %x %x\n", &next_event, action, &next_port, &next_kcode) != 4) + { + fclose(replay_file); + replay_file = NULL; + printf("Input replay terminated\n"); + do_screenshot = true; + break; + } + } +} +#endif diff --git a/core/input/gamepad_device.h b/core/input/gamepad_device.h index 92a75692d..11b3d8279 100644 --- a/core/input/gamepad_device.h +++ b/core/input/gamepad_device.h @@ -91,3 +91,8 @@ private: static std::vector> _gamepads; static std::mutex _gamepads_mutex; }; + +#ifdef TEST_AUTOMATION +void replay_input(); +#endif + diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 4d3003569..056489562 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -657,7 +657,7 @@ static bool RenderFrame() scale_x=fb_scale_x; scale_y=fb_scale_y; if (SCALER_CTL.interlace == 0 && SCALER_CTL.vscalefactor >= 0x400) - scale_y *= SCALER_CTL.vscalefactor / 0x400; + scale_y *= (float)SCALER_CTL.vscalefactor / 0x400; //work out scaling parameters ! //Pixel doubling is on VO, so it does not affect any pixel operations @@ -719,7 +719,7 @@ static bool RenderFrame() gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; - //printf("scale: %f, %f, %f, %f\n",gl4ShaderUniforms.scale_coefs[0],gl4ShaderUniforms.scale_coefs[1],gl4ShaderUniforms.scale_coefs[2],gl4ShaderUniforms.scale_coefs[3]); + //printf("scale: %f, %f, %f, %f\n", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]); //VERT and RAM fog color constants u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT; @@ -873,8 +873,8 @@ static bool RenderFrame() if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor >= 0x400) { // Clipping is done after scaling/filtering so account for that if enabled - height *= SCALER_CTL.vscalefactor / 0x400; - min_y *= SCALER_CTL.vscalefactor / 0x400; + height *= (float)SCALER_CTL.vscalefactor / 0x400; + min_y *= (float)SCALER_CTL.vscalefactor / 0x400; } if (settings.rend.Rotate90) { diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 0f65d02b4..ebaf90e35 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -33,6 +33,7 @@ int fbdev = -1; #ifdef _ANDROID #include // requires ndk r5 or newer #endif +#include "deps/libpng/png.h" /* GL|ES 2 @@ -446,6 +447,48 @@ int screen_width; int screen_height; GLuint fogTextureId; +#ifdef TEST_AUTOMATION +void dump_screenshot(u8 *buffer, u32 width, u32 height) +{ + FILE *fp = fopen("screenshot.png", "wb"); + if (fp == NULL) + { + printf("Failed to open screenshot.png for writing\n"); + return; + } + + png_bytepp rows = (png_bytepp)malloc(height * sizeof(png_bytep)); + for (int y = 0; y < height; y++) + { + rows[height - y - 1] = (png_bytep)buffer + y * width * 3; + } + + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_infop info_ptr = png_create_info_struct(png_ptr); + + png_init_io(png_ptr, fp); + + + // write header + png_set_IHDR(png_ptr, info_ptr, width, height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + + // write bytes + png_write_image(png_ptr, rows); + + // end write + png_write_end(png_ptr, NULL); + fclose(fp); + + free(rows); + +} +#endif + #ifdef USE_EGL extern "C" void load_gles_symbols(); @@ -819,6 +862,33 @@ GLuint fogTextureId; void gl_swap() { +#ifdef TEST_AUTOMATION + static FILE* video_file = fopen(cfgLoadStr("record", "rawvid","").c_str(), "wb"); + extern bool do_screenshot; + + if (video_file) + { + int bytesz = screen_width * screen_height * 3; + u8* img = new u8[bytesz]; + + glReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, img); + fwrite(img, 1, bytesz, video_file); + fflush(video_file); + } + + if (do_screenshot) + { + extern void dc_exit(); + int bytesz = screen_width * screen_height * 3; + u8* img = new u8[bytesz]; + + glReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, img); + dump_screenshot(img, screen_width, screen_height); + delete[] img; + dc_exit(); + exit(0); + } +#endif glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); Window win; @@ -1655,7 +1725,7 @@ bool RenderFrame() scale_x=fb_scale_x; scale_y=fb_scale_y; if (SCALER_CTL.interlace == 0 && SCALER_CTL.vscalefactor >= 0x400) - scale_y *= SCALER_CTL.vscalefactor / 0x400; + scale_y *= (float)SCALER_CTL.vscalefactor / 0x400; //work out scaling parameters ! //Pixel doubling is on VO, so it does not affect any pixel operations @@ -1908,8 +1978,8 @@ bool RenderFrame() if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor >= 0x400) { // Clipping is done after scaling/filtering so account for that if enabled - height *= SCALER_CTL.vscalefactor / 0x400; - min_y *= SCALER_CTL.vscalefactor / 0x400; + height *= (float)SCALER_CTL.vscalefactor / 0x400; + min_y *= (float)SCALER_CTL.vscalefactor / 0x400; } if (settings.rend.Rotate90) { @@ -2027,8 +2097,6 @@ struct glesrend : Renderer }; -#include "deps/libpng/png.h" - FILE* pngfile; void png_cstd_read(png_structp png_ptr, png_bytep data, png_size_t length) diff --git a/shell/linux/Makefile b/shell/linux/Makefile index 355903c09..d0e6d529b 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -392,6 +392,10 @@ ifdef HAS_SOFTREND CXXFLAGS += -DTARGET_SOFTREND endif +ifdef TEST_AUTOMATION + CFLAGS += -DTEST_AUTOMATION +endif + EXECUTABLE_STRIPPED=nosym-reicast.$(PLATFORM_EXT) ifdef NAOMI CFLAGS += -D TARGET_NAOMI From 91717d706a7143100ed08da0d88a58989027467d Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 23 Jun 2019 17:06:59 +0200 Subject: [PATCH 087/158] wince: disable vmem32 for Marionette Company 1 & 2 and Rune Jade --- core/nullDC.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 222ca241e..7dceaf2b1 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -199,7 +199,13 @@ void LoadSpecialSettings() // Resident Evil 2 (US) || !strncmp("T1205N", reios_product_number, 6) // Resident Evil 2 (EU) - || !strncmp("T7004D 50", reios_product_number, 10)) + || !strncmp("T7004D 50", reios_product_number, 10) + // Rune Jade + || !strncmp("T14304M", reios_product_number, 7) + // Marionette Company + || !strncmp("T5202M", reios_product_number, 6) + // Marionette Company 2 + || !strncmp("T5203M", reios_product_number, 6)) { printf("Disabling 32-bit virtual memory for game %s\n", reios_product_number); settings.dynarec.disable_vmem32 = true; From f862903a74356fd5274138971a31a17c77dc1764 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 23 Jun 2019 21:30:46 +0200 Subject: [PATCH 088/158] Don't unprotect vram when a texture is updated Adjacent textures in other pages still need vram protection Fixes texture corruption in many games since ad5ab6240b45e1c41402b8ad902cf0a9f5441944 --- core/hw/mem/_vmem.cpp | 1 - core/rend/TexCache.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index a3af713c3..ec349bb36 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -724,7 +724,6 @@ void _vmem_unprotect_vram(u32 addr, u32 size) //mem_region_unlock(virt_ram_base + 0xA4000000 + addr + VRAM_SIZE, size); //mem_region_unlock(virt_ram_base + 0xC4000000 + addr + VRAM_SIZE, size); } - vmem32_unprotect_vram(addr, size); } } diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index e68a28ee2..2fc09c0ac 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -279,7 +279,8 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block) msgboxf("Error : block end is after vram , skipping unlock",MBX_OK); else { - _vmem_unprotect_vram(block->start, block->len); + if (mmu_enabled()) + vmem32_unprotect_vram(block->start, block->len); vramlock_list_remove(block); //more work needed free(block); From c27975fb3763f3ccfa18f49f6af9b2f8eee14178 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 24 Jun 2019 18:56:09 +0200 Subject: [PATCH 089/158] ssa: don't propagate const over interpreter fallback, sync_sr and sync_fpscr rec-x64: support immediate args for xtract Set write rtt to vram for Super Speed Racing (a.k.a Flag to Flag) --- core/hw/sh4/dyna/ssa.h | 37 +++++++++++++++++++++++++++++++++---- core/nullDC.cpp | 6 ++++-- core/rec-x64/rec_x64.cpp | 20 ++++++++++++++------ 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 0252c956a..523230b8d 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -37,12 +37,14 @@ public: { AddVersionPass(); #if DEBUG - printf("BEFORE\n"); - PrintBlock(); + printf("BEFORE\n"); + PrintBlock(); #endif ConstPropPass(); - WriteAfterWritePass(); + // This should only be done for ram/vram/aram access + // Disabled for now and probably not worth the trouble + //WriteAfterWritePass(); DeadCodeRemovalPass(); SimplifyExpressionPass(); CombineShiftsPass(); @@ -170,7 +172,34 @@ private: if (op.op != shop_fmac && op.op != shop_adc) ConstPropOperand(op.rs3); - if (op.op == shop_readm || op.op == shop_writem) + if (op.op == shop_ifb) + { + constprop_values.clear(); + } + else if (op.op == shop_sync_sr) + { + for (auto it = constprop_values.begin(); it != constprop_values.end(); ) + { + Sh4RegType reg = it->first.get_reg(); + if (reg == reg_sr_status || reg == reg_old_sr_status || (reg >= reg_r0 && reg <= reg_r7) + || (reg >= reg_r0_Bank && reg <= reg_r7_Bank)) + it = constprop_values.erase(it); + else + it++; + } + } + else if (op.op == shop_sync_fpscr) + { + for (auto it = constprop_values.begin(); it != constprop_values.end(); ) + { + Sh4RegType reg = it->first.get_reg(); + if (reg == reg_fpscr || reg == reg_old_fpscr || (reg >= reg_fr_0 && reg <= reg_xf_15)) + it = constprop_values.erase(it); + else + it++; + } + } + else if (op.op == shop_readm || op.op == shop_writem) { if (op.rs1.is_imm()) { diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 7dceaf2b1..7218173b4 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -158,8 +158,10 @@ void LoadSpecialSettings() || !strncmp("T40204D", reios_product_number, 7) // Skies of Arcadia || !strncmp("MK-51052", reios_product_number, 8) - // Flag to Flag - || !strncmp("MK-51007", reios_product_number, 8)) + // Flag to Flag (US) + || !strncmp("MK-51007", reios_product_number, 8) + // Super Speed Racing (JP) + || !strncmp("HDR-0013", reios_product_number, 8)) { settings.rend.RenderToTextureBuffer = 1; rtt_to_buffer_game = true; diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 59349d5f2..b315d18ff 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -948,9 +948,17 @@ public: case shop_xtrct: { Xbyak::Reg32 rd = regalloc.MapRegister(op.rd); - Xbyak::Reg32 rs1 = regalloc.MapRegister(op.rs1); - Xbyak::Reg32 rs2 = regalloc.MapRegister(op.rs2); - if (regalloc.mapg(op.rd) == regalloc.mapg(op.rs2)) + Xbyak::Reg32 rs1 = ecx; + if (op.rs1.is_reg()) + rs1 = regalloc.MapRegister(op.rs1); + else + mov(rs1, op.rs1.imm_value()); + Xbyak::Reg32 rs2 = eax; + if (op.rs2.is_reg()) + rs2 = regalloc.MapRegister(op.rs2); + else + mov(rs2, op.rs2.imm_value()); + if (rd == rs2) { shl(rd, 16); mov(eax, rs1); @@ -958,7 +966,7 @@ public: or_(rd, eax); break; } - else if (regalloc.mapg(op.rd) != regalloc.mapg(op.rs1)) + else if (rd != rs1) { mov(rd, rs1); } @@ -1693,7 +1701,7 @@ private: mov(dword[rax], op.rs2._imm); else { - mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(rcx, (uintptr_t)op.rs2.reg_ptr()); mov(ecx, dword[rcx]); mov(dword[rax], ecx); } @@ -1711,7 +1719,7 @@ private: else #endif { - mov(rcx, (uintptr_t)op.rd.reg_ptr()); + mov(rcx, (uintptr_t)op.rs2.reg_ptr()); mov(rcx, qword[rcx]); mov(qword[rax], rcx); } From 7dab84fd8012e93d927d2340810471ace850a3ce Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 24 Jun 2019 22:56:07 +0200 Subject: [PATCH 090/158] vmem handlers: last block wasn't mapped --- core/hw/mem/_vmem.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index dc31d93c4..c75974540 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -75,7 +75,13 @@ void _vmem_map_handler(_vmem_handler Handler,u32 start,u32 end); void _vmem_map_block(void* base,u32 start,u32 end,u32 mask); void _vmem_mirror_mapping(u32 new_region,u32 start,u32 size); -#define _vmem_map_block_mirror(base,start,end,blck_size) {u32 block_size=(blck_size)>>24;u32 map_sz=(end)-(start)+1;/*verify((map_sz%block_size)==0);u32 map_times=map_sz/(block_size);*/ for (u32 _maip=(start);_maip<(end);_maip+=block_size) _vmem_map_block((base),_maip,_maip+block_size-1,blck_size-1);} +#define _vmem_map_block_mirror(base, start, end, blck_size) { \ + u32 block_size = (blck_size) >> 24; \ + u32 map_sz = (end) - (start) + 1; \ + /* verify((map_sz % block_size) == 0); */ \ + for (u32 _maip = (start); _maip <= (end); _maip += block_size) \ + _vmem_map_block((base), _maip, _maip + block_size - 1, blck_size - 1); \ +} //ReadMem(s) u32 DYNACALL _vmem_ReadMem8SX32(u32 Address); From fd7cf9a0f529529803cdfb1d327add1224a5b7a6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 24 Jun 2019 23:18:04 +0200 Subject: [PATCH 091/158] linux-x64: make a non position independent exec --- shell/linux/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/linux/Makefile b/shell/linux/Makefile index d0e6d529b..0b4f36d83 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -121,6 +121,7 @@ else ifneq (,$(findstring x64,$(platform))) USE_X11 := 1 CFLAGS += -D TARGET_LINUX_x64 -D TARGET_NO_AREC -fno-builtin-sqrtf CXXFLAGS += -fexceptions + LDFLAGS := -no-pie ifneq (,$(findstring sse4_1,$(platform))) HAS_SOFTREND := 1 From 927298f3537dff9e186bac69df6dfa5017e6421a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 25 Jun 2019 19:10:20 +0200 Subject: [PATCH 092/158] naomi: fix coin chute (compiler bug?). Disable verify in TA parsing Fix F1 World Grand Prix for Dreamcast --- core/hw/maple/maple_devs.cpp | 28 ++++++++++++++++++++-------- core/hw/pvr/ta.cpp | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 76c2153c6..1c138d118 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -1675,6 +1675,10 @@ struct maple_naomi_jamma : maple_sega_controller break; } } + virtual ~maple_naomi_jamma() + { + EEPROM_loaded = false; + } virtual MapleDeviceType get_device_type() { @@ -2353,8 +2357,6 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou LOGJVS("JVS Node %d: ", node_id); PlainJoystickState pjs; parent->config->GetInput(&pjs); - u32 keycode = ~kcode[0]; - u32 keycode2 = ~kcode[1]; JVS_STATUS1(); // status for (int cmdi = 0; cmdi < length_in; ) @@ -2365,6 +2367,8 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou { JVS_STATUS1(); // report byte + u32 keycode = ~kcode[0]; + u32 keycode2 = ~kcode[1]; u16 buttons[4] = { 0 }; for (int player = 0; player < buffer_in[cmdi + 1] && first_player + player < ARRAY_SIZE(kcode); player++) { @@ -2397,17 +2401,25 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou { JVS_STATUS1(); // report byte LOGJVS("coins "); + u32 mask = 0; + for (int i = 0; i < 16; i++) + { + if (naomi_button_mapping[i] == NAOMI_COIN_KEY) + { + mask = 1 << i; + break; + } + } for (int slot = 0; slot < buffer_in[cmdi + 1]; slot++) { + u16 keycode = ~kcode[first_player + slot]; bool coin_chute = false; - u32 keycode = ~kcode[first_player + slot]; - for (int i = 0; i < 16 && !coin_chute; i++) + if (keycode & mask) { - if (naomi_button_mapping[i] == NAOMI_COIN_KEY && (keycode & (1 << i)) != 0) - coin_chute = true; + coin_chute = true; + if (!old_coin_chute[first_player + slot]) + coin_count[first_player + slot] += 1; } - if (coin_chute && !old_coin_chute[first_player + slot]) - coin_count[first_player + slot] += 1; old_coin_chute[first_player + slot] = coin_chute; LOGJVS("%d:%d ", slot + 1 + first_player, coin_count[first_player + slot]); diff --git a/core/hw/pvr/ta.cpp b/core/hw/pvr/ta.cpp index 3829c1a50..edfd40384 100644 --- a/core/hw/pvr/ta.cpp +++ b/core/hw/pvr/ta.cpp @@ -257,7 +257,7 @@ NOINLINE void DYNACALL ta_handle_cmd(u32 trans) if (ta_fsm_cl==7) ta_fsm_cl=dat->pcw.ListType; - verify(!IsModVolList(ta_fsm_cl)); + //verify(!IsModVolList(ta_fsm_cl)); // fails with "F1 World Grand Prix for Dreamcast" and only with dynarec... trans=TAS_PLV32; } else From 871260cfcf562688204f5fea09ced0e7078600af Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 26 Jun 2019 19:06:30 +0200 Subject: [PATCH 093/158] naomi: better error handling when loading a gdrom x64 and arm64 dynarecs: Support 64-bit immediate readm (ninjaslt) --- core/hw/naomi/gdcartridge.cpp | 13 +++++- core/hw/naomi/naomi_cart.cpp | 8 +++- core/hw/naomi/naomi_cart.h | 8 ++++ core/rec-ARM64/rec_arm64.cpp | 82 +++++++++++++++++++++++------------ core/rec-x64/rec_x64.cpp | 75 ++++++++++++++++++++++---------- 5 files changed, 134 insertions(+), 52 deletions(-) diff --git a/core/hw/naomi/gdcartridge.cpp b/core/hw/naomi/gdcartridge.cpp index faa81768f..a4fd4c25f 100644 --- a/core/hw/naomi/gdcartridge.cpp +++ b/core/hw/naomi/gdcartridge.cpp @@ -507,7 +507,8 @@ void GDCartridge::device_start() if (gdrom == NULL) gdrom = OpenDisc((gdrom_path + ".gdi").c_str()); if (gdrom == NULL) - return; + throw NaomiCartException("Naomi GDROM: Cannot open " + gdrom_path + ".chd or " + gdrom_path + ".gdi"); + // primary volume descriptor // read frame 0xb06e (frame=sector+150) // dimm board firmware starts straight from this frame @@ -564,6 +565,7 @@ void GDCartridge::device_start() u32 file_rounded_size = (file_size + 2047) & -2048; for (dimm_data_size = 4096; dimm_data_size < file_rounded_size; dimm_data_size <<= 1); dimm_data = (u8 *)malloc(dimm_data_size); + verify(dimm_data != NULL); if (dimm_data_size != file_rounded_size) memset(dimm_data + file_rounded_size, 0, dimm_data_size - file_rounded_size); @@ -583,7 +585,7 @@ void GDCartridge::device_start() delete gdrom; if (!dimm_data) - printf("Naomi GDROM: Could not find the file to decrypt.\n"); + throw NaomiCartException("Naomi GDROM: Could not find the file to decrypt."); } } @@ -593,6 +595,8 @@ void GDCartridge::device_reset() } void *GDCartridge::GetDmaPtr(u32 &size) { + if (dimm_data == NULL) + return NULL; dimm_cur_address = DmaOffset & (dimm_data_size-1); size = min(size, dimm_data_size - dimm_cur_address); return dimm_data + dimm_cur_address; @@ -607,6 +611,11 @@ void GDCartridge::AdvancePtr(u32 size) bool GDCartridge::Read(u32 offset, u32 size, void *dst) { + if (dimm_data == NULL) + { + *(u32 *)dst = 0; + return true; + } u32 addr = offset & (dimm_data_size-1); memcpy(dst, &dimm_data[addr], min(size, dimm_data_size - addr)); return true; diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 55bfdd5c1..30bfe5c84 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -331,7 +331,12 @@ static bool naomi_cart_LoadZip(char *filename) if (parent_archive != NULL) delete parent_archive; - CurrentCartridge->Init(); + try { + CurrentCartridge->Init(); + } catch (NaomiCartException& e) { + printf("%s\n", e.reason.c_str()); + return false; + } strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); printf("NAOMI GAME ID [%s]\n", naomi_game_id); @@ -604,6 +609,7 @@ void naomi_cart_Close() delete[] RomCacheMap; RomCacheMap = NULL; } + bios_loaded = false; } bool naomi_cart_SelectFile() diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h index 85758fb28..e189bb107 100644 --- a/core/hw/naomi/naomi_cart.h +++ b/core/hw/naomi/naomi_cart.h @@ -78,6 +78,14 @@ private: u8 naomi_cart_ram[64 * 1024]; }; +class NaomiCartException +{ +public: + NaomiCartException(std::string reason) : reason(reason) {} + + std::string reason; +}; + bool naomi_cart_SelectFile(); void naomi_cart_Close(); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index dd3fbbe1b..4ce70f8d7 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -1639,18 +1639,28 @@ private: return false; u32 paddr; u32 rv; - if (size == 2) + switch (size) + { + case 1: + rv = mmu_data_translation(addr, paddr); + break; + case 2: rv = mmu_data_translation(addr, paddr); - else if (size == 4) + break; + case 4: + case 8: rv = mmu_data_translation(addr, paddr); - else + break; + default: die("Invalid immediate size"); + break; + } if (rv != MMU_ERROR_NONE) return false; addr = paddr; } bool isram = false; - void* ptr = _vmem_read_const(addr, isram, size); + void* ptr = _vmem_read_const(addr, isram, size > 4 ? 4 : size); if (isram) { @@ -1712,35 +1722,50 @@ private: else { // Not RAM - Mov(w0, addr); - - switch(size) + if (size == 8) { - case 1: + verify(!regalloc.IsAllocAny(op.rd)); + // Need to call the handler twice + Mov(w0, addr); GenCallRuntime((void (*)())ptr); - Sxtb(w0, w0); - break; + Str(w0, sh4_context_mem_operand(op.rd.reg_ptr())); - case 2: + Mov(w0, addr + 4); GenCallRuntime((void (*)())ptr); - Sxth(w0, w0); - break; - - case 4: - GenCallRuntime((void (*)())ptr); - break; - - case 8: - die("SZ_64F not supported"); - break; + Str(w0, sh4_context_mem_operand((u8*)op.rd.reg_ptr() + 4)); } - - if (regalloc.IsAllocg(op.rd)) - Mov(regalloc.MapRegister(op.rd), w0); else { - verify(regalloc.IsAllocf(op.rd)); - Fmov(regalloc.MapVRegister(op.rd), w0); + Mov(w0, addr); + + switch(size) + { + case 1: + GenCallRuntime((void (*)())ptr); + Sxtb(w0, w0); + break; + + case 2: + GenCallRuntime((void (*)())ptr); + Sxth(w0, w0); + break; + + case 4: + GenCallRuntime((void (*)())ptr); + break; + + default: + die("Invalid size"); + break; + } + + if (regalloc.IsAllocg(op.rd)) + Mov(regalloc.MapRegister(op.rd), w0); + else + { + verify(regalloc.IsAllocf(op.rd)); + Fmov(regalloc.MapVRegister(op.rd), w0); + } } } @@ -1848,13 +1873,16 @@ private: case 8: rv = mmu_data_translation(addr, paddr); break; + default: + die("Invalid immediate size"); + break; } if (rv != MMU_ERROR_NONE) return false; addr = paddr; } bool isram = false; - void* ptr = _vmem_write_const(addr, isram, size); + void* ptr = _vmem_write_const(addr, isram, size > 4 ? 4 : size); Register reg2; if (op.rs2.is_imm()) diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index b315d18ff..1bb975fe2 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -1517,19 +1517,29 @@ private: u32 paddr; u32 rv; - if (size == 2) + switch (size) + { + case 1: + rv = mmu_data_translation(addr, paddr); + break; + case 2: rv = mmu_data_translation(addr, paddr); - else if (size == 4) + break; + case 4: + case 8: rv = mmu_data_translation(addr, paddr); - else + break; + default: die("Invalid immediate size"); + break; + } if (rv != MMU_ERROR_NONE) return false; addr = paddr; } bool isram = false; - void* ptr = _vmem_read_const(addr, isram, size); + void* ptr = _vmem_read_const(addr, isram, size > 4 ? 4 : size); if (isram) { @@ -1597,29 +1607,47 @@ private: else { // Not RAM: the returned pointer is a memory handler - mov(call_regs[0], addr); - - switch(size) + if (size == 8) { - case 1: - GenCall((void (*)())ptr); - movsx(eax, al); - break; + verify(!regalloc.IsAllocAny(op.rd)); - case 2: + // Need to call the handler twice + mov(call_regs[0], addr); GenCall((void (*)())ptr); - movsx(eax, ax); - break; + mov(rcx, (size_t)op.rd.reg_ptr()); + mov(dword[rcx], eax); - case 4: + mov(call_regs[0], addr + 4); GenCall((void (*)())ptr); - break; - - default: - die("Invalid immediate size"); - break; + mov(rcx, (size_t)op.rd.reg_ptr() + 4); + mov(dword[rcx], eax); + } + else + { + mov(call_regs[0], addr); + + switch(size) + { + case 1: + GenCall((void (*)())ptr); + movsx(eax, al); + break; + + case 2: + GenCall((void (*)())ptr); + movsx(eax, ax); + break; + + case 4: + GenCall((void (*)())ptr); + break; + + default: + die("Invalid immediate size"); + break; + } + host_reg_to_shil_param(op.rd, eax); } - host_reg_to_shil_param(op.rd, eax); } return true; @@ -1651,6 +1679,9 @@ private: case 8: rv = mmu_data_translation(addr, paddr); break; + default: + die("Invalid immediate size"); + break; } if (rv != MMU_ERROR_NONE) return false; @@ -1658,7 +1689,7 @@ private: addr = paddr; } bool isram = false; - void* ptr = _vmem_write_const(addr, isram, size); + void* ptr = _vmem_write_const(addr, isram, size > 4 ? 4 : size); if (isram) { From e6b8c46557e07d3eb55edd96818e83fab729a4a4 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 27 Jun 2019 09:03:49 +0200 Subject: [PATCH 094/158] atomiswave: fix coin error --- core/hw/naomi/naomi.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index 1b75b1a03..3ea7c570c 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -7,6 +7,7 @@ #include "hw/sh4/sh4_mem.h" #include "hw/holly/holly_intc.h" #include "hw/maple/maple_cfg.h" +#include "hw/sh4/sh4_sched.h" #include "naomi.h" #include "naomi_cart.h" @@ -55,7 +56,7 @@ unsigned int ShiftCRC(unsigned int CRC,unsigned int rounds) return CRC; } -unsigned short CRCSerial(unsigned char *Serial,unsigned int len) +unsigned short CRCSerial(const u8 *Serial,unsigned int len) { unsigned int CRC=0xDEBDEB00; unsigned int i; @@ -463,7 +464,8 @@ void Naomi_DmaStart(u32 addr, u32 data) { u32 block_len = len; void* ptr = CurrentCartridge->GetDmaPtr(block_len); - WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); + if (ptr != NULL) + WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); CurrentCartridge->AdvancePtr(block_len); len -= block_len; offset += block_len; @@ -555,7 +557,22 @@ void naomi_reg_Reset(bool Manual) { NaomiDataRead = false; aw_ram_test_skipped = false; + GSerialBuffer = 0; + BSerialBuffer = 0; + GBufPos = 0; + BBufPos = 0; + GState = 0; + BState = 0; + GOldClk = 0; + BOldClk = 0; + BControl = 0; + BCmd = 0; BLastCmd = 0; + GControl = 0; + GCmd = 0; + GLastCmd = 0; + SerStep = 0; + SerStep2 = 0; } void Update_naomi() @@ -635,6 +652,7 @@ void Update_naomi() } static u8 aw_maple_devs; +static u64 coin_chute_time[4]; u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { addr &= 0x7ff; @@ -655,9 +673,25 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { } { u8 coin_input = 0xF; + u64 now = sh4_sched_now64(); for (int slot = 0; slot < 4; slot++) + { if (maple_atomiswave_coin_chute(slot)) - coin_input &= ~(1 << slot); + { + // ggx15 needs 4 or 5 reads to register the coin but it needs to be limited to avoid coin errors + // 1 s of cpu time is too much, 1/2 s seems to work, let's use 100 ms + if (coin_chute_time[slot] == 0 || now - coin_chute_time[slot] < SH4_MAIN_CLOCK / 10) + { + if (coin_chute_time[slot] == 0) + coin_chute_time[slot] = now; + coin_input &= ~(1 << slot); + } + } + else + { + coin_chute_time[slot] = 0; + } + } return coin_input; } From 99778a7715d5962c80d949310b08ac6ae1bf0281 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 27 Jun 2019 22:41:16 +0200 Subject: [PATCH 095/158] per-pixel renderer: RTT might need bigger buffers than screen --- core/rend/gl4/abuffer.cpp | 54 +++++++++++-------------- core/rend/gl4/gl4.h | 4 +- core/rend/gl4/gldraw.cpp | 55 +++++++++++-------------- core/rend/gl4/gles.cpp | 84 +++++++++++++++++++++++---------------- core/rend/gles/gles.cpp | 4 +- core/rend/gles/gltex.cpp | 2 +- 6 files changed, 101 insertions(+), 102 deletions(-) diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index 7e9b67c64..49f52a787 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -280,9 +280,6 @@ void main(void) \n\ void initABuffer() { - g_imageWidth = (int)roundf(screen_width * settings.rend.ScreenScaling / 100.f); - g_imageHeight = (int)roundf(screen_height * settings.rend.ScreenScaling / 100.f); - if (g_imageWidth > 0 && g_imageHeight > 0) { if (pixels_pointers == 0) @@ -384,7 +381,7 @@ void initABuffer() glcache.UseProgram(g_abuffer_clear_shader.program); gl4ShaderUniforms.Set(&g_abuffer_clear_shader); - abufferDrawQuad(); + abufferDrawQuad(g_imageWidth, g_imageHeight); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glCheck(); @@ -432,39 +429,34 @@ void termABuffer() void reshapeABuffer(int w, int h) { - w = (int)roundf(w * settings.rend.ScreenScaling / 100.f); - h = (int)roundf(h * settings.rend.ScreenScaling / 100.f); - if (w != g_imageWidth || h != g_imageHeight) { if (pixels_pointers != 0) { glcache.DeleteTextures(1, &pixels_pointers); pixels_pointers = 0; } - + g_imageWidth = w; + g_imageHeight = h; initABuffer(); } } -void abufferDrawQuad(bool upsideDown, float x, float y, float w, float h) +void abufferDrawQuad(float w, float h) { - if (w == 0 || h == 0) - { - float scl = 480.f / screen_height; - float tx = (screen_width * scl - 640.f) / 2; + float scl = 480.f / h; + float tx = (w * scl - 640.f) / 2; - x = -tx; - y = 0.f; - w = 640.f + tx * 2; - h = 480.f; - } + float x = -tx; + float y = 0.f; + w = 640.f + tx * 2; + h = 480.f; glBindVertexArray(g_quadVertexArray); struct Vertex vertices[] = { - { x, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, upsideDown ? 0.f : 1.f }, - { x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, upsideDown ? 1.f : 0.f }, - { x + w, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, upsideDown ? 0.f : 1.f }, - { x + w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, upsideDown ? 1.f : 0.f }, + { x, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, + { x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, + { x + w, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, + { x + w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, }; GLushort indices[] = { 0, 1, 2, 1, 3 }; @@ -574,15 +566,15 @@ void checkOverflowAndReset() glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0 , sizeof(GLuint), &max_pixel_index); } -void renderABuffer(bool sortFragments) +void renderABuffer(bool sortFragments, int width, int height) { // Reset scale params to a standard 640x480 dc screen - float scale_h = screen_height / 480.f; - float offs_x = (screen_width - scale_h * 640.f) / 2.f; - gl4ShaderUniforms.scale_coefs[0] = 2.f / (screen_width / scale_h); - gl4ShaderUniforms.scale_coefs[1]= -2.f / 480.f; - gl4ShaderUniforms.scale_coefs[2]= 1.f - 2.f * offs_x / screen_width; - gl4ShaderUniforms.scale_coefs[3]= -1.f; + float scale_h = height / 480.f; + float offs_x = (width - scale_h * 640.f) / 2.f; + gl4ShaderUniforms.scale_coefs[0] = 2.f / (width / scale_h); + gl4ShaderUniforms.scale_coefs[1] = -2.f / 480.f; + gl4ShaderUniforms.scale_coefs[2] = 1.f - 2.f * offs_x / width; + gl4ShaderUniforms.scale_coefs[3] = -1.f; // Render to output FBO glcache.UseProgram(sortFragments ? g_abuffer_final_shader.program : g_abuffer_final_nosort_shader.program); @@ -592,7 +584,7 @@ void renderABuffer(bool sortFragments) glcache.Disable(GL_CULL_FACE); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); - abufferDrawQuad(); + abufferDrawQuad(width, height); glCheck(); @@ -601,7 +593,7 @@ void renderABuffer(bool sortFragments) gl4ShaderUniforms.Set(&g_abuffer_clear_shader); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - abufferDrawQuad(); + abufferDrawQuad(width, height); glActiveTexture(GL_TEXTURE0); diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 4c3ca82ac..4e5262316 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -2,7 +2,7 @@ #include "rend/gles/gles.h" #include -void gl4DrawStrips(GLuint output_fbo); +void gl4DrawStrips(GLuint output_fbo, int width, int height); struct gl4PipelineShader { @@ -64,7 +64,7 @@ extern int screen_height; GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt); void gl4DrawFramebuffer(float w, float h); bool gl4_render_output_framebuffer(); -void abufferDrawQuad(bool upsideDown = false, float x = 0.f, float y = 0.f, float w = 0.f, float h = 0.f); +void abufferDrawQuad(float w, float h); extern const char *gl4PixelPipelineShader; bool gl4CompilePipelineShader(gl4PipelineShader* s, bool rotate_90, const char *source = gl4PixelPipelineShader); diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index dfa403a19..b10e9da7f 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -386,7 +386,7 @@ static void DrawModVols(int first, int count) glcache.DepthMask(GL_TRUE); } -void renderABuffer(bool sortFragments); +void renderABuffer(bool sortFragments, int width, int height); void DrawTranslucentModVols(int first, int count); void checkOverflowAndReset(); @@ -403,8 +403,14 @@ static GLuint CreateColorFBOTexture(int width, int height) return texId; } -static void CreateTextures(int width, int height) +void gl4CreateTextures(int width, int height) { + if (geom_fbo == 0) + { + glGenFramebuffers(1, &geom_fbo); + } + glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); + stencilTexId = glcache.GenTexture(); glBindTexture(GL_TEXTURE_2D, stencilTexId); glCheck(); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); // OpenGL >= 4.3 @@ -425,31 +431,16 @@ static void CreateTextures(int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glCheck(); + + GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + verify(uStatus == GL_FRAMEBUFFER_COMPLETE); } -void gl4DrawStrips(GLuint output_fbo) +void gl4DrawStrips(GLuint output_fbo, int width, int height) { checkOverflowAndReset(); - int scaled_width = (int)roundf(screen_width * settings.rend.ScreenScaling / 100.f); - int scaled_height = (int)roundf(screen_height * settings.rend.ScreenScaling / 100.f); - - if (geom_fbo == 0) - { - glGenFramebuffers(1, &geom_fbo); - glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); - - CreateTextures(scaled_width, scaled_height); - - GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - verify(uStatus == GL_FRAMEBUFFER_COMPLETE); - } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); - if (stencilTexId == 0) - CreateTextures(scaled_width, scaled_height); - } + glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); if (texSamplers[0] == 0) glGenSamplers(2, texSamplers); @@ -514,14 +505,14 @@ void gl4DrawStrips(GLuint output_fbo) glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, scaled_width, scaled_height, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL); glCheck(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL); glCheck(); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthSaveTexId, 0); glCheck(); } GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); verify(uStatus == GL_FRAMEBUFFER_COMPLETE); glBindFramebuffer(GL_READ_FRAMEBUFFER, geom_fbo); - glBlitFramebuffer(0, 0, scaled_width, scaled_height, 0, 0, scaled_width, scaled_height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); glCheck(); glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); @@ -553,7 +544,7 @@ void gl4DrawStrips(GLuint output_fbo) // FIXME This is pretty slow apparently (CS) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, geom_fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, depth_fbo); - glBlitFramebuffer(0, 0, scaled_width, scaled_height, 0, 0, scaled_width, scaled_height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST); glCheck(); glBindFramebuffer(GL_FRAMEBUFFER, geom_fbo); } @@ -621,7 +612,7 @@ void gl4DrawStrips(GLuint output_fbo) // // PASS 3c: Render a-buffer to temporary texture // - GLuint texId = CreateColorFBOTexture(scaled_width, scaled_height); + GLuint texId = CreateColorFBOTexture(width, height); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -629,7 +620,7 @@ void gl4DrawStrips(GLuint output_fbo) glBindSampler(0, 0); glBindTexture(GL_TEXTURE_2D, opaqueTexId); - renderABuffer(current_pass.autosort); + renderABuffer(current_pass.autosort, width, height); glcache.DeleteTextures(1, &opaqueTexId); opaqueTexId = texId; @@ -657,10 +648,10 @@ void gl4DrawStrips(GLuint output_fbo) glActiveTexture(GL_TEXTURE0); glBindSampler(0, 0); glBindTexture(GL_TEXTURE_2D, opaqueTexId); - renderABuffer(previous_pass.autosort); + renderABuffer(previous_pass.autosort, width, height); } -static void gl4_draw_quad_texture(GLuint texture, bool upsideDown, float x = 0.f, float y = 0.f, float w = 0.f, float h = 0.f) +static void gl4_draw_quad_texture(GLuint texture, float w, float h) { glcache.Disable(GL_SCISSOR_TEST); glcache.Disable(GL_DEPTH_TEST); @@ -690,12 +681,12 @@ static void gl4_draw_quad_texture(GLuint texture, bool upsideDown, float x = 0.f glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); - abufferDrawQuad(upsideDown, x, y, w, h); + abufferDrawQuad(w, h); } void gl4DrawFramebuffer(float w, float h) { - gl4_draw_quad_texture(fbTextureId, false, 0, 0, w, h); + gl4_draw_quad_texture(fbTextureId, w, h); glcache.DeleteTextures(1, &fbTextureId); fbTextureId = 0; } diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 056489562..81bfe2a16 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -561,6 +561,8 @@ static bool gl_create_resources() //setup extern void initABuffer(); +void reshapeABuffer(int width, int height); +extern void gl4CreateTextures(int width, int height); static bool gles_init() { @@ -610,15 +612,41 @@ static bool gles_init() return true; } +static void resize(int w, int h) +{ + static int cur_width, cur_height; + if (w > cur_width || h > cur_height || stencilTexId == 0) + { + cur_width = w; + cur_height = h; + + if (stencilTexId != 0) + { + glcache.DeleteTextures(1, &stencilTexId); + stencilTexId = 0; + } + if (depthTexId != 0) + { + glcache.DeleteTextures(1, &depthTexId); + depthTexId = 0; + } + if (opaqueTexId != 0) + { + glcache.DeleteTextures(1, &opaqueTexId); + opaqueTexId = 0; + } + if (depthSaveTexId != 0) + { + glcache.DeleteTextures(1, &depthSaveTexId); + depthSaveTexId = 0; + } + gl4CreateTextures(w, h); + reshapeABuffer(w, h); + } +} + static bool RenderFrame() { - static int old_screen_width, old_screen_height, old_screen_scaling; - if (screen_width != old_screen_width || screen_height != old_screen_height || settings.rend.ScreenScaling != old_screen_scaling) { - rend_resize(screen_width, screen_height); - old_screen_width = screen_width; - old_screen_height = screen_height; - old_screen_scaling = settings.rend.ScreenScaling; - } DoCleanup(); create_modvol_shader(); @@ -687,12 +715,17 @@ static bool RenderFrame() float dc2s_scale_h; float ds2s_offs_x; + int rendering_width; + int rendering_height; if (is_rtt) { gl4ShaderUniforms.scale_coefs[0] = 2.0f / dc_width; gl4ShaderUniforms.scale_coefs[1] = 2.0f / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512 gl4ShaderUniforms.scale_coefs[2] = 1; gl4ShaderUniforms.scale_coefs[3] = 1; + int scaling = settings.rend.RenderToTextureBuffer ? 1 : settings.rend.RenderToTextureUpscale; + rendering_width = dc_width * scaling; + rendering_height = dc_height * scaling; } else { @@ -715,7 +748,10 @@ static bool RenderFrame() gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width; gl4ShaderUniforms.scale_coefs[3] = -1; } + rendering_width = screen_width * screen_scaling + 0.5f; + rendering_height = screen_height * screen_scaling + 0.5f; } + resize(rendering_width, rendering_height); gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; @@ -808,7 +844,7 @@ static bool RenderFrame() { if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) { - output_fbo = init_output_framebuffer(screen_width * screen_scaling + 0.5f, screen_height * screen_scaling + 0.5f); + output_fbo = init_output_framebuffer(rendering_width, rendering_width); } else { @@ -820,9 +856,9 @@ static bool RenderFrame() bool wide_screen_on = !is_rtt && settings.rend.WideScreen && pvrrc.fb_X_CLIP.min == 0 - && (pvrrc.fb_X_CLIP.max + 1) / scale_x == 640 + && int((pvrrc.fb_X_CLIP.max + 1) / scale_x + 0.5f) == 640 && pvrrc.fb_Y_CLIP.min == 0 - && (pvrrc.fb_Y_CLIP.max + 1) / scale_y == 480; + && int((pvrrc.fb_Y_CLIP.max + 1) / scale_y + 0.5f) == 480; //Color is cleared by the background plane @@ -898,9 +934,9 @@ static bool RenderFrame() glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glcache.Enable(GL_SCISSOR_TEST); - glScissor(0, 0, scaled_offs_x + 0.5f, screen_height * screen_scaling + 0.5f); + glScissor(0, 0, scaled_offs_x + 0.5f, rendering_height); glClear(GL_COLOR_BUFFER_BIT); - glScissor(screen_width * screen_scaling - scaled_offs_x + 0.5f, 0, scaled_offs_x + 1.f, screen_height * screen_scaling + 0.5f); + glScissor(screen_width * screen_scaling - scaled_offs_x + 0.5f, 0, scaled_offs_x + 1.f, rendering_height); glClear(GL_COLOR_BUFFER_BIT); } } @@ -918,7 +954,7 @@ static bool RenderFrame() //restore scale_x scale_x /= scissoring_scale_x; - gl4DrawStrips(output_fbo); + gl4DrawStrips(output_fbo, rendering_width, rendering_height); } else { @@ -952,27 +988,7 @@ struct gl4rend : Renderer { screen_width=w; screen_height=h; - if (stencilTexId != 0) - { - glcache.DeleteTextures(1, &stencilTexId); - stencilTexId = 0; - } - if (depthTexId != 0) - { - glcache.DeleteTextures(1, &depthTexId); - depthTexId = 0; - } - if (opaqueTexId != 0) - { - glcache.DeleteTextures(1, &opaqueTexId); - opaqueTexId = 0; - } - if (depthSaveTexId != 0) - { - glcache.DeleteTextures(1, &depthSaveTexId); - depthSaveTexId = 0; - } - reshapeABuffer(w, h); + resize(w * settings.rend.ScreenScaling / 100.f + 0.5f, h * settings.rend.ScreenScaling / 100.f + 0.5f); } void Term() { diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index ebaf90e35..fa1976d4c 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1924,9 +1924,9 @@ bool RenderFrame() bool wide_screen_on = !is_rtt && settings.rend.WideScreen && pvrrc.fb_X_CLIP.min == 0 - && (pvrrc.fb_X_CLIP.max + 1) / scale_x == 640 + && int((pvrrc.fb_X_CLIP.max + 1) / scale_x + 0.5f) == 640 && pvrrc.fb_Y_CLIP.min == 0 - && (pvrrc.fb_Y_CLIP.max + 1) / scale_y == 480; + && int((pvrrc.fb_Y_CLIP.max + 1) / scale_y + 0.5f) == 480; //Color is cleared by the background plane diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index f25779dc2..b8d595da8 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -482,7 +482,7 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt) gl.rtt.TexAddr=addy>>3; - // Find the smallest power of two texture that fits into the viewport + // Find the smallest power of two texture that fits the viewport int fbh2 = 2; while (fbh2 < fbh) fbh2 *= 2; From 0a95a60ac6e44fa754959d107d8d3da8bb69742e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 28 Jun 2019 11:42:35 +0200 Subject: [PATCH 096/158] less verbose logs. unbuffered stdout when test automation --- core/hw/flashrom/flashrom.h | 10 +++++----- core/hw/pvr/pvr_mem.cpp | 4 ++-- core/nullDC.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index 89c5305ce..ca453ebf8 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -283,13 +283,13 @@ struct DCFlashChip : MemChip state = FS_ReadAMDID1; break; default: - printf("Unknown FlashWrite mode: %x\n", val); + EMUERROR("Unknown FlashWrite mode: %x\n", val); break; } break; case FS_ReadAMDID1: - if ((addr & 0xffff) == 0x2aa && (val & 0xff) == 0x55) + if ((addr & 0xffff) == 0x02aa && (val & 0xff) == 0x55) state = FS_ReadAMDID2; else if ((addr & 0xffff) == 0x2aaa && (val & 0xff) == 0x55) state = FS_ReadAMDID2; @@ -303,13 +303,13 @@ struct DCFlashChip : MemChip break; case FS_ReadAMDID2: - if ((addr & 0xffff) == 0x555 && (val & 0xff) == 0x80) + if ((addr & 0xffff) == 0x0555 && (val & 0xff) == 0x80) state = FS_EraseAMD1; else if ((addr & 0xffff) == 0x5555 && (val & 0xff) == 0x80) state = FS_EraseAMD1; else if ((addr & 0xfff) == 0xaaa && (val & 0xff) == 0x80) state = FS_EraseAMD1; - else if ((addr & 0xffff) == 0x555 && (val & 0xff) == 0xa0) + else if ((addr & 0xffff) == 0x0555 && (val & 0xff) == 0xa0) state = FS_ByteProgram; else if ((addr & 0xffff) == 0x5555 && (val & 0xff) == 0xa0) state = FS_ByteProgram; @@ -339,7 +339,7 @@ struct DCFlashChip : MemChip break; case FS_EraseAMD2: - if ((addr & 0xffff) == 0x2aa && (val & 0xff) == 0x55) + if ((addr & 0xffff) == 0x02aa && (val & 0xff) == 0x55) state = FS_EraseAMD3; else if ((addr & 0xffff) == 0x2aaa && (val & 0xff) == 0x55) state = FS_EraseAMD3; diff --git a/core/hw/pvr/pvr_mem.cpp b/core/hw/pvr/pvr_mem.cpp index a9d125ec7..fac15f4c3 100644 --- a/core/hw/pvr/pvr_mem.cpp +++ b/core/hw/pvr/pvr_mem.cpp @@ -212,7 +212,7 @@ void YUV_data(u32* data , u32 count) //read u8 DYNACALL pvr_read_area1_8(u32 addr) { - printf("8-bit VRAM reads are not possible\n"); + EMUERROR("8-bit VRAM reads are not possible\n"); return 0; } @@ -228,7 +228,7 @@ u32 DYNACALL pvr_read_area1_32(u32 addr) //write void DYNACALL pvr_write_area1_8(u32 addr,u8 data) { - printf("8-bit VRAM writes are not possible\n"); + EMUERROR("8-bit VRAM writes are not possible\n"); } void DYNACALL pvr_write_area1_16(u32 addr,u16 data) { diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 7218173b4..fcdccf8f0 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -289,7 +289,7 @@ static bool reset_requested; int reicast_init(int argc, char* argv[]) { -#ifdef _WIN32 +#if defined(_WIN32) || defined(TEST_AUTOMATION) setbuf(stdout, 0); setbuf(stderr, 0); #endif From 5f5f3006044188daf06ec6e4101f4fc2d5415393 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 28 Jun 2019 17:37:06 +0200 Subject: [PATCH 097/158] gl4: fix issue with RTT regarding buffer dimension fixes shadow in THPS 1 & 2 --- core/rend/gl4/abuffer.cpp | 51 +++++++++++--------------------- core/rend/gl4/gl4.h | 2 ++ core/rend/gl4/gldraw.cpp | 4 +-- core/rend/gl4/gles.cpp | 62 +++++++++++++++++++-------------------- 4 files changed, 52 insertions(+), 67 deletions(-) diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index 49f52a787..6aea0aeb0 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -18,9 +18,6 @@ gl4PipelineShader g_abuffer_tr_modvol_shaders[ModeCount]; static GLuint g_quadBuffer = 0; static GLuint g_quadVertexArray = 0; -static int g_imageWidth = 0; -static int g_imageHeight = 0; - GLuint pixel_buffer_size = 512 * 1024 * 1024; // Initial size 512 MB #define MAX_PIXELS_PER_FRAGMENT "32" @@ -280,7 +277,7 @@ void main(void) \n\ void initABuffer() { - if (g_imageWidth > 0 && g_imageHeight > 0) + if (max_image_width > 0 && max_image_height > 0) { if (pixels_pointers == 0) pixels_pointers = glcache.GenTexture(); @@ -288,7 +285,7 @@ void initABuffer() glBindTexture(GL_TEXTURE_2D, pixels_pointers); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, g_imageWidth, g_imageHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, max_image_width, max_image_height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); glBindImageTexture(4, pixels_pointers, 0, false, 0, GL_READ_WRITE, GL_R32UI); glCheck(); } @@ -381,7 +378,7 @@ void initABuffer() glcache.UseProgram(g_abuffer_clear_shader.program); gl4ShaderUniforms.Set(&g_abuffer_clear_shader); - abufferDrawQuad(g_imageWidth, g_imageHeight); + abufferDrawQuad(max_image_width, max_image_height); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glCheck(); @@ -429,34 +426,23 @@ void termABuffer() void reshapeABuffer(int w, int h) { - if (w != g_imageWidth || h != g_imageHeight) { - if (pixels_pointers != 0) - { - glcache.DeleteTextures(1, &pixels_pointers); - pixels_pointers = 0; - } - g_imageWidth = w; - g_imageHeight = h; - initABuffer(); + if (pixels_pointers != 0) + { + glcache.DeleteTextures(1, &pixels_pointers); + pixels_pointers = 0; } + initABuffer(); } void abufferDrawQuad(float w, float h) { - float scl = 480.f / h; - float tx = (w * scl - 640.f) / 2; - - float x = -tx; - float y = 0.f; - w = 640.f + tx * 2; - h = 480.f; glBindVertexArray(g_quadVertexArray); struct Vertex vertices[] = { - { x, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, - { x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, - { x + w, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, - { x + w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, + { 0, h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, + { 0, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, + { w, h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, + { w, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, }; GLushort indices[] = { 0, 1, 2, 1, 3 }; @@ -568,14 +554,11 @@ void checkOverflowAndReset() void renderABuffer(bool sortFragments, int width, int height) { - // Reset scale params to a standard 640x480 dc screen - float scale_h = height / 480.f; - float offs_x = (width - scale_h * 640.f) / 2.f; - gl4ShaderUniforms.scale_coefs[0] = 2.f / (width / scale_h); - gl4ShaderUniforms.scale_coefs[1] = -2.f / 480.f; - gl4ShaderUniforms.scale_coefs[2] = 1.f - 2.f * offs_x / width; - gl4ShaderUniforms.scale_coefs[3] = -1.f; - + // Reset scale params + gl4ShaderUniforms.scale_coefs[0] = 2.0f / width; + gl4ShaderUniforms.scale_coefs[1] = 2.0f / height; + gl4ShaderUniforms.scale_coefs[2] = 1; + gl4ShaderUniforms.scale_coefs[3] = 1; // Render to output FBO glcache.UseProgram(sortFragments ? g_abuffer_final_shader.program : g_abuffer_final_nosort_shader.program); gl4ShaderUniforms.Set(&g_abuffer_final_shader); diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 4e5262316..020910c30 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -60,6 +60,8 @@ extern gl4_ctx gl4; extern int screen_width; extern int screen_height; +extern int max_image_width; +extern int max_image_height; GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt); void gl4DrawFramebuffer(float w, float h); diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index b10e9da7f..123b7f410 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -505,7 +505,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL); glCheck(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, max_image_width, max_image_height, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL); glCheck(); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthSaveTexId, 0); glCheck(); } GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -612,7 +612,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) // // PASS 3c: Render a-buffer to temporary texture // - GLuint texId = CreateColorFBOTexture(width, height); + GLuint texId = CreateColorFBOTexture(max_image_width, max_image_height); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 81bfe2a16..d418c5ac6 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -396,6 +396,8 @@ void main() \n\ gl4_ctx gl4; struct gl4ShaderUniforms_t gl4ShaderUniforms; +int max_image_width; +int max_image_height; bool gl4CompilePipelineShader( gl4PipelineShader* s, bool rotate_90, const char *source /* = PixelPipelineShader */) { @@ -614,11 +616,10 @@ static bool gles_init() static void resize(int w, int h) { - static int cur_width, cur_height; - if (w > cur_width || h > cur_height || stencilTexId == 0) + if (w > max_image_width || h > max_image_height || stencilTexId == 0) { - cur_width = w; - cur_height = h; + max_image_width = w; + max_image_height = h; if (stencilTexId != 0) { @@ -978,7 +979,6 @@ static bool RenderFrame() return !is_rtt; } -void reshapeABuffer(int w, int h); void termABuffer(); struct gl4rend : Renderer @@ -993,34 +993,34 @@ struct gl4rend : Renderer void Term() { termABuffer(); - if (stencilTexId != 0) - { - glcache.DeleteTextures(1, &stencilTexId); - stencilTexId = 0; - } - if (depthTexId != 0) - { - glcache.DeleteTextures(1, &depthTexId); - depthTexId = 0; - } - if (opaqueTexId != 0) - { - glcache.DeleteTextures(1, &opaqueTexId); - opaqueTexId = 0; - } - if (depthSaveTexId != 0) - { - glcache.DeleteTextures(1, &depthSaveTexId); - depthSaveTexId = 0; - } - if (KillTex) - killtex(); + if (stencilTexId != 0) + { + glcache.DeleteTextures(1, &stencilTexId); + stencilTexId = 0; + } + if (depthTexId != 0) + { + glcache.DeleteTextures(1, &depthTexId); + depthTexId = 0; + } + if (opaqueTexId != 0) + { + glcache.DeleteTextures(1, &opaqueTexId); + opaqueTexId = 0; + } + if (depthSaveTexId != 0) + { + glcache.DeleteTextures(1, &depthSaveTexId); + depthSaveTexId = 0; + } + if (KillTex) + killtex(); - CollectCleanup(); + CollectCleanup(); - gl_free_osd_resources(); - free_output_framebuffer(); - gles_term(); + gl_free_osd_resources(); + free_output_framebuffer(); + gles_term(); } bool Process(TA_context* ctx) { return ProcessFrame(ctx); } From a14bf29f5f1b204a0fc00af28531bafb2688ae39 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 28 Jun 2019 18:26:36 +0200 Subject: [PATCH 098/158] gl4: scaling and coords must be different with rtt vs screen --- core/rend/gl4/abuffer.cpp | 41 +++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index 6aea0aeb0..f6a9ce3e9 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -436,13 +436,26 @@ void reshapeABuffer(int w, int h) void abufferDrawQuad(float w, float h) { + float x = 0; + float y = 0; + if (gl4ShaderUniforms.scale_coefs[3] < 0) + { + // rendering to screen + float scl = 480.f / h; + float tx = (w * scl - 640.f) / 2; + + x = -tx; + y = 0.f; + w = 640.f + tx * 2; + h = 480.f; + } glBindVertexArray(g_quadVertexArray); struct Vertex vertices[] = { - { 0, h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, - { 0, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, - { w, h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, - { w, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, + { x, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, + { x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, + { x + w, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, + { x + w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, }; GLushort indices[] = { 0, 1, 2, 1, 3 }; @@ -555,10 +568,22 @@ void checkOverflowAndReset() void renderABuffer(bool sortFragments, int width, int height) { // Reset scale params - gl4ShaderUniforms.scale_coefs[0] = 2.0f / width; - gl4ShaderUniforms.scale_coefs[1] = 2.0f / height; - gl4ShaderUniforms.scale_coefs[2] = 1; - gl4ShaderUniforms.scale_coefs[3] = 1; + if (gl4ShaderUniforms.scale_coefs[3] < 0) + { + // screen + float scale_h = height / 480.f; + float offs_x = (width - scale_h * 640.f) / 2.f; + gl4ShaderUniforms.scale_coefs[0] = 2.f / (width / scale_h); + gl4ShaderUniforms.scale_coefs[1] = -2.f / 480.f; + gl4ShaderUniforms.scale_coefs[2] = 1.f - 2.f * offs_x / width; + } + else + { + // RTT + gl4ShaderUniforms.scale_coefs[0] = 2.0f / width; + gl4ShaderUniforms.scale_coefs[1] = 2.0f / height; + gl4ShaderUniforms.scale_coefs[2] = 1; + } // Render to output FBO glcache.UseProgram(sortFragments ? g_abuffer_final_shader.program : g_abuffer_final_nosort_shader.program); gl4ShaderUniforms.Set(&g_abuffer_final_shader); From 838cbe59e37d87b1d36b0336f3325a216087d038 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 11:40:42 +0200 Subject: [PATCH 099/158] gl4: get rid of scaling params and use normalized coords in abuffer add Eternal Arcadia and Yu Suzuki Game Works to render rtt to vram game list --- core/nullDC.cpp | 6 ++- core/rend/gl4/abuffer.cpp | 85 ++++++++++++--------------------------- core/rend/gl4/gl4.h | 4 +- core/rend/gl4/gldraw.cpp | 20 +++++++-- core/rend/gl4/gles.cpp | 18 +++++---- core/rend/gui.cpp | 4 ++ 6 files changed, 63 insertions(+), 74 deletions(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index fcdccf8f0..a34c63ddc 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -158,10 +158,14 @@ void LoadSpecialSettings() || !strncmp("T40204D", reios_product_number, 7) // Skies of Arcadia || !strncmp("MK-51052", reios_product_number, 8) + // Eternal Arcadia (JP) + || !strncmp("HDR-0076", reios_product_number, 8) // Flag to Flag (US) || !strncmp("MK-51007", reios_product_number, 8) // Super Speed Racing (JP) - || !strncmp("HDR-0013", reios_product_number, 8)) + || !strncmp("HDR-0013", reios_product_number, 8) + // Yu Suzuki Game Works Vol. 1 + || !strncmp("6108099", reios_product_number, 7)) { settings.rend.RenderToTextureBuffer = 1; rtt_to_buffer_game = true; diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index f6a9ce3e9..f0e9bb0f4 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -275,6 +275,16 @@ void main(void) \n\ } \n\ "; +static const char* VertexShaderSource = +"#version 430 \n" +"\ +in highp vec3 in_pos; \n\ + \n\ +void main() \n\ +{ \n\ + gl_Position = vec4(in_pos, 1.0); \n\ +}"; + void initABuffer() { if (max_image_width > 0 && max_image_height > 0) @@ -325,23 +335,23 @@ void initABuffer() { char source[16384]; sprintf(source, final_shader_source, 1); - gl4CompilePipelineShader(&g_abuffer_final_shader, false, source); + gl4CompilePipelineShader(&g_abuffer_final_shader, false, source, VertexShaderSource); } if (g_abuffer_final_nosort_shader.program == 0) { char source[16384]; sprintf(source, final_shader_source, 0); - gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, false, source); + gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, false, source, VertexShaderSource); } if (g_abuffer_clear_shader.program == 0) - gl4CompilePipelineShader(&g_abuffer_clear_shader, false, clear_shader_source); + gl4CompilePipelineShader(&g_abuffer_clear_shader, false, clear_shader_source, VertexShaderSource); if (g_abuffer_tr_modvol_shaders[0].program == 0) { char source[16384]; for (int mode = 0; mode < ModeCount; mode++) { sprintf(source, tr_modvol_shader_source, mode); - gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], false, source); + gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], false, source, VertexShaderSource); } } @@ -353,21 +363,8 @@ void initABuffer() glGenBuffers(1, &g_quadBuffer); glBindBuffer(GL_ARRAY_BUFFER, g_quadBuffer); glCheck(); - glEnableVertexAttribArray(VERTEX_POS_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_POS_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,x)); glCheck(); - - glEnableVertexAttribArray(VERTEX_COL_BASE_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_COL_BASE_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,col)); glCheck(); - - glEnableVertexAttribArray(VERTEX_COL_OFFS_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_COL_OFFS_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,spc)); glCheck(); - - glEnableVertexAttribArray(VERTEX_UV_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,u)); glCheck(); - - glDisableVertexAttribArray(VERTEX_UV1_ARRAY); - glDisableVertexAttribArray(VERTEX_COL_OFFS1_ARRAY); - glDisableVertexAttribArray(VERTEX_COL_BASE1_ARRAY); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glCheck(); glBindVertexArray(0); @@ -378,7 +375,7 @@ void initABuffer() glcache.UseProgram(g_abuffer_clear_shader.program); gl4ShaderUniforms.Set(&g_abuffer_clear_shader); - abufferDrawQuad(max_image_width, max_image_height); + abufferDrawQuad(); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glCheck(); @@ -434,28 +431,15 @@ void reshapeABuffer(int w, int h) initABuffer(); } -void abufferDrawQuad(float w, float h) +void abufferDrawQuad() { - float x = 0; - float y = 0; - if (gl4ShaderUniforms.scale_coefs[3] < 0) - { - // rendering to screen - float scl = 480.f / h; - float tx = (w * scl - 640.f) / 2; - - x = -tx; - y = 0.f; - w = 640.f + tx * 2; - h = 480.f; - } glBindVertexArray(g_quadVertexArray); - struct Vertex vertices[] = { - { x, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1.f }, - { x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0.f }, - { x + w, y + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1.f }, - { x + w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0.f }, + float vertices[] = { + -1, 1, 1, + -1, -1, 1, + 1, 1, 1, + 1, -1, 1, }; GLushort indices[] = { 0, 1, 2, 1, 3 }; @@ -565,25 +549,8 @@ void checkOverflowAndReset() glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0 , sizeof(GLuint), &max_pixel_index); } -void renderABuffer(bool sortFragments, int width, int height) +void renderABuffer(bool sortFragments) { - // Reset scale params - if (gl4ShaderUniforms.scale_coefs[3] < 0) - { - // screen - float scale_h = height / 480.f; - float offs_x = (width - scale_h * 640.f) / 2.f; - gl4ShaderUniforms.scale_coefs[0] = 2.f / (width / scale_h); - gl4ShaderUniforms.scale_coefs[1] = -2.f / 480.f; - gl4ShaderUniforms.scale_coefs[2] = 1.f - 2.f * offs_x / width; - } - else - { - // RTT - gl4ShaderUniforms.scale_coefs[0] = 2.0f / width; - gl4ShaderUniforms.scale_coefs[1] = 2.0f / height; - gl4ShaderUniforms.scale_coefs[2] = 1; - } // Render to output FBO glcache.UseProgram(sortFragments ? g_abuffer_final_shader.program : g_abuffer_final_nosort_shader.program); gl4ShaderUniforms.Set(&g_abuffer_final_shader); @@ -592,7 +559,7 @@ void renderABuffer(bool sortFragments, int width, int height) glcache.Disable(GL_CULL_FACE); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT); - abufferDrawQuad(width, height); + abufferDrawQuad(); glCheck(); @@ -601,7 +568,7 @@ void renderABuffer(bool sortFragments, int width, int height) gl4ShaderUniforms.Set(&g_abuffer_clear_shader); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - abufferDrawQuad(width, height); + abufferDrawQuad(); glActiveTexture(GL_TEXTURE0); diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 020910c30..8c8344f94 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -66,10 +66,10 @@ extern int max_image_height; GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt); void gl4DrawFramebuffer(float w, float h); bool gl4_render_output_framebuffer(); -void abufferDrawQuad(float w, float h); +void abufferDrawQuad(); extern const char *gl4PixelPipelineShader; -bool gl4CompilePipelineShader(gl4PipelineShader* s, bool rotate_90, const char *source = gl4PixelPipelineShader); +bool gl4CompilePipelineShader(gl4PipelineShader* s, bool rotate_90, const char *pixel_source = gl4PixelPipelineShader, const char *vertex_source = NULL); void gl4_delete_shaders(); extern GLuint stencilTexId; diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index 123b7f410..ee3e72694 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -386,7 +386,7 @@ static void DrawModVols(int first, int count) glcache.DepthMask(GL_TRUE); } -void renderABuffer(bool sortFragments, int width, int height); +void renderABuffer(bool sortFragments); void DrawTranslucentModVols(int first, int count); void checkOverflowAndReset(); @@ -620,7 +620,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glBindSampler(0, 0); glBindTexture(GL_TEXTURE_2D, opaqueTexId); - renderABuffer(current_pass.autosort, width, height); + renderABuffer(current_pass.autosort); glcache.DeleteTextures(1, &opaqueTexId); opaqueTexId = texId; @@ -648,7 +648,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glActiveTexture(GL_TEXTURE0); glBindSampler(0, 0); glBindTexture(GL_TEXTURE_2D, opaqueTexId); - renderABuffer(previous_pass.autosort, width, height); + renderABuffer(previous_pass.autosort); } static void gl4_draw_quad_texture(GLuint texture, float w, float h) @@ -681,7 +681,19 @@ static void gl4_draw_quad_texture(GLuint texture, float w, float h) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); - abufferDrawQuad(w, h); + struct Vertex vertices[] = { + { 0, 0 + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1 }, + { 0, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0 }, + { 0 + w, 0 + h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1 }, + { 0 + w, 0, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0 }, + }; + GLushort indices[] = { 0, 1, 2, 1, 3 }; + + gl4SetupMainVBO(); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW); + + glDrawElements(GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, (void *)0); } void gl4DrawFramebuffer(float w, float h) diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index d418c5ac6..348530876 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -399,15 +399,15 @@ struct gl4ShaderUniforms_t gl4ShaderUniforms; int max_image_width; int max_image_height; -bool gl4CompilePipelineShader( gl4PipelineShader* s, bool rotate_90, const char *source /* = PixelPipelineShader */) +bool gl4CompilePipelineShader( gl4PipelineShader* s, bool rotate_90, const char *pixel_source /* = PixelPipelineShader */, const char *vertex_source /* = NULL */) { char vshader[16384]; - sprintf(vshader, VertexShaderSource, s->pp_Gouraud, rotate_90); + sprintf(vshader, vertex_source == NULL ? VertexShaderSource : vertex_source, s->pp_Gouraud, rotate_90); char pshader[16384]; - sprintf(pshader, source, + sprintf(pshader, pixel_source, s->cp_AlphaTest,s->pp_ClipTestMode,s->pp_UseAlpha, s->pp_Texture,s->pp_IgnoreTexA,s->pp_ShadInstr,s->pp_Offset,s->pp_FogCtrl, s->pp_TwoVolumes, s->pp_DepthFunc, s->pp_Gouraud, s->pp_BumpMap, s->fog_clamping, s->pass); @@ -618,8 +618,10 @@ static void resize(int w, int h) { if (w > max_image_width || h > max_image_height || stencilTexId == 0) { - max_image_width = w; - max_image_height = h; + if (w > max_image_width) + max_image_width = w; + if (h > max_image_height) + max_image_height = h; if (stencilTexId != 0) { @@ -641,8 +643,8 @@ static void resize(int w, int h) glcache.DeleteTextures(1, &depthSaveTexId); depthSaveTexId = 0; } - gl4CreateTextures(w, h); - reshapeABuffer(w, h); + gl4CreateTextures(max_image_width, max_image_height); + reshapeABuffer(max_image_width, max_image_height); } } @@ -845,7 +847,7 @@ static bool RenderFrame() { if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) { - output_fbo = init_output_framebuffer(rendering_width, rendering_width); + output_fbo = init_output_framebuffer(rendering_width, rendering_height); } else { diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 00f6c41a2..551b688d9 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -1565,6 +1565,10 @@ void gui_display_ui() { gui_state = ClosedNoResume; gui_start_game(game_file); +#ifdef TEST_AUTOMATION + if (gui_state == Main) + die("Game load failed"); +#endif } else gui_display_content(); From ec0d21148d24a3d5c51ff782d449b18319960046 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 13:33:15 +0200 Subject: [PATCH 100/158] L.O.L and Miss Moonlight need RTT to vram option --- core/nullDC.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index a34c63ddc..fa95cab25 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -165,7 +165,11 @@ void LoadSpecialSettings() // Super Speed Racing (JP) || !strncmp("HDR-0013", reios_product_number, 8) // Yu Suzuki Game Works Vol. 1 - || !strncmp("6108099", reios_product_number, 7)) + || !strncmp("6108099", reios_product_number, 7) + // L.O.L + || !strncmp("T2106M", reios_product_number, 6) + // Miss Moonlight + || !strncmp("T18702M", reios_product_number, 7)) { settings.rend.RenderToTextureBuffer = 1; rtt_to_buffer_game = true; From 8404c6322cf76214aa837ebb83229959561d8f7e Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:06:46 +0200 Subject: [PATCH 101/158] New logging framework stolen from dolphin --- core/core.mk | 2 +- core/hw/mem/_vmem.cpp | 18 +- core/linux-dist/evdev.cpp | 4 +- core/linux-dist/evdev_gamepad.h | 10 +- core/linux-dist/main.cpp | 8 +- core/linux-dist/x11.cpp | 22 +- core/linux/common.cpp | 16 +- core/linux/posix_vmem.cpp | 2 +- core/log/BitSet.h | 218 ++++++++++++++++ core/log/ConsoleListener.h | 19 ++ core/log/ConsoleListenerDroid.cpp | 46 ++++ core/log/ConsoleListenerNix.cpp | 53 ++++ core/log/ConsoleListenerWin.cpp | 23 ++ core/log/Log.h | 95 +++++++ core/log/LogManager.cpp | 244 ++++++++++++++++++ core/log/LogManager.h | 80 ++++++ core/log/StringUtil.h | 113 ++++++++ core/nullDC.cpp | 70 ++--- core/rend/gl4/gles.cpp | 20 +- core/rend/gles/gles.cpp | 64 ++--- core/serialize.cpp | 2 +- core/stdclass.h | 65 +---- core/types.h | 10 +- core/windows/winmain.cpp | 2 + .../reicast/src/main/jni/src/Android.cpp | 2 + .../emulator-osx/emulator-osx/osx-main.mm | 2 + 26 files changed, 1031 insertions(+), 179 deletions(-) create mode 100644 core/log/BitSet.h create mode 100644 core/log/ConsoleListener.h create mode 100644 core/log/ConsoleListenerDroid.cpp create mode 100644 core/log/ConsoleListenerNix.cpp create mode 100644 core/log/ConsoleListenerWin.cpp create mode 100644 core/log/Log.h create mode 100644 core/log/LogManager.cpp create mode 100644 core/log/LogManager.h create mode 100644 core/log/StringUtil.h diff --git a/core/core.mk b/core/core.mk index 4573ba5e7..82ff5c045 100755 --- a/core/core.mk +++ b/core/core.mk @@ -11,7 +11,7 @@ RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \ hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \ hw/extdev/ hw/arm/ hw/naomi/ imgread/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \ deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/ deps/xbrz/ \ - deps/xxhash/ deps/libzip/ deps/imgui/ archive/ input/ + deps/xxhash/ deps/libzip/ deps/imgui/ archive/ input/ log/ ifdef WEBUI RZDCY_MODULES += webui/ diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index ec349bb36..1eb8d6bf9 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -299,31 +299,31 @@ void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet(Address //default read handlers u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss) { - //printf("[sh4]Read8 from 0x%X, not mapped [_vmem default handler]\n",addresss); + DEBUG_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); return (u8)MEM_ERROR_RETURN_VALUE; } u16 DYNACALL _vmem_ReadMem16_not_mapped(u32 addresss) { - //printf("[sh4]Read16 from 0x%X, not mapped [_vmem default handler]\n",addresss); + DEBUG_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); return (u16)MEM_ERROR_RETURN_VALUE; } u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 addresss) { - //printf("[sh4]Read32 from 0x%X, not mapped [_vmem default handler]\n",addresss); + DEBUG_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", addresss); return (u32)MEM_ERROR_RETURN_VALUE; } //default write handers void DYNACALL _vmem_WriteMem8_not_mapped(u32 addresss,u8 data) { - //printf("[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]\n",addresss,data); + DEBUG_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } void DYNACALL _vmem_WriteMem16_not_mapped(u32 addresss,u16 data) { - //printf("[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]\n",addresss,data); + DEBUG_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } void DYNACALL _vmem_WriteMem32_not_mapped(u32 addresss,u32 data) { - //printf("[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]\n",addresss,data); + DEBUG_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } //code to register handlers //0 is considered error :) @@ -522,7 +522,7 @@ bool _vmem_reserve() { // Fallback to statically allocated buffers, this results in slow-ops being generated. if (vmemstatus == MemTypeError) { - printf("Warning! nvmem is DISABLED (due to failure or not being built-in\n"); + WARN_LOG(VMEM, "Warning! nvmem is DISABLED (due to failure or not being built-in"); virt_ram_base = 0; // Allocate it all and initialize it. @@ -539,8 +539,8 @@ bool _vmem_reserve() { aica_ram.data = (u8*)malloc_pages(ARAM_SIZE); } else { - printf("Info: nvmem is enabled, with addr space of size %s\n", vmemstatus == MemType4GB ? "4GB" : "512MB"); - printf("Info: p_sh4rcb: %p virt_ram_base: %p\n", p_sh4rcb, virt_ram_base); + NOTICE_LOG(VMEM, "Info: nvmem is enabled, with addr space of size %s", vmemstatus == MemType4GB ? "4GB" : "512MB"); + INFO_LOG(VMEM, "Info: p_sh4rcb: %p virt_ram_base: %p", p_sh4rcb, virt_ram_base); // Map the different parts of the memory file into the new memory range we got. if (vmemstatus == MemType512MB) { diff --git a/core/linux-dist/evdev.cpp b/core/linux-dist/evdev.cpp index d1001ac72..aea1a989f 100644 --- a/core/linux-dist/evdev.cpp +++ b/core/linux-dist/evdev.cpp @@ -147,12 +147,12 @@ static void get_udev_events() { if (strstr(action, "add") != NULL) { - //printf("udev monitor: device added %s\n", devnode); + DEBUG_LOG(INPUT, "udev monitor: device added %s", devnode); input_evdev_add_device(devnode); } else if (strstr(action, "remove") != NULL) { - //printf("udev monitor: device removed %s\n", devnode); + DEBUG_LOG(INPUT, "udev monitor: device removed %s", devnode); input_evdev_remove_device(devnode); } } diff --git a/core/linux-dist/evdev_gamepad.h b/core/linux-dist/evdev_gamepad.h index 05eef706c..1af98d3a2 100644 --- a/core/linux-dist/evdev_gamepad.h +++ b/core/linux-dist/evdev_gamepad.h @@ -13,7 +13,7 @@ public: if (ioctl(fd, EVIOCGNAME(sizeof(buf) - 1), buf) < 0) perror("evdev: ioctl(EVIOCGNAME)"); else - printf("evdev: Opened device '%s' ", buf); + INFO_LOG(INPUT, "evdev: Opened device '%s'", buf); _name = buf; buf[0] = 0; if (ioctl(fd, EVIOCGUNIQ(sizeof(buf) - 1), buf) == 0) @@ -50,7 +50,7 @@ public: #endif if (find_mapping(mapping_file)) { - printf("using default mapping '%s'\n", input_mapper->name.c_str()); + INFO_LOG(INPUT, "using default mapping '%s'", input_mapper->name.c_str()); input_mapper = new InputMapping(*input_mapper); } else @@ -59,11 +59,11 @@ public: save_mapping(); } else - printf("using custom mapping '%s'\n", input_mapper->name.c_str()); + INFO_LOG(INPUT, "using custom mapping '%s'", input_mapper->name.c_str()); } virtual ~EvdevGamepadDevice() override { - printf("evdev: Device '%s' on port %d disconnected\n", _name.c_str(), maple_port()); + INFO_LOG(INPUT, "evdev: Device '%s' on port %d disconnected", _name.c_str(), maple_port()); close(_fd); } @@ -138,7 +138,7 @@ protected: } axis_min_values[axis] = abs.minimum; axis_ranges[axis] = abs.maximum - abs.minimum; - //printf("evdev: range of axis %d is from %d to %d\n", axis, axis_min_values[axis], axis_min_values[axis] + axis_ranges[axis]); + DEBUG_LOG(INPUT, "evdev: range of axis %d is from %d to %d", axis, axis_min_values[axis], axis_min_values[axis] + axis_ranges[axis]); } private: diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index b6931a125..633fd1f54 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -12,6 +12,7 @@ #include #include "hw/sh4/dyna/blockmanager.h" #include "hw/maple/maple_cfg.h" +#include "log/LogManager.h" #include #if defined(TARGET_EMSCRIPTEN) @@ -87,7 +88,7 @@ void os_SetupInput() #if defined(USE_JOYSTICK) int joystick_device_id = cfgLoadInt("input", "joystick_device_id", JOYSTICK_DEFAULT_DEVICE_ID); if (joystick_device_id < 0) { - puts("Legacy Joystick input disabled by config.\n"); + INFO_LOG(INPUT, "Legacy Joystick input disabled by config."); } else { @@ -342,6 +343,7 @@ std::vector find_system_data_dirs() int main(int argc, wchar* argv[]) { + LogManager::Init(); #ifdef TARGET_PANDORA signal(SIGSEGV, clean_exit); signal(SIGKILL, clean_exit); @@ -361,8 +363,8 @@ int main(int argc, wchar* argv[]) { add_system_data_dir(dirs[i]); } - printf("Config dir is: %s\n", get_writable_config_path("/").c_str()); - printf("Data dir is: %s\n", get_writable_data_path("/").c_str()); + INFO_LOG(BOOT, "Config dir is: %s", get_writable_config_path("/").c_str()); + INFO_LOG(BOOT, "Data dir is: %s", get_writable_data_path("/").c_str()); #if defined(USE_SDL) if (SDL_Init(0) != 0) diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp index af8e47730..27fc430fd 100644 --- a/core/linux-dist/x11.cpp +++ b/core/linux-dist/x11.cpp @@ -107,7 +107,7 @@ void x11_window_set_fullscreen(bool fullscreen) xev.xclient.data.l[3] = 1; xev.xclient.data.l[4] = 0; - printf("x11: setting fullscreen to %d\n", fullscreen); + INFO_LOG(RENDERER, "x11: setting fullscreen to %d", fullscreen); XSendEvent((Display*)x11_disp, DefaultRootWindow((Display*)x11_disp), False, SubstructureNotifyMask, &xev); } @@ -261,9 +261,9 @@ void input_x11_handle() if (e.type == KeyRelease && e.xkey.keycode == KEY_F10) { if (sample_Switch(3000)) { - printf("Starting profiling\n"); + INFO_LOG(COMMON, "Starting profiling"); } else { - printf("Stopping profiling\n"); + INFO_LOG(COMMON, "Stopping profiling"); } } else @@ -358,7 +358,7 @@ void input_x11_init() x11_keyboard_input = (cfgLoadInt("input", "enable_x11_keyboard", 1) >= 1); if (!x11_keyboard_input) - printf("X11 Keyboard input disabled by config.\n"); + INFO_LOG(INPUT, "X11 Keyboard input disabled by config."); } static int x11_error_handler(Display *, XErrorEvent *) @@ -390,7 +390,7 @@ void x11_window_create() x11Display = XOpenDisplay(NULL); if (!x11Display && !(x11Display = XOpenDisplay(":0"))) { - printf("Error: Unable to open X display\n"); + ERROR_LOG(RENDERER, "Error: Unable to open X display"); return; } x11Screen = XDefaultScreen(x11Display); @@ -437,17 +437,17 @@ void x11_window_create() GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); if (!fbc) { - printf("Failed to retrieve a framebuffer config\n"); + ERROR_LOG(RENDERER, "Failed to retrieve a framebuffer config"); exit(1); } - printf("Found %d matching FB configs.\n", fbcount); + INFO_LOG(RENDERER, "Found %d matching FB configs.", fbcount); GLXFBConfig bestFbc = fbc[0]; XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(x11Display, bestFbc); - printf("Chosen visual ID = 0x%lx\n", vi->visualid); + INFO_LOG(RENDERER, "Chosen visual ID = 0x%lx", vi->visualid); depth = vi->depth; @@ -460,7 +460,7 @@ void x11_window_create() XMatchVisualInfo(x11Display, x11Screen, i32Depth, TrueColor, x11Visual); if (!x11Visual) { - printf("Error: Unable to acquire visual\n"); + ERROR_LOG(RENDERER, "Error: Unable to acquire visual"); return; } x11Colormap = XCreateColormap(x11Display, sRootWindow, x11Visual->visual, AllocNone); @@ -529,7 +529,7 @@ void x11_window_create() x11_glc = glXCreateContextAttribsARB(x11Display, bestFbc, 0, True, context_attribs); if (!x11_glc) { - printf("Open GL 4.3 not supported\n"); + INFO_LOG(RENDERER, "Open GL 4.3 not supported"); // Try GL 3.0 context_attribs[1] = 3; context_attribs[3] = 0; @@ -555,7 +555,7 @@ void x11_window_create() } else { - printf("Not creating X11 window ..\n"); + INFO_LOG(RENDERER, "Not creating X11 window .."); } } diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 879e7c887..e98e0032e 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -45,7 +45,7 @@ void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) { unat pc = (unat)ctx.pc; bool dyna_cde = (pc>(unat)CodeCache) && (pc<(unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE)); - printf("SIGILL @ %lx -> %p was not in vram, dynacode:%d\n", pc, si->si_addr, dyna_cde); + ERROR_LOG(COMMON, "SIGILL @ %lx -> %p was not in vram, dynacode:%d", pc, si->si_addr, dyna_cde); //printf("PC is used here %08X\n", pc); kill(getpid(), SIGABRT); @@ -109,7 +109,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) #endif else { - printf("SIGSEGV @ %lx -> %p was not in vram, dynacode:%d\n", ctx.pc, si->si_addr, dyna_cde); + ERROR_LOG(COMMON, "SIGSEGV @ %lx -> %p was not in vram, dynacode:%d", ctx.pc, si->si_addr, dyna_cde); die("segfault"); signal(SIGSEGV, SIG_DFL); } @@ -172,15 +172,15 @@ void enable_runfast() : "r"(x), "r"(y) ); - printf("ARM VFP-Run Fast (NFP) enabled !\n"); + DEBUG_LOG(BOOT, "ARM VFP-Run Fast (NFP) enabled !"); #endif } void linux_fix_personality() { #if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_OS_MAC) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN) - printf("Personality: %08X\n", personality(0xFFFFFFFF)); + DEBUG_LOG(BOOT, "Personality: %08X", personality(0xFFFFFFFF)); personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF)); - printf("Updated personality: %08X\n", personality(0xFFFFFFFF)); + DEBUG_LOG(BOOT, "Updated personality: %08X", personality(0xFFFFFFFF)); #endif } @@ -192,10 +192,10 @@ void linux_rpi2_init() { handle = dlopen("libbcm_host.so", RTLD_LAZY); if (handle) { - printf("found libbcm_host\n"); + DEBUG_LOG(BOOT, "found libbcm_host"); *(void**) (&rpi_bcm_init) = dlsym(handle, "bcm_host_init"); if (rpi_bcm_init) { - printf("rpi2: bcm_init\n"); + DEBUG_LOG(BOOT, "rpi2: bcm_init"); rpi_bcm_init(); } } @@ -213,7 +213,7 @@ void common_linux_setup() settings.profile.run_counts=0; - printf("Linux paging: %ld %08X %08X\n",sysconf(_SC_PAGESIZE),PAGE_SIZE,PAGE_MASK); + DEBUG_LOG(BOOT, "Linux paging: %ld %08X %08X", sysconf(_SC_PAGESIZE), PAGE_SIZE, PAGE_MASK); verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1)); } #endif diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index 5a2a43456..921dfd16c 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -275,7 +275,7 @@ bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code *code_area_rw = ptr_rw; *rx_offset = (char*)ptr_rx - (char*)ptr_rw; - printf("Info: Using NO_RWX mode, rx ptr: %p, rw ptr: %p, offset: %lu\n", ptr_rx, ptr_rw, (unsigned long)*rx_offset); + INFO_LOG(DYNAREC, "Info: Using NO_RWX mode, rx ptr: %p, rw ptr: %p, offset: %lu", ptr_rx, ptr_rw, (unsigned long)*rx_offset); return (ptr_rw != MAP_FAILED); } diff --git a/core/log/BitSet.h b/core/log/BitSet.h new file mode 100644 index 000000000..4bf909df8 --- /dev/null +++ b/core/log/BitSet.h @@ -0,0 +1,218 @@ +// This file is under the public domain. + +#pragma once + +#include +#include +#include +#include "types.h" + +#ifdef _WIN32 + +#include + +namespace Common +{ +template +constexpr int CountSetBits(T v) +{ + // from https://graphics.stanford.edu/~seander/bithacks.html + // GCC has this built in, but MSVC's intrinsic will only emit the actual + // POPCNT instruction, which we're not depending on + v = v - ((v >> 1) & (T) ~(T)0 / 3); + v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3); + v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15; + return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8; +} +inline int LeastSignificantSetBit(u8 val) +{ + unsigned long index; + _BitScanForward(&index, val); + return (int)index; +} +inline int LeastSignificantSetBit(u16 val) +{ + unsigned long index; + _BitScanForward(&index, val); + return (int)index; +} +inline int LeastSignificantSetBit(u32 val) +{ + unsigned long index; + _BitScanForward(&index, val); + return (int)index; +} +inline int LeastSignificantSetBit(u64 val) +{ + unsigned long index; + _BitScanForward64(&index, val); + return (int)index; +} +#else +namespace Common +{ +constexpr int CountSetBits(u8 val) +{ + return __builtin_popcount(val); +} +constexpr int CountSetBits(u16 val) +{ + return __builtin_popcount(val); +} +constexpr int CountSetBits(u32 val) +{ + return __builtin_popcount(val); +} +constexpr int CountSetBits(u64 val) +{ + return __builtin_popcountll(val); +} +inline int LeastSignificantSetBit(u8 val) +{ + return __builtin_ctz(val); +} +inline int LeastSignificantSetBit(u16 val) +{ + return __builtin_ctz(val); +} +inline int LeastSignificantSetBit(u32 val) +{ + return __builtin_ctz(val); +} +inline int LeastSignificantSetBit(u64 val) +{ + return __builtin_ctzll(val); +} +#endif + +// Similar to std::bitset, this is a class which encapsulates a bitset, i.e. +// using the set bits of an integer to represent a set of integers. Like that +// class, it acts like an array of bools: +// BitSet32 bs; +// bs[1] = true; +// but also like the underlying integer ([0] = least significant bit): +// BitSet32 bs2 = ...; +// bs = (bs ^ bs2) & BitSet32(0xffff); +// The following additional functionality is provided: +// - Construction using an initializer list. +// BitSet bs { 1, 2, 4, 8 }; +// - Efficiently iterating through the set bits: +// for (int i : bs) +// [i is the *index* of a set bit] +// (This uses the appropriate CPU instruction to find the next set bit in one +// operation.) +// - Counting set bits using .Count() - see comment on that method. + +// TODO: use constexpr when MSVC gets out of the Dark Ages + +template +class BitSet +{ + static_assert(!std::is_signed::value, "BitSet should not be used with signed types"); + +public: + // A reference to a particular bit, returned from operator[]. + class Ref + { + public: + constexpr Ref(Ref&& other) : m_bs(other.m_bs), m_mask(other.m_mask) {} + constexpr Ref(BitSet* bs, IntTy mask) : m_bs(bs), m_mask(mask) {} + constexpr operator bool() const { return (m_bs->m_val & m_mask) != 0; } + bool operator=(bool set) + { + m_bs->m_val = (m_bs->m_val & ~m_mask) | (set ? m_mask : 0); + return set; + } + + private: + BitSet* m_bs; + IntTy m_mask; + }; + + // A STL-like iterator is required to be able to use range-based for loops. + class Iterator + { + public: + constexpr Iterator(const Iterator& other) : m_val(other.m_val), m_bit(other.m_bit) {} + constexpr Iterator(IntTy val, int bit) : m_val(val), m_bit(bit) {} + Iterator& operator=(Iterator other) + { + new (this) Iterator(other); + return *this; + } + Iterator& operator++() + { + if (m_val == 0) + { + m_bit = -1; + } + else + { + int bit = LeastSignificantSetBit(m_val); + m_val &= ~(1 << bit); + m_bit = bit; + } + return *this; + } + Iterator operator++(int) + { + Iterator other(*this); + ++*this; + return other; + } + constexpr int operator*() const { return m_bit; } + constexpr bool operator==(Iterator other) const { return m_bit == other.m_bit; } + constexpr bool operator!=(Iterator other) const { return m_bit != other.m_bit; } + + private: + IntTy m_val; + int m_bit; + }; + + constexpr BitSet() : m_val(0) {} + constexpr explicit BitSet(IntTy val) : m_val(val) {} + BitSet(std::initializer_list init) + { + m_val = 0; + for (int bit : init) + m_val |= (IntTy)1 << bit; + } + + constexpr static BitSet AllTrue(size_t count) + { + return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1)); + } + + Ref operator[](size_t bit) { return Ref(this, (IntTy)1 << bit); } + constexpr const Ref operator[](size_t bit) const { return (*const_cast(this))[bit]; } + constexpr bool operator==(BitSet other) const { return m_val == other.m_val; } + constexpr bool operator!=(BitSet other) const { return m_val != other.m_val; } + constexpr bool operator<(BitSet other) const { return m_val < other.m_val; } + constexpr bool operator>(BitSet other) const { return m_val > other.m_val; } + constexpr BitSet operator|(BitSet other) const { return BitSet(m_val | other.m_val); } + constexpr BitSet operator&(BitSet other) const { return BitSet(m_val & other.m_val); } + constexpr BitSet operator^(BitSet other) const { return BitSet(m_val ^ other.m_val); } + constexpr BitSet operator~() const { return BitSet(~m_val); } + constexpr BitSet operator<<(IntTy shift) const { return BitSet(m_val << shift); } + constexpr BitSet operator>>(IntTy shift) const { return BitSet(m_val >> shift); } + constexpr explicit operator bool() const { return m_val != 0; } + BitSet& operator|=(BitSet other) { return *this = *this | other; } + BitSet& operator&=(BitSet other) { return *this = *this & other; } + BitSet& operator^=(BitSet other) { return *this = *this ^ other; } + BitSet& operator<<=(IntTy shift) { return *this = *this << shift; } + BitSet& operator>>=(IntTy shift) { return *this = *this >> shift; } + // Warning: Even though on modern CPUs this is a single fast instruction, + // Dolphin's official builds do not currently assume POPCNT support on x86, + // so slower explicit bit twiddling is generated. Still should generally + // be faster than a loop. + constexpr unsigned int Count() const { return CountSetBits(m_val); } + constexpr Iterator begin() const { return ++Iterator(m_val, 0); } + constexpr Iterator end() const { return Iterator(m_val, -1); } + IntTy m_val; +}; +} // namespace Common + +using BitSet8 = Common::BitSet; +using BitSet16 = Common::BitSet; +using BitSet32 = Common::BitSet; +using BitSet64 = Common::BitSet; diff --git a/core/log/ConsoleListener.h b/core/log/ConsoleListener.h new file mode 100644 index 000000000..f1b90ae01 --- /dev/null +++ b/core/log/ConsoleListener.h @@ -0,0 +1,19 @@ +// Copyright 2010 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "LogManager.h" + +class ConsoleListener : public LogListener +{ +public: + ConsoleListener(); + ~ConsoleListener(); + + void Log(LogTypes::LOG_LEVELS, const char* text) override; + +private: + bool m_use_color; +}; diff --git a/core/log/ConsoleListenerDroid.cpp b/core/log/ConsoleListenerDroid.cpp new file mode 100644 index 000000000..d840e5bef --- /dev/null +++ b/core/log/ConsoleListenerDroid.cpp @@ -0,0 +1,46 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. +#ifdef _ANDROID + +#include + +#include "types.h" +#include "ConsoleListener.h" + +ConsoleListener::ConsoleListener() +{ +} + +ConsoleListener::~ConsoleListener() +{ +} + +void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char* text) +{ + android_LogPriority logLevel = ANDROID_LOG_UNKNOWN; + + // Map dolphin's log levels to android's + switch (level) + { + case LogTypes::LOG_LEVELS::LDEBUG: + logLevel = ANDROID_LOG_DEBUG; + break; + case LogTypes::LOG_LEVELS::LINFO: + logLevel = ANDROID_LOG_INFO; + break; + case LogTypes::LOG_LEVELS::LWARNING: + logLevel = ANDROID_LOG_WARN; + break; + case LogTypes::LOG_LEVELS::LERROR: + logLevel = ANDROID_LOG_ERROR; + break; + case LogTypes::LOG_LEVELS::LNOTICE: + logLevel = ANDROID_LOG_INFO; + break; + } + + __android_log_write(logLevel, LOG_TAG, text); +} + +#endif // _ANDROID diff --git a/core/log/ConsoleListenerNix.cpp b/core/log/ConsoleListenerNix.cpp new file mode 100644 index 000000000..4a5439478 --- /dev/null +++ b/core/log/ConsoleListenerNix.cpp @@ -0,0 +1,53 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. +#if !defined(_WIN32) && !defined(_ANDROID) +#include +#include + +#ifndef _WIN32 +#include +#endif + +#include "ConsoleListener.h" +#include "Log.h" + +ConsoleListener::ConsoleListener() +{ + m_use_color = !!isatty(fileno(stdout)); +} + +ConsoleListener::~ConsoleListener() +{ + fflush(nullptr); +} + +void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char* text) +{ + char color_attr[16] = ""; + char reset_attr[16] = ""; + + if (m_use_color) + { + strcpy(reset_attr, "\x1b[0m"); + switch (level) + { + case LogTypes::LOG_LEVELS::LNOTICE: + // light green + strcpy(color_attr, "\x1b[92m"); + break; + case LogTypes::LOG_LEVELS::LERROR: + // light red + strcpy(color_attr, "\x1b[91m"); + break; + case LogTypes::LOG_LEVELS::LWARNING: + // light yellow + strcpy(color_attr, "\x1b[93m"); + break; + default: + break; + } + } + fprintf(stderr, "%s%s%s", color_attr, text, reset_attr); +} +#endif // !_WIN32 && !_ANDROID diff --git a/core/log/ConsoleListenerWin.cpp b/core/log/ConsoleListenerWin.cpp new file mode 100644 index 000000000..188346541 --- /dev/null +++ b/core/log/ConsoleListenerWin.cpp @@ -0,0 +1,23 @@ +// Copyright 2015 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. +#ifdef _WIN32 + +#include + +#include "ConsoleListener.h" + +ConsoleListener::ConsoleListener() +{ +} + +ConsoleListener::~ConsoleListener() +{ +} + +void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char* text) +{ + ::OutputDebugStringA(text); +} + +#endif // _WIN32 diff --git a/core/log/Log.h b/core/log/Log.h new file mode 100644 index 000000000..a0062c052 --- /dev/null +++ b/core/log/Log.h @@ -0,0 +1,95 @@ +// Copyright 2009 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +namespace LogTypes +{ +enum LOG_TYPE +{ + AICA, + AICA_ARM, + AUDIO, + BOOT, + COMMON, + DYNAREC, + FLASHROM, + GDROM, + HOLLY, + INPUT, + JVS, + MAPLE, + INTERPRETER, + MEMORY, + VMEM, + MODEM, + NAOMI, + PVR, + RENDERER, + SAVESTATE, + + NUMBER_OF_LOGS // Must be last +}; + +enum LOG_LEVELS +{ + LNOTICE = 1, // VERY important information that is NOT errors. Like startup and OSReports. + LERROR = 2, // Critical errors + LWARNING = 3, // Something is suspicious. + LINFO = 4, // General information. + LDEBUG = 5, // Detailed debugging - might make things slow. +}; + +static const char LOG_LEVEL_TO_CHAR[7] = "-NEWID"; + +} // namespace LogTypes + +void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, + const char* fmt, ...) +#ifdef __GNUC__ +__attribute__((format(printf, 5, 6))) +#endif +; + +#if !defined(RELEASE) || defined(DEBUGFAST) +#define MAX_LOGLEVEL LogTypes::LOG_LEVELS::LDEBUG +#else +#ifndef MAX_LOGLEVEL +#define MAX_LOGLEVEL LogTypes::LOG_LEVELS::LINFO +#endif // loglevel +#endif // logging + +// Let the compiler optimize this out +#define GENERIC_LOG(t, v, ...) \ + do \ + { \ + if (v <= MAX_LOGLEVEL) \ + GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ + } while (0) + +#define ERROR_LOG(t, ...) \ + do \ + { \ + GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__); \ + } while (0) +#define WARN_LOG(t, ...) \ + do \ + { \ + GENERIC_LOG(LogTypes::t, LogTypes::LWARNING, __VA_ARGS__); \ + } while (0) +#define NOTICE_LOG(t, ...) \ + do \ + { \ + GENERIC_LOG(LogTypes::t, LogTypes::LNOTICE, __VA_ARGS__); \ + } while (0) +#define INFO_LOG(t, ...) \ + do \ + { \ + GENERIC_LOG(LogTypes::t, LogTypes::LINFO, __VA_ARGS__); \ + } while (0) +#define DEBUG_LOG(t, ...) \ + do \ + { \ + GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__); \ + } while (0) diff --git a/core/log/LogManager.cpp b/core/log/LogManager.cpp new file mode 100644 index 000000000..bf2ccefc2 --- /dev/null +++ b/core/log/LogManager.cpp @@ -0,0 +1,244 @@ +// Copyright 2009 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "LogManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ConsoleListener.h" +#include "Log.h" +#include "StringUtil.h" +#include "cfg/cfg.h" +#include "oslib/oslib.h" + +constexpr size_t MAX_MSGLEN = 1024; + +template +void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmode openmode) +{ +#ifdef _WIN32 + fstream.open(UTF8ToTStr(filename).c_str(), openmode); +#else + fstream.open(filename.c_str(), openmode); +#endif +} + +class FileLogListener : public LogListener +{ +public: + FileLogListener(const std::string& filename) + { + OpenFStream(m_logfile, filename, std::ios::app); + SetEnable(true); + } + + void Log(LogTypes::LOG_LEVELS, const char* msg) override + { + if (!IsEnabled() || !IsValid()) + return; + + std::lock_guard lk(m_log_lock); + m_logfile << msg << std::flush; + } + + bool IsValid() const { return m_logfile.good(); } + bool IsEnabled() const { return m_enable; } + void SetEnable(bool enable) { m_enable = enable; } + +private: + std::mutex m_log_lock; + std::ofstream m_logfile; + bool m_enable; +}; + +void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, + const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + if (LogManager::GetInstance()) + LogManager::GetInstance()->Log(level, type, file, line, fmt, args); + va_end(args); +} + +static size_t DeterminePathCutOffPoint() +{ + constexpr const char* pattern = "/core/"; +#ifdef _WIN32 + constexpr const char* pattern2 = "\\core\\"; +#endif + std::string path = __FILE__; + std::transform(path.begin(), path.end(), path.begin(), + [](char c) { return std::tolower(c, std::locale::classic()); }); + size_t pos = path.find(pattern); +#ifdef _WIN32 + if (pos == std::string::npos) + pos = path.find(pattern2); +#endif + if (pos != std::string::npos) + return pos + strlen(pattern); + return 0; +} + +LogManager::LogManager() +{ + // create log containers + m_log[LogTypes::AICA] = {"AICA", "AICA Audio Emulation"}; + m_log[LogTypes::AICA_ARM] = {"AICA_ARM", "AICA ARM Emulation"}; + m_log[LogTypes::AUDIO] = {"Audio", "Audio Ouput Interface"}; + m_log[LogTypes::BOOT] = {"BOOT", "Boot"}; + m_log[LogTypes::COMMON] = {"COMMON", "Common"}; + m_log[LogTypes::DYNAREC] = {"DYNAREC", "Dynamic Recompiler"}; + m_log[LogTypes::FLASHROM] = {"FLASHROM", "FlashROM / EEPROM"}; + m_log[LogTypes::GDROM] = {"GDROM", "GD-Rom Drive"}; + m_log[LogTypes::HOLLY] = {"HOLLY", "Holly Chipset"}; + m_log[LogTypes::INPUT] = {"INPUT", "Input Peripherals"}; + m_log[LogTypes::JVS] = {"JVS", "Naomi JVS Protocol"}; + m_log[LogTypes::MAPLE] = {"MAPLE", "Maple Bus and Peripherals"}; + m_log[LogTypes::INTERPRETER] = {"INTERPRETER", "SH4 Interpreter"}; + m_log[LogTypes::MEMORY] = {"MEMORY", "Memory Management"}; + m_log[LogTypes::VMEM] = {"VMEM", "Virtual Memory Management"}; + m_log[LogTypes::MODEM] = {"MODEM", "Modem and Network"}; + m_log[LogTypes::NAOMI] = {"NAOMI", "Naomi"}; + m_log[LogTypes::PVR] = {"PVR", "PowerVR GPU"}; + m_log[LogTypes::RENDERER] = {"RENDERER", "OpenGL Renderer"}; + m_log[LogTypes::SAVESTATE] = {"SAVESTATE", "Save States"}; + + RegisterListener(LogListener::FILE_LISTENER, new FileLogListener("flycast.log")); + RegisterListener(LogListener::CONSOLE_LISTENER, new ConsoleListener()); + + // Set up log listeners + int verbosity = cfgLoadInt("log", "Verbosity", LogTypes::LDEBUG); + + // Ensure the verbosity level is valid + if (verbosity < 1) + verbosity = 1; + if (verbosity > MAX_LOGLEVEL) + verbosity = MAX_LOGLEVEL; + + SetLogLevel(static_cast(verbosity)); + EnableListener(LogListener::FILE_LISTENER, cfgLoadBool("log", "LogToFile", false)); + EnableListener(LogListener::CONSOLE_LISTENER, cfgLoadBool("log", "LogToConsole", true)); + // EnableListener(LogListener::LOG_WINDOW_LISTENER, Config::Get(LOGGER_WRITE_TO_WINDOW)); + + for (LogContainer& container : m_log) + { + container.m_enable = cfgLoadBool("log", container.m_short_name, true); + } + + m_path_cutoff_point = DeterminePathCutOffPoint(); +} + +LogManager::~LogManager() +{ + // The log window listener pointer is owned by the GUI code. + delete m_listeners[LogListener::CONSOLE_LISTENER]; + delete m_listeners[LogListener::FILE_LISTENER]; +} + +// Return the current time formatted as Minutes:Seconds:Milliseconds +// in the form 00:00:000. +static std::string GetTimeFormatted() +{ + double now = os_GetSeconds(); + u32 minutes = (u32)now / 60; + u32 seconds = (u32)now % 60; + u32 ms = (now - (u32)now) * 1000; + return StringFromFormat("%02d:%02d:%03d", minutes, seconds, ms); +} + +void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, + int line, const char* format, va_list args) +{ + return LogWithFullPath(level, type, file + m_path_cutoff_point, line, format, args); +} + +void LogManager::LogWithFullPath(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, + const char* file, int line, const char* format, va_list args) +{ + if (!IsEnabled(type, level) || !static_cast(m_listener_ids)) + return; + + char temp[MAX_MSGLEN]; + CharArrayFromFormatV(temp, MAX_MSGLEN, format, args); + + std::string msg = + StringFromFormat("%s %s:%u %c[%s]: %s\n", GetTimeFormatted().c_str(), file, + line, LogTypes::LOG_LEVEL_TO_CHAR[(int)level], GetShortName(type), temp); + + for (auto listener_id : m_listener_ids) + if (m_listeners[listener_id]) + m_listeners[listener_id]->Log(level, msg.c_str()); +} + +LogTypes::LOG_LEVELS LogManager::GetLogLevel() const +{ + return m_level; +} + +void LogManager::SetLogLevel(LogTypes::LOG_LEVELS level) +{ + m_level = level; +} + +void LogManager::SetEnable(LogTypes::LOG_TYPE type, bool enable) +{ + m_log[type].m_enable = enable; +} + +bool LogManager::IsEnabled(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level) const +{ + return m_log[type].m_enable && GetLogLevel() >= level; +} + +const char* LogManager::GetShortName(LogTypes::LOG_TYPE type) const +{ + return m_log[type].m_short_name; +} + +const char* LogManager::GetFullName(LogTypes::LOG_TYPE type) const +{ + return m_log[type].m_full_name; +} + +void LogManager::RegisterListener(LogListener::LISTENER id, LogListener* listener) +{ + m_listeners[id] = listener; +} + +void LogManager::EnableListener(LogListener::LISTENER id, bool enable) +{ + m_listener_ids[id] = enable; +} + +bool LogManager::IsListenerEnabled(LogListener::LISTENER id) const +{ + return m_listener_ids[id]; +} + +// Singleton. Ugh. +static LogManager* s_log_manager; + +LogManager* LogManager::GetInstance() +{ + return s_log_manager; +} + +void LogManager::Init() +{ + s_log_manager = new LogManager(); +} + +void LogManager::Shutdown() +{ + delete s_log_manager; + s_log_manager = nullptr; +} diff --git a/core/log/LogManager.h b/core/log/LogManager.h new file mode 100644 index 000000000..dda1acbfa --- /dev/null +++ b/core/log/LogManager.h @@ -0,0 +1,80 @@ +// Copyright 2009 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +#include "BitSet.h" +#include "Log.h" + +// pure virtual interface +class LogListener +{ +public: + virtual ~LogListener() {} + virtual void Log(LogTypes::LOG_LEVELS, const char* msg) = 0; + + enum LISTENER + { + FILE_LISTENER = 0, + CONSOLE_LISTENER, + LOG_WINDOW_LISTENER, + + NUMBER_OF_LISTENERS // Must be last + }; +}; + +class LogManager +{ +public: + static LogManager* GetInstance(); + static void Init(); + static void Shutdown(); + + void Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, int line, + const char* fmt, va_list args); + void LogWithFullPath(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char* file, + int line, const char* fmt, va_list args); + + LogTypes::LOG_LEVELS GetLogLevel() const; + void SetLogLevel(LogTypes::LOG_LEVELS level); + + void SetEnable(LogTypes::LOG_TYPE type, bool enable); + bool IsEnabled(LogTypes::LOG_TYPE type, LogTypes::LOG_LEVELS level = LogTypes::LNOTICE) const; + + const char* GetShortName(LogTypes::LOG_TYPE type) const; + const char* GetFullName(LogTypes::LOG_TYPE type) const; + + void RegisterListener(LogListener::LISTENER id, LogListener* listener); + void EnableListener(LogListener::LISTENER id, bool enable); + bool IsListenerEnabled(LogListener::LISTENER id) const; + +private: + struct LogContainer + { + LogContainer() : m_short_name(NULL), m_full_name(NULL) {} + LogContainer(const char* shortName, const char* fullName, bool enable = false) + : m_short_name(shortName), m_full_name(fullName), m_enable(enable) + {} + const char* m_short_name; + const char* m_full_name; + bool m_enable = false; + }; + + LogManager(); + ~LogManager(); + + LogManager(const LogManager&) = delete; + LogManager& operator=(const LogManager&) = delete; + LogManager(LogManager&&) = delete; + LogManager& operator=(LogManager&&) = delete; + + LogTypes::LOG_LEVELS m_level; + std::array m_log{}; + std::array m_listeners{}; + BitSet32 m_listener_ids; + size_t m_path_cutoff_point = 0; +}; diff --git a/core/log/StringUtil.h b/core/log/StringUtil.h new file mode 100644 index 000000000..ba12159cf --- /dev/null +++ b/core/log/StringUtil.h @@ -0,0 +1,113 @@ +#include + +#ifdef _WIN32 +#include +constexpr u32 CODEPAGE_SHIFT_JIS = 932; +constexpr u32 CODEPAGE_WINDOWS_1252 = 1252; +#else +#include +#include +#include +#include +#endif + +#if !defined(_WIN32) && !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__) +static locale_t GetCLocale() +{ + static locale_t c_locale = newlocale(LC_ALL_MASK, "C", nullptr); + return c_locale; +} +#endif + +bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) +{ + int writtenCount; + +#ifdef _WIN32 + // You would think *printf are simple, right? Iterate on each character, + // if it's a format specifier handle it properly, etc. + // + // Nooooo. Not according to the C standard. + // + // According to the C99 standard (7.19.6.1 "The fprintf function") + // The format shall be a multibyte character sequence + // + // Because some character encodings might have '%' signs in the middle of + // a multibyte sequence (SJIS for example only specifies that the first + // byte of a 2 byte sequence is "high", the second byte can be anything), + // printf functions have to decode the multibyte sequences and try their + // best to not screw up. + // + // Unfortunately, on Windows, the locale for most languages is not UTF-8 + // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the + // locale, and completely fails when trying to decode UTF-8 as EUC-CN. + // + // On the other hand, the fix is simple: because we use UTF-8, no such + // multibyte handling is required as we can simply assume that no '%' char + // will be present in the middle of a multibyte sequence. + // + // This is why we look up the default C locale here and use _vsnprintf_l. + static _locale_t c_locale = nullptr; + if (!c_locale) + c_locale = _create_locale(LC_ALL, "C"); + writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); +#else +#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__) + locale_t previousLocale = uselocale(GetCLocale()); +#endif + writtenCount = vsnprintf(out, outsize, format, args); +#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__) + uselocale(previousLocale); +#endif +#endif + + if (writtenCount > 0 && writtenCount < outsize) + { + out[writtenCount] = '\0'; + return true; + } + else + { + out[outsize - 1] = '\0'; + return false; + } +} + +std::string StringFromFormatV(const char* format, va_list args) +{ + char* buf = nullptr; +#ifdef _WIN32 + int required = _vscprintf(format, args); + buf = new char[required + 1]; + CharArrayFromFormatV(buf, required + 1, format, args); + + std::string temp = buf; + delete[] buf; +#else +#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__) + locale_t previousLocale = uselocale(GetCLocale()); +#endif + if (vasprintf(&buf, format, args) < 0) + { + ERROR_LOG(COMMON, "Unable to allocate memory for string"); + buf = nullptr; + } + +#if !defined(ANDROID) && !defined(__HAIKU__) && !defined(__OpenBSD__) + uselocale(previousLocale); +#endif + + std::string temp = buf; + free(buf); +#endif + return temp; +} + +std::string StringFromFormat(const char* format, ...) +{ + va_list args; + va_start(args, format); + std::string res = StringFromFormatV(format, args); + va_end(args); + return res; +} diff --git a/core/nullDC.cpp b/core/nullDC.cpp index fa95cab25..5522915d2 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -24,6 +24,7 @@ #include "profiler/profiler.h" #include "input/gamepad_device.h" #include "hw/sh4/dyna/blockmanager.h" +#include "log/LogManager.h" void FlushCache(); void LoadCustom(); @@ -132,7 +133,7 @@ void plugins_Reset(bool Manual) void LoadSpecialSettings() { #if DC_PLATFORM == DC_PLATFORM_DREAMCAST - printf("Game ID is [%s]\n", reios_product_number); + INFO_LOG(BOOT, "Game ID is [%s]", reios_product_number); rtt_to_buffer_game = false; safemode_game = false; tr_poly_depth_mask_game = false; @@ -142,7 +143,7 @@ void LoadSpecialSettings() if (reios_windows_ce) { - printf("Enabling Full MMU and Extra depth scaling for Windows CE game\n"); + INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game\n"); settings.rend.ExtraDepthScale = 0.1; extra_depth_game = true; settings.dreamcast.FullMMU = true; @@ -187,14 +188,14 @@ void LoadSpecialSettings() // Ducati World (PAL) || !strncmp("T-8121D-50", reios_product_number, 10)) { - printf("Enabling Dynarec safe mode for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s\n", reios_product_number); settings.dynarec.safemode = 1; safemode_game = true; } // NHL 2K2 if (!strncmp("MK-51182", reios_product_number, 8)) { - printf("Enabling Extra depth scaling for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s\n", reios_product_number); settings.rend.ExtraDepthScale = 10000; extra_depth_game = true; } @@ -217,22 +218,22 @@ void LoadSpecialSettings() // Marionette Company 2 || !strncmp("T5203M", reios_product_number, 6)) { - printf("Disabling 32-bit virtual memory for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s\n", reios_product_number); settings.dynarec.disable_vmem32 = true; disable_vmem32_game = true; } #elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - printf("Game ID is [%s]\n", naomi_game_id); + INFO_LOG(BOOT, "Game ID is [%s]", naomi_game_id); if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id)) { - printf("Enabling Dynarec safe mode for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", naomi_game_id); settings.dynarec.safemode = 1; safemode_game = true; } if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id)) { - printf("Enabling Extra depth scaling for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id); settings.rend.ExtraDepthScale = 1e26; extra_depth_game = true; } @@ -243,41 +244,41 @@ void LoadSpecialSettings() || !strcmp("CRACKIN'DJ PART2 ver JAPAN", naomi_game_id) || !strcmp("KICK '4' CASH", naomi_game_id)) { - printf("Enabling JVS rotary encoders for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id); settings.input.JammaSetup = 2; } else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi || !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW { - printf("Enabling 4-player setup for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling 4-player setup for game %s", naomi_game_id); settings.input.JammaSetup = 1; } else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id) || !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW { - printf("Enabling specific JVS setup for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); settings.input.JammaSetup = 3; } else if (!strcmp("RINGOUT 4X4 JAPAN", naomi_game_id)) { - printf("Enabling specific JVS setup for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); settings.input.JammaSetup = 4; } else if (!strcmp("NINJA ASSAULT", naomi_game_id) || !strcmp(naomi_game_id, "Sports Shooting USA") // AW || !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE")) // AW { - printf("Enabling lightgun setup for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling lightgun setup for game %s", naomi_game_id); settings.input.JammaSetup = 5; } else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id)) { - printf("Enabling specific JVS setup for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); settings.input.JammaSetup = 7; } if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id)) { - printf("Enabling translucent depth multipass for game %s\n", naomi_game_id); + INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id); settings.rend.TranslucentPolygonDepthMask = true; tr_poly_depth_mask_game = true; } @@ -303,7 +304,7 @@ int reicast_init(int argc, char* argv[]) #endif if (!_vmem_reserve()) { - printf("Failed to alloc mem\n"); + ERROR_LOG(VMEM, "Failed to alloc mem"); return -1; } if (ParseCommandLine(argc, argv)) @@ -311,13 +312,18 @@ int reicast_init(int argc, char* argv[]) return 69; } InitSettings(); + LogManager::Shutdown(); if (!cfgOpen()) { - printf("Config directory is not set. Starting onboarding\n"); + LogManager::Init(); + NOTICE_LOG(BOOT, "Config directory is not set. Starting onboarding"); gui_open_onboarding(); } else + { + LogManager::Init(); LoadSettings(false); + } os_CreateWindow(); os_SetupInput(); @@ -392,10 +398,10 @@ int dc_start_game(const char *path) } else { - printf("Did not load bios, using reios\n"); + NOTICE_LOG(BOOT, "Did not load bios, using reios\n"); } #else - printf("Cannot find BIOS files\n"); + ERROR_LOG(BOOT, "Cannot find BIOS files\n"); return -5; #endif } @@ -415,14 +421,14 @@ int dc_start_game(const char *path) sh4_cpu.Init(); // Also initialize the interpreter if(settings.dynarec.Enable) { - printf("Using Recompiler\n"); + INFO_LOG(DYNAREC, "Using Recompiler"); } else #endif { Get_Sh4Interpreter(&sh4_cpu); sh4_cpu.Init(); - printf("Using Interpreter\n"); + INFO_LOG(INTERPRETER, "Using Interpreter"); } mem_Init(); @@ -461,12 +467,12 @@ void* dc_run(void*) if (settings.dynarec.Enable) { Get_Sh4Recompiler(&sh4_cpu); - printf("Using Recompiler\n"); + INFO_LOG(DYNAREC, "Using Recompiler"); } else { Get_Sh4Interpreter(&sh4_cpu); - printf("Using Interpreter\n"); + INFO_LOG(DYNAREC, "Using Interpreter"); } do { reset_requested = false; @@ -877,7 +883,7 @@ void dc_savestate() if ( ! dc_serialize(&data, &total_size) ) { - printf("Failed to save state - could not initialize total size\n") ; + WARN_LOG(SAVESTATE, "Failed to save state - could not initialize total size") ; gui_display_notification("Save state failed", 2000); cleanup_serialize(data) ; return; @@ -886,7 +892,7 @@ void dc_savestate() data = malloc(total_size) ; if ( data == NULL ) { - printf("Failed to save state - could not malloc %d bytes", total_size) ; + WARN_LOG(SAVESTATE, "Failed to save state - could not malloc %d bytes", total_size) ; gui_display_notification("Save state failed - memory full", 2000); cleanup_serialize(data) ; return; @@ -896,7 +902,7 @@ void dc_savestate() if ( ! dc_serialize(&data_ptr, &total_size) ) { - printf("Failed to save state - could not serialize data\n") ; + WARN_LOG(SAVESTATE, "Failed to save state - could not serialize data") ; gui_display_notification("Save state failed", 2000); cleanup_serialize(data) ; return; @@ -907,7 +913,7 @@ void dc_savestate() if ( f == NULL ) { - printf("Failed to save state - could not open %s for writing\n", filename.c_str()) ; + WARN_LOG(SAVESTATE, "Failed to save state - could not open %s for writing", filename.c_str()) ; gui_display_notification("Cannot open save file", 2000); cleanup_serialize(data) ; return; @@ -917,7 +923,7 @@ void dc_savestate() fclose(f); cleanup_serialize(data) ; - printf("Saved state to %s\n size %d", filename.c_str(), total_size) ; + INFO_LOG(SAVESTATE, "Saved state to %s size %d", filename.c_str(), total_size) ; gui_display_notification("State saved", 1000); } @@ -936,7 +942,7 @@ void dc_loadstate() if ( f == NULL ) { - printf("Failed to load state - could not open %s for reading\n", filename.c_str()) ; + WARN_LOG(SAVESTATE, "Failed to load state - could not open %s for reading", filename.c_str()) ; gui_display_notification("Save state not found", 2000); cleanup_serialize(data) ; return; @@ -947,7 +953,7 @@ void dc_loadstate() data = malloc(total_size) ; if ( data == NULL ) { - printf("Failed to load state - could not malloc %d bytes", total_size) ; + WARN_LOG(SAVESTATE, "Failed to load state - could not malloc %d bytes", total_size) ; gui_display_notification("Failed to load state - memory full", 2000); cleanup_serialize(data) ; return; @@ -969,7 +975,7 @@ void dc_loadstate() if ( ! dc_unserialize(&data_ptr, &total_size) ) { - printf("Failed to load state - could not unserialize data\n") ; + WARN_LOG(SAVESTATE, "Failed to load state - could not unserialize data") ; gui_display_notification("Invalid save state", 2000); cleanup_serialize(data) ; return; @@ -982,5 +988,5 @@ void dc_loadstate() CalculateSync(); cleanup_serialize(data) ; - printf("Loaded state from %s size %d\n", filename.c_str(), total_size) ; + INFO_LOG(SAVESTATE, "Loaded state from %s size %d", filename.c_str(), total_size) ; } diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 348530876..17bd9c7f4 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -579,10 +579,10 @@ static bool gles_init() glGetIntegerv(GL_MINOR_VERSION, &minor); if (major < 4 || (major == 4 && minor < 3)) { - printf("Warning: OpenGL version doesn't support per-pixel sorting.\n"); + WARN_LOG(RENDERER, "Warning: OpenGL version doesn't support per-pixel sorting."); return false; } - printf("Per-pixel sorting enabled\n"); + INFO_LOG(RENDERER, "Per-pixel sorting enabled"); glcache.DisableCache(); @@ -758,7 +758,7 @@ static bool RenderFrame() gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; - //printf("scale: %f, %f, %f, %f\n", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]); + DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f\n", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]); //VERT and RAM fog color constants u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT; @@ -832,15 +832,15 @@ static bool RenderFrame() case 4: //0x4 888 RGB 24 bit packed case 5: //0x5 0888 KRGB 32 bit K is the value of fk_kval. case 6: //0x6 8888 ARGB 32 bit - fprintf(stderr, "Unsupported render to texture format: %d\n", FB_W_CTRL.fb_packmode); + WARN_LOG(RENDERER, "Unsupported render to texture format: %d", FB_W_CTRL.fb_packmode); return false; case 7: //7 invalid die("7 is not valid"); break; } - //printf("RTT packmode=%d stride=%d - %d,%d -> %d,%d\n", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8, - // FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max); + DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8, + FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max); output_fbo = gl4BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format); } else @@ -896,9 +896,9 @@ static bool RenderFrame() #if 0 //handy to debug really stupid render-not-working issues ... - printf("SS: %dx%d\n", screen_width, screen_height); - printf("SCI: %d, %f\n", pvrrc.fb_X_CLIP.max, dc2s_scale_h); - printf("SCI: %f, %f, %f, %f\n", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); + DEBUG_LOG(RENDERER, "SS: %dx%d", screen_width, screen_height); + DEBUG_LOG(RENDERER, "SCI: %d, %f", pvrrc.fb_X_CLIP.max, dc2s_scale_h); + DEBUG_LOG(RENDERER, "SCI: %f, %f, %f, %f", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); #endif if (!wide_screen_on) @@ -1027,7 +1027,7 @@ struct gl4rend : Renderer bool Process(TA_context* ctx) { return ProcessFrame(ctx); } bool Render() { return RenderFrame(); } - bool RenderLastFrame() { return gl4_render_output_framebuffer(); } + bool RenderLastFrame() { return gl.swap_buffer_not_preserved ? gl4_render_output_framebuffer() : false; } void Present() { gl_swap(); } diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index fa1976d4c..9a61ab41e 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -453,7 +453,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) FILE *fp = fopen("screenshot.png", "wb"); if (fp == NULL) { - printf("Failed to open screenshot.png for writing\n"); + ERROR_LOG(RENDERER, "Failed to open screenshot.png for writing\n"); return; } @@ -519,7 +519,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) EGLint maj, min; if (!eglInitialize(gl.setup.display, &maj, &min)) { - printf("EGL Error: eglInitialize failed\n"); + ERROR_LOG(RENDERER, "EGL Error: eglInitialize failed"); return false; } @@ -548,7 +548,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) }; if (!eglChooseConfig(gl.setup.display, pi32ConfigFallbackAttribs, &config, 1, &num_config) || (num_config != 1)) { - printf("EGL Error: eglChooseConfig failed\n"); + ERROR_LOG(RENDERER, "EGL Error: eglChooseConfig failed"); return false; } } @@ -556,7 +556,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) EGLint format; if (!eglGetConfigAttrib(gl.setup.display, config, EGL_NATIVE_VISUAL_ID, &format)) { - printf("eglGetConfigAttrib() returned error %x\n", eglGetError()); + ERROR_LOG(RENDERER, "eglGetConfigAttrib() returned error %x", eglGetError()); return false; } ANativeWindow_setBuffersGeometry((ANativeWindow *)wind, 0, 0, format); @@ -565,7 +565,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) if (gl.setup.surface == EGL_NO_SURFACE) { - printf("EGL Error: eglCreateWindowSurface failed: %x\n", eglGetError()); + ERROR_LOG(RENDERER, "EGL Error: eglCreateWindowSurface failed: %x", eglGetError()); return false; } @@ -573,7 +573,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) bool try_full_gl = true; if (!eglBindAPI(EGL_OPENGL_API)) { - printf("eglBindAPI(EGL_OPENGL_API) failed: %x\n", eglGetError()); + INFO_LOG(RENDERER, "eglBindAPI(EGL_OPENGL_API) failed: %x", eglGetError()); try_full_gl = false; } if (try_full_gl) @@ -586,7 +586,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) { egl_makecurrent(); if (gl3wInit()) - printf("gl3wInit() failed\n"); + ERROR_LOG(RENDERER, "gl3wInit() failed"); } } #endif @@ -594,7 +594,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) { if (!eglBindAPI(EGL_OPENGL_ES_API)) { - printf("eglBindAPI() failed: %x\n", eglGetError()); + ERROR_LOG(RENDERER, "eglBindAPI() failed: %x", eglGetError()); return false; } EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2 , EGL_NONE }; @@ -603,7 +603,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) if (gl.setup.context == EGL_NO_CONTEXT) { - printf("eglCreateContext() failed: %x\n", eglGetError()); + ERROR_LOG(RENDERER, "eglCreateContext() failed: %x", eglGetError()); return false; } #ifdef GLES @@ -612,7 +612,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) #else egl_makecurrent(); if (gl3wInit()) - printf("gl3wInit() failed\n"); + INFO_LOG(RENDERER, "gl3wInit() failed"); #endif } created_context = true; @@ -625,7 +625,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) if (!egl_makecurrent()) { - printf("eglMakeCurrent() failed: %x\n", eglGetError()); + ERROR_LOG(RENDERER, "eglMakeCurrent() failed: %x", eglGetError()); return false; } @@ -639,11 +639,11 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) // Required when doing partial redraws if (!eglSurfaceAttrib(gl.setup.display, gl.setup.surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { - printf("Swap buffers are not preserved. Last frame copy enabled\n"); + INFO_LOG(RENDERER, "Swap buffers are not preserved. Last frame copy enabled"); gl.swap_buffer_not_preserved = true; } - printf("EGL config: %p, %p, %p %dx%d\n",gl.setup.context,gl.setup.display,gl.setup.surface,w,h); + INFO_LOG(RENDERER, "EGL config: %p, %p, %p %dx%d", gl.setup.context, gl.setup.display, gl.setup.surface, w, h); return true; } @@ -801,7 +801,7 @@ void dump_screenshot(u8 *buffer, u32 width, u32 height) if (!m_hrc) { - printf("Open GL 4.3 not supported\n"); + INFO_LOG(RENDERER, "Open GL 4.3 not supported"); // Try Gl 3.1 attribs[1] = 3; attribs[3] = 1; @@ -966,7 +966,7 @@ void findGLVersion() if (glGetError() == GL_INVALID_ENUM) gl.gl_major = 2; const char *version = (const char *)glGetString(GL_VERSION); - printf("OpenGL version: %s\n", version); + INFO_LOG(RENDERER, "OpenGL version: %s", version); if (!strncmp(version, "OpenGL ES", 9)) { gl.is_gles = true; @@ -988,7 +988,7 @@ void findGLVersion() if (strstr(extensions, "GL_OES_depth24") != NULL) gl.GL_OES_depth24_supported = true; if (!gl.GL_OES_packed_depth_stencil_supported) - printf("Packed depth/stencil not supported: no modifier volumes when rendering to a texture\n"); + INFO_LOG(RENDERER, "Packed depth/stencil not supported: no modifier volumes when rendering to a texture"); } else { @@ -1032,7 +1032,7 @@ GLuint gl_CompileShader(const char* shader,GLuint type) *compile_log=0; glGetShaderInfoLog(rv, compile_log_len, &compile_log_len, compile_log); - printf("Shader: %s \n%s\n",result?"compiled!":"failed to compile",compile_log); + WARN_LOG(RENDERER, "Shader: %s \n%s", result ? "compiled!" : "failed to compile", compile_log); free(compile_log); } @@ -1080,13 +1080,13 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader) *compile_log=0; glGetProgramInfoLog(program, compile_log_len, &compile_log_len, compile_log); - printf("Shader linking: %s \n (%d bytes), - %s -\n",result?"linked":"failed to link", compile_log_len,compile_log); + WARN_LOG(RENDERER, "Shader linking: %s \n (%d bytes), - %s -", result ? "linked" : "failed to link", compile_log_len, compile_log); free(compile_log); // Dump the shaders source for troubleshooting - printf("// VERTEX SHADER\n%s\n// END\n", VertexShader); - printf("// FRAGMENT SHADER\n%s\n// END\n", FragmentShader); + INFO_LOG(RENDERER, "// VERTEX SHADER\n%s\n// END", VertexShader); + INFO_LOG(RENDERER, "// FRAGMENT SHADER\n%s\n// END", FragmentShader); die("shader compile fail\n"); } @@ -1578,7 +1578,7 @@ bool ProcessFrame(TA_context* ctx) CollectCleanup(); if (ctx->rend.Overrun) - printf("ERROR: TA context overrun\n"); + WARN_LOG(PVR, "ERROR: TA context overrun"); return !ctx->rend.Overrun; } @@ -1895,15 +1895,15 @@ bool RenderFrame() case 4: //0x4 888 RGB 24 bit packed case 5: //0x5 0888 KRGB 32 bit K is the value of fk_kval. case 6: //0x6 8888 ARGB 32 bit - fprintf(stderr, "Unsupported render to texture format: %d\n", FB_W_CTRL.fb_packmode); + WARN_LOG(RENDERER, "Unsupported render to texture format: %d", FB_W_CTRL.fb_packmode); return false; case 7: //7 invalid die("7 is not valid"); break; } - //printf("RTT packmode=%d stride=%d - %d,%d -> %d,%d\n", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8, - // FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max); + DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8, + FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max); BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format); } else @@ -2069,7 +2069,7 @@ struct glesrend : Renderer bool Process(TA_context* ctx) { return ProcessFrame(ctx); } bool Render() { return RenderFrame(); } - bool RenderLastFrame() { return render_output_framebuffer(); } + bool RenderLastFrame() { return gl.swap_buffer_not_preserved ? render_output_framebuffer() : false; } void Present() { gl_swap(); glViewport(0, 0, screen_width, screen_height); } void DrawOSD(bool clear_screen) @@ -2127,7 +2127,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) if (!is_png) { fclose(file); - printf("Not a PNG file : %s\n", filename); + WARN_LOG(RENDERER, "Not a PNG file : %s", filename); return NULL; } @@ -2137,7 +2137,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) if (!png_ptr) { fclose(file); - printf("Unable to create PNG struct : %s\n", filename); + WARN_LOG(RENDERER, "Unable to create PNG struct : %s", filename); return (NULL); } @@ -2146,7 +2146,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); - printf("Unable to create PNG info : %s\n", filename); + WARN_LOG(RENDERER, "Unable to create PNG info : %s", filename); fclose(file); return (NULL); } @@ -2156,7 +2156,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); - printf("Unable to create PNG end info : %s\n", filename); + WARN_LOG(RENDERER, "Unable to create PNG end info : %s", filename); fclose(file); return (NULL); } @@ -2165,7 +2165,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) if (setjmp(png_jmpbuf(png_ptr))) { fclose(file); - printf("Error during setjmp : %s\n", filename); + WARN_LOG(RENDERER, "Error during setjmp : %s", filename); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return (NULL); } @@ -2204,7 +2204,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) { //clean up memory and close stuff png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - printf("Unable to allocate image_data while loading %s\n", filename); + WARN_LOG(RENDERER, "Unable to allocate image_data while loading %s", filename); fclose(file); return NULL; } @@ -2216,7 +2216,7 @@ u8* loadPNGData(const string& fname, int &width, int &height) //clean up memory and close stuff png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); delete[] image_data; - printf("Unable to allocate row_pointer while loading %s\n", filename); + WARN_LOG(RENDERER, "Unable to allocate row_pointer while loading %s", filename); fclose(file); return NULL; } diff --git a/core/serialize.cpp b/core/serialize.cpp index e5f4538eb..699757a68 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -1526,7 +1526,7 @@ bool dc_unserialize(void **data, unsigned int *total_size) return dc_unserialize_libretro(data, total_size); if (version != V4) { - fprintf(stderr, "Save State version not supported: %d\n", version); + WARN_LOG(SAVESTATE, "Save State version not supported: %d", version); return false; } REICAST_US(aica_interr) ; diff --git a/core/stdclass.h b/core/stdclass.h index 7b6cd17d0..3b1347349 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -64,7 +64,7 @@ public: if (data) { #ifdef MEM_ALLOC_TRACE - printf("WARNING : DESTRUCTOR WITH NON FREED ARRAY [arrayid:%d]\n",id); + DEBUG_LOG(COMMON, "WARNING : DESTRUCTOR WITH NON FREED ARRAY [arrayid:%d]", id); #endif Free(); } @@ -85,7 +85,7 @@ public: if (data) { #ifdef MEM_ALLOC_TRACE - printf("Freeing data -> resize to zero[Array:%d]\n",id); + DEBUG_LOG(COMMON, "Freeing data -> resize to zero[Array:%d]", id); #endif Free(); } @@ -140,7 +140,7 @@ public: #ifdef MEM_BOUND_CHECK if (i>=Size) { - printf("Error: Array %d , index out of range (%d>%d)\n",id,i,Size-1); + ERROR_LOG(COMMON, "Error: Array %d , index out of range (%d > %d)", id, i, Size - 1); MEM_DO_BREAK; } #endif @@ -152,7 +152,7 @@ public: #ifdef MEM_BOUND_CHECK if (!(i>=0 && i<(s32)Size)) { - printf("Error: Array %d , index out of range (%d > %d)\n",id,i,Size-1); + ERROR_LOG(COMMON, "Error: Array %d , index out of range (%d > %d)", id, i, Size - 1); MEM_DO_BREAK; } #endif @@ -308,7 +308,7 @@ public: #ifdef MEM_BOUND_CHECK if (i >= size) { - printf("Error: VLockedMemory , index out of range (%d > %d)\n", i, size-1); + ERROR_LOG(COMMON, "Error: VLockedMemory , index out of range (%d > %d)\n", i, size - 1); MEM_DO_BREAK; } #endif @@ -318,55 +318,6 @@ public: int msgboxf(const wchar* text,unsigned int type,...); - -#define MBX_OK 0x00000000L -#define MBX_OKCANCEL 0x00000001L -#define MBX_ABORTRETRYIGNORE 0x00000002L -#define MBX_YESNOCANCEL 0x00000003L -#define MBX_YESNO 0x00000004L -#define MBX_RETRYCANCEL 0x00000005L - - -#define MBX_ICONHAND 0x00000010L -#define MBX_ICONQUESTION 0x00000020L -#define MBX_ICONEXCLAMATION 0x00000030L -#define MBX_ICONASTERISK 0x00000040L - - -#define MBX_USERICON 0x00000080L -#define MBX_ICONWARNING MBX_ICONEXCLAMATION -#define MBX_ICONERROR MBX_ICONHAND - - -#define MBX_ICONINFORMATION MBX_ICONASTERISK -#define MBX_ICONSTOP MBX_ICONHAND - -#define MBX_DEFBUTTON1 0x00000000L -#define MBX_DEFBUTTON2 0x00000100L -#define MBX_DEFBUTTON3 0x00000200L - -#define MBX_DEFBUTTON4 0x00000300L - - -#define MBX_APPLMODAL 0x00000000L -#define MBX_SYSTEMMODAL 0x00001000L -#define MBX_TASKMODAL 0x00002000L - -#define MBX_HELP 0x00004000L // Help Button - - -#define MBX_NOFOCUS 0x00008000L -#define MBX_SETFOREGROUND 0x00010000L -#define MBX_DEFAULT_DESKTOP_ONLY 0x00020000L - -#define MBX_TOPMOST 0x00040000L -#define MBX_RIGHT 0x00080000L -#define MBX_RTLREADING 0x00100000L - -#define MBX_RV_OK 1 -#define MBX_RV_CANCEL 2 -#define MBX_RV_ABORT 3 -#define MBX_RV_RETRY 4 -#define MBX_RV_IGNORE 5 -#define MBX_RV_YES 6 -#define MBX_RV_NO 7 +#define MBX_OK 0 +#define MBX_ICONEXCLAMATION 0 +#define MBX_ICONERROR 0 diff --git a/core/types.h b/core/types.h index a5fdd8b83..94156d2d4 100644 --- a/core/types.h +++ b/core/types.h @@ -385,13 +385,9 @@ using namespace std; //basic includes #include "stdclass.h" -#ifndef RELEASE -#define EMUERROR(format, ...) printf("Error in %20s:%s:%d: " format "\n", \ - __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) -//strlen(__FILE__) <= 20 ? __FILE__ : __FILE__ + strlen(__FILE__) - 20, -#else -#define EMUERROR(format, ...) -#endif +#include "log/Log.h" + +#define EMUERROR(...) INFO_LOG(COMMON, __VA_ARGS__) #define EMUERROR2 EMUERROR #define EMUERROR3 EMUERROR #define EMUERROR4 EMUERROR diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 398ed1ce9..60e2fad55 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -7,6 +7,7 @@ #include "xinput_gamepad.h" #include "win_keyboard.h" #include "hw/sh4/dyna/blockmanager.h" +#include "log/LogManager.h" #define _WIN32_WINNT 0x0500 #include @@ -695,6 +696,7 @@ int main(int argc, char **argv) int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShowCmd) { + LogManager::Init(); int argc=0; wchar* cmd_line=GetCommandLineA(); wchar** argv=CommandLineToArgvA(cmd_line,&argc); diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 3800636ae..ce7d78956 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -24,6 +24,7 @@ #include "imgread/common.h" #include "rend/gui.h" #include "cfg/cfg.h" +#include "log/LogManager.h" JavaVM* g_jvm; @@ -230,6 +231,7 @@ JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnvironment(JN if (first_init) { // Do one-time initialization + LogManager::Init(); jstring msg = NULL; int rc = reicast_init(0, NULL); if (rc == -4) diff --git a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm index 4cbe78a51..adca53d51 100644 --- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm +++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm @@ -12,6 +12,7 @@ #include "types.h" #include "hw/maple/maple_cfg.h" +#include "log/LogManager.h" #include "rend/gui.h" #include "osx_keyboard.h" #include "osx_gamepad.h" @@ -161,6 +162,7 @@ extern "C" void emu_gles_init(int width, int height) { extern "C" int emu_reicast_init() { + LogManager::Init(); common_linux_setup(); return reicast_init(0, NULL); } From 0c9e3bbd7d410bc7c4f8990faed4bc26b82369b5 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:22:37 +0200 Subject: [PATCH 102/158] OSX: add log files to project --- .../reicast-osx.xcodeproj/project.pbxproj | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index 05cb60b6f..3130bb2ee 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -204,6 +204,10 @@ AE2A2D7F21D6851E004B308D /* 7zFile.c in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D7321D6851D004B308D /* 7zFile.c */; }; AE2A2D8021D6851E004B308D /* 7zDec.c in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D7721D6851E004B308D /* 7zDec.c */; }; AE2A2D8321D7DB78004B308D /* CustomTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE2A2D8121D7DB77004B308D /* CustomTexture.cpp */; }; + AE43537222C9420C005E19CE /* ConsoleListenerDroid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE43536B22C9420C005E19CE /* ConsoleListenerDroid.cpp */; }; + AE43537322C9420C005E19CE /* ConsoleListenerNix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE43536C22C9420C005E19CE /* ConsoleListenerNix.cpp */; }; + AE43537422C9420C005E19CE /* ConsoleListenerWin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE43536D22C9420C005E19CE /* ConsoleListenerWin.cpp */; }; + AE43537522C9420C005E19CE /* LogManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE43536F22C9420C005E19CE /* LogManager.cpp */; }; AE649BB62188689000EF4A81 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BB42188689000EF4A81 /* xxhash.c */; }; AE649BF3218C552500EF4A81 /* bitmath.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BCD218C552500EF4A81 /* bitmath.c */; }; AE649BF4218C552500EF4A81 /* bitreader.c in Sources */ = {isa = PBXBuildFile; fileRef = AE649BCE218C552500EF4A81 /* bitreader.c */; }; @@ -673,6 +677,15 @@ AE2A2D7721D6851E004B308D /* 7zDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 7zDec.c; sourceTree = ""; }; AE2A2D8121D7DB77004B308D /* CustomTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomTexture.cpp; sourceTree = ""; }; AE2A2D8221D7DB78004B308D /* CustomTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTexture.h; sourceTree = ""; }; + AE43536922C9420C005E19CE /* BitSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitSet.h; sourceTree = ""; }; + AE43536A22C9420C005E19CE /* ConsoleListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleListener.h; sourceTree = ""; }; + AE43536B22C9420C005E19CE /* ConsoleListenerDroid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleListenerDroid.cpp; sourceTree = ""; }; + AE43536C22C9420C005E19CE /* ConsoleListenerNix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleListenerNix.cpp; sourceTree = ""; }; + AE43536D22C9420C005E19CE /* ConsoleListenerWin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleListenerWin.cpp; sourceTree = ""; }; + AE43536E22C9420C005E19CE /* Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = ""; }; + AE43536F22C9420C005E19CE /* LogManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogManager.cpp; sourceTree = ""; }; + AE43537022C9420C005E19CE /* LogManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogManager.h; sourceTree = ""; }; + AE43537122C9420C005E19CE /* StringUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringUtil.h; sourceTree = ""; }; AE60BD9F22256E2500FA8A5B /* osx_keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = osx_keyboard.h; sourceTree = ""; }; AE60BDA02225725800FA8A5B /* osx_gamepad.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = osx_gamepad.h; sourceTree = ""; }; AE649BB42188689000EF4A81 /* xxhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xxhash.c; sourceTree = ""; }; @@ -1005,6 +1018,7 @@ AEE6278022131BB500EC7E89 /* input */, 84B7BE4D1B72720100F9733F /* khronos */, 84B7BE641B72720100F9733F /* linux */, + AE43536822C9420C005E19CE /* log */, 84B7BE6E1B72720200F9733F /* nullDC.cpp */, 84B7BE6F1B72720200F9733F /* oslib */, 84B7BE7C1B72720200F9733F /* profiler */, @@ -1715,6 +1729,23 @@ path = ../../../core/archive; sourceTree = ""; }; + AE43536822C9420C005E19CE /* log */ = { + isa = PBXGroup; + children = ( + AE43536922C9420C005E19CE /* BitSet.h */, + AE43536A22C9420C005E19CE /* ConsoleListener.h */, + AE43536B22C9420C005E19CE /* ConsoleListenerDroid.cpp */, + AE43536C22C9420C005E19CE /* ConsoleListenerNix.cpp */, + AE43536D22C9420C005E19CE /* ConsoleListenerWin.cpp */, + AE43536E22C9420C005E19CE /* Log.h */, + AE43536F22C9420C005E19CE /* LogManager.cpp */, + AE43537022C9420C005E19CE /* LogManager.h */, + AE43537122C9420C005E19CE /* StringUtil.h */, + ); + name = log; + path = ../../../core/log; + sourceTree = ""; + }; AE649BB32188689000EF4A81 /* xxhash */ = { isa = PBXGroup; children = ( @@ -2251,6 +2282,7 @@ AE2A2D8321D7DB78004B308D /* CustomTexture.cpp in Sources */, 84B7BF191B72720200F9733F /* deflate.c in Sources */, 84B7BF7E1B72720200F9733F /* TexCache.cpp in Sources */, + AE43537522C9420C005E19CE /* LogManager.cpp in Sources */, AEFF7F4E214D9D590068CE11 /* pico_dev_ppp.c in Sources */, 84B7BEE41B72720200F9733F /* zip_delete.c in Sources */, 84B7BF1A1B72720200F9733F /* infback.c in Sources */, @@ -2307,6 +2339,7 @@ 84B7BEE61B72720200F9733F /* zip_entry_free.c in Sources */, 84B7BF511B72720200F9733F /* tmu.cpp in Sources */, 84B7BF181B72720200F9733F /* crc32.c in Sources */, + AE43537422C9420C005E19CE /* ConsoleListenerWin.cpp in Sources */, 84B7BEF21B72720200F9733F /* zip_file_get_offset.c in Sources */, 84B7BF7B1B72720200F9733F /* gltex.cpp in Sources */, 84B7BEF41B72720200F9733F /* zip_filerange_crc.c in Sources */, @@ -2380,6 +2413,7 @@ 84B7BEB61B72720200F9733F /* sha256.cpp in Sources */, 84B7BF5A1B72720200F9733F /* cdi.cpp in Sources */, AE649C05218C552500EF4A81 /* stream_decoder.c in Sources */, + AE43537322C9420C005E19CE /* ConsoleListenerNix.cpp in Sources */, 84B7BEF91B72720200F9733F /* zip_get_archive_comment.c in Sources */, AE649C02218C552500EF4A81 /* memory.c in Sources */, 84B7BF831B727AD700F9733F /* osx-main.mm in Sources */, @@ -2485,6 +2519,7 @@ 84B7BF491B72720200F9733F /* bsc.cpp in Sources */, AE649BFB218C552500EF4A81 /* format.c in Sources */, 84B7BF2D1B72720200F9733F /* virt_arm.cpp in Sources */, + AE43537222C9420C005E19CE /* ConsoleListenerDroid.cpp in Sources */, 84A388B91B1CDD3E000166C0 /* AppDelegate.swift in Sources */, 84B7BF001B72720200F9733F /* zip_new.c in Sources */, 84B7BF0A1B72720200F9733F /* zip_source_filep.c in Sources */, From 7bcd98527618c254787b2c99b1239c18de0b1665 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:28:30 +0200 Subject: [PATCH 103/158] win32: logging fixes --- core/log/StringUtil.h | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/core/log/StringUtil.h b/core/log/StringUtil.h index ba12159cf..6835ad0e0 100644 --- a/core/log/StringUtil.h +++ b/core/log/StringUtil.h @@ -111,3 +111,76 @@ std::string StringFromFormat(const char* format, ...) va_end(args); return res; } + + +#ifdef _WIN32 +std::wstring CPToUTF16(u32 code_page, const std::string& input) +{ + auto const size = + MultiByteToWideChar(code_page, 0, input.data(), static_cast(input.size()), nullptr, 0); + + std::wstring output; + output.resize(size); + + if (size == 0 || + size != MultiByteToWideChar(code_page, 0, input.data(), static_cast(input.size()), + &output[0], static_cast(output.size()))) + { + output.clear(); + } + + return output; +} + +std::string UTF16ToCP(u32 code_page, const std::wstring& input) +{ + auto const size = WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), + nullptr, 0, nullptr, false); + + std::string output; + output.resize(size); + + if (size == 0 || + size != WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), + &output[0], static_cast(output.size()), nullptr, false)) + { + const DWORD error_code = GetLastError(); + ERROR_LOG(COMMON, "WideCharToMultiByte Error in String '%s': %lu", input.c_str(), error_code); + output.clear(); + } + return output; +} + +std::string UTF16ToUTF8(const std::wstring& input) +{ + return UTF16ToCP(CP_UTF8, input); +} + +std::wstring UTF8ToUTF16(const std::string& input) +{ + return CPToUTF16(CP_UTF8, input); +} + +#ifdef _UNICODE +inline std::string TStrToUTF8(const std::wstring& str) +{ + return UTF16ToUTF8(str); +} + +inline std::wstring UTF8ToTStr(const std::string& str) +{ + return UTF8ToUTF16(str); +} +#else +inline std::string TStrToUTF8(const std::string& str) +{ + return str; +} + +inline std::string UTF8ToTStr(const std::string& str) +{ + return str; +} +#endif + +#endif From 40c841a05798e337cabb1a76b7157e9983bf6f64 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:39:38 +0200 Subject: [PATCH 104/158] win32: build fix --- core/log/StringUtil.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/log/StringUtil.h b/core/log/StringUtil.h index 6835ad0e0..60cf9c163 100644 --- a/core/log/StringUtil.h +++ b/core/log/StringUtil.h @@ -134,15 +134,17 @@ std::wstring CPToUTF16(u32 code_page, const std::string& input) std::string UTF16ToCP(u32 code_page, const std::wstring& input) { + bool usedDefaultChar; auto const size = WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), - nullptr, 0, nullptr, false); + nullptr, 0, nullptr, &usedDefaultChar); std::string output; output.resize(size); + bool usedDefaultChar; if (size == 0 || size != WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), - &output[0], static_cast(output.size()), nullptr, false)) + &output[0], static_cast(output.size()), nullptr, &usedDefaultChar)) { const DWORD error_code = GetLastError(); ERROR_LOG(COMMON, "WideCharToMultiByte Error in String '%s': %lu", input.c_str(), error_code); From 20bff396c3814dc7180071c802fd3b026b7c73f9 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:46:33 +0200 Subject: [PATCH 105/158] win32: more build fix --- core/log/StringUtil.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/log/StringUtil.h b/core/log/StringUtil.h index 60cf9c163..f1ab11767 100644 --- a/core/log/StringUtil.h +++ b/core/log/StringUtil.h @@ -140,7 +140,6 @@ std::string UTF16ToCP(u32 code_page, const std::wstring& input) std::string output; output.resize(size); - bool usedDefaultChar; if (size == 0 || size != WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), From 5881791817debc8915611f7b66c5b5d563037100 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 21:54:37 +0200 Subject: [PATCH 106/158] win32: yabf --- core/log/StringUtil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/log/StringUtil.h b/core/log/StringUtil.h index f1ab11767..abfe6028b 100644 --- a/core/log/StringUtil.h +++ b/core/log/StringUtil.h @@ -134,7 +134,7 @@ std::wstring CPToUTF16(u32 code_page, const std::string& input) std::string UTF16ToCP(u32 code_page, const std::wstring& input) { - bool usedDefaultChar; + int usedDefaultChar; auto const size = WideCharToMultiByte(code_page, 0, input.data(), static_cast(input.size()), nullptr, 0, nullptr, &usedDefaultChar); From cf6887a5d05bf778557be85b961d6bafc5874898 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 22:09:32 +0200 Subject: [PATCH 107/158] aica: use new logging --- core/hw/aica/aica_if.cpp | 24 ++++++++---------------- core/hw/aica/dsp_arm64.cpp | 12 +++++------- core/hw/aica/sgc_if.cpp | 20 ++++++++++---------- core/hw/arm7/arm64.cpp | 4 ++-- core/hw/arm7/arm7.cpp | 12 ++++-------- 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/core/hw/aica/aica_if.cpp b/core/hw/aica/aica_if.cpp index c1799793b..e66171a5f 100644 --- a/core/hw/aica/aica_if.cpp +++ b/core/hw/aica/aica_if.cpp @@ -47,7 +47,7 @@ u32 ReadMem_aica_rtc(u32 addr,u32 sz) return 0; } - printf("ReadMem_aica_rtc : invalid address\n"); + WARN_LOG(AICA, "ReadMem_aica_rtc : invalid address %x sz %d", addr, sz); return 0; } @@ -123,12 +123,12 @@ void WriteMem_aica_reg(u32 addr,u32 data,u32 sz) if (addr==0x2C01) { VREG=data; - printf("VREG = %02X\n",VREG); + INFO_LOG(AICA, "VREG = %02X", VREG); } else if (addr==0x2C00) { ARMRST=data; - printf("ARMRST = %02X\n",ARMRST); + INFO_LOG(AICA, "ARMRST = %02X", ARMRST); ArmSetRST(); } else @@ -142,7 +142,7 @@ void WriteMem_aica_reg(u32 addr,u32 data,u32 sz) { VREG=(data>>8)&0xFF; ARMRST=data&0xFF; - printf("VREG = %02X ARMRST %02X\n",VREG,ARMRST); + INFO_LOG(AICA, "VREG = %02X ARMRST %02X", VREG, ARMRST); ArmSetRST(); } else @@ -216,17 +216,9 @@ void Write_SB_ADST(u32 addr, u32 data) u32 tmp=src; src=dst; dst=tmp; - printf("**AICA DMA : SB_ADDIR==1: Not sure this works, please report if broken/missing sound or crash\n**"); } WriteMemBlock_nommu_dma(dst,src,len); - /* - for (u32 i=0;iDSP = DSP; - //printf("DSPAssembler::DSPCompile recompiling for arm64 at %p\n", GetBuffer()->GetStartAddress()); + DEBUG_LOG(AICA_ARM, "DSPAssembler::DSPCompile recompiling for arm64 at %p", GetBuffer()->GetStartAddress()); if (DSP->Stopped) { @@ -101,7 +101,7 @@ public: #ifndef _ANDROID Instruction* instr_cur = GetBuffer()->GetEndAddress(); - printf("DSP PROLOGUE\n"); + DEBUG_LOG(AICA_ARM, "DSP PROLOGUE"); Disassemble(instr_start, instr_cur); instr_start = instr_cur; #endif @@ -358,7 +358,7 @@ public: } #ifndef _ANDROID instr_cur = GetBuffer()->GetEndAddress(); - printf("DSP STEP %d: %04x %04x %04x %04x\n", step, mpro[0], mpro[1], mpro[2], mpro[3]); + DEBUG_LOG(AICA_ARM, "DSP STEP %d: %04x %04x %04x %04x", step, mpro[0], mpro[1], mpro[2], mpro[3]); Disassemble(instr_start, instr_cur); instr_start = instr_cur; #endif @@ -380,7 +380,7 @@ public: Ret(); #ifndef _ANDROID instr_cur = GetBuffer()->GetEndAddress(); - printf("DSP EPILOGUE\n"); + DEBUG_LOG(AICA_ARM, "DSP EPILOGUE"); Disassemble(instr_start, instr_cur); instr_start = instr_cur; #endif @@ -486,9 +486,7 @@ private: Instruction* instr; for (instr = instr_start; instr < instr_end; instr += kInstructionSize) { decoder.Decode(instr); - printf("\t %p:\t%s\n", - reinterpret_cast(instr), - disasm.GetOutput()); + DEBUG_LOG(AICA_ARM, " %p:\t%s", reinterpret_cast(instr), disasm.GetOutput()); } } diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 4b970ee32..20e52f0a9 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -8,9 +8,9 @@ using namespace std; #undef FAR //#define CLIP_WARN -#define key_printf(...) -#define aeg_printf(...) -#define step_printf(...) +#define key_printf(...) DEBUG_LOG(AICA, __VA_ARGS__) +#define aeg_printf(...) DEBUG_LOG(AICA, __VA_ARGS__) +#define step_printf(...) DEBUG_LOG(AICA, __VA_ARGS__) #ifdef CLIP_WARN #define clip_verify(x) verify(x) @@ -490,7 +490,7 @@ struct ChannelEx StepStreamInitial(this); - key_printf("[%d] KEY_ON %s @ %f Hz, loop : %d\n",Channel,stream_names[ChanData->PCMS],(44100.0*update_rate)/1024,ChanData->LPCTL); + key_printf("[%p] KEY_ON %s @ %f Hz, loop : %d", this, stream_names[ccd->PCMS], (44100.0 * update_rate) / 1024, ccd->LPCTL); } else { @@ -501,7 +501,7 @@ struct ChannelEx { if (AEG.state!=EG_Release) { - key_printf("[%d] KEY_OFF -> Release\n",Channel); + key_printf("[%p] KEY_OFF -> Release\n", this); SetAegState(EG_Release); //switch to release state } @@ -862,7 +862,7 @@ void StreamStep(ChannelEx* ch) if ((ch->AEG.state==EG_Attack) && (CA>=ch->loop.LSA)) { - step_printf("[%d]LPSLNK : Switching to EG_Decay1 %X\n",Channel,AEG.GetValue()); + step_printf("[%p]LPSLNK : Switching to EG_Decay1 %X\n", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay1); } } @@ -963,7 +963,7 @@ void AegStep(ChannelEx* ch) ch->AEG.SetValue(0); if (!ch->ccd->LPSLNK) { - aeg_printf("[%d]AEG_step : Switching to EG_Decay1 %d\n",ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Decay1 %d\n", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay1); } } @@ -975,7 +975,7 @@ void AegStep(ChannelEx* ch) ch->AEG.val+=ch->AEG.Decay1Rate; if (((u32)ch->AEG.GetValue())>=ch->AEG.Decay2Value) { - aeg_printf("[%d]AEG_step : Switching to EG_Decay2 @ %x\n",ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Decay2 @ %x\n", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay2); } } @@ -986,7 +986,7 @@ void AegStep(ChannelEx* ch) ch->AEG.val+=ch->AEG.Decay2Rate; if (ch->AEG.GetValue()>=0x3FF) { - aeg_printf("[%d]AEG_step : Switching to EG_Release @ %x\n",ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Release @ %x\n", ch, ch->AEG.GetValue()); ch->AEG.SetValue(0x3FF); ch->SetAegState(EG_Release); } @@ -998,7 +998,7 @@ void AegStep(ChannelEx* ch) if (ch->AEG.GetValue()>=0x3FF) { - aeg_printf("[%d]AEG_step : EG_Release End @ %x\n",ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : EG_Release End @ %x\n", ch, ch->AEG.GetValue()); ch->AEG.SetValue(0x3FF); // TODO: mnn, should we do anything about it running wild ? ch->disable(); // TODO: Is this ok here? It's a speed optimisation (since the channel is muted) } diff --git a/core/hw/arm7/arm64.cpp b/core/hw/arm7/arm64.cpp index e712855bd..5e86900ca 100644 --- a/core/hw/arm7/arm64.cpp +++ b/core/hw/arm7/arm64.cpp @@ -157,7 +157,7 @@ void armv_end(void* codestart, u32 cycl) Instruction* instr; for (instr = instr_start; instr < instr_end; instr += kInstructionSize) { decoder.Decode(instr); - printf("arm64 arec\t %p:\t%s\n", + DEBUG_LOG(AICA_ARM, "arm64 arec\t %p:\t%s", reinterpret_cast(instr), disasm.GetOutput()); } @@ -206,7 +206,7 @@ class android_buf : public std::stringbuf { public: virtual int sync() override { - LOGI("ARM7: %s\n", this->str().c_str()); + DEBUG_LOG(AICA_ARM, "ARM7: %s", this->str().c_str()); str(""); return 0; diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 4d5f0e117..b79a273de 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -7,11 +7,7 @@ #define C_CORE -#if 0 - #define arm_printf printf -#else - void arm_printf(...) { } -#endif +#define arm_printf(...) DEBUG_LOG(AICA_ARM, __VA_ARGS__) //#define CPUReadHalfWordQuick(addr) arm_ReadMem16(addr & 0x7FFFFF) #define CPUReadMemoryQuick(addr) (*(u32*)&aica_ram[addr&ARAM_MASK]) @@ -224,7 +220,7 @@ void CPUSwitchMode(int mode, bool saveState, bool breakLoop) reg[17].I = reg[SPSR_UND].I; break; default: - printf("Unsupported ARM mode %02x\n", mode); + ERROR_LOG(AICA_ARM, "Unsupported ARM mode %02x", mode); die("Arm error.."); break; } @@ -298,7 +294,7 @@ void CPUSoftwareInterrupt(int comment) void CPUUndefinedException() { - printf("arm7: CPUUndefinedException(). SOMETHING WENT WRONG\n"); + WARN_LOG(AICA_ARM, "arm7: CPUUndefinedException(). SOMETHING WENT WRONG"); u32 PC = reg[R15_ARM_NEXT].I+4; CPUSwitchMode(0x1b, true, false); reg[14].I = PC; @@ -1345,7 +1341,7 @@ void DumpRegs(const char* output) void DYNACALL PrintOp(u32 opcd) { - printf("%08X\n",opcd); + DEBUG_LOG(AICA_ARM, "%08X", opcd); } void armv_imm_to_reg(u32 regn, u32 imm) From 58e1c68eb855e979d24f58a331a76e9f95523d86 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 22:41:55 +0200 Subject: [PATCH 108/158] flashrom, gdrom: use new logging --- core/hw/flashrom/flashrom.h | 20 +++---- core/hw/gdrom/gdromv3.cpp | 102 ++++++++++++++++++------------------ 2 files changed, 60 insertions(+), 62 deletions(-) diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index ca453ebf8..807f128e6 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -101,7 +101,7 @@ struct MemChip if (Load(temp)) { - printf("Loaded %s as %s\n\n",temp,title.c_str()); + INFO_LOG(FLASHROM, "Loaded %s as %s", temp, title.c_str()); return true; } } while(next); @@ -116,7 +116,7 @@ struct MemChip sprintf(path,"%s%s%s",root.c_str(),prefix.c_str(),name_ro.c_str()); Save(path); - printf("Saved %s as %s\n\n",path,title.c_str()); + INFO_LOG(FLASHROM, "Saved %s as %s", path, title.c_str()); } virtual void Reset() {} }; @@ -297,7 +297,7 @@ struct DCFlashChip : MemChip state = FS_ReadAMDID2; else { - printf("FlashRom: ReadAMDID1 unexpected write @ %x: %x\n", addr, val); + WARN_LOG(FLASHROM, "FlashRom: ReadAMDID1 unexpected write @ %x: %x", addr, val); state = FS_Normal; } break; @@ -317,7 +317,7 @@ struct DCFlashChip : MemChip state = FS_ByteProgram; else { - printf("FlashRom: ReadAMDID2 unexpected write @ %x: %x\n", addr, val); + WARN_LOG(FLASHROM, "FlashRom: ReadAMDID2 unexpected write @ %x: %x", addr, val); state = FS_Normal; } break; @@ -334,7 +334,7 @@ struct DCFlashChip : MemChip state = FS_EraseAMD2; else { - printf("FlashRom: EraseAMD1 unexpected write @ %x: %x\n", addr, val); + WARN_LOG(FLASHROM, "FlashRom: EraseAMD1 unexpected write @ %x: %x", addr, val); } break; @@ -347,7 +347,7 @@ struct DCFlashChip : MemChip state = FS_EraseAMD3; else { - printf("FlashRom: EraseAMD2 unexpected write @ %x: %x\n", addr, val); + WARN_LOG(FLASHROM, "FlashRom: EraseAMD2 unexpected write @ %x: %x", addr, val); } break; @@ -356,7 +356,7 @@ struct DCFlashChip : MemChip || ((addr & 0xfff) == 0xaaa && (val & 0xff) == 0x10)) { // chip erase - printf("Erasing Chip!\n"); + INFO_LOG(FLASHROM, "Erasing Chip!"); #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE u8 save[0x2000]; // this area is write-protected on AW @@ -378,7 +378,7 @@ struct DCFlashChip : MemChip // this area is write-protected on AW memcpy(save, data + 0x1a000, 0x2000); #endif - printf("Erase Sector %08X! (%08X)\n",addr,addr&(~0x3FFF)); + INFO_LOG(FLASHROM, "Erase Sector %08X! (%08X)", addr, addr & ~0x3FFF); memset(&data[addr&(~0x3FFF)],0xFF,0x4000); #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE memcpy(data + 0x1a000, save, 0x2000); @@ -388,7 +388,7 @@ struct DCFlashChip : MemChip } else { - printf("FlashRom: EraseAMD3 unexpected write @ %x: %x\n", addr, val); + WARN_LOG(FLASHROM, "FlashRom: EraseAMD3 unexpected write @ %x: %x", addr, val); } break; } @@ -617,7 +617,7 @@ private: if (user.block_id == block_id) { if (!validate_crc(&user)) - printf("flash_lookup_block physical block %d has an invalid crc\n", phys_id); + WARN_LOG(FLASHROM, "flash_lookup_block physical block %d has an invalid crc", phys_id); else result = phys_id; } diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index e714f9c22..d41036597 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -59,13 +59,11 @@ u32 data_write_mode=0; //end -void nilprintf(...){} - -#define printf_rm nilprintf -#define printf_ata nilprintf -#define printf_spi nilprintf -#define printf_spicmd nilprintf -#define printf_subcode nilprintf +#define printf_rm(...) DEBUG_LOG(GDROM, __VA_ARGS__) +#define printf_ata(...) DEBUG_LOG(GDROM, __VA_ARGS__) +#define printf_spi(...) DEBUG_LOG(GDROM, __VA_ARGS__) +#define printf_spicmd(...) DEBUG_LOG(GDROM, __VA_ARGS__) +#define printf_subcode(...) DEBUG_LOG(GDROM, __VA_ARGS__) void libCore_CDDA_Sector(s16* sector) { @@ -309,7 +307,7 @@ u32 GetFAD(u8* data, bool msf) { if(msf) { - printf("GDROM: MSF FORMAT\n"); + printf("GDROM: MSF FORMAT"); return ((data[0]*60*75) + (data[1]*75) + (data[2])); } else @@ -372,7 +370,7 @@ void gd_process_ata_cmd() switch(ata_cmd.command) { case ATA_NOP: - printf_ata("ATA_NOP\n"); + printf_ata("ATA_NOP"); /* Setting "abort" in the error register Setting an error in the status register @@ -394,29 +392,29 @@ void gd_process_ata_cmd() case ATA_SOFT_RESET: { - printf_ata("ATA_SOFT_RESET\n"); + printf_ata("ATA_SOFT_RESET"); //DRV -> preserved -> wtf is it anyway ? gd_reset(); } break; case ATA_EXEC_DIAG: - printf_ata("ATA_EXEC_DIAG\n"); - printf("ATA_EXEC_DIAG -- not implemented\n"); + printf_ata("ATA_EXEC_DIAG"); + printf("ATA_EXEC_DIAG -- not implemented"); break; case ATA_SPI_PACKET: - printf_ata("ATA_SPI_PACKET\n"); + printf_ata("ATA_SPI_PACKET"); gd_set_state(gds_waitpacket); break; case ATA_IDENTIFY_DEV: - printf_ata("ATA_IDENTIFY_DEV\n"); + printf_ata("ATA_IDENTIFY_DEV"); gd_spi_pio_end((u8*)&reply_a1[packet_cmd.data_8[2]>>1],packet_cmd.data_8[4]); break; case ATA_SET_FEATURES: - printf_ata("ATA_SET_FEATURES\n"); + printf_ata("ATA_SET_FEATURES"); //Set features sets : //Error : ABRT @@ -440,10 +438,10 @@ void gd_process_ata_cmd() void gd_process_spi_cmd() { - printf_spi("Sense: %02x %02x %02x \n", sns_asc, sns_ascq, sns_key); + printf_spi("Sense: %02x %02x %02x", sns_asc, sns_ascq, sns_key); printf_spi("SPI command %02x;",packet_cmd.data_8[0]); - printf_spi("Params: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n", + printf_spi("Params: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", packet_cmd.data_8[0], packet_cmd.data_8[1], packet_cmd.data_8[2], packet_cmd.data_8[3], packet_cmd.data_8[4], packet_cmd.data_8[5], packet_cmd.data_8[6], packet_cmd.data_8[7], packet_cmd.data_8[8], packet_cmd.data_8[9], packet_cmd.data_8[10], packet_cmd.data_8[11] ); @@ -455,7 +453,7 @@ void gd_process_spi_cmd() switch(packet_cmd.data_8[0]) { case SPI_TEST_UNIT: - printf_spicmd("SPI_TEST_UNIT\n"); + printf_spicmd("SPI_TEST_UNIT"); GDStatus.CHECK=SecNumber.Status==GD_BUSY; // Drive is ready ;) @@ -463,7 +461,7 @@ void gd_process_spi_cmd() break; case SPI_REQ_MODE: - printf_spicmd("SPI_REQ_MODE\n"); + printf_spicmd("SPI_REQ_MODE"); gd_spi_pio_end((u8*)&reply_11[packet_cmd.data_8[2]>>1],packet_cmd.data_8[4]); break; @@ -477,7 +475,7 @@ void gd_process_spi_cmd() if (readcmd.head ==1 && readcmd.subh==1 && readcmd.data==1 && readcmd.expdtype==3 && readcmd.other==0) sector_type=2340; else if(readcmd.head ||readcmd.subh || readcmd.other || (!readcmd.data)) // assert - printf("GDROM: *FIXME* ADD MORE CD READ SETTINGS %d %d %d %d 0x%01X\n",readcmd.head,readcmd.subh,readcmd.other,readcmd.data,readcmd.expdtype); + printf("GDROM: *FIXME* ADD MORE CD READ SETTINGS %d %d %d %d 0x%01X",readcmd.head,readcmd.subh,readcmd.other,readcmd.data,readcmd.expdtype); u32 start_sector = GetFAD(&readcmd.b[2],readcmd.prmtype); u32 sector_count = (readcmd.b[8]<<16) | (readcmd.b[9]<<8) | (readcmd.b[10]); @@ -486,7 +484,7 @@ void gd_process_spi_cmd() read_params.remaining_sectors=sector_count; read_params.sector_type = sector_type;//yeah i know , not really many types supported... - printf_spicmd("SPI_CD_READ - Sector=%d Size=%d/%d DMA=%d\n",read_params.start_sector,read_params.remaining_sectors,read_params.sector_type,Features.CDRead.DMA); + printf_spicmd("SPI_CD_READ - Sector=%d Size=%d/%d DMA=%d",read_params.start_sector,read_params.remaining_sectors,read_params.sector_type,Features.CDRead.DMA); if (Features.CDRead.DMA == 1) { gd_set_state(gds_readsector_dma); @@ -500,7 +498,7 @@ void gd_process_spi_cmd() case SPI_GET_TOC: { - printf_spicmd("SPI_GET_TOC\n"); + printf_spicmd("SPI_GET_TOC"); //printf("SPI_GET_TOC - %d\n",(packet_cmd.data_8[4]) | (packet_cmd.data_8[3]<<8) ); u32 toc_gd[102]; @@ -514,7 +512,7 @@ void gd_process_spi_cmd() //mount/map drive ? some kind of reset/unlock ?? //seems like a non data command :) case 0x70: - printf_spicmd("SPI : unknown ? [0x70]\n"); + printf_spicmd("SPI : unknown ? [0x70]"); //printf("SPI : unknown ? [0x70]\n"); /*GDStatus.full=0x50; //FIXME RaiseInterrupt(holly_GDROM_CMD);*/ @@ -530,7 +528,7 @@ void gd_process_spi_cmd() // This is more or less a hack until more info about this command becomes available. ~Psy case 0x71: { - printf_spicmd("SPI : unknown ? [0x71]\n"); + printf_spicmd("SPI : unknown ? [0x71]"); //printf("SPI : unknown ? [0x71]\n"); extern u32 reply_71_sz; @@ -545,7 +543,7 @@ void gd_process_spi_cmd() break; case SPI_SET_MODE: { - printf_spicmd("SPI_SET_MODE\n"); + printf_spicmd("SPI_SET_MODE"); u32 Offset = packet_cmd.data_8[2]; u32 Count = packet_cmd.data_8[4]; verify((Offset+Count)<11); //cant set write olny things :P @@ -556,8 +554,8 @@ void gd_process_spi_cmd() break; case SPI_CD_READ2: - printf_spicmd("SPI_CD_READ2\n"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_READ2\n"); + printf_spicmd("SPI_CD_READ2"); + printf("GDROM: Unhandled Sega SPI frame: SPI_CD_READ2"); gd_set_state(gds_procpacketdone); break; @@ -565,7 +563,7 @@ void gd_process_spi_cmd() case SPI_REQ_STAT: { - printf_spicmd("SPI_REQ_STAT\n"); + printf_spicmd("SPI_REQ_STAT"); //printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_STAT\n"); u8 stat[10]; @@ -597,7 +595,7 @@ void gd_process_spi_cmd() break; case SPI_REQ_ERROR: - printf_spicmd("SPI_REQ_ERROR\n"); + printf_spicmd("SPI_REQ_ERROR"); //printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n"); u8 resp[10]; @@ -617,7 +615,7 @@ void gd_process_spi_cmd() break; case SPI_REQ_SES: - printf_spicmd("SPI_REQ_SES\n"); + printf_spicmd("SPI_REQ_SES"); u8 ses_inf[6]; libGDR_GetSessionInfo(ses_inf,packet_cmd.data_8[2]); @@ -626,7 +624,7 @@ void gd_process_spi_cmd() break; case SPI_CD_OPEN: - printf_spicmd("SPI_CD_OPEN\n"); + printf_spicmd("SPI_CD_OPEN"); printf("GDROM: Unhandled Sega SPI frame: SPI_CD_OPEN\n"); @@ -635,7 +633,7 @@ void gd_process_spi_cmd() case SPI_CD_PLAY: { - printf_spicmd("SPI_CD_PLAY\n"); + printf_spicmd("SPI_CD_PLAY"); printf("GDROM: Unhandled Sega SPI frame: SPI_CD_PLAY\n"); //cdda.CurrAddr.FAD=60000; @@ -677,7 +675,7 @@ void gd_process_spi_cmd() case SPI_CD_SEEK: { - printf_spicmd("SPI_CD_SEEK\n"); + printf_spicmd("SPI_CD_SEEK"); printf("GDROM: Unhandled Sega SPI frame: SPI_CD_SEEK\n"); SecNumber.Status=GD_PAUSE; @@ -723,7 +721,7 @@ void gd_process_spi_cmd() break; case SPI_CD_SCAN: - printf_spicmd("SPI_CD_SCAN\n"); + printf_spicmd("SPI_CD_SCAN"); printf("GDROM: Unhandled Sega SPI frame: SPI_CD_SCAN\n"); @@ -732,7 +730,7 @@ void gd_process_spi_cmd() case SPI_GET_SCD: { - printf_spicmd("SPI_GET_SCD\n"); + printf_spicmd("SPI_GET_SCD"); //printf("\nGDROM:\tUnhandled Sega SPI frame: SPI_GET_SCD\n"); u32 format; @@ -804,7 +802,7 @@ void gd_process_spi_cmd() data_q[8]=0x0; //(u8)(cdda.CurrAddr.FAD>>8); data_q[9]=0x96;//(u8)(cdda.CurrAddr.FAD>>0); sz=0xE; - printf_subcode("NON raw subcode read -- partially wrong [format=%d]\n",format); + printf_subcode("NON raw subcode read -- partially wrong [format=%d]",format); } gd_spi_pio_end((u8*)&subc_info[0],sz); @@ -826,19 +824,19 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz) //cancel interrupt case GD_STATUS_Read : asic_CancelInterrupt(holly_GDROM_CMD); //Clear INTRQ signal - printf_rm("GDROM: STATUS [cancel int](v=%X)\n",GDStatus.full); + printf_rm("GDROM: STATUS [cancel int](v=%X)",GDStatus.full); return GDStatus.full | (1<<4); case GD_ALTSTAT_Read: - printf_rm("GDROM: Read From AltStatus (v=%X)\n",GDStatus.full); + printf_rm("GDROM: Read From AltStatus (v=%X)",GDStatus.full); return GDStatus.full | (1<<4); case GD_BYCTLLO : - printf_rm("GDROM: Read From GD_BYCTLLO\n"); + printf_rm("GDROM: Read From GD_BYCTLLO"); return ByteCount.low; case GD_BYCTLHI : - printf_rm("GDROM: Read From GD_BYCTLHI\n"); + printf_rm("GDROM: Read From GD_BYCTLHI"); return ByteCount.hi; case GD_DATA: @@ -872,24 +870,24 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz) return 0; case GD_DRVSEL: - printf_rm("GDROM: Read From DriveSel\n"); + printf_rm("GDROM: Read From DriveSel"); return DriveSel; case GD_ERROR_Read: - printf_rm("GDROM: Read from ERROR Register\n"); + printf_rm("GDROM: Read from ERROR Register"); Error.Sense=sns_key; return Error.full; case GD_IREASON_Read: - printf_rm("GDROM: Read from INTREASON Register\n"); + printf_rm("GDROM: Read from INTREASON Register"); return IntReason.full; case GD_SECTNUM: - printf_rm("GDROM: Read from SecNumber Register (v=%X)\n", SecNumber.full); + printf_rm("GDROM: Read from SecNumber Register (v=%X)", SecNumber.full); return SecNumber.full; default: - printf("GDROM: Unhandled read from address %X, Size:%X\n",Addr,sz); + printf("GDROM: Unhandled read from address %X, Size:%X",Addr,sz); return 0; } } @@ -900,12 +898,12 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) switch(Addr) { case GD_BYCTLLO: - printf_rm("GDROM: Write to GD_BYCTLLO = %X, Size:%X\n",data,sz); + printf_rm("GDROM: Write to GD_BYCTLLO = %X, Size:%X",data,sz); ByteCount.low =(u8) data; break; case GD_BYCTLHI: - printf_rm("GDROM: Write to GD_BYCTLHI = %X, Size:%X\n",data,sz); + printf_rm("GDROM: Write to GD_BYCTLHI = %X, Size:%X",data,sz); ByteCount.hi =(u8) data; break; @@ -953,17 +951,17 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) // The actual transfer mode is specified by the Sector Counter Register. case GD_FEATURES_Write: - printf_rm("GDROM: Write to GD_FEATURES\n"); + printf_rm("GDROM: Write to GD_FEATURES"); Features.full =(u8) data; break; case GD_SECTCNT_Write: - printf("GDROM: Write to SecCount = %X\n", data); + printf("GDROM: Write to SecCount = %X", data); SecCount.full =(u8) data; break; case GD_SECTNUM: - printf("GDROM: Write to SecNum; not possible = %X\n", data); + printf("GDROM: Write to SecNum; not possible = %X", data); break; case GD_COMMAND_Write: @@ -976,7 +974,7 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) break; default: - printf("\nGDROM:\tUnhandled write to address %X <= %X, Size:%X\n",Addr,data,sz); + printf("\nGDROM:\tUnhandled write to address %X <= %X, Size:%X",Addr,data,sz); break; } } @@ -1125,7 +1123,7 @@ void GDROM_DmaEnable(u32 addr, u32 data) SB_GDEN = (data & 1); if (SB_GDEN == 0 && SB_GDST == 1) { - printf_spi("GD-DMA aborted\n"); + printf_spi("GD-DMA aborted"); SB_GDST = 0; } } From fcc6fd784c98ca65ba9771ef3f066b8598222eac Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 23:02:26 +0200 Subject: [PATCH 109/158] holly: use new logging --- core/hw/aica/sgc_if.cpp | 12 ++++++------ core/hw/holly/sb.cpp | 12 ++++++------ core/hw/holly/sb_mem.cpp | 13 +++++++------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 20e52f0a9..5dd37a729 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -501,7 +501,7 @@ struct ChannelEx { if (AEG.state!=EG_Release) { - key_printf("[%p] KEY_OFF -> Release\n", this); + key_printf("[%p] KEY_OFF -> Release", this); SetAegState(EG_Release); //switch to release state } @@ -862,7 +862,7 @@ void StreamStep(ChannelEx* ch) if ((ch->AEG.state==EG_Attack) && (CA>=ch->loop.LSA)) { - step_printf("[%p]LPSLNK : Switching to EG_Decay1 %X\n", ch, ch->AEG.GetValue()); + step_printf("[%p]LPSLNK : Switching to EG_Decay1 %X", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay1); } } @@ -963,7 +963,7 @@ void AegStep(ChannelEx* ch) ch->AEG.SetValue(0); if (!ch->ccd->LPSLNK) { - aeg_printf("[%p]AEG_step : Switching to EG_Decay1 %d\n", ch, ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Decay1 %d", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay1); } } @@ -975,7 +975,7 @@ void AegStep(ChannelEx* ch) ch->AEG.val+=ch->AEG.Decay1Rate; if (((u32)ch->AEG.GetValue())>=ch->AEG.Decay2Value) { - aeg_printf("[%p]AEG_step : Switching to EG_Decay2 @ %x\n", ch, ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Decay2 @ %x", ch, ch->AEG.GetValue()); ch->SetAegState(EG_Decay2); } } @@ -986,7 +986,7 @@ void AegStep(ChannelEx* ch) ch->AEG.val+=ch->AEG.Decay2Rate; if (ch->AEG.GetValue()>=0x3FF) { - aeg_printf("[%p]AEG_step : Switching to EG_Release @ %x\n", ch, ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : Switching to EG_Release @ %x", ch, ch->AEG.GetValue()); ch->AEG.SetValue(0x3FF); ch->SetAegState(EG_Release); } @@ -998,7 +998,7 @@ void AegStep(ChannelEx* ch) if (ch->AEG.GetValue()>=0x3FF) { - aeg_printf("[%p]AEG_step : EG_Release End @ %x\n", ch, ch->AEG.GetValue()); + aeg_printf("[%p]AEG_step : EG_Release End @ %x", ch, ch->AEG.GetValue()); ch->AEG.SetValue(0x3FF); // TODO: mnn, should we do anything about it running wild ? ch->disable(); // TODO: Is this ok here? It's a speed optimisation (since the channel is muted) } diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index 4c962b6f6..28d4df457 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -35,7 +35,7 @@ u32 sb_ReadMem(u32 addr,u32 sz) #ifdef TRACE if (offset & 3/*(size-1)*/) //4 is min align size { - EMUERROR("Unaligned System Bus register read"); + INFO_LOG(HOLLY, "Unaligned System Bus register read"); } #endif @@ -59,7 +59,7 @@ u32 sb_ReadMem(u32 addr,u32 sz) //printf("SB: %08X\n",addr); if ((sb_regs[offset].flags & REG_WO) || sb_regs[offset].readFunctionAddr == NULL) { - EMUERROR("sb_ReadMem write-only reg %08x %d\n", addr, sz); + INFO_LOG(HOLLY, "sb_ReadMem write-only reg %08x %d", addr, sz); return 0; } return sb_regs[offset].readFunctionAddr(addr); @@ -69,7 +69,7 @@ u32 sb_ReadMem(u32 addr,u32 sz) else { if (!(sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR("ERROR [wrong size read on register]"); + INFO_LOG(HOLLY, "ERROR [wrong size read on register]"); } #endif // if ((sb_regs[offset].flags& REG_NOT_IMPL)) @@ -83,7 +83,7 @@ void sb_WriteMem(u32 addr,u32 data,u32 sz) #ifdef TRACE if (offset & 3/*(size-1)*/) //4 is min align size { - EMUERROR("Unaligned System bus register write"); + INFO_LOG(HOLLY, "Unaligned System bus register write"); } #endif offset>>=2; @@ -128,10 +128,10 @@ offset>>=2; else { if (!(sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR4("ERROR :wrong size write on register ; offset=%x , data=%x,sz=%d",offset,data,sz); + INFO_LOG(HOLLY, "ERROR: wrong size write on register; offset=%x, data=%x, sz=%d", offset, data, sz); } if ((sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR3("Write to System Control Regs , not implemented , addr=%x,data=%x",addr,data); + INFO_LOG(HOLLY, "Write to System Control Regs, not implemented, addr=%x, data=%x", addr, data); #endif } diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index 21c593c43..dae8bae8e 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -56,10 +56,11 @@ bool LoadRomFiles(const string& root) { if (NVR_OPTIONAL) { - printf("flash/nvmem is missing, will create new file...\n"); + INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); } else { + ERROR_LOG(FLASHROM, "Unable to find flash/nvmem in %s. Exiting...", root.c_str()); msgboxf("Unable to find flash/nvmem in \n%s\nExiting...", MBX_ICONERROR, root.c_str()); return false; } @@ -86,7 +87,7 @@ bool LoadRomFiles(const string& root) syscfg.lang = settings.dreamcast.language; if (sys_nvmem.WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) - printf("Failed to save time and language to flash RAM\n"); + WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); #endif @@ -111,7 +112,7 @@ void SaveRomFiles(const string& root) bool LoadHle(const string& root) { if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { - printf("No nvmem loaded\n"); + INFO_LOG(FLASHROM, "No nvmem loaded"); } return reios_init(sys_rom.data, sys_nvmem.data); @@ -123,7 +124,7 @@ void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem.Write(addr,data,sz); } #if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2) u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); } -void WriteBios(u32 addr,u32 data,u32 sz) { EMUERROR4("Write to [Boot ROM] is not possible, addr=%x,data=%x,size=%d",addr,data,sz); } +void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz); } #elif (DC_PLATFORM == DC_PLATFORM_ATOMISWAVE) u32 ReadBios(u32 addr,u32 sz) @@ -135,7 +136,7 @@ void WriteBios(u32 addr,u32 data,u32 sz) { EMUERROR4("Write to [Boot ROM] is not { if (sz != 1) { - EMUERROR("Invalid access size @%08x data %x sz %d\n", addr, data, sz); + INFO_LOG(MEMORY, "Invalid access size @%08x data %x sz %d", addr, data, sz); return; } sys_rom.Write(addr, data, sz); @@ -192,7 +193,7 @@ T DYNACALL ReadMem_area0(u32 addr) { if ( /*&& (addr>= 0x00400000)*/ (addr<= 0x005F67FF)) // :Unassigned { - EMUERROR2("Read from area0_32 not implemented [Unassigned], addr=%x",addr); + INFO_LOG(MEMORY, "Read from area0_32 not implemented [Unassigned], addr=%x", addr); } else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM { From a31f573c691a222c564247e45f258c95645392c5 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 30 Jun 2019 23:38:58 +0200 Subject: [PATCH 110/158] maple: use new logging --- core/hw/maple/maple_devs.cpp | 110 +++++++++++++++++------------------ core/hw/maple/maple_if.cpp | 20 +++---- 2 files changed, 62 insertions(+), 68 deletions(-) diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 1c138d118..714f4b526 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -13,18 +13,7 @@ #include "deps/zlib/zlib.h" #include "deps/xxhash/xxhash.h" -#if _ANDROID -#include -#include -#else -#define LOGW printf -#define LOGI printf -#endif -#ifndef RELEASE -#define LOGJVS(...) LOGI(__VA_ARGS__) -#else -#define LOGJVS(...) -#endif +#define LOGJVS(...) DEBUG_LOG(JVS, __VA_ARGS__) #define SAVE_EEPROM 1 @@ -385,7 +374,7 @@ struct maple_sega_vmu: maple_base // creates an empty VMU bool init_emptyvmu() { - printf("Initialising empty VMU...\n"); + INFO_LOG(MAPLE, "Initialising empty VMU..."); uLongf dec_sz = sizeof(flash_data); int rv = uncompress(flash_data, &dec_sz, vmu_default, sizeof(vmu_default)); @@ -421,24 +410,24 @@ struct maple_sega_vmu: maple_base file = fopen(apath.c_str(), "rb+"); if (!file) { - printf("Unable to open VMU save file \"%s\", creating new file\n",apath.c_str()); + INFO_LOG(MAPLE, "Unable to open VMU save file \"%s\", creating new file", apath.c_str()); file = fopen(apath.c_str(), "wb"); if (file) { if (!init_emptyvmu()) - printf("Failed to initialize an empty VMU, you should reformat it using the BIOS\n"); + INFO_LOG(MAPLE, "Failed to initialize an empty VMU, you should reformat it using the BIOS"); fwrite(flash_data, sizeof(flash_data), 1, file); fseek(file, 0, SEEK_SET); } else { - printf("Unable to create VMU!\n"); + INFO_LOG(MAPLE, "Unable to create VMU!"); } } if (!file) { - printf("Failed to create VMU save file \"%s\"\n",apath.c_str()); + INFO_LOG(MAPLE, "Failed to create VMU save file \"%s\"", apath.c_str()); } else { @@ -462,12 +451,12 @@ struct maple_sega_vmu: maple_base fseek(file, 0, SEEK_SET); } else { - printf("Unable to create VMU!\n"); + INFO_LOG(MAPLE, "Unable to create VMU!"); } } else { - printf("Failed to initialize an empty VMU, you should reformat it using the BIOS\n"); + INFO_LOG(MAPLE, "Failed to initialize an empty VMU, you should reformat it using the BIOS"); } } @@ -534,7 +523,7 @@ struct maple_sega_vmu: maple_base u32 pt=r32(); if (pt!=0) { - printf("VMU: MDCF_GetMediaInfo -> bad input |%08X|, returning MDRE_UnknownCmd\n",pt); + INFO_LOG(MAPLE, "VMU: MDCF_GetMediaInfo -> bad input |%08X|, returning MDRE_UnknownCmd", pt); return MDRE_UnknownCmd; } else @@ -552,7 +541,7 @@ struct maple_sega_vmu: maple_base break; default: - printf("VMU: MDCF_GetMediaInfo -> Bad function used |%08X|, returning -2\n",function); + INFO_LOG(MAPLE, "VMU: MDCF_GetMediaInfo -> Bad function used |%08X|, returning -2", function); return MDRE_UnknownFunction;//bad function } } @@ -572,8 +561,8 @@ struct maple_sega_vmu: maple_base if (Block>255) { - printf("Block read : %d\n",Block); - printf("BLOCK READ ERROR\n"); + DEBUG_LOG(MAPLE, "Block read : %d", Block); + DEBUG_LOG(MAPLE, "BLOCK READ ERROR"); Block&=255; } wptr(flash_data+Block*512,512); @@ -596,7 +585,7 @@ struct maple_sega_vmu: maple_base { if (r32()!=0) { - printf("VMU: Block read: MFID_3_Clock : invalid params \n"); + INFO_LOG(MAPLE, "VMU: Block read: MFID_3_Clock : invalid params"); return MDRE_TransmitAgain; //invalid params } else @@ -620,7 +609,13 @@ struct maple_sega_vmu: maple_base w8(timenow->tm_sec); w8(0); - printf("VMU: CLOCK Read-> datetime is %04d/%02d/%02d ~ %02d:%02d:%02d!\n",timebuf[0]+timebuf[1]*256,timebuf[2],timebuf[3],timebuf[4],timebuf[5],timebuf[6]); + DEBUG_LOG(MAPLE, "VMU: CLOCK Read-> datetime is %04d/%02d/%02d ~ %02d:%02d:%02d!", + timebuf[0] + timebuf[1] * 256, + timebuf[2], + timebuf[3], + timebuf[4], + timebuf[5], + timebuf[6]); return MDRS_DataTransfer;//transfer reply ... } @@ -628,7 +623,7 @@ struct maple_sega_vmu: maple_base break; default: - printf("VMU: cmd MDCF_BlockRead -> Bad function |%08X| used, returning -2\n",function); + INFO_LOG(MAPLE, "VMU: cmd MDCF_BlockRead -> Bad function |%08X| used, returning -2", function); return MDRE_UnknownFunction;//bad function } } @@ -655,7 +650,7 @@ struct maple_sega_vmu: maple_base } else { - printf("Failed to save VMU %s data\n",logical_port); + INFO_LOG(MAPLE, "Failed to save VMU %s data", logical_port); } return MDRS_DeviceReply;//just ko } @@ -746,7 +741,8 @@ struct maple_sega_vmu: maple_base { u8 timebuf[8]; rptr(timebuf,8); - printf("VMU: CLOCK Write-> datetime is %04d/%02d/%02d ~ %02d:%02d:%02d! Nothing set tho ...\n",timebuf[0]+timebuf[1]*256,timebuf[2],timebuf[3],timebuf[4],timebuf[5],timebuf[6]); + DEBUG_LOG(MAPLE, "VMU: CLOCK Write-> datetime is %04d/%02d/%02d ~ %02d:%02d:%02d! Nothing set tho ...", + timebuf[0]+timebuf[1]*256,timebuf[2],timebuf[3],timebuf[4],timebuf[5],timebuf[6]); return MDRS_DeviceReply;//ok ! } } @@ -754,7 +750,7 @@ struct maple_sega_vmu: maple_base default: { - printf("VMU: command MDCF_BlockWrite -> Bad function used, returning MDRE_UnknownFunction\n"); + INFO_LOG(MAPLE, "VMU: command MDCF_BlockWrite -> Bad function used, returning MDRE_UnknownFunction"); return MDRE_UnknownFunction;//bad function } } @@ -773,7 +769,7 @@ struct maple_sega_vmu: maple_base u32 bp=r32(); if (bp) { - printf("BEEP : %08X\n",bp); + INFO_LOG(MAPLE, "BEEP : %08X", bp); } return MDRS_DeviceReply;//just ko } @@ -781,7 +777,7 @@ struct maple_sega_vmu: maple_base default: { - printf("VMU: command MDCF_SetCondition -> Bad function used, returning MDRE_UnknownFunction\n"); + INFO_LOG(MAPLE, "VMU: command MDCF_SetCondition -> Bad function used, returning MDRE_UnknownFunction"); return MDRE_UnknownFunction;//bad function } break; @@ -790,7 +786,7 @@ struct maple_sega_vmu: maple_base default: - //printf("Unknown MAPLE COMMAND %d\n",cmd); + DEBUG_LOG(MAPLE, "Unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -829,7 +825,7 @@ struct maple_microphone: maple_base switch (cmd) { case MDC_DeviceRequest: - LOGI("maple_microphone::dma MDC_DeviceRequest\n"); + DEBUG_LOG(MAPLE, "maple_microphone::dma MDC_DeviceRequest"); //this was copied from the controller case with just the id and name replaced! //caps @@ -864,7 +860,7 @@ struct maple_microphone: maple_base case MDCF_GetCondition: { - LOGI("maple_microphone::dma MDCF_GetCondition\n"); + DEBUG_LOG(MAPLE, "maple_microphone::dma MDCF_GetCondition"); //this was copied from the controller case with just the id replaced! //PlainJoystickState pjs; @@ -901,7 +897,7 @@ struct maple_microphone: maple_base case MDC_DeviceReset: //uhhh do nothing? - LOGI("maple_microphone::dma MDC_DeviceReset\n"); + DEBUG_LOG(MAPLE, "maple_microphone::dma MDC_DeviceReset"); return MDRS_DeviceReply; case MDCF_MICControl: @@ -964,29 +960,29 @@ struct maple_microphone: maple_base return MDRS_DataTransfer; } case 0x02: - LOGI("maple_microphone::dma MDCF_MICControl toggle recording %#010x\n",secondword); + DEBUG_LOG(MAPLE, "maple_microphone::dma MDCF_MICControl toggle recording %#010x", secondword); return MDRS_DeviceReply; case 0x03: - LOGI("maple_microphone::dma MDCF_MICControl set gain %#010x\n",secondword); + DEBUG_LOG(MAPLE, "maple_microphone::dma MDCF_MICControl set gain %#010x", secondword); return MDRS_DeviceReply; case MDRE_TransmitAgain: - LOGW("maple_microphone::dma MDCF_MICControl MDRE_TransmitAgain\n"); + WARN_LOG(MAPLE, "maple_microphone::dma MDCF_MICControl MDRE_TransmitAgain"); //apparently this doesnt matter //wptr(micdata, SIZE_OF_MIC_DATA); return MDRS_DeviceReply;//MDRS_DataTransfer; default: - LOGW("maple_microphone::dma UNHANDLED secondword %#010x\n",secondword); + INFO_LOG(MAPLE, "maple_microphone::dma UNHANDLED secondword %#010x", secondword); return MDRE_UnknownFunction; } } default: - LOGW("maple_microphone::dma UNHANDLED function %#010x\n",function); + INFO_LOG(MAPLE, "maple_microphone::dma UNHANDLED function %#010x", function); return MDRE_UnknownFunction; } } default: - LOGW("maple_microphone::dma UNHANDLED MAPLE COMMAND %d\n",cmd); + INFO_LOG(MAPLE, "maple_microphone::dma UNHANDLED MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1121,7 +1117,7 @@ struct maple_sega_purupuru : maple_base return MDRS_DeviceReply; default: - //printf("UNKOWN MAPLE COMMAND %d\n",cmd); + INFO_LOG(MAPLE, "UNKOWN MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1192,7 +1188,7 @@ struct maple_keyboard : maple_base return MDRS_DataTransfer; default: - //printf("Keyboard: unknown MAPLE COMMAND %d\n", cmd); + DEBUG_LOG(MAPLE, "Keyboard: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1299,7 +1295,7 @@ struct maple_mouse : maple_base return MDRS_DataTransfer; default: - //printf("Mouse: unknown MAPLE COMMAND %d\n", cmd); + DEBUG_LOG(MAPLE, "Mouse: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1379,7 +1375,7 @@ struct maple_lightgun : maple_base return MDRS_DataTransfer; default: - //printf("Light gun: unknown MAPLE COMMAND %d\n", cmd); + DEBUG_LOG(MAPLE, "Light gun: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1851,7 +1847,7 @@ struct maple_naomi_jamma : maple_sega_controller case 0x13: // Store repeated request if (len > 0 && node_id > 0 && node_id <= 0x1f) { - printf("JVS node %d: Storing %d cmd bytes\n", node_id, len); + INFO_LOG(MAPLE, "JVS node %d: Storing %d cmd bytes", node_id, len); jvs_repeat_request[node_id - 1][0] = len; memcpy(&jvs_repeat_request[node_id - 1][1], cmd, len); } @@ -1956,7 +1952,7 @@ struct maple_naomi_jamma : maple_sega_controller { int address = dma_buffer_in[1]; int size = dma_buffer_in[2]; - //printf("EEprom write %08X %08X\n",address,size); + DEBUG_LOG(MAPLE, "EEprom write %08X %08X\n", address, size); //printState(Command,buffer_in,buffer_in_len); memcpy(EEPROM + address, dma_buffer_in + 4, size); @@ -1967,10 +1963,10 @@ struct maple_naomi_jamma : maple_sega_controller { fwrite(EEPROM, 1, 0x80, f); fclose(f); - printf("Saved EEPROM to %s\n", eeprom_file.c_str()); + INFO_LOG(MAPLE, "Saved EEPROM to %s", eeprom_file.c_str()); } else - printf("EEPROM SAVE FAILED to %s\n", eeprom_file.c_str()); + WARN_LOG(MAPLE, "EEPROM SAVE FAILED to %s", eeprom_file.c_str()); #endif w8(MDRS_JVSReply); w8(0x00); @@ -1994,15 +1990,15 @@ struct maple_naomi_jamma : maple_sega_controller { fread(EEPROM, 1, 0x80, f); fclose(f); - printf("Loaded EEPROM from %s\n", eeprom_file.c_str()); + DEBUG_LOG(MAPLE, "Loaded EEPROM from %s", eeprom_file.c_str()); } else if (naomi_default_eeprom != NULL) { - printf("Using default EEPROM file\n"); + DEBUG_LOG(MAPLE, "Using default EEPROM file"); memcpy(EEPROM, naomi_default_eeprom, 0x80); } else - printf("EEPROM file not found at %s and no default found\n", eeprom_file.c_str()); + DEBUG_LOG(MAPLE, "EEPROM file not found at %s and no default found", eeprom_file.c_str()); } #endif //printf("EEprom READ\n"); @@ -2057,7 +2053,7 @@ struct maple_naomi_jamma : maple_sega_controller break; default: - printf("JVS: Unknown 0x86 sub-command %x\n", subcode); + INFO_LOG(MAPLE, "JVS: Unknown 0x86 sub-command %x", subcode); w8(MDRE_UnknownCmd); w8(0x00); w8(0x20); @@ -2115,7 +2111,7 @@ struct maple_naomi_jamma : maple_sega_controller if (fw_dump == NULL) { fw_dump = fopen(filename, "w"); - printf("Saving JVS firmware to %s\n", filename); + INFO_LOG(MAPLE, "Saving JVS firmware to %s", filename); break; } } @@ -2194,7 +2190,7 @@ struct maple_naomi_jamma : maple_sega_controller break; default: - //printf("Unknown Maple command %x\n", cmd); + INFO_LOG(MAPLE, "Unknown Maple command %x", cmd); w8(MDRE_UnknownCmd); w8(0x00); w8(0x00); @@ -2573,7 +2569,7 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou break; default: - printf("JVS: Unknown input type %x\n", buffer_in[cmdi]); + INFO_LOG(MAPLE, "JVS: Unknown input type %x", buffer_in[cmdi]); JVS_OUT(2); // report byte: command error cmdi = length_in; // Ignore subsequent commands break; @@ -2583,7 +2579,7 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou } else { - printf("JVS: Unknown JVS command %x\n", jvs_cmd); + INFO_LOG(MAPLE, "JVS: Unknown JVS command %x", jvs_cmd); JVS_OUT(2); // Unknown command } break; diff --git a/core/hw/maple/maple_if.cpp b/core/hw/maple/maple_if.cpp index f66d56259..c666f7189 100644 --- a/core/hw/maple/maple_if.cpp +++ b/core/hw/maple/maple_if.cpp @@ -52,11 +52,11 @@ void maple_vblank() { if (maple_ddt_pending_reset) { - //printf("DDT vblank ; reset pending\n"); + DEBUG_LOG(MAPLE, "DDT vblank ; reset pending"); } else { - //printf("DDT vblank\n"); + DEBUG_LOG(MAPLE, "DDT vblank"); SB_MDST = 1; maple_DoDma(); SB_MDST = 0; @@ -98,7 +98,7 @@ void maple_SB_MDEN_Write(u32 addr, u32 data) if ((data & 0x1)==0 && SB_MDST) { - printf("Maple DMA abort ?\n"); + INFO_LOG(MAPLE, "Maple DMA abort ?"); } } @@ -122,9 +122,7 @@ void maple_DoDma() verify(SB_MDEN &1) verify(SB_MDST &1) -#if debug_maple - printf("Maple: DoMapleDma SB_MDSTAR=%x\n", SB_MDSTAR); -#endif + DEBUG_LOG(MAPLE, "Maple: DoMapleDma SB_MDSTAR=%x", SB_MDSTAR); u32 addr = SB_MDSTAR; u32 xfer_count=0; bool last = false; @@ -147,7 +145,7 @@ void maple_DoDma() { if (!IsOnSh4Ram(header_2)) { - printf("MAPLE ERROR : DESTINATION NOT ON SH4 RAM 0x%X\n",header_2); + INFO_LOG(MAPLE, "MAPLE ERROR : DESTINATION NOT ON SH4 RAM 0x%X", header_2); header_2&=0xFFFFFF; header_2|=(3<<26); } @@ -157,7 +155,7 @@ void maple_DoDma() u32* p_data =(u32*) GetMemPtr(addr + 8,(plen)*sizeof(u32)); if (p_data == NULL) { - printf("MAPLE ERROR : INVALID SB_MDSTAR value 0x%X\n", addr); + INFO_LOG(MAPLE, "MAPLE ERROR : INVALID SB_MDSTAR value 0x%X", addr); SB_MDST=0; return; } @@ -183,7 +181,7 @@ void maple_DoDma() else { if (port != 5 && command != 1) - printf("MAPLE: Unknown device bus %d port %d cmd %d\n", bus, port, command); + INFO_LOG(MAPLE, "MAPLE: Unknown device bus %d port %d cmd %d", bus, port, command); outlen=4; p_out[0]=0xFFFFFFFF; } @@ -216,7 +214,7 @@ void maple_DoDma() break; default: - printf("MAPLE: Unknown maple_op == %d length %d\n", maple_op, plen * 4); + INFO_LOG(MAPLE, "MAPLE: Unknown maple_op == %d length %d", maple_op, plen * 4); addr += 1 * 4; } } @@ -234,7 +232,7 @@ int maple_schd(int tag, int c, int j) } else { - printf("WARNING: MAPLE DMA ABORT\n"); + INFO_LOG(MAPLE, "WARNING: MAPLE DMA ABORT"); SB_MDST=0; //I really wonder what this means, can the DMA be continued ? } From c60e2d29e867389d6d4cab12e0dc4b1caae7cd5a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 10:28:31 +0200 Subject: [PATCH 111/158] modem: add termination function to stop pico thread use new logging log: set max verbosity to warning for release builds --- core/hw/holly/sb.cpp | 6 +++++ core/hw/maple/maple_devs.cpp | 8 +++--- core/hw/mem/vmem32.cpp | 6 ++--- core/hw/modem/modem.cpp | 19 +++++++------- core/hw/modem/modem.h | 1 + core/hw/modem/net_platform.h | 4 ++- core/hw/modem/picoppp.cpp | 48 +++++++++++++++++------------------- core/hw/sh4/sh4_mem.cpp | 4 +-- core/log/Log.h | 2 +- core/nullDC.cpp | 1 + 10 files changed, 54 insertions(+), 45 deletions(-) diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index 28d4df457..a3f50bcf6 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -790,6 +790,9 @@ void sb_Init() void sb_Reset(bool Manual) { +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) + ModemTerm(); +#endif asic_reg_Reset(Manual); #if DC_PLATFORM == DC_PLATFORM_DREAMCAST gdrom_reg_Reset(Manual); @@ -803,6 +806,9 @@ void sb_Reset(bool Manual) void sb_Term() { +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) + ModemTerm(); +#endif aica_sb_Term(); maple_Term(); pvr_sb_Term(); diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 714f4b526..f7acc5e38 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -1188,7 +1188,7 @@ struct maple_keyboard : maple_base return MDRS_DataTransfer; default: - DEBUG_LOG(MAPLE, "Keyboard: unknown MAPLE COMMAND %d", cmd); + INFO_LOG(MAPLE, "Keyboard: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1295,7 +1295,7 @@ struct maple_mouse : maple_base return MDRS_DataTransfer; default: - DEBUG_LOG(MAPLE, "Mouse: unknown MAPLE COMMAND %d", cmd); + INFO_LOG(MAPLE, "Mouse: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -1375,7 +1375,7 @@ struct maple_lightgun : maple_base return MDRS_DataTransfer; default: - DEBUG_LOG(MAPLE, "Light gun: unknown MAPLE COMMAND %d", cmd); + INFO_LOG(MAPLE, "Light gun: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; } } @@ -2569,7 +2569,7 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou break; default: - INFO_LOG(MAPLE, "JVS: Unknown input type %x", buffer_in[cmdi]); + DEBUG_LOG(MAPLE, "JVS: Unknown input type %x", buffer_in[cmdi]); JVS_OUT(2); // report byte: command error cmdi = length_in; // Ignore subsequent commands break; diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index 90fb531ad..e40c89360 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -99,7 +99,7 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w rv = mmap(&virt_ram_base[dst], size, prot, MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); if (MAP_FAILED == rv) { - printf("MAP1 failed %d\n", errno); + ERROR_LOG(VMEM, "MAP1 failed %d", errno); return NULL; } @@ -109,7 +109,7 @@ static void* vmem32_map_buffer(u32 dst, u32 addrsz, u32 offset, u32 size, bool w ptr = mmap(&virt_ram_base[dst], size, prot , MAP_SHARED | MAP_NOSYNC | MAP_FIXED, vmem_fd, offset); if (MAP_FAILED == ptr) { - printf("MAP2 failed %d\n", errno); + ERROR_LOG(VMEM, "MAP2 failed %d", errno); return NULL; } } @@ -346,7 +346,7 @@ bool vmem32_handle_signal(void *fault_addr, bool write, u32 exception_pc) //vmem32_page_faults++; u32 guest_addr = (u8*)fault_addr - virt_ram_base; u32 rv = vmem32_map_address(guest_addr, write); - //printf("vmem32_handle_signal handled signal %s @ %p -> %08x rv=%d\n", write ? "W" : "R", fault_addr, guest_addr, rv); + DEBUG_LOG(VMEM, "vmem32_handle_signal handled signal %s @ %p -> %08x rv=%d", write ? "W" : "R", fault_addr, guest_addr, rv); if (rv == MMU_ERROR_NONE) return true; if (rv == VMEM32_ERROR_NOT_MAPPED) diff --git a/core/hw/modem/modem.cpp b/core/hw/modem/modem.cpp index a5415af55..6ac7541fd 100644 --- a/core/hw/modem/modem.cpp +++ b/core/hw/modem/modem.cpp @@ -43,11 +43,7 @@ #define MODEM_DEVICE_TYPE_336K 0 -#ifdef RELEASE -#define LOG(...) -#else -#define LOG(...) do { printf("[%d.%03d] MODEM ", (int)os_GetSeconds(), (int)(os_GetSeconds() * 1000) % 1000); printf(__VA_ARGS__); putchar('\n'); } while (false); -#endif +#define LOG(...) DEBUG_LOG(MODEM, __VA_ARGS__) const static u32 MODEM_ID[2] = { @@ -142,7 +138,7 @@ static int modem_sched_func(int tag, int c, int j) { if (last_comm_stats != 0) { - printf("Stats sent %d (%.2f kB/s) received %d (%.2f kB/s) TDBE %d RDBF %d\n", sent_bytes, sent_bytes / 2000.0, + DEBUG_LOG(MODEM, "Stats sent %d (%.2f kB/s) received %d (%.2f kB/s) TDBE %d RDBF %d\n", sent_bytes, sent_bytes / 2000.0, recvd_bytes, recvd_bytes / 2000.0, modem_regs.reg1e.TDBE, modem_regs.reg1e.RDBF); sent_bytes = 0; @@ -211,7 +207,7 @@ static int modem_sched_func(int tag, int c, int j) break; case PRE_CONNECTED: - printf("MODEM Connected\n"); + INFO_LOG(MODEM, "MODEM Connected"); if (modem_regs.reg03.RLSDE) SET_STATUS_BIT(0x0f, modem_regs.reg0f.RLSD, 1); if (modem_regs.reg12 == 0xAA) @@ -319,6 +315,11 @@ void ModemInit() modem_sched = sh4_sched_register(0, &modem_sched_func); } +void ModemTerm() +{ + stop_pppd(); +} + static void schedule_callback(int ms) { sh4_sched_request(modem_sched, SH4_MAIN_CLOCK / 1000 * ms); @@ -428,7 +429,7 @@ static void modem_reset(u32 v) state=MS_RESETING; modem_regs.ptr[0x20]=1; ControllerTestStart(); - printf("MODEM Reset\n"); + INFO_LOG(MODEM, "MODEM Reset"); } } @@ -495,7 +496,7 @@ static void ModemNormalWrite(u32 reg, u32 data) //LOG("ModemNormalWrite : TBUFFER = %X", data); if (connect_state == DISCONNECTED) { - printf("MODEM Dialing\n"); + INFO_LOG(MODEM, "MODEM Dialing"); connect_state = DIALING; } schedule_callback(100); diff --git a/core/hw/modem/modem.h b/core/hw/modem/modem.h index 50e5af26c..32a72cc60 100644 --- a/core/hw/modem/modem.h +++ b/core/hw/modem/modem.h @@ -25,5 +25,6 @@ #include "types.h" void ModemInit(); +void ModemTerm(); u32 ModemReadMem_A0_006(u32 addr,u32 size); void ModemWriteMem_A0_006(u32 addr,u32 data,u32 size); diff --git a/core/hw/modem/net_platform.h b/core/hw/modem/net_platform.h index 8ec9ba9ee..264772076 100644 --- a/core/hw/modem/net_platform.h +++ b/core/hw/modem/net_platform.h @@ -24,13 +24,15 @@ typedef int sock_t; #define L_EAGAIN EAGAIN #define get_last_error() (errno) #define INVALID_SOCKET (-1) +#define perror(s) do { INFO_LOG(MODEM, "%s: %s", (s) != NULL ? (s) : "", strerror(get_last_error())); } while (false) #else typedef SOCKET sock_t; #define VALID(s) ((s) != INVALID_SOCKET) #define L_EWOULDBLOCK WSAEWOULDBLOCK #define L_EAGAIN WSAEWOULDBLOCK #define get_last_error() (WSAGetLastError()) -#define perror(s) do { if (s) printf("%s: ", s); printf("Winsock error: %d\n", WSAGetLastError()); } while (false) +#define perror(s) do { INFO_LOG(MODEM, "%s: Winsock error: %d\n", (s) != NULL ? (s) : "", WSAGetLastError()); } while (false) #endif + #endif diff --git a/core/hw/modem/picoppp.cpp b/core/hw/modem/picoppp.cpp index afdeb612c..e297e6c63 100644 --- a/core/hw/modem/picoppp.cpp +++ b/core/hw/modem/picoppp.cpp @@ -213,7 +213,7 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) if (it == tcp_sockets.end()) { if (tcp_connecting_sockets.find(s) == tcp_connecting_sockets.end()) - printf("Unknown socket: remote port %d\n", short_be(s->remote_port)); + INFO_LOG(MODEM, "Unknown socket: remote port %d", short_be(s->remote_port)); } else { @@ -234,7 +234,7 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) { // Also called for child sockets if (tcp_sockets.find(s) == tcp_sockets.end()) - printf("pico_socket_accept: %s\n", strerror(pico_err)); + INFO_LOG(MODEM, "pico_socket_accept: %s\n", strerror(pico_err)); } else { @@ -270,8 +270,7 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) if (get_last_error() != EINPROGRESS && get_last_error() != L_EWOULDBLOCK) { pico_ipv4_to_string(peer, sock_a->local_addr.ip4.addr); - printf("TCP connection to %s:%d failed: ", peer, short_be(sock_a->local_port)); - perror(NULL); + INFO_LOG(MODEM, "TCP connection to %s:%d failed: %s", peer, short_be(sock_a->local_port), strerror(get_last_error())); closesocket(sockfd); } else @@ -291,7 +290,7 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) auto it = tcp_sockets.find(s); if (it == tcp_sockets.end()) { - printf("PICO_SOCK_EV_FIN: Unknown socket: remote port %d\n", short_be(s->remote_port)); + INFO_LOG(MODEM, "PICO_SOCK_EV_FIN: Unknown socket: remote port %d", short_be(s->remote_port)); } else { @@ -301,11 +300,11 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) } if (ev & PICO_SOCK_EV_ERR) { - printf("Socket error received: %s\n", strerror(pico_err)); + INFO_LOG(MODEM, "Socket error received: %s", strerror(pico_err)); auto it = tcp_sockets.find(s); if (it == tcp_sockets.end()) { - printf("PICO_SOCK_EV_ERR: Unknown socket: remote port %d\n", short_be(s->remote_port)); + INFO_LOG(MODEM, "PICO_SOCK_EV_ERR: Unknown socket: remote port %d", short_be(s->remote_port)); } else { @@ -319,7 +318,7 @@ static void tcp_callback(uint16_t ev, struct pico_socket *s) auto it = tcp_sockets.find(s); if (it == tcp_sockets.end()) { - printf("PICO_SOCK_EV_CLOSE: Unknown socket: remote port %d\n", short_be(s->remote_port)); + INFO_LOG(MODEM, "PICO_SOCK_EV_CLOSE: Unknown socket: remote port %d", short_be(s->remote_port)); } else { @@ -374,7 +373,7 @@ static void udp_callback(uint16_t ev, struct pico_socket *s) if (r <= 0) { if (r < 0) - printf("%s: error UDP recv: %s\n", __FUNCTION__, strerror(pico_err)); + INFO_LOG(MODEM, "error UDP recv: %s", strerror(pico_err)); break; } @@ -394,7 +393,7 @@ static void udp_callback(uint16_t ev, struct pico_socket *s) } if (ev & PICO_SOCK_EV_ERR) { - printf("UDP Callback error received\n"); + INFO_LOG(MODEM, "UDP Callback error received"); } } @@ -420,7 +419,7 @@ static void read_native_sockets() struct pico_socket *ps = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &tcp_callback); if (ps == NULL) { - printf("pico_socket_open failed: error %d\n", pico_err); + INFO_LOG(MODEM, "pico_socket_open failed: error %d", pico_err); closesocket(sockfd); continue; } @@ -428,7 +427,7 @@ static void read_native_sockets() ps->local_port = src_addr.sin_port; if (pico_socket_connect(ps, &dcaddr.addr, it->first) != 0) { - printf("pico_socket_connect failed: error %d\n", pico_err); + INFO_LOG(MODEM, "pico_socket_connect failed: error %d", pico_err); closesocket(sockfd); pico_socket_close(ps); continue; @@ -469,8 +468,7 @@ static void read_native_sockets() { char peer[30]; pico_ipv4_to_string(peer, it->first->local_addr.ip4.addr); - printf("TCP connection to %s:%d failed: ", peer, short_be(it->first->local_port)); - perror(NULL); + INFO_LOG(MODEM, "TCP connection to %s:%d failed: %s", peer, short_be(it->first->local_port), strerror(get_last_error())); pico_socket_close(it->first); closesocket(it->second); } @@ -511,7 +509,7 @@ static void read_native_sockets() //printf("read_native_sockets UDP received %d bytes from %08x:%d\n", r, long_be(msginfo.local_addr.ip4.addr), short_be(msginfo.local_port)); int r2 = pico_socket_sendto_extended(pico_udp_socket, buf, r, &dcaddr, it->first, &msginfo); if (r2 < r) - printf("%s: error UDP sending to %d: %s\n", __FUNCTION__, short_be(it->first), strerror(pico_err)); + INFO_LOG(MODEM, "error UDP sending to %d: %s", short_be(it->first), strerror(pico_err)); } else if (r < 0 && get_last_error() != L_EAGAIN && get_last_error() != L_EWOULDBLOCK) { @@ -543,10 +541,10 @@ static void read_native_sockets() int r2 = pico_socket_send(it->first, buf, r); if (r2 < 0) - printf("%s: error TCP sending: %s\n", __FUNCTION__, strerror(pico_err)); + INFO_LOG(MODEM, "error TCP sending: %s", strerror(pico_err)); else if (r2 < r) // FIXME EAGAIN errors. Need to buffer data or wait for call back. - printf("%s: truncated send: %d -> %d\n", __FUNCTION__, r, r2); + INFO_LOG(MODEM, "truncated send: %d -> %d", r, r2); } else if (r == 0) { @@ -629,7 +627,7 @@ static void check_dns_entries() dns_query_start = 0; char myip[16]; pico_ipv4_to_string(myip, public_ip.addr); - printf("My IP is %s\n", myip); + INFO_LOG(MODEM, "My IP is %s", myip); } else { @@ -662,7 +660,7 @@ static void check_dns_entries() dns_query_start = 0; char afoip[16]; pico_ipv4_to_string(afoip, afo_ip.addr); - printf("AFO server IP is %s\n", afoip); + INFO_LOG(MODEM, "AFO server IP is %s", afoip); } else { @@ -698,7 +696,7 @@ static void *pico_thread_func(void *) #if _WIN32 static WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) - printf("WSAStartup failed\n"); + WARN_LOG(MODEM, "WSAStartup failed"); #endif } @@ -717,28 +715,28 @@ static void *pico_thread_func(void *) pico_udp_socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &udp_callback); if (pico_udp_socket == NULL) { - printf("%s: error opening UDP socket: %s\n", __FUNCTION__, strerror(pico_err)); + INFO_LOG(MODEM, "error opening UDP socket: %s", strerror(pico_err)); } int yes = 1; struct pico_ip4 inaddr_any = {0}; uint16_t listen_port = 0; int ret = pico_socket_bind(pico_udp_socket, &inaddr_any, &listen_port); if (ret < 0) - printf("%s: error binding UDP socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err)); + INFO_LOG(MODEM, "error binding UDP socket to port %u: %s", short_be(listen_port), strerror(pico_err)); pico_tcp_socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &tcp_callback); if (pico_tcp_socket == NULL) { - printf("%s: error opening TCP socket: %s\n", __FUNCTION__, strerror(pico_err)); + INFO_LOG(MODEM, "error opening TCP socket: %s", strerror(pico_err)); } pico_socket_setoption(pico_tcp_socket, PICO_TCP_NODELAY, &yes); ret = pico_socket_bind(pico_tcp_socket, &inaddr_any, &listen_port); if (ret < 0) { - printf("%s: error binding TCP socket to port %u: %s\n", __FUNCTION__, short_be(listen_port), strerror(pico_err)); + INFO_LOG(MODEM, "error binding TCP socket to port %u: %s", short_be(listen_port), strerror(pico_err)); } else { if (pico_socket_listen(pico_tcp_socket, 10) != 0) - printf("%s: error listening on port %u\n", __FUNCTION__, short_be(listen_port)); + INFO_LOG(MODEM, "error listening on port %u", short_be(listen_port)); } ppp->proxied = 1; diff --git a/core/hw/sh4/sh4_mem.cpp b/core/hw/sh4/sh4_mem.cpp index e3a76f08f..a61a7f85d 100644 --- a/core/hw/sh4/sh4_mem.cpp +++ b/core/hw/sh4/sh4_mem.cpp @@ -214,8 +214,8 @@ void mem_Term() sh4_mmr_term(); sh4_area0_Term(); - //write back Flash/SRAM - SaveRomFiles(get_writable_data_path("/data/")); + // done by emulator thread + //SaveRomFiles(get_writable_data_path("/data/")); //mem_b.Term(); // handled by vmem diff --git a/core/log/Log.h b/core/log/Log.h index a0062c052..dc35e1615 100644 --- a/core/log/Log.h +++ b/core/log/Log.h @@ -56,7 +56,7 @@ __attribute__((format(printf, 5, 6))) #define MAX_LOGLEVEL LogTypes::LOG_LEVELS::LDEBUG #else #ifndef MAX_LOGLEVEL -#define MAX_LOGLEVEL LogTypes::LOG_LEVELS::LINFO +#define MAX_LOGLEVEL LogTypes::LOG_LEVELS::LWARNING #endif // loglevel #endif // logging diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 5522915d2..6814addaf 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -499,6 +499,7 @@ void dc_term() naomi_cart_Close(); #endif plugins_Term(); + mem_Term(); _vmem_release(); mcfg_DestroyDevices(); From 74186d2518582a602c9b8b15cee8f43110e3edd6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 11:14:18 +0200 Subject: [PATCH 112/158] naomi: use new logging --- core/hw/naomi/awcartridge.cpp | 6 +- core/hw/naomi/gdcartridge.cpp | 8 +- core/hw/naomi/naomi.cpp | 38 +++++----- core/hw/naomi/naomi_cart.cpp | 134 +++++++++++++++++----------------- 4 files changed, 94 insertions(+), 92 deletions(-) diff --git a/core/hw/naomi/awcartridge.cpp b/core/hw/naomi/awcartridge.cpp index f013ce8f7..136ef4215 100644 --- a/core/hw/naomi/awcartridge.cpp +++ b/core/hw/naomi/awcartridge.cpp @@ -190,7 +190,7 @@ u32 AWCartridge::ReadMem(u32 address, u32 size) { if (roffset >= (mpr_offset / 2)) roffset += mpr_bank * 0x4000000; u16 retval = (RomSize > (roffset * 2)) ? ((u16 *)RomPtr)[roffset] : 0; // not endian-safe? - //printf("AWCART ReadMem %08x: %x\n", address, retval); + DEBUG_LOG(NAOMI, "AWCART ReadMem %08x: %x", address, retval); return retval; } default: @@ -240,7 +240,7 @@ void AWCartridge::WriteMem(u32 address, u32 data, u32 size) break; default: - EMUERROR("%X: %d sz %d", address, data, size); + INFO_LOG(NAOMI, "%X: %d sz %d", address, data, size); break; } } @@ -336,7 +336,7 @@ u16 AWCartridge::decrypt(u16 cipherText, u32 address, const u32 key) void AWCartridge::Init() { mpr_offset = decrypt16(0x58/2) | (decrypt16(0x5a/2) << 16); - printf("AWCartridge::SetKey rombd_key %08x mpr_offset %08x\n", rombd_key, mpr_offset); + INFO_LOG(NAOMI, "AWCartridge::SetKey rombd_key %08x mpr_offset %08x", rombd_key, mpr_offset); device_reset(); } diff --git a/core/hw/naomi/gdcartridge.cpp b/core/hw/naomi/gdcartridge.cpp index a4fd4c25f..30385edf6 100644 --- a/core/hw/naomi/gdcartridge.cpp +++ b/core/hw/naomi/gdcartridge.cpp @@ -409,7 +409,7 @@ void GDCartridge::find_file(const char *name, const u8 *dir_sector, u32 &file_st { file_start = 0; file_size = 0; - printf("Looking for file [%s]\n", name); + DEBUG_LOG(NAOMI, "Looking for file [%s]", name); for(u32 pos = 0; pos < 2048; pos += dir_sector[pos]) { int fnlen = 0; if(!(dir_sector[pos+25] & 2)) { @@ -441,7 +441,7 @@ void GDCartridge::find_file(const char *name, const u8 *dir_sector, u32 &file_st (dir_sector[pos+12] << 16) | (dir_sector[pos+13] << 24)); - printf("start %08x size %08x\n", file_start, file_size); + DEBUG_LOG(NAOMI, "start %08x size %08x", file_start, file_size); break; } if (dir_sector[pos] == 0) @@ -470,7 +470,7 @@ void GDCartridge::device_start() if (RomSize > 0 && gdrom_name != NULL) { if (RomSize >= 0x4000) { - printf("Real PIC binary found\n"); + DEBUG_LOG(NAOMI, "Real PIC binary found"); for(int i=0;i<7;i++) name[i] = picdata[0x7c0+i*2]; for(int i=0;i<7;i++) @@ -499,7 +499,7 @@ void GDCartridge::device_start() (u64(picdata[0x29]) << 0)); } - printf("key is %08x%08x\n", (u32)((key & 0xffffffff00000000ULL)>>32), (u32)(key & 0x00000000ffffffffULL)); + DEBUG_LOG(NAOMI, "key is %08x%08x\n", (u32)((key & 0xffffffff00000000ULL)>>32), (u32)(key & 0x00000000ffffffffULL)); u8 buffer[2048]; std::string gdrom_path = get_game_basename() + "/" + gdrom_name; diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index 3ea7c570c..131559ea7 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -347,13 +347,13 @@ u32 _ReadMem_naomi(u32 Addr, u32 sz) { verify(sz!=1); - EMUERROR("naomi?WTF? ReadMem: %X, %d", Addr, sz); + DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", Addr, sz); return 1; } void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) { - EMUERROR("naomi?WTF? WriteMem: %X <= %X, %d", Addr, data, sz); + DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", Addr, data, sz); } @@ -394,23 +394,23 @@ static bool aw_ram_test_skipped = false; void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) { - printf("Naomi process 0x%04X 0x%04X 0x%04X 0x%04X\n",r3c,r40,r44,r48); - printf("Possible format 0 %d 0x%02X 0x%04X\n",r3c>>15,(r3c&0x7e00)>>9,r3c&0x1FF); - printf("Possible format 1 0x%02X 0x%02X\n",(r3c&0xFF00)>>8,r3c&0xFF); + DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", r3c, r40, r44, r48); + DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",r3c >> 15,(r3c & 0x7e00) >> 9, r3c & 0x1FF); + DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (r3c & 0xFF00) >> 8,r3c & 0xFF); u32 param=(r3c&0xFF); if (param==0xFF) { - printf("invalid opcode or smth ?"); + DEBUG_LOG(NAOMI, "invalid opcode or smth ?"); } static int opcd=0; //else if (param!=3) if (opcd<255) { reg_dimm_3c=0x8000 | (opcd%12<<9) | (0x0); - printf("new reg is 0x%X\n",reg_dimm_3c); + DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_3c); asic_RaiseInterrupt(holly_EXP_PCI); - printf("Interrupt raised\n"); + DEBUG_LOG(NAOMI, "Interrupt raised"); opcd++; } } @@ -420,7 +420,7 @@ u32 ReadMem_naomi(u32 Addr, u32 sz) verify(sz!=1); if (unlikely(CurrentCartridge == NULL)) { - EMUERROR("called without cartridge\n"); + INFO_LOG(NAOMI, "called without cartridge"); return 0xFFFF; } return CurrentCartridge->ReadMem(Addr, sz); @@ -430,7 +430,7 @@ void WriteMem_naomi(u32 Addr, u32 data, u32 sz) { if (unlikely(CurrentCartridge == NULL)) { - EMUERROR("called without cartridge\n"); + INFO_LOG(NAOMI, "called without cartridge"); return; } CurrentCartridge->WriteMem(Addr, data, sz); @@ -441,7 +441,7 @@ void Naomi_DmaStart(u32 addr, u32 data) { if (SB_GDEN==0) { - printf("Invalid (NAOMI)GD-DMA start, SB_GDEN=0.Ingoring it.\n"); + INFO_LOG(NAOMI, "Invalid (NAOMI)GD-DMA start, SB_GDEN=0. Ignoring it."); return; } @@ -482,7 +482,7 @@ void Naomi_DmaEnable(u32 addr, u32 data) SB_GDEN=data&1; if (SB_GDEN==0 && SB_GDST==1) { - printf("(NAOMI)GD-DMA aborted\n"); + INFO_LOG(NAOMI, "(NAOMI)GD-DMA aborted"); SB_GDST=0; } } @@ -602,17 +602,17 @@ void Update_naomi() //len=min(len,(u32)32); // do we need to do this for gdrom dma ? if(0x8201 != (dmaor &DMAOR_MASK)) { - printf("\n!\tGDROM: DMAOR has invalid settings (%X) !\n", dmaor); + INFO_LOG(NAOMI, "GDROM: DMAOR has invalid settings (%X) !", dmaor); //return; } if(len & 0x1F) { - printf("\n!\tGDROM: SB_GDLEN has invalid size (%X) !\n", len); + INFO_LOG(NAOMI, "GDROM: SB_GDLEN has invalid size (%X) !", len); return; } if(0 == len) { - printf("\n!\tGDROM: Len: %X, Abnormal Termination !\n", len); + INFO_LOG(NAOMI, "GDROM: Len: %X, Abnormal Termination !", len); } u32 len_backup=len; if( 1 == SB_GDDIR ) @@ -622,7 +622,7 @@ void Update_naomi() DmaCount=0xffff; } else - msgboxf(L"GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)",MBX_ICONERROR, SB_GDDIR); + INFO_LOG(NAOMI, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)"); //SB_GDLEN = 0x00000000; //13/5/2k7 -> acording to docs these regs are not updated by hardware //SB_GDSTAR = (src + len_backup); @@ -707,7 +707,7 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { return 0; } - EMUERROR("Unhandled read @ %x sz %d", addr, size); + INFO_LOG(NAOMI, "Unhandled read @ %x sz %d", addr, size); return 0xFF; } @@ -717,7 +717,7 @@ void libExtDevice_WriteMem_A0_006(u32 addr,u32 data,u32 size) { switch (addr) { case 0x284: // Atomiswave maple devices - printf("NAOMI 600284 write %x\n", data); + DEBUG_LOG(NAOMI, "NAOMI 600284 write %x", data); aw_maple_devs = data & 0xF0; return; case 0x288: @@ -727,5 +727,5 @@ void libExtDevice_WriteMem_A0_006(u32 addr,u32 data,u32 size) { default: break; } - EMUERROR("Unhandled write @ %x (%d): %x", addr, size, data); + INFO_LOG(NAOMI, "Unhandled write @ %x (%d): %x", addr, size, data); } diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 30bfe5c84..5234c420f 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -44,7 +44,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive break; if (BIOS[biosid].name == NULL) { - printf("Unknown BIOS %s\n", filename); + WARN_LOG(NAOMI, "Unknown BIOS %s", filename); return false; } @@ -74,7 +74,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); verify(bios->blobs[romid].src_offset + bios->blobs[romid].length <= BIOS_SIZE); memcpy(sys_rom.data + bios->blobs[romid].offset, sys_rom.data + bios->blobs[romid].src_offset, bios->blobs[romid].length); - printf("Copied: %x bytes from %07x to %07x\n", bios->blobs[romid].length, bios->blobs[romid].src_offset, bios->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Copied: %x bytes from %07x to %07x", bios->blobs[romid].length, bios->blobs[romid].src_offset, bios->blobs[romid].offset); } else { @@ -86,21 +86,21 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive if (file == NULL && bios_archive != NULL) file = bios_archive->OpenFile(bios->blobs[romid].filename); if (!file) { - printf("%s: Cannot open %s\n", filename, bios->blobs[romid].filename); + ERROR_LOG(NAOMI, "%s: Cannot open %s", filename, bios->blobs[romid].filename); goto error; } if (bios->blobs[romid].blob_type == Normal) { verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); u32 read = file->Read(sys_rom.data + bios->blobs[romid].offset, bios->blobs[romid].length); - printf("Mapped %s: %x bytes at %07x\n", bios->blobs[romid].filename, read, bios->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); } else if (bios->blobs[romid].blob_type == InterleavedWord) { u8 *buf = (u8 *)malloc(bios->blobs[romid].length); if (buf == NULL) { - printf("malloc failed\n"); + ERROR_LOG(NAOMI, "malloc failed"); delete file; goto error; } @@ -111,7 +111,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive for (int i = bios->blobs[romid].length / 2; --i >= 0; to++) *to++ = *from++; free(buf); - printf("Mapped %s: %x bytes (interleaved word) at %07x\n", bios->blobs[romid].filename, read, bios->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); } else die("Unknown blob type\n"); @@ -158,7 +158,7 @@ static bool naomi_cart_LoadZip(char *filename) break; if (Games[gameid].name == NULL) { - printf("Unknown game %s\n", filename); + ERROR_LOG(NAOMI, "Unknown game %s", filename); return false; } @@ -166,34 +166,36 @@ static bool naomi_cart_LoadZip(char *filename) #if DC_PLATFORM == DC_PLATFORM_NAOMI if (game->cart_type == AW) { + ERROR_LOG(NAOMI, "Atomiswave cartridges are not supported by NAOMI"); msgboxf("Atomiswave cartridges are not supported by NAOMI", 0); return false; } #else if (game->cart_type != AW) { + ERROR_LOG(NAOMI, "NAOMI cartridges are not supported by Atomiswave"); msgboxf("NAOMI cartridges are not supported by Atomiswave", 0); return false; } #endif Archive *archive = OpenArchive(filename); if (archive != NULL) - printf("Opened %s\n", filename); + INFO_LOG(NAOMI, "Opened %s", filename); Archive *parent_archive = NULL; if (game->parent_name != NULL) { parent_archive = OpenArchive((get_game_dir() + game->parent_name).c_str()); if (parent_archive != NULL) - printf("Opened %s\n", game->parent_name); + INFO_LOG(NAOMI, "Opened %s", game->parent_name); } if (archive == NULL && parent_archive == NULL) { if (game->parent_name != NULL) - printf("Cannot open %s or %s\n", filename, game->parent_name); + ERROR_LOG(NAOMI, "Cannot open %s or %s", filename, game->parent_name); else - printf("Cannot open %s\n", filename); + ERROR_LOG(NAOMI, "Cannot open %s", filename); return false; } @@ -205,13 +207,13 @@ static bool naomi_cart_LoadZip(char *filename) region_flag = game->region_flag; if (!naomi_LoadBios(bios, archive, parent_archive, region_flag)) { - printf("Warning: Region %d bios not found in %s\n", region_flag, bios); + WARN_LOG(NAOMI, "Warning: Region %d bios not found in %s", region_flag, bios); if (!naomi_LoadBios(bios, archive, parent_archive, -1)) { // If a specific BIOS is needed for this game, fail. if (game->bios != NULL || !bios_loaded) { - printf("Error: cannot load BIOS. Exiting\n"); + ERROR_LOG(NAOMI, "Error: cannot load BIOS. Exiting"); return false; } // otherwise use the default BIOS @@ -256,7 +258,7 @@ static bool naomi_cart_LoadZip(char *filename) u8 *dst = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); u8 *src = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].src_offset, len); memcpy(dst, src, game->blobs[romid].length); - printf("Copied: %x bytes from %07x to %07x\n", game->blobs[romid].length, game->blobs[romid].src_offset, game->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Copied: %x bytes from %07x to %07x", game->blobs[romid].length, game->blobs[romid].src_offset, game->blobs[romid].offset); } else { @@ -266,7 +268,7 @@ static bool naomi_cart_LoadZip(char *filename) if (file == NULL && parent_archive != NULL) file = parent_archive->OpenFile(game->blobs[romid].filename); if (!file) { - printf("%s: Cannot open %s\n", filename, game->blobs[romid].filename); + WARN_LOG(NAOMI, "%s: Cannot open %s", filename, game->blobs[romid].filename); if (game->blobs[romid].blob_type != Eeprom) // Default eeprom file is optional goto error; @@ -277,14 +279,14 @@ static bool naomi_cart_LoadZip(char *filename) { u8 *dst = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); u32 read = file->Read(dst, game->blobs[romid].length); - printf("Mapped %s: %x bytes at %07x\n", game->blobs[romid].filename, read, game->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); } else if (game->blobs[romid].blob_type == InterleavedWord) { u8 *buf = (u8 *)malloc(game->blobs[romid].length); if (buf == NULL) { - printf("malloc failed\n"); + ERROR_LOG(NAOMI, "malloc failed"); delete file; goto error; } @@ -294,32 +296,32 @@ static bool naomi_cart_LoadZip(char *filename) for (int i = game->blobs[romid].length / 2; --i >= 0; to++) *to++ = *from++; free(buf); - printf("Mapped %s: %x bytes (interleaved word) at %07x\n", game->blobs[romid].filename, read, game->blobs[romid].offset); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); } else if (game->blobs[romid].blob_type == Key) { u8 *buf = (u8 *)malloc(game->blobs[romid].length); if (buf == NULL) { - printf("malloc failed\n"); + ERROR_LOG(NAOMI, "malloc failed"); delete file; goto error; } u32 read = file->Read(buf, game->blobs[romid].length); CurrentCartridge->SetKeyData(buf); - printf("Loaded %s: %x bytes cart key\n", game->blobs[romid].filename, read); + DEBUG_LOG(NAOMI, "Loaded %s: %x bytes cart key", game->blobs[romid].filename, read); } else if (game->blobs[romid].blob_type == Eeprom) { naomi_default_eeprom = (u8 *)malloc(game->blobs[romid].length); if (naomi_default_eeprom == NULL) { - printf("malloc failed\n"); + ERROR_LOG(NAOMI, "malloc failed"); delete file; goto error; } u32 read = file->Read(naomi_default_eeprom, game->blobs[romid].length); - printf("Loaded %s: %x bytes default eeprom\n", game->blobs[romid].filename, read); + DEBUG_LOG(NAOMI, "Loaded %s: %x bytes default eeprom", game->blobs[romid].filename, read); } else die("Unknown blob type\n"); @@ -334,12 +336,12 @@ static bool naomi_cart_LoadZip(char *filename) try { CurrentCartridge->Init(); } catch (NaomiCartException& e) { - printf("%s\n", e.reason.c_str()); + ERROR_LOG(NAOMI, "%s", e.reason.c_str()); return false; } strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); - printf("NAOMI GAME ID [%s]\n", naomi_game_id); + NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id); return true; @@ -361,7 +363,7 @@ error: bool naomi_cart_LoadRom(char* file) { - printf("\nnullDC-Naomi rom loader v1.2\n"); + INFO_LOG(NAOMI, "nullDC-Naomi rom loader v1.2"); naomi_cart_Close(); @@ -392,15 +394,15 @@ bool naomi_cart_LoadRom(char* file) // Try to load BIOS from naomi.zip if (!naomi_LoadBios("naomi", NULL, NULL, settings.dreamcast.region)) { - printf("Warning: Region %d bios not found in naomi.zip\n", settings.dreamcast.region); - if (!naomi_LoadBios("naomi", NULL, NULL, -1)) - { - if (!bios_loaded) - { - printf("Error: cannot load BIOS. Exiting\n"); - return false; - } - } + WARN_LOG(NAOMI, "Warning: Region %d bios not found in naomi.zip", settings.dreamcast.region); + if (!naomi_LoadBios("naomi", NULL, NULL, -1)) + { + if (!bios_loaded) + { + ERROR_LOG(NAOMI, "Error: cannot load BIOS. Exiting"); + return false; + } + } } u8* RomPtr; @@ -423,11 +425,11 @@ bool naomi_cart_LoadRom(char* file) char* eon = strstr(line, "\n"); if (!eon) - printf("+Loading naomi rom that has no name\n"); + DEBUG_LOG(NAOMI, "+Loading naomi rom that has no name"); else *eon = 0; - printf("+Loading naomi rom : %s\n", line); + DEBUG_LOG(NAOMI, "+Loading naomi rom : %s", line); line = fgets(t, 512, fl); if (!line) @@ -451,7 +453,7 @@ bool naomi_cart_LoadRom(char* file) RomSize = max(RomSize, (addr + sz)); } else if (line[0] != 0 && line[0] != '\n' && line[0] != '\r') - printf("Warning: invalid line in .lst file: %s\n", line); + WARN_LOG(NAOMI, "Warning: invalid line in .lst file: %s", line); line = fgets(t, 512, fl); } @@ -475,7 +477,7 @@ bool naomi_cart_LoadRom(char* file) raw_bin_file = true; } - printf("+%ld romfiles, %.2f MB set size, %.2f MB set address space\n", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f); + INFO_LOG(NAOMI, "+%ld romfiles, %.2f MB set size, %.2f MB set address space", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f); if (RomCacheMap) { @@ -525,7 +527,7 @@ bool naomi_cart_LoadRom(char* file) #endif if (RomCache == INVALID_FD) { - printf("-Unable to read file %s: error %d\n", t, errno); + ERROR_LOG(NAOMI, "-Unable to read file %s: error %d", t, errno); RomCacheMap[i] = INVALID_FD; load_error = true; break; @@ -577,18 +579,18 @@ bool naomi_cart_LoadRom(char* file) bool mapped = RomDest == (u8 *)mem_region_map_file((void *)(uintptr_t)RomCacheMap[i], RomDest, fsize[i], 0, false); if (!mapped) { - printf("-Mapping ROM FAILED: %s @ %08x size %x\n", files[i].c_str(), fstart[i], fsize[i]); + ERROR_LOG(NAOMI, "-Mapping ROM FAILED: %s @ %08x size %x", files[i].c_str(), fstart[i], fsize[i]); return false; } } } //done :) - printf("\nMapped ROM Successfully !\n\n"); + INFO_LOG(NAOMI, "Mapped ROM Successfully !"); CurrentCartridge = new DecryptedCartridge(RomPtr, RomSize); strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); - printf("NAOMI GAME ID [%s]\n", naomi_game_id); + NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id); return true; } @@ -620,7 +622,7 @@ bool naomi_cart_SelectFile() if (!naomi_cart_LoadRom(SelectedFile)) { - printf("Cannot load %s: error %d\n", SelectedFile, errno); + ERROR_LOG(NAOMI, "Cannot load %s: error %d", SelectedFile, errno); cfgSetVirtual("config", "image", ""); return false; @@ -650,7 +652,7 @@ bool Cartridge::Read(u32 offset, u32 size, void* dst) static u32 ones = 0xffffffff; // Makes Outtrigger boot - EMUERROR("offset %d > %d\n", offset, RomSize); + INFO_LOG(NAOMI, "offset %d > %d", offset, RomSize); memcpy(dst, &ones, size); } else @@ -663,7 +665,7 @@ bool Cartridge::Read(u32 offset, u32 size, void* dst) bool Cartridge::Write(u32 offset, u32 size, u32 data) { - EMUERROR("Invalid write @ %08x data %x\n", offset, data); + INFO_LOG(NAOMI, "Invalid write @ %08x data %x", offset, data); return false; } @@ -695,7 +697,7 @@ void* NaomiCartridge::GetDmaPtr(u32& size) { if ((DmaOffset & 0x1fffffff) >= RomSize) { - EMUERROR("Error: DmaOffset >= RomSize\n"); + INFO_LOG(NAOMI, "Error: DmaOffset >= RomSize"); size = 0; return NULL; } @@ -713,16 +715,16 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) switch(address & 255) { case 0x3c: - EMUERROR("naomi GD? READ: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_3c | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios case 0x40: - EMUERROR("naomi GD? READ: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_40; case 0x44: - EMUERROR("naomi GD? READ: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_44; case 0x48: - EMUERROR("naomi GD? READ: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_48; //These are known to be valid on normal ROMs and DIMM board @@ -751,12 +753,12 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) //What should i do to emulate 'nothing' ? case NAOMI_COMM_OFFSET_addr&255: #ifdef NAOMI_COMM - printf("naomi COMM offs READ: %X, %d\n", address, size); + DEBUG_LOG(NAOMI, "naomi COMM offs READ: %X, %d", address, size); return CommOffset; #endif case NAOMI_COMM_DATA_addr&255: #ifdef NAOMI_COMM - printf("naomi COMM data read: %X, %d\n", CommOffset, size); + DEBUG_LOG(NAOMI, "naomi COMM data read: %X, %d", CommOffset, size); if (CommSharedMem) { return CommSharedMem[CommOffset&0xF]; @@ -772,21 +774,21 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) return DmaOffset&0xFFFF; case NAOMI_BOARDID_WRITE_addr&255: - EMUERROR("naomi ReadBoardId: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi ReadBoardId: %X, %d", address, size); return 1; case 0x04C: - EMUERROR("naomi GD? READ: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_4c; case 0x18: - printf("naomi reg 0x18 : returning random data\n"); + DEBUG_LOG(NAOMI, "naomi reg 0x18 : returning random data"); return 0x4000^rand(); break; default: break; } - //EMUERROR("naomi?WTF? ReadMem: %X, %d", address, size); + DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", address, size); return 0xFFFF; } @@ -805,20 +807,20 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) reg_dimm_4c|=1;*/ } reg_dimm_3c=data; - EMUERROR("naomi GD? Write: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); return; case 0x40: reg_dimm_40=data; - EMUERROR("naomi GD? Write: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); return; case 0x44: reg_dimm_44=data; - EMUERROR("naomi GD? Write: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); return; case 0x48: reg_dimm_48=data; - EMUERROR("naomi GD? Write: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); return; case 0x4C: @@ -835,7 +837,7 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) naomi_process(reg_dimm_3c,reg_dimm_40,reg_dimm_44,reg_dimm_48); } reg_dimm_4c=data&~0x100; - EMUERROR("naomi GD? Write: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); return; //These are known to be valid on normal ROMs and DIMM board @@ -883,14 +885,14 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) //What should i do to emulate 'nothing' ? case NAOMI_COMM_OFFSET_addr&255: #ifdef NAOMI_COMM - printf("naomi COMM ofset Write: %X <= %X, %d\n", address, data, size); + DEBUG_LOG(NAOMI, "naomi COMM ofset Write: %X <= %X, %d", address, data, size); CommOffset=data&0xFFFF; #endif return; case NAOMI_COMM_DATA_addr&255: #ifdef NAOMI_COMM - printf("naomi COMM data Write: %X <= %X, %d\n", CommOffset, data, size); + DEBUG_LOG(NAOMI, "naomi COMM data Write: %X <= %X, %d", CommOffset, data, size); if (CommSharedMem) { CommSharedMem[CommOffset&0xF]=data; @@ -900,12 +902,12 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) //This should be valid case NAOMI_BOARDID_READ_addr&255: - EMUERROR("naomi WriteMem: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi WriteMem: %X <= %X, %d", address, data, size); return; default: break; } - EMUERROR("naomi?WTF? WriteMem: %X <= %X, %d", address, data, size); + DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", address, data, size); } void NaomiCartridge::Serialize(void** data, unsigned int* total_size) @@ -938,7 +940,7 @@ bool M2Cartridge::Read(u32 offset, u32 size, void* dst) *(u16 *)dst = data; return true; } - EMUERROR("Invalid read @ %08x\n", offset); + INFO_LOG(NAOMI, "Invalid read @ %08x", offset); return false; } else if (!(RomPioOffset & 0x20000000)) From cd0849a8f5491469c06e1dcb263c46023540856a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 11:42:00 +0200 Subject: [PATCH 113/158] pvr: use new logging --- core/hw/pvr/Renderer_if.cpp | 7 ++++--- core/hw/pvr/helper_classes.h | 2 +- core/hw/pvr/pvr_mem.cpp | 8 ++++---- core/hw/pvr/pvr_sb_regs.cpp | 4 ++-- core/hw/pvr/spg.cpp | 9 +-------- core/hw/pvr/ta.cpp | 2 +- core/hw/pvr/ta_vtx.cpp | 4 ++-- 7 files changed, 15 insertions(+), 21 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index bfa7c94df..20c2d1309 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -386,7 +386,7 @@ void rend_init_renderer() delete fallback_renderer; die("Renderer initialization failed\n"); } - printf("Selected renderer initialization failed. Falling back to default renderer.\n"); + INFO_LOG(PVR, "Selected renderer initialization failed. Falling back to default renderer."); renderer = fallback_renderer; fallback_renderer = NULL; // avoid double-free } @@ -485,7 +485,7 @@ void rend_start_render() int ch = fgetc(fCheckFrames); if (ch == EOF) { - printf("Testing: TA Hash log matches, exiting\n"); + INFO_LOG(PVR, "Testing: TA Hash log matches, exiting"); exit(1); } @@ -548,7 +548,7 @@ void rend_start_render() else { ovrn++; - printf("WARNING: Rendering context is overrun (%d), aborting frame\n",ovrn); + INFO_LOG(PVR, "WARNING: Rendering context is overrun (%d), aborting frame", ovrn); tactx_Recycle(ctx); } } @@ -585,6 +585,7 @@ void rend_vblank() { if (!render_called && fb_dirty && FB_R_CTRL.fb_enable) { + DEBUG_LOG(PVR, "Direct framebuffer write detected"); SetCurrentTARC(CORE_CURRENT_CTX); ta_ctx->rend.isRenderFramebuffer = true; rend_start_render(); diff --git a/core/hw/pvr/helper_classes.h b/core/hw/pvr/helper_classes.h index 2e1f01d63..353004639 100644 --- a/core/hw/pvr/helper_classes.h +++ b/core/hw/pvr/helper_classes.h @@ -19,7 +19,7 @@ struct List *overrun |= true; Clear(); if (list_name != NULL) - printf("List overrun for list %s\n", list_name); + WARN_LOG(PVR, "List overrun for list %s", list_name); return daty; } diff --git a/core/hw/pvr/pvr_mem.cpp b/core/hw/pvr/pvr_mem.cpp index fac15f4c3..e079a3831 100644 --- a/core/hw/pvr/pvr_mem.cpp +++ b/core/hw/pvr/pvr_mem.cpp @@ -212,7 +212,7 @@ void YUV_data(u32* data , u32 count) //read u8 DYNACALL pvr_read_area1_8(u32 addr) { - EMUERROR("8-bit VRAM reads are not possible\n"); + INFO_LOG(MEMORY, "%08x: 8-bit VRAM reads are not possible", addr); return 0; } @@ -228,7 +228,7 @@ u32 DYNACALL pvr_read_area1_32(u32 addr) //write void DYNACALL pvr_write_area1_8(u32 addr,u8 data) { - EMUERROR("8-bit VRAM writes are not possible\n"); + INFO_LOG(MEMORY, "%08x: 8-bit VRAM writes are not possible", addr); } void DYNACALL pvr_write_area1_16(u32 addr,u16 data) { @@ -263,7 +263,7 @@ void TAWrite(u32 address,u32* data,u32 count) else //Vram Writef { //shouldn't really get here (?) -> works on dc :D need to handle lmmodes - //printf("Vram TAWrite 0x%X , bkls %d\n",address,count); + DEBUG_LOG(MEMORY, "Vram TAWrite 0x%X , bkls %d\n", address, count); verify(SB_LMMODE0 == 0); memcpy(&vram.data[address&VRAM_MASK],data,count*32); } @@ -293,7 +293,7 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb) else //Vram Writef { // Used by WinCE - //printf("Vram TAWriteSQ 0x%X SB_LMMODE0 %d\n",address, SB_LMMODE0); + DEBUG_LOG(MEMORY, "Vram TAWriteSQ 0x%X SB_LMMODE0 %d", address, SB_LMMODE0); if (SB_LMMODE0 == 0) { // 64b path diff --git a/core/hw/pvr/pvr_sb_regs.cpp b/core/hw/pvr/pvr_sb_regs.cpp index ee73482df..dfdfbd785 100644 --- a/core/hw/pvr/pvr_sb_regs.cpp +++ b/core/hw/pvr/pvr_sb_regs.cpp @@ -33,13 +33,13 @@ void do_pvr_dma() if(0x8201 != (dmaor &DMAOR_MASK)) { - printf("\n!\tDMAC: DMAOR has invalid settings (%X) !\n", dmaor); + INFO_LOG(PVR, "DMAC: DMAOR has invalid settings (%X) !", dmaor); return; } if (len & 0x1F) { - printf("\n!\tDMAC: SB_C2DLEN has invalid size (%X) !\n", len); + INFO_LOG(PVR, "DMAC: SB_C2DLEN has invalid size (%X) !", len); return; } diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index 053baa5b7..d0572e9d3 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -197,19 +197,12 @@ int spg_line_sched(int tag, int cycl, int jit) full_rps=(spd_fps+fskip/ts); - #ifdef TARGET_PANDORA - printf("CPU: %4.2f V: %4.2f (%s%s%4.2f) R: %4.2f+%4.2f\n", - spd_cpu*100/200,spd_vbs, - mode,res,fullvbs, - spd_fps,fskip/ts); - #else - printf("%s/%c - %4.2f - %4.2f - V: %4.2f (%.2f, %s%s%4.2f) R: %4.2f+%4.2f VTX: %4.2f%c, MIPS: %.2f\n", + INFO_LOG(COMMON, "%s/%c - %4.2f - %4.2f - V: %4.2f (%.2f, %s%s%4.2f) R: %4.2f+%4.2f VTX: %4.2f%c, MIPS: %.2f", VER_SHORTNAME,'n',mspdf,spd_cpu*100/200,spd_vbs, spd_vbs/full_rps,mode,res,fullvbs, spd_fps,fskip/ts , mv, mv_c, mips_counter/ 1024.0 / 1024.0); mips_counter = 0; - #endif fskip=0; last_fps=os_GetSeconds(); diff --git a/core/hw/pvr/ta.cpp b/core/hw/pvr/ta.cpp index edfd40384..bb83177c1 100644 --- a/core/hw/pvr/ta.cpp +++ b/core/hw/pvr/ta.cpp @@ -297,7 +297,7 @@ void DYNACALL ta_thd_data32_i(void* data) { if (ta_ctx == NULL) { - printf("Warning: data sent to TA prior to ListInit. Implied\n"); + INFO_LOG(PVR, "Warning: data sent to TA prior to ListInit. Implied"); ta_vtx_ListInit(); } diff --git a/core/hw/pvr/ta_vtx.cpp b/core/hw/pvr/ta_vtx.cpp index f25ea0f4d..20a41efee 100644 --- a/core/hw/pvr/ta_vtx.cpp +++ b/core/hw/pvr/ta_vtx.cpp @@ -159,7 +159,7 @@ public: static Ta_Dma* DYNACALL NullVertexData(Ta_Dma* data,Ta_Dma* data_end) { - printf("TA: Invalid state, ignoring VTX data\n"); + INFO_LOG(PVR, "TA: Invalid state, ignoring VTX data"); return data+SZ32; } @@ -427,7 +427,7 @@ public: //32B case ParamType_Object_List_Set: { - printf("Unsupported list type: ParamType_Object_List_Set\n"); // NAOMI Virtual on Oratorio Tangram + INFO_LOG(PVR, "Unsupported list type: ParamType_Object_List_Set"); // NAOMI Virtual on Oratorio Tangram // *cough* ignore it :p data+=SZ32; From feb1b7935329aba9eff53f9a44123344b47f9b8c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 12:17:51 +0200 Subject: [PATCH 114/158] sh4/dyna: use new logging --- core/hw/sh4/dyna/blockmanager.cpp | 54 ++++++++++++------------- core/hw/sh4/dyna/decoder.cpp | 4 +- core/hw/sh4/dyna/driver.cpp | 26 ++++++------- core/hw/sh4/dyna/regalloc.h | 20 ++++------ core/hw/sh4/dyna/shil.cpp | 38 +++++++++--------- core/hw/sh4/dyna/shil_canonical.h | 4 +- core/hw/sh4/dyna/ssa.cpp | 2 +- core/hw/sh4/dyna/ssa.h | 8 ++-- core/hw/sh4/dyna/ssa_regalloc.h | 65 +++++++++++++++++++++++++++---- 9 files changed, 133 insertions(+), 88 deletions(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 864a14212..008345abe 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -171,7 +171,7 @@ void bm_AddBlock(RuntimeBlockInfo* blk) all_temp_blocks.insert(block); auto iter = blkmap.find((void*)blk->code); if (iter != blkmap.end()) { - printf("DUP: %08X %p %08X %p\n", iter->second->addr, iter->second->code, block->addr, block->code); + INFO_LOG(DYNAREC, "DUP: %08X %p %08X %p", iter->second->addr, iter->second->code, block->addr, block->code); verify(false); } blkmap[(void*)block->code] = block; @@ -188,7 +188,7 @@ void bm_AddBlock(RuntimeBlockInfo* blk) if (op_write_native_code(oprofHandle, fname, (uint64_t)block->code, (void*)block->code, block->host_code_size) != 0) { - printf("op_write_native_code error\n"); + INFO_LOG(DYNAREC, "op_write_native_code error"); } } #endif @@ -268,9 +268,9 @@ u32 FindPath(RuntimeBlockInfo* rbi, u32 sa,s32 mc,u32& plc) else { if (plc!=1) - printf("Chain lost due to %d\n",rbi->BlockType); + INFO_LOG(DYNAREC, "Chain lost due to %d", rbi->BlockType); else - printf("Chain fail due to %d\n",rbi->BlockType); + INFO_LOG(DYNAREC, "Chain fail due to %d", rbi->BlockType); return rbi->guest_cycles; } } @@ -287,7 +287,7 @@ void FindPath(u32 start) if (plen>1) { total_saved+=(plen-1)*2*rbi->runs; - printf("%08X: %d, %d, %.2f, %.2f\n",start,pclc,plen,pclc/(float)plen,plen*2*rbi->runs/1000.f); + INFO_LOG(DYNAREC, "%08X: %d, %d, %.2f, %.2f",start,pclc,plen,pclc/(float)plen,plen*2*rbi->runs/1000.f); } rbi->runs=0; } @@ -347,7 +347,7 @@ void bm_Periodical_1s() for(int i=0;iruns=0; - printf("Total Saved: %.2f || Total Loop Runs: %.2f || Total Runs: %.2f\n",total_saved/1000.f,total_l_runs/1000.f,total_runs/1000.f); + INFO_LOG(DYNAREC, "Total Saved: %.2f || Total Loop Runs: %.2f || Total Runs: %.2f",total_saved/1000.f,total_l_runs/1000.f,total_runs/1000.f); #endif } @@ -477,7 +477,7 @@ void bm_ResetCache() { if (op_unload_native_code(oprofHandle, (uint64_t)del_blocks[i]->code) != 0) { - printf("op_unload_native_code error\n"); + INFO_LOG(DYNAREC, "op_unload_native_code error"); } } } @@ -504,9 +504,9 @@ void bm_Init() #ifdef DYNA_OPROF oprofHandle=op_open_agent(); if (oprofHandle==0) - printf("bm: Failed to open oprofile\n"); + INFO_LOG(DYNAREC, "bm: Failed to open oprofile"); else - printf("bm: Oprofile integration enabled !\n"); + INFO_LOG(DYNAREC, "bm: Oprofile integration enabled !"); #endif bm_Reset(); } @@ -526,7 +526,7 @@ void bm_WriteBlockMap(const string& file) FILE* f=fopen(file.c_str(),"wb"); if (f) { - printf("Writing block map !\n"); + INFO_LOG(DYNAREC, "Writing block map !"); for (auto& it : blkmap) { RuntimeBlockInfoPtr& block = it.second; @@ -535,7 +535,7 @@ void bm_WriteBlockMap(const string& file) fprintf(f,"\top: %zd:%d:%s\n", j, block->oplist[j].guest_offs, block->oplist[j].dissasm().c_str()); } fclose(f); - printf("Finished writing block map\n"); + INFO_LOG(DYNAREC, "Finished writing block map"); } } @@ -585,7 +585,7 @@ void bm_PrintTopBlocks() total_runs+=all_blocks[i]->runs; } - printf("Total lookups: %.0fKRuns, %.0fKLuops, Total cycles: %.0fMhz, Total Hops: %.0fMips, Total Sops: %.0fMips! \n",total_runs/1000,total_lups/1000,total_cycles/1000/1000,total_hops/1000/1000,total_sops/1000/1000); + INFO_LOG(DYNAREC, "Total lookups: %.0fKRuns, %.0fKLuops, Total cycles: %.0fMhz, Total Hops: %.0fMips, Total Sops: %.0fMips!",total_runs/1000,total_lups/1000,total_cycles/1000/1000,total_hops/1000/1000,total_sops/1000/1000); total_hops/=100; total_cycles/=100; total_runs/=100; @@ -593,7 +593,7 @@ void bm_PrintTopBlocks() double sel_hops=0; for (size_t i=0;i<(all_blocks.size()/100);i++) { - printf("Block %08X: %p, r: %d (c: %d, s: %d, h: %d) (r: %.2f%%, c: %.2f%%, h: %.2f%%)\n", + INFO_LOG(DYNAREC, "Block %08X: %p, r: %d (c: %d, s: %d, h: %d) (r: %.2f%%, c: %.2f%%, h: %.2f%%)", all_blocks[i]->addr, all_blocks[i]->code,all_blocks[i]->runs, all_blocks[i]->guest_cycles,all_blocks[i]->guest_opcodes,all_blocks[i]->host_opcodes, @@ -604,12 +604,12 @@ void bm_PrintTopBlocks() sel_hops+=all_blocks[i]->host_opcodes*all_blocks[i]->runs; } - printf(" >-< %.2f%% covered in top 1%% blocks\n",sel_hops/total_hops); + INFO_LOG(DYNAREC, " >-< %.2f%% covered in top 1%% blocks",sel_hops/total_hops); size_t i; for (i=all_blocks.size()/100;sel_hops/total_hops<50;i++) { - printf("Block %08X: %p, r: %d (c: %d, s: %d, h: %d) (r: %.2f%%, c: %.2f%%, h: %.2f%%)\n", + INFO_LOG(DYNAREC, "Block %08X: %p, r: %d (c: %d, s: %d, h: %d) (r: %.2f%%, c: %.2f%%, h: %.2f%%)", all_blocks[i]->addr, all_blocks[i]->code,all_blocks[i]->runs, all_blocks[i]->guest_cycles,all_blocks[i]->guest_opcodes,all_blocks[i]->host_opcodes, @@ -620,31 +620,31 @@ void bm_PrintTopBlocks() sel_hops+=all_blocks[i]->host_opcodes*all_blocks[i]->runs; } - printf(" >-< %.2f%% covered in top %.2f%% blocks\n",sel_hops/total_hops,i*100.0/all_blocks.size()); + INFO_LOG(DYNAREC, " >-< %.2f%% covered in top %.2f%% blocks",sel_hops/total_hops,i*100.0/all_blocks.size()); } void bm_Sort() { - printf("!!!!!!!!!!!!!!!!!!! BLK REPORT !!!!!!!!!!!!!!!!!!!!n"); + INFO_LOG(DYNAREC, "!!!!!!!!!!!!!!!!!!! BLK REPORT !!!!!!!!!!!!!!!!!!!!"); - printf(" ---- Blocks: Sorted based on Runs ! ---- \n"); + INFO_LOG(DYNAREC, " ---- Blocks: Sorted based on Runs ! ---- "); std::sort(all_blocks.begin(),all_blocks.end(),UDgreater); bm_PrintTopBlocks(); - printf("<><><><><><><><><><><><><><><><><><><><><><><><><>\n"); + INFO_LOG(DYNAREC, "<><><><><><><><><><><><><><><><><><><><><><><><><>"); - printf(" ---- Blocks: Sorted based on hops ! ---- \n"); + INFO_LOG(DYNAREC, " ---- Blocks: Sorted based on hops ! ---- "); std::sort(all_blocks.begin(),all_blocks.end(),UDgreater2); bm_PrintTopBlocks(); - printf("<><><><><><><><><><><><><><><><><><><><><><><><><>\n"); + INFO_LOG(DYNAREC, "<><><><><><><><><><><><><><><><><><><><><><><><><>"); - printf(" ---- Blocks: Sorted based on wefs ! ---- \n"); + INFO_LOG(DYNAREC, " ---- Blocks: Sorted based on wefs ! ---- "); std::sort(all_blocks.begin(),all_blocks.end(),UDgreater3); bm_PrintTopBlocks(); - printf("^^^^^^^^^^^^^^^^^^^ END REPORT ^^^^^^^^^^^^^^^^^^^\n"); + INFO_LOG(DYNAREC, "^^^^^^^^^^^^^^^^^^^ END REPORT ^^^^^^^^^^^^^^^^^^^"); for (size_t i=0;i& block_list = blocks_per_page[addr / PAGE_SIZE]; vector list_copy; list_copy.insert(list_copy.begin(), block_list.begin(), block_list.end()); - //if (!list_copy.empty()) - // printf("bm_RamWriteAccess write access to %08x\n", addr); + if (!list_copy.empty()) + DEBUG_LOG(DYNAREC, "bm_RamWriteAccess write access to %08x pc %08x", addr, next_pc); for (auto& block : list_copy) { bm_DiscardBlock(block); @@ -808,7 +808,7 @@ void print_blocks() f=fopen(get_writable_data_path("/blkmap.lst").c_str(),"w"); print_stats=0; - printf("Writing blocks to %p\n",f); + INFO_LOG(DYNAREC, "Writing blocks to %p", f); } for (RuntimeBlockInfo *blk : blkmap) diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index c1763a2cb..c1e6a056e 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -1063,7 +1063,7 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) if (op==0 && state.cpu.is_delayslot) { - printf("Delayslot 0 hack!\n"); + INFO_LOG(DYNAREC, "Delayslot 0 hack!"); } else { @@ -1152,7 +1152,7 @@ _end: case 0x8C0BA506: case 0x8C0BA526: case 0x8C224800: - printf("HASH: %08X reloc %s\n",blk->addr,blk->hash(false,true)); + INFO_LOG(DYNAREC, "HASH: %08X reloc %s",blk->addr,blk->hash(false,true)); break; } #endif diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 936d077cb..5926bb842 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -53,13 +53,13 @@ void emit_WriteCodeCache() wchar path[512]; sprintf(path,"/code_cache_%8p.bin",CodeCache); string pt2=get_writable_data_path(path); - printf("Writing code cache to %s\n",pt2.c_str()); + INFO_LOG(DYNAREC, "Writing code cache to %s",pt2.c_str()); FILE*f=fopen(pt2.c_str(),"wb"); if (f) { fwrite(CodeCache,LastAddr,1,f); fclose(f); - printf("Written!\n"); + INFO_LOG(DYNAREC, "Written!"); } bm_WriteBlockMap(pt2+".map"); @@ -80,7 +80,7 @@ void clear_temp_cache(bool full) void recSh4_ClearCache() { - printf("recSh4:Dynarec Cache clear at %08X free space %d\n", next_pc, emit_FreeSpace()); + INFO_LOG(DYNAREC, "recSh4:Dynarec Cache clear at %08X free space %d", next_pc, emit_FreeSpace()); LastAddr=LastAddr_min; bm_ResetCache(); smc_hotspots.clear(); @@ -92,16 +92,16 @@ void recSh4_Run() sh4_int_bCpuRun=true; sh4_dyna_rcb=(u8*)&Sh4cntx + sizeof(Sh4cntx); - printf("cntx // fpcb offset: %td // pc offset: %td // pc %08X\n",(u8*)&sh4rcb.fpcb - sh4_dyna_rcb, (u8*)&sh4rcb.cntx.pc - sh4_dyna_rcb,sh4rcb.cntx.pc); + INFO_LOG(DYNAREC, "cntx // fpcb offset: %td // pc offset: %td // pc %08X", (u8*)&sh4rcb.fpcb - sh4_dyna_rcb, (u8*)&sh4rcb.cntx.pc - sh4_dyna_rcb, sh4rcb.cntx.pc); if (!settings.dynarec.safemode) - printf("Warning: Dynarec safe mode is off\n"); + NOTICE_LOG(DYNAREC, "Warning: Dynarec safe mode is off"); if (settings.dynarec.unstable_opt) - printf("Warning: Unstable optimizations is on\n"); + NOTICE_LOG(DYNAREC, "Warning: Unstable optimizations is on"); if (settings.dynarec.SmcCheckLevel != FullCheck) - printf("Warning: SMC check mode is %d\n", settings.dynarec.SmcCheckLevel); + NOTICE_LOG(DYNAREC, "Warning: SMC check mode is %d", settings.dynarec.SmcCheckLevel); verify(rcb_noffs(&next_pc)==-184); ngen_mainloop(sh4_dyna_rcb); @@ -304,7 +304,7 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) emit_ptr_limit = (u32 *)(TempCodeCache + TEMP_CODE_SIZE); rbi->temp_block = true; if (rbi->read_only) - printf("WARNING: temp block %x (%x) is protected!\n", rbi->vaddr, rbi->addr); + INFO_LOG(DYNAREC, "WARNING: temp block %x (%x) is protected!", rbi->vaddr, rbi->addr); } bool do_opts = !rbi->temp_block; rbi->staging_runs=do_opts?100:-100; @@ -386,8 +386,8 @@ DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 addr) if (blockcheck_failures > 5) { bool inserted = smc_hotspots.insert(addr).second; - //if (inserted) - // printf("rdv_BlockCheckFail SMC hotspot @ %08x fails %d\n", addr, blockcheck_failures); + if (inserted) + DEBUG_LOG(DYNAREC, "rdv_BlockCheckFail SMC hotspot @ %08x fails %d", addr, blockcheck_failures); } bm_DiscardBlock(block.get()); } @@ -479,7 +479,7 @@ void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc) } else { - printf(" .. null RBI: from %08X to %08X -- unlinked stale block -- code %p next %p\n", rbi->vaddr, next_pc, code, rv); + INFO_LOG(DYNAREC, "null RBI: from %08X to %08X -- unlinked stale block -- code %p next %p", rbi->vaddr, next_pc, code, rv); } return (void*)rv; @@ -513,7 +513,7 @@ void recSh4_Reset(bool Manual) void recSh4_Init() { - printf("recSh4 Init\n"); + INFO_LOG(DYNAREC, "recSh4 Init"); Sh4_int_Init(); bm_Init(); @@ -556,7 +556,7 @@ void recSh4_Init() void recSh4_Term() { - printf("recSh4 Term\n"); + INFO_LOG(DYNAREC, "recSh4 Term"); bm_Term(); Sh4_int_Term(); } diff --git a/core/hw/sh4/dyna/regalloc.h b/core/hw/sh4/dyna/regalloc.h index 3a24c275c..1a54d05e6 100644 --- a/core/hw/sh4/dyna/regalloc.h +++ b/core/hw/sh4/dyna/regalloc.h @@ -728,13 +728,13 @@ struct RegAlloc if (false) { - printf("After reduction ..\n"); + INFO_LOG(DYNAREC, "After reduction .."); for (u32 sid=0;sidcontains(opid)) - printf("\t[%c]span: %d (r%d), [%d:%d],n: %d, p: %d\n",spn->cacc(opid)?'x':' ',sid,all_spans[sid]->regstart,all_spans[sid]->start,all_spans[sid]->end,all_spans[sid]->nacc(opid),all_spans[sid]->pacc(opid)); + INFO_LOG(DYNAREC, "[%c]span: %d (r%d), [%d:%d],n: %d, p: %d",spn->cacc(opid)?'x':' ',sid,all_spans[sid]->regstart,all_spans[sid]->start,all_spans[sid]->end,all_spans[sid]->nacc(opid),all_spans[sid]->pacc(opid)); } } } @@ -839,12 +839,12 @@ struct RegAlloc if ( do_move) { - printf("Span PLD is movable by %d, moved by %d w/ %d!!\n",slack,spn->start-opid_found,opid_plc); + DEBUG_LOG(DYNAREC, "Span PLD is movable by %d, moved by %d w/ %d!!",slack,spn->start-opid_found,opid_plc); spn->start=opid_found; } else { - printf("Span PLD is movable by %d but %d -> not moved :(\n",slack,opid_plc); + DEBUG_LOG(DYNAREC, "Span PLD is movable by %d but %d -> not moved :(",slack,opid_plc); } } } @@ -908,12 +908,12 @@ struct RegAlloc if ( do_move) { - printf("Span WB is movable by %d, moved by %d w/ %d!!\n",slack,opid_found-spn->end,opid_plc); + DEBUG_LOG(DYNAREC, "Span WB is movable by %d, moved by %d w/ %d!!",slack,opid_found-spn->end,opid_plc); spn->end=opid_found; } else { - printf("Span WB is movable by %d but %d -> not moved :(\n",slack,opid_plc); + DEBUG_LOG(DYNAREC, "Span WB is movable by %d but %d -> not moved :(",slack,opid_plc); } } } @@ -926,12 +926,9 @@ struct RegAlloc void SplitSpans(u32 cc,u32 reg_cc_max ,bool fpr,u32 opid) { - bool was_large=false; //this control prints - while (cc>reg_cc_max) { - if (was_large) - printf("Opcode: %d, %d active spans\n",opid,cc); + DEBUG_LOG(DYNAREC, "Opcode: %d, %d active spans", opid, cc); RegSpan* last_pacc=0; RegSpan* last_nacc=0; @@ -948,8 +945,7 @@ struct RegAlloc if (!last_pacc || span->pacc(opid)pacc(opid)) last_pacc=span; } - if (was_large) - printf("\t[%c]span: r%d, [%d:%d],n: %d, p: %d\n",span->cacc(opid)?'x':' ',span->regstart,span->start,span->end,span->nacc(opid),span->pacc(opid)); + DEBUG_LOG(DYNAREC, "[%c]span: r%d, [%d:%d],n: %d, p: %d",span->cacc(opid)?'x':' ',span->regstart,span->start,span->end,span->nacc(opid),span->pacc(opid)); } } diff --git a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp index 47b963b4c..628a453fc 100644 --- a/core/hw/sh4/dyna/shil.cpp +++ b/core/hw/sh4/dyna/shil.cpp @@ -31,7 +31,7 @@ void RegWriteInfo(shil_opcode* ops, shil_param p,size_t ord) { if (RegisterWrite[p._reg+i]>=RegisterRead[p._reg+i] && RegisterWrite[p._reg+i]!=0xFFFFFFFF) //if last read was before last write, and there was a last write { - printf("DEAD OPCODE %d %zd!\n",RegisterWrite[p._reg+i],ord); + DEBUG_LOG(DYNAREC, "DEAD OPCODE %d %zd!\n",RegisterWrite[p._reg+i],ord); ops[RegisterWrite[p._reg+i]].Flow=1; //the last write was unused } RegisterWrite[p._reg+i]=ord; @@ -112,11 +112,11 @@ void sq_pref(RuntimeBlockInfo* blk, int i, Sh4RegType rt, bool mark) { blk->oplist[i].flags =0x1337; sq_pref(blk,i,rt,true); - printf("SQW-WM match %d !\n",data); + DEBUG_LOG(DYNAREC, "SQW-WM match %d !",data); } else if (data) { - printf("SQW-WM FAIL %d !\n",data); + DEBUG_LOG(DYNAREC, "SQW-WM FAIL %d !",data); } } @@ -187,11 +187,11 @@ void rdgrp(RuntimeBlockInfo* blk) blk->oplist[started].Flow=(rdc-1)*2 - (pend_add?1:0); blk->oplist[started+1].rs2._imm=addv; - printf("Read Combination %d %d!\n",rdc,addv); + DEBUG_LOG(DYNAREC, "Read Combination %d %d!",rdc,addv); } else if (rdc!=1) { - printf("Read Combination failed %d %d %d\n",rdc,rdc*stride*4,addv); + DEBUG_LOG(DYNAREC, "Read Combination failed %d %d %d",rdc,rdc*stride*4,addv); } started=-1; } @@ -272,11 +272,11 @@ void wtgrp(RuntimeBlockInfo* blk) blk->oplist[started].Flow=(rdc-1)*2 - (pend_add?1:0); blk->oplist[started+1].rs2._imm=addv; - printf("Write Combination %d %d!\n",rdc,addv); + DEBUG_LOG(DYNAREC, "Write Combination %d %d!",rdc,addv); } else if (rdc!=1) { - printf("Write Combination failed fr%d,%d, %d %d %d\n",regd,mask,rdc,rdc*stride*4,addv); + DEBUG_LOG(DYNAREC, "Write Combination failed fr%d,%d, %d %d %d",regd,mask,rdc,rdc*stride*4,addv); } i=started; started=-1; @@ -406,7 +406,7 @@ void constprop(RuntimeBlockInfo* blk) { //convert em to mov/shl/shr - printf("sh*d -> s*l !\n"); + DEBUG_LOG(DYNAREC, "sh*d -> s*l !"); s32 v=op->rs2._imm; if (v>=0) @@ -460,7 +460,7 @@ void constprop(RuntimeBlockInfo* blk) op->rs1._imm+=op->rs3._imm; op->rs3.type=FMT_NULL; } - printf("%s promotion: %08X\n",shop_readm==op->op?"shop_readm":"shop_writem",op->rs1._imm); + DEBUG_LOG(DYNAREC, "%s promotion: %08X",shop_readm==op->op?"shop_readm":"shop_writem",op->rs1._imm); } else if (op->op==shop_jdyn) { @@ -473,12 +473,12 @@ void constprop(RuntimeBlockInfo* blk) blk->BlockType=blk->BlockType==BET_DynamicJump?BET_StaticJump:BET_StaticCall; blk->oplist.erase(blk->oplist.begin()+i); i--; - printf("SBP: %08X -> %08X!\n",blk->addr,blk->BranchBlock); + DEBUG_LOG(DYNAREC, "SBP: %08X -> %08X!",blk->addr,blk->BranchBlock); continue; } else { - printf("SBP: failed :(\n"); + DEBUG_LOG(DYNAREC, "SBP: failed :("); } } else if (op->op==shop_mov32) @@ -495,7 +495,7 @@ void constprop(RuntimeBlockInfo* blk) (rv[op->rs1._reg]+op->rs2._imm): (rv[op->rs1._reg]-op->rs2._imm); op->rs2.type = FMT_NULL; - printf("%s -> mov32!\n",op->op==shop_add?"shop_add":"shop_sub"); + DEBUG_LOG(DYNAREC, "%s -> mov32!",op->op==shop_add?"shop_add":"shop_sub"); op->op=shop_mov32; } @@ -505,7 +505,7 @@ void constprop(RuntimeBlockInfo* blk) op->rs1=op->rs2; op->rs2.type = FMT_IMM; op->rs2._imm=immy; - printf("%s -> imm prm (%08X)!\n",op->op==shop_add?"shop_add":"shop_sub",immy); + DEBUG_LOG(DYNAREC, "%s -> imm prm (%08X)!",op->op==shop_add?"shop_add":"shop_sub",immy); } } else @@ -533,7 +533,7 @@ void constprop(RuntimeBlockInfo* blk) { isi[op->rd._reg]=true; rv[op->rd._reg]= ReadMem32(op->rs1._imm); - printf("IMM MOVE: %08X -> %08X\n",op->rs1._imm,rv[op->rd._reg]); + DEBUG_LOG(DYNAREC, "IMM MOVE: %08X -> %08X",op->rs1._imm,rv[op->rd._reg]); op->op=shop_mov32; op->rs1._imm=rv[op->rd._reg]; @@ -625,7 +625,7 @@ void read_v4m3z1(RuntimeBlockInfo* blk) if (b) st_sta--; if (a) - printf("NOT B\b"); + DEBUG_LOG(DYNAREC, "NOT B"); u32 start=st_sta; for (int j=0;j<5;j++) @@ -742,7 +742,7 @@ void enswap(RuntimeBlockInfo* blk) } else { - printf("bswap -- wrong regs\n"); + DEBUG_LOG(DYNAREC, "bswap -- wrong regs"); } } @@ -757,7 +757,7 @@ void enswap(RuntimeBlockInfo* blk) } else { - printf("bswap -- wrong regs\n"); + DEBUG_LOG(DYNAREC, "bswap -- wrong regs"); } } @@ -765,11 +765,11 @@ void enswap(RuntimeBlockInfo* blk) { if (op->rd._reg!=r) { - printf("oops?\n"); + DEBUG_LOG(DYNAREC, "oops?"); } else { - printf("SWAPM!\n"); + DEBUG_LOG(DYNAREC, "SWAPM!"); } op->Flow=1; state=0; diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index a91a01384..556e446c1 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -688,7 +688,7 @@ shil_opc(debug_3) shil_canonical ( void,f1,(u32 r1,u32 r2,u32 r3), - printf("%08X, %08X, %08X\n",r1,r2,r3); + INFO_LOG(DYNAREC, "debug_3: %08X, %08X, %08X", r1, r2, r3); ) shil_compile @@ -706,7 +706,7 @@ shil_opc(debug_1) shil_canonical ( void,f1,(u32 r1), - printf("%08X\n",r1); + INFO_LOG(DYNAREC, "debug_1: %08X", r1); ) shil_compile diff --git a/core/hw/sh4/dyna/ssa.cpp b/core/hw/sh4/dyna/ssa.cpp index 3bf32258e..8baee7160 100644 --- a/core/hw/sh4/dyna/ssa.cpp +++ b/core/hw/sh4/dyna/ssa.cpp @@ -355,7 +355,7 @@ bool SSAOptimizer::ExecuteConstOp(shil_opcode* op) break; default: - printf("unhandled constant op %d\n", op->op); + ERROR_LOG(DYNAREC, "unhandled constant op %d", op->op); die("unhandled constant op"); break; } diff --git a/core/hw/sh4/dyna/ssa.h b/core/hw/sh4/dyna/ssa.h index 523230b8d..0e6d69555 100644 --- a/core/hw/sh4/dyna/ssa.h +++ b/core/hw/sh4/dyna/ssa.h @@ -37,7 +37,7 @@ public: { AddVersionPass(); #if DEBUG - printf("BEFORE\n"); + INFO_LOG(DYNAREC, "BEFORE"); PrintBlock(); #endif @@ -55,9 +55,9 @@ public: if (stats.prop_constants > 0 || stats.dead_code_ops > 0 || stats.constant_ops_replaced > 0 || stats.dead_registers > 0 || stats.dyn_to_stat_blocks > 0 || stats.waw_blocks > 0 || stats.combined_shifts > 0) { - //printf("AFTER %08x\n", block->vaddr); + //INFO_LOG(DYNAREC, "AFTER %08x", block->vaddr); //PrintBlock(); - printf("STATS: %08x ops %zd constants %d constops replaced %d dead code %d dead regs %d dyn2stat blks %d waw %d shifts %d\n", block->vaddr, block->oplist.size(), + INFO_LOG(DYNAREC, "STATS: %08x ops %zd constants %d constops replaced %d dead code %d dead regs %d dyn2stat blks %d waw %d shifts %d", block->vaddr, block->oplist.size(), stats.prop_constants, stats.constant_ops_replaced, stats.dead_code_ops, stats.dead_registers, stats.dyn_to_stat_blocks, stats.waw_blocks, stats.combined_shifts); } @@ -101,7 +101,7 @@ private: { for (const shil_opcode& op : block->oplist) { - printf("%08x %s\n", block->vaddr + op.guest_offs, op.dissasm().c_str()); + INFO_LOG(DYNAREC, "%08x %s", block->vaddr + op.guest_offs, op.dissasm().c_str()); } } void AddVersionToOperand(shil_param& param, bool define) diff --git a/core/hw/sh4/dyna/ssa_regalloc.h b/core/hw/sh4/dyna/ssa_regalloc.h index 930446b4b..f5190457f 100644 --- a/core/hw/sh4/dyna/ssa_regalloc.h +++ b/core/hw/sh4/dyna/ssa_regalloc.h @@ -26,7 +26,7 @@ #include "hw/sh4/modules/mmu.h" #include "ssa.h" -#define ssa_printf(...) +#define ssa_printf(...) DEBUG_LOG(DYNAREC, __VA_ARGS__) template class RegAlloc @@ -120,7 +120,7 @@ public: AllocDestReg(op->rd); AllocDestReg(op->rd2); } - ssa_printf("%08x %s gregs %ld fregs %ld\n", block->vaddr + op->guest_offs, op->dissasm().c_str(), host_gregs.size(), host_fregs.size()); + ssa_printf("%08x %s gregs %ld fregs %ld", block->vaddr + op->guest_offs, op->dissasm().c_str(), host_gregs.size(), host_fregs.size()); } void OpEnd(shil_opcode* op) @@ -310,7 +310,7 @@ private: { if (!fast_forwarding) { - ssa_printf("WB %s.%d <- %cx\n", name_reg(reg_num).c_str(), reg_alloc.version, 'a' + reg_alloc.host_reg); + ssa_printf("WB %s.%d <- %cx", name_reg(reg_num).c_str(), reg_alloc.version, 'a' + reg_alloc.host_reg); if (IsFloat(reg_num)) Writeback_FPU(reg_num, (nregf_t)reg_alloc.host_reg); else @@ -384,7 +384,7 @@ private: reg_alloced[param._reg] = { host_reg, param.version[0], false, false }; if (!fast_forwarding) { - ssa_printf("PL %s.%d -> %cx\n", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg); + ssa_printf("PL %s.%d -> %cx", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg); if (IsFloat(param._reg)) Preload_FPU(param._reg, (nregf_t)host_reg); else @@ -450,7 +450,7 @@ private: host_fregs.pop_back(); } reg_alloced[param._reg] = { host_reg, param.version[0], NeedsWriteBack(param._reg, param.version[0]), true }; - ssa_printf(" %s.%d -> %cx %s\n", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg, reg_alloced[param._reg].write_back ? "(wb)" : ""); + ssa_printf(" %s.%d -> %cx %s", name_reg(param._reg).c_str(), param.version[0], 'a' + host_reg, reg_alloced[param._reg].write_back ? "(wb)" : ""); } else { @@ -515,7 +515,7 @@ private: } if (latest_use != -1) { - ssa_printf("RegAlloc: non optimal alloc? reg %s used in op %d\n", name_reg(spilled_reg).c_str(), latest_use); + ssa_printf("RegAlloc: non optimal alloc? reg %s used in op %d", name_reg(spilled_reg).c_str(), latest_use); spills++; // need to write-back if dirty so reload works if (reg_alloced[spilled_reg].dirty) @@ -574,6 +574,57 @@ private: return true; return false; } +#if 0 + // Currently unused. Doesn't seem to help much + bool DefsReg(int from, int to, Sh4RegType reg) + { + for (int i = from; i <= to; i++) + { + shil_opcode* op = &block->oplist[i]; + if (op->rd.is_reg() && reg >= op->rd._reg && reg < (Sh4RegType)(op->rd._reg + op->rd.count())) + return true; + if (op->rd2.is_reg() && reg >= op->rd2._reg && reg < (Sh4RegType)(op->rd2._reg + op->rd2.count())) + return true; + } + return false; + } + + bool EarlyLoad(int cur_op, int early_op) + { + shil_opcode* op = &block->oplist[cur_op]; + shil_opcode* next_op = &block->oplist[early_op]; + if (next_op->op == shop_ifb || next_op->op == shop_sync_sr || next_op->op == shop_sync_fpscr) + return false; + if (next_op->rs1.is_r32() && !DefsReg(cur_op, early_op - 1, next_op->rs1._reg)) + { + if ((next_op->rs1.is_r32i() && !host_gregs.empty()) + || (next_op->rs1.is_r32f() && !host_fregs.empty())) + { + ssa_printf("Early loading (+%d) rs1: %s", early_op - cur_op, name_reg(next_op->rs1._reg).c_str()); + AllocSourceReg(next_op->rs1); + } + } + if (next_op->rs2.is_r32() && !DefsReg(cur_op, early_op - 1, next_op->rs2._reg)) + { + if ((next_op->rs2.is_r32i() && !host_gregs.empty()) + || (next_op->rs2.is_r32f() && !host_fregs.empty())) + { + ssa_printf("Early loading (+%d) rs2: %s", early_op - cur_op, name_reg(next_op->rs1._reg).c_str()); + AllocSourceReg(next_op->rs2); + } + } + if (next_op->rs3.is_r32() && !DefsReg(cur_op, early_op - 1, next_op->rs3._reg)) + { + if ((next_op->rs3.is_r32i() && !host_gregs.empty()) + || (next_op->rs3.is_r32f() && !host_fregs.empty())) + { + ssa_printf("Early loading (+%d) rs3: %s", early_op - cur_op, name_reg(next_op->rs1._reg).c_str()); + AllocSourceReg(next_op->rs3); + } + } + return true; + } +#endif RuntimeBlockInfo* block = NULL; deque host_gregs; @@ -587,5 +638,3 @@ private: public: u32 spills = 0; }; - -#undef printf From 35cd1fcf144c585a09b6b9cf08b81b9f41f218cc Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 15:22:04 +0200 Subject: [PATCH 115/158] sh4: use new logging --- core/hw/sh4/interpr/sh4_fpu.cpp | 6 +- core/hw/sh4/interpr/sh4_interpreter.cpp | 12 ++-- core/hw/sh4/interpr/sh4_opcodes.cpp | 79 ++++++++++----------- core/hw/sh4/modules/bsc.cpp | 3 + core/hw/sh4/modules/ccn.cpp | 10 ++- core/hw/sh4/modules/dmac.cpp | 8 +-- core/hw/sh4/modules/fastmmu.cpp | 6 +- core/hw/sh4/modules/mmu.cpp | 50 +++++++------- core/hw/sh4/modules/tmu.cpp | 10 +-- core/hw/sh4/modules/wince.h | 28 ++++---- core/hw/sh4/sh4_core.h | 8 +-- core/hw/sh4/sh4_core_regs.cpp | 4 +- core/hw/sh4/sh4_mmr.cpp | 91 ++++++++++++------------- core/hw/sh4/sh4_opcode_list.cpp | 2 +- core/log/Log.h | 1 + core/log/LogManager.cpp | 1 + 16 files changed, 157 insertions(+), 162 deletions(-) diff --git a/core/hw/sh4/interpr/sh4_fpu.cpp b/core/hw/sh4/interpr/sh4_fpu.cpp index 71d6abd2c..859c87512 100644 --- a/core/hw/sh4/interpr/sh4_fpu.cpp +++ b/core/hw/sh4/interpr/sh4_fpu.cpp @@ -61,12 +61,12 @@ INLINE void Denorm32(float &value) if ((*v<=0x007FFFFF) && *v>0) { *v=0; - printf("Fixed +denorm\n"); + INFO_LOG(INTERPRETER, "Fixed +denorm"); } else if ((*v<=0x807FFFFF) && *v>0x80000000) { *v=0x80000000; - printf("Fixed -denorm\n"); + INFO_LOG(INTERPRETER, "Fixed -denorm"); } } } @@ -733,6 +733,6 @@ sh4op(i1111_nn01_1111_1101) void iNimp(const char*str) { - printf("Unimplemented sh4 FPU instruction: %s\n", str); + WARN_LOG(INTERPRETER, "Unimplemented sh4 FPU instruction: %s", str); //Sh4_int_Stop(); } diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index a2074443d..3a1c9e3c2 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -102,7 +102,7 @@ void Sh4_int_Step() { if (sh4_int_bCpuRun) { - printf("Sh4 Is running , can't step\n"); + WARN_LOG(INTERPRETER, "Sh4 Is running , can't step"); } else { @@ -116,7 +116,7 @@ void Sh4_int_Skip() { if (sh4_int_bCpuRun) { - printf("Sh4 Is running, can't Skip\n"); + WARN_LOG(INTERPRETER, "Sh4 Is running, can't Skip"); } else { @@ -128,7 +128,7 @@ void Sh4_int_Reset(bool Manual) { if (sh4_int_bCpuRun) { - printf("Sh4 Is running, can't Reset\n"); + WARN_LOG(INTERPRETER, "Sh4 Is running, can't Reset"); } else { @@ -149,7 +149,7 @@ void Sh4_int_Reset(bool Manual) UpdateFPSCR(); //Any more registers have default value ? - printf("Sh4 Reset\n"); + INFO_LOG(INTERPRETER, "Sh4 Reset"); } } @@ -189,7 +189,7 @@ void ExecuteDelayslot_RTE() #if !defined(NO_MMU) } catch (SH4ThrownException& ex) { - msgboxf("Exception in RTE delay slot", MBX_ICONERROR); + ERROR_LOG(INTERPRETER, "Exception in RTE delay slot"); } #endif } @@ -300,7 +300,7 @@ void Sh4_int_Init() void Sh4_int_Term() { Sh4_int_Stop(); - printf("Sh4 Term\n"); + INFO_LOG(INTERPRETER, "Sh4 Term"); } /* diff --git a/core/hw/sh4/interpr/sh4_opcodes.cpp b/core/hw/sh4/interpr/sh4_opcodes.cpp index 7330db791..9ede446f2 100644 --- a/core/hw/sh4/interpr/sh4_opcodes.cpp +++ b/core/hw/sh4/interpr/sh4_opcodes.cpp @@ -61,7 +61,7 @@ void dofoo(sh4_opcode op) // 0xxx void cpu_iNimp(u32 op, const char* info) { - printf("\n\nUnimplemented opcode: %08X next_pc: %08X pr: %08X msg: %s\n", op, next_pc, pr, info); + ERROR_LOG(INTERPRETER, "Unimplemented opcode: %08X next_pc: %08X pr: %08X msg: %s", op, next_pc, pr, info); //next_pc = pr; //debug hackfix: try to recover by returning from call die("iNimp reached\n"); //sh4_cpu.Stop(); @@ -69,9 +69,7 @@ void cpu_iNimp(u32 op, const char* info) void cpu_iWarn(u32 op, const char* info) { - printf("Check opcode : %X : ", op); - printf("%s", info); - printf(" @ %X\n", curr_pc); + INFO_LOG(INTERPRETER, "Check opcode : %X : %s @ %X", op, info, curr_pc); } //this file contains ALL register to register full moves @@ -1586,7 +1584,7 @@ sh4op(i0011_nnnn_mmmm_0100) u32 n=GetN(op); u32 m=GetM(op); - unsigned long tmp0, tmp2; + u32 tmp0, tmp2; unsigned char old_q, tmp1; old_q = sr.Q; @@ -1596,39 +1594,44 @@ sh4op(i0011_nnnn_mmmm_0100) r[n] |= (unsigned long)sr.T; tmp0 = r[n]; // this need only be done once here .. - tmp2 = r[m]; + // Old implementation +// tmp2 = r[m]; +// +// if( 0 == old_q ) +// { +// if( 0 == sr.M ) +// { +// r[n] -= tmp2; +// tmp1 = (r[n]>tmp0); +// sr.Q = (sr.Q==0) ? tmp1 : (u8)(tmp1==0) ; +// } +// else +// { +// r[n] += tmp2; +// tmp1 =(r[n]tmp0); +// sr.Q = (sr.Q==0) ? (u8)(tmp1==0) : tmp1 ; +// } +// } - if( 0 == old_q ) - { - if( 0 == sr.M ) - { - r[n] -= tmp2; - tmp1 = (r[n]>tmp0); - sr.Q = (sr.Q==0) ? tmp1 : (u8)(tmp1==0) ; - } - else - { - r[n] += tmp2; - tmp1 =(r[n]tmp0); - sr.Q = (sr.Q==0) ? (u8)(tmp1==0) : tmp1 ; - } - } - sr.T = (sr.Q==sr.M); + r[n] += (2 * (old_q ^ sr.M) - 1) * r[m]; + sr.Q ^= old_q ^ (sr.M ? r[n] > tmp0 : r[n] >= tmp0); + + sr.T = (sr.Q == sr.M); } //************************ Simple maths ************************ @@ -2136,7 +2139,7 @@ sh4op(i0100_nnnn_0000_1110) sh4op(iNotImplemented) { #ifndef NO_MMU - printf("iNimp %04X\n", op); + INFO_LOG(INTERPRETER, "iNimp %04X", op); SH4ThrownException ex = { next_pc - 2, 0x180, 0x100 }; throw ex; #else diff --git a/core/hw/sh4/modules/bsc.cpp b/core/hw/sh4/modules/bsc.cpp index a0a5889f3..c939c4e5e 100644 --- a/core/hw/sh4/modules/bsc.cpp +++ b/core/hw/sh4/modules/bsc.cpp @@ -160,6 +160,9 @@ void bsc_reset() BSC_PCTRB.full=0x0; //BSC_PDTRB.full; undef BSC_GPIOIC.full=0x0; +#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + BSC_RFCR.full = 17; +#endif } void bsc_term() { diff --git a/core/hw/sh4/modules/ccn.cpp b/core/hw/sh4/modules/ccn.cpp index 459771393..a455e97c1 100644 --- a/core/hw/sh4/modules/ccn.cpp +++ b/core/hw/sh4/modules/ccn.cpp @@ -13,9 +13,6 @@ //Types -#define printf_smc(...) // printf - - u32 CCN_QACR_TR[2]; template @@ -86,15 +83,16 @@ void CCN_CCR_write(u32 addr, u32 value) if (temp.ICI) { - printf_smc("Sh4: i-cache invalidation %08X\n",curr_pc); + DEBUG_LOG(SH4, "Sh4: i-cache invalidation %08X", curr_pc); if (settings.dynarec.SmcCheckLevel == NoCheck) { //TODO: Add skip/check vectors for Shikigami No Shiro II (uses ICI frequently) //which game is 0xAC13DBF8 from ? if (curr_pc != 0xAC13DBF8) { - printf("Sh4: code cache clear (ICI) pc: %08X\n",curr_pc); - sh4_cpu.ResetCache(); + // Disabled as it causes instant crash by invalidating the block the dynarec is currently running + //DEBUG_LOG(DYNAREC, "Sh4: code cache clear (ICI) pc: %08X", curr_pc); + //sh4_cpu.ResetCache(); } } } diff --git a/core/hw/sh4/modules/dmac.cpp b/core/hw/sh4/modules/dmac.cpp index 887aeb4df..57fd87242 100644 --- a/core/hw/sh4/modules/dmac.cpp +++ b/core/hw/sh4/modules/dmac.cpp @@ -36,17 +36,17 @@ void DMAC_Ch2St() if(0x8201 != (dmaor &DMAOR_MASK)) { - printf("\n!\tDMAC: DMAOR has invalid settings (%X) !\n", dmaor); + INFO_LOG(SH4, "DMAC: DMAOR has invalid settings (%X) !", dmaor); return; } if (len & 0x1F) { - printf("\n!\tDMAC: SB_C2DLEN has invalid size (%X) !\n", len); + INFO_LOG(SH4, "DMAC: SB_C2DLEN has invalid size (%X) !", len); return; } - //printf(">>\tDMAC: Ch2 DMA SRC=%X DST=%X LEN=%X\n", src, dst, len ); + DEBUG_LOG(SH4, ">> DMAC: Ch2 DMA SRC=%X DST=%X LEN=%X", src, dst, len); // Direct DList DMA (Ch2) @@ -127,7 +127,7 @@ void DMAC_Ch2St() } else { - printf("\n!\tDMAC: SB_C2DSTAT has invalid address (%X) !\n", dst); + INFO_LOG(SH4, "DMAC: SB_C2DSTAT has invalid address (%X) !", dst); src+=len; } diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index 798d1cd50..c1d685b4e 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -39,10 +39,6 @@ extern u32 sq_remap[64]; #include "wince.h" -#define printf_mmu(...) -//#define printf_mmu printf -#define printf_win32(...) - extern const u32 mmu_mask[4]; const TLB_Entry *lru_entry = NULL; @@ -327,7 +323,7 @@ u32 mmu_data_translation(u32 va, u32& rv) if (va == unresolved_unicode_string) { unresolved_unicode_string = 0; - printf("RESOLVED %s\n", get_unicode_string(va).c_str()); + INFO_LOG(SH4, "RESOLVED %s", get_unicode_string(va).c_str()); } } #endif diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 83981dde3..d3aae1f62 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -21,11 +21,11 @@ bool UTLB_Sync(u32 entry) { u32 vpn_sq = ((UTLB[entry].Address.VPN & 0x7FFFF) >> 10) & 0x3F;//upper bits are always known [0xE0/E1/E2/E3] sq_remap[vpn_sq] = UTLB[entry].Data.PPN << 10; - printf("SQ remap %d : 0x%X to 0x%X\n", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10); + INFO_LOG(SH4, "SQ remap %d : 0x%X to 0x%X", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10); } else { - printf("MEM remap %d : 0x%X to 0x%X\n", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10); + INFO_LOG(SH4, "MEM remap %d : 0x%X to 0x%X", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10); } return true; @@ -33,7 +33,7 @@ bool UTLB_Sync(u32 entry) //Sync memory mapping to MMU, suspend compiled blocks if needed.entry is a ITLB entry # , -1 is for full sync void ITLB_Sync(u32 entry) { - printf("ITLB MEM remap %d : 0x%X to 0x%X\n",entry,ITLB[entry].Address.VPN<<10,ITLB[entry].Data.PPN<<10); + INFO_LOG(SH4, "ITLB MEM remap %d : 0x%X to 0x%X",entry,ITLB[entry].Address.VPN<<10,ITLB[entry].Data.PPN<<10); } void mmu_set_state() @@ -83,8 +83,7 @@ u32 mmu_full_lookup(u32 va, u32& idx, u32& rv); #include "wince.h" #endif -#define printf_mmu(...) -#define printf_win32(...) +#define printf_mmu(...) DEBUG_LOG(SH4, __VA_ARGS__) ReadMem8Func ReadMem8; ReadMem16Func ReadMem16; @@ -134,7 +133,7 @@ u32 ITLB_LRU_USE[64]; //sync mem mapping to mmu , suspend compiled blocks if needed.entry is a UTLB entry # , -1 is for full sync bool UTLB_Sync(u32 entry) { - printf_mmu("UTLB MEM remap %d : 0x%X to 0x%X : %d asid %d size %d\n", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10, UTLB[entry].Data.V, + printf_mmu("UTLB MEM remap %d : 0x%X to 0x%X : %d asid %d size %d", entry, UTLB[entry].Address.VPN << 10, UTLB[entry].Data.PPN << 10, UTLB[entry].Data.V, UTLB[entry].Address.ASID, UTLB[entry].Data.SZ0 + UTLB[entry].Data.SZ1 * 2); if (UTLB[entry].Data.V == 0) return true; @@ -155,7 +154,7 @@ bool UTLB_Sync(u32 entry) //sync mem mapping to mmu , suspend compiled blocks if needed.entry is a ITLB entry # , -1 is for full sync void ITLB_Sync(u32 entry) { - printf_mmu("ITLB MEM remap %d : 0x%X to 0x%X : %d\n", entry, ITLB[entry].Address.VPN << 10, ITLB[entry].Data.PPN << 10, ITLB[entry].Data.V); + printf_mmu("ITLB MEM remap %d : 0x%X to 0x%X : %d", entry, ITLB[entry].Address.VPN << 10, ITLB[entry].Data.PPN << 10, ITLB[entry].Data.V); } #endif @@ -178,13 +177,12 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) { //No error case MMU_ERROR_NONE: - printf("Error : mmu_raise_exception(MMU_ERROR_NONE)\n"); - getc(stdin); + die("Error : mmu_raise_exception(MMU_ERROR_NONE)"); break; //TLB miss case MMU_ERROR_TLB_MISS: - printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled", address); if (am == MMU_TT_DWRITE) //WTLBMISS - Write Data TLB Miss Exception RaiseException(0x60, 0x400); else if (am == MMU_TT_DREAD) //RTLBMISS - Read Data TLB Miss Exception @@ -197,12 +195,12 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) //TLB Multihit case MMU_ERROR_TLB_MHIT: - printf("MMU_ERROR_TLB_MHIT @ 0x%X\n", address); + INFO_LOG(SH4, "MMU_ERROR_TLB_MHIT @ 0x%X", address); break; //Mem is read/write protected (depends on translation type) case MMU_ERROR_PROTECTED: - printf_mmu("MMU_ERROR_PROTECTED 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_PROTECTED 0x%X, handled", address); if (am == MMU_TT_DWRITE) //WRITEPROT - Write Data TLB Protection Violation Exception RaiseException(0xC0, 0x100); else if (am == MMU_TT_DREAD) //READPROT - Data TLB Protection Violation Exception @@ -216,7 +214,7 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) //Mem is write protected , firstwrite case MMU_ERROR_FIRSTWRITE: - printf_mmu("MMU_ERROR_FIRSTWRITE\n"); + printf_mmu("MMU_ERROR_FIRSTWRITE"); verify(am == MMU_TT_DWRITE); //FIRSTWRITE - Initial Page Write Exception RaiseException(0x80, 0x100); @@ -235,17 +233,17 @@ void mmu_raise_exception(u32 mmu_error, u32 address, u32 am) #ifdef TRACE_WINCE_SYSCALLS if (!print_wince_syscall(address)) #endif - printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); + printf_mmu("MMU_ERROR_BADADDR(i) 0x%X", address); RaiseException(0xE0, 0x100); return; } - printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled", address); return; break; //Can't Execute case MMU_ERROR_EXECPROT: - printf("MMU_ERROR_EXECPROT 0x%X\n", address); + INFO_LOG(SH4, "MMU_ERROR_EXECPROT 0x%X", address); //EXECPROT - Instruction TLB Protection Violation Exception RaiseException(0xA0, 0x100); @@ -267,12 +265,12 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type) { //No error case MMU_ERROR_NONE: - printf("Error : mmu_raise_exception(MMU_ERROR_NONE)\n"); + die("Error : mmu_raise_exception(MMU_ERROR_NONE)"); break; //TLB miss case MMU_ERROR_TLB_MISS: - printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_UTLB_MISS 0x%X, handled", address); if (access_type == MMU_TT_DWRITE) //WTLBMISS - Write Data TLB Miss Exception Do_Exception(next_pc, 0x60, 0x400); else if (access_type == MMU_TT_DREAD) //RTLBMISS - Read Data TLB Miss Exception @@ -285,12 +283,12 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type) //TLB Multihit case MMU_ERROR_TLB_MHIT: - printf("MMU_ERROR_TLB_MHIT @ 0x%X\n", address); + INFO_LOG(SH4, "MMU_ERROR_TLB_MHIT @ 0x%X", address); break; //Mem is read/write protected (depends on translation type) case MMU_ERROR_PROTECTED: - printf_mmu("MMU_ERROR_PROTECTED 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_PROTECTED 0x%X, handled", address); if (access_type == MMU_TT_DWRITE) //WRITEPROT - Write Data TLB Protection Violation Exception Do_Exception(next_pc, 0xC0, 0x100); else if (access_type == MMU_TT_DREAD) //READPROT - Data TLB Protection Violation Exception @@ -304,7 +302,7 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type) //Mem is write protected , firstwrite case MMU_ERROR_FIRSTWRITE: - printf_mmu("MMU_ERROR_FIRSTWRITE\n"); + printf_mmu("MMU_ERROR_FIRSTWRITE"); verify(access_type == MMU_TT_DWRITE); //FIRSTWRITE - Initial Page Write Exception Do_Exception(next_pc, 0x80, 0x100); @@ -323,17 +321,17 @@ void DoMMUException(u32 address, u32 mmu_error, u32 access_type) #ifdef TRACE_WINCE_SYSCALLS if (!print_wince_syscall(address)) #endif - printf_mmu("MMU_ERROR_BADADDR(i) 0x%X\n", address); + printf_mmu("MMU_ERROR_BADADDR(i) 0x%X", address); Do_Exception(next_pc, 0xE0, 0x100); return; } - printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled\n", address); + printf_mmu("MMU_ERROR_BADADDR(d) 0x%X, handled", address); return; break; //Can't Execute case MMU_ERROR_EXECPROT: - printf("MMU_ERROR_EXECPROT 0x%X\n", address); + INFO_LOG(SH4, "MMU_ERROR_EXECPROT 0x%X", address); //EXECPROT - Instruction TLB Protection Violation Exception Do_Exception(next_pc, 0xA0, 0x100); @@ -526,7 +524,7 @@ u32 mmu_data_translation(u32 va, u32& rv) if (va == unresolved_unicode_string) { unresolved_unicode_string = 0; - printf("RESOLVED %s\n", get_unicode_string(va).c_str()); + INFO_LOG(SH4, "RESOLVED %s", get_unicode_string(va).c_str()); } } #endif @@ -651,7 +649,7 @@ void mmu_set_state() { if (CCN_MMUCR.AT == 1 && settings.dreamcast.FullMMU) { - printf("Enabling Full MMU support\n"); + NOTICE_LOG(SH4, "Enabling Full MMU support"); IReadMem16 = &mmu_IReadMem16; ReadMem8 = &mmu_ReadMem; ReadMem16 = &mmu_ReadMem; diff --git a/core/hw/sh4/modules/tmu.cpp b/core/hw/sh4/modules/tmu.cpp index 90be18616..b37951c53 100644 --- a/core/hw/sh4/modules/tmu.cpp +++ b/core/hw/sh4/modules/tmu.cpp @@ -176,15 +176,15 @@ void UpdateTMUCounts(u32 reg) break; case 5: //reserved - printf("TMU ch%d - TCR%d mode is reserved (5)",reg,reg); + INFO_LOG(SH4, "TMU ch%d - TCR%d mode is reserved (5)",reg,reg); break; case 6: //RTC - printf("TMU ch%d - TCR%d mode is RTC (6), can't be used on Dreamcast",reg,reg); + INFO_LOG(SH4, "TMU ch%d - TCR%d mode is RTC (6), can't be used on Dreamcast",reg,reg); break; case 7: //external - printf("TMU ch%d - TCR%d mode is External (7), can't be used on Dreamcast",reg,reg); + INFO_LOG(SH4, "TMU ch%d - TCR%d mode is External (7), can't be used on Dreamcast",reg,reg); break; } tmu_shift[reg]+=2; @@ -203,13 +203,13 @@ void TMU_TCR_write(u32 addr, u32 data) //Chan 2 not used functions u32 TMU_TCPR2_read(u32 addr) { - EMUERROR("Read from TMU_TCPR2 - this register should be not used on Dreamcast according to docs"); + INFO_LOG(SH4, "Read from TMU_TCPR2 - this register should be not used on Dreamcast according to docs"); return 0; } void TMU_TCPR2_write(u32 addr, u32 data) { - EMUERROR2("Write to TMU_TCPR2 - this register should be not used on Dreamcast according to docs, data=%d",data); + INFO_LOG(SH4, "Write to TMU_TCPR2 - this register should be not used on Dreamcast according to docs, data=%d", data); } void write_TMU_TSTR(u32 addr, u32 data) diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index eb724c64c..d967df55b 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -312,33 +312,31 @@ static bool print_wince_syscall(u32 address) sprintf(method_buf, "[%d]", meth_id); method = method_buf; } - printf("WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); + INFO_LOG(SH4, "WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); if (address == 0xfffffd51) // SetLastError - printf(" dwErrCode = %x\n", r[4]); + INFO_LOG(SH4, " dwErrCode = %x", r[4]); else if (address == 0xffffd5ef) // CreateFile - printf(" lpFileName = %s\n", get_unicode_string(r[4]).c_str()); + INFO_LOG(SH4, " lpFileName = %s", get_unicode_string(r[4]).c_str()); else if (address == 0xfffffd97) // CreateProc - printf(" imageName = %s, commandLine = %s\n", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); + INFO_LOG(SH4, " imageName = %s, commandLine = %s", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); else if (!strcmp("DebugNotify", method)) - printf(" %x, %x\n", r[4], r[5]); + INFO_LOG(SH4, " %x, %x\n", r[4], r[5]); else if (address == 0xffffd5d3) // RegOpenKeyExW - printf(" hKey = %x, lpSubKey = %s\n", r[4], get_unicode_string(r[5]).c_str()); + INFO_LOG(SH4, " hKey = %x, lpSubKey = %s", r[4], get_unicode_string(r[5]).c_str()); else if (!strcmp("LoadLibraryW", method)) - printf(" fileName = %s\n", get_unicode_string(r[4]).c_str()); + INFO_LOG(SH4, " fileName = %s", get_unicode_string(r[4]).c_str()); else if (!strcmp("GetProcAddressW", method)) - printf(" hModule = %x, procName = %s\n", r[4], get_unicode_string(r[5]).c_str()); + INFO_LOG(SH4, " hModule = %x, procName = %s", r[4], get_unicode_string(r[5]).c_str()); else if (!strcmp("NKvDbgPrintfW", method)) - printf(" fmt = %s\n", get_unicode_string(r[4]).c_str()); + INFO_LOG(SH4, " fmt = %s", get_unicode_string(r[4]).c_str()); else if (!strcmp("OutputDebugStringW", method)) - printf(" str = %s\n", get_unicode_string(r[4]).c_str()); + INFO_LOG(SH4, " str = %s", get_unicode_string(r[4]).c_str()); else if (!strcmp("RegisterAFSName", method)) - printf(" name = %s\n", get_unicode_string(r[4]).c_str()); + INFO_LOG(SH4, " name = %s", get_unicode_string(r[4]).c_str()); else if (!strcmp("CreateAPISet", method)) - printf(" name = %s\n", get_ascii_string(r[4]).c_str()); + INFO_LOG(SH4, " name = %s", get_ascii_string(r[4]).c_str()); else if (!strcmp("Register", method) && !strcmp("APISET", api)) - printf(" p = %x, id = %x\n", r[4], r[5]); - else - printf("\n"); + INFO_LOG(SH4, " p = %x, id = %x", r[4], r[5]); // might be useful to detect errors? (hidden & dangerous) //if (!strcmp("GetProcName", method)) // os_DebugBreak(); diff --git a/core/hw/sh4/sh4_core.h b/core/hw/sh4/sh4_core.h index 15ec9fb02..42eb69dac 100644 --- a/core/hw/sh4/sh4_core.h +++ b/core/hw/sh4/sh4_core.h @@ -43,7 +43,7 @@ static INLINE f64 GetDR(u32 n) { #ifdef TRACE if (n>7) - printf("DR_r INDEX OVERRUN %d >7",n); + INFO_LOG(SH4, "DR_r INDEX OVERRUN %d >7", n); #endif DoubleReg t; @@ -57,7 +57,7 @@ static INLINE f64 GetXD(u32 n) { #ifdef TRACE if (n>7) - printf("XD_r INDEX OVERRUN %d >7",n); + INFO_LOG(SH4, "XD_r INDEX OVERRUN %d >7", n); #endif DoubleReg t; @@ -71,7 +71,7 @@ static INLINE void SetDR(u32 n,f64 val) { #ifdef TRACE if (n>7) - printf("DR_w INDEX OVERRUN %d >7",n); + INFO_LOG(SH4, "DR_w INDEX OVERRUN %d >7", n); #endif DoubleReg t; t.dbl=val; @@ -85,7 +85,7 @@ static INLINE void SetXD(u32 n,f64 val) { #ifdef TRACE if (n>7) - printf("XD_w INDEX OVERRUN %d >7",n); + INFO_LOG(SH4, "XD_w INDEX OVERRUN %d >7", n); #endif DoubleReg t; diff --git a/core/hw/sh4/sh4_core_regs.cpp b/core/hw/sh4/sh4_core_regs.cpp index 5bbfff5c7..c20c7ddef 100644 --- a/core/hw/sh4/sh4_core_regs.cpp +++ b/core/hw/sh4/sh4_core_regs.cpp @@ -45,7 +45,7 @@ bool UpdateSR() { if (sr.RB) { - printf("UpdateSR MD=0;RB=1 , this must not happen\n"); + WARN_LOG(SH4, "UpdateSR MD=0;RB=1 , this must not happen"); sr.RB =0;//error - must always be 0 } if (old_sr.RB) @@ -240,7 +240,7 @@ u32* Sh4_int_GetRegisterPtr(Sh4RegType reg) return &Sh4cntx.jdyn; default: - EMUERROR2("Unknown register ID %d",reg); + ERROR_LOG(SH4, "Unknown register ID %d", reg); die("Invalid reg"); return 0; break; diff --git a/core/hw/sh4/sh4_mmr.cpp b/core/hw/sh4/sh4_mmr.cpp index da28ec5d4..ca6ca8830 100644 --- a/core/hw/sh4/sh4_mmr.cpp +++ b/core/hw/sh4/sh4_mmr.cpp @@ -28,17 +28,17 @@ Array SCIF(10,true); //SCIF : 10 registers u32 sh4io_read_noacc(u32 addr) { - EMUERROR("sh4io: Invalid read access @@ %08X",addr); + INFO_LOG(SH4, "sh4io: Invalid read access @@ %08X", addr); return 0; } void sh4io_write_noacc(u32 addr, u32 data) { - EMUERROR("sh4io: Invalid write access @@ %08X %08X",addr,data); + INFO_LOG(SH4, "sh4io: Invalid write access @@ %08X %08X", addr, data); //verify(false); } void sh4io_write_const(u32 addr, u32 data) { - EMUERROR("sh4io: Const write ignored @@ %08X <- %08X",addr,data); + INFO_LOG(SH4, "sh4io: Const write ignored @@ %08X <- %08X", addr, data); } void sh4_rio_reg(Array& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf, RegWriteAddrFP* wf) @@ -77,7 +77,7 @@ u32 sh4_rio_read(Array& sb_regs, u32 addr) #ifdef TRACE if (offset & 3/*(size-1)*/) //4 is min align size { - EMUERROR("Unaligned System Bus register read"); + INFO_LOG(SH4, "Unaligned System Bus register read"); } #endif @@ -105,7 +105,7 @@ u32 sh4_rio_read(Array& sb_regs, u32 addr) else { if (!(sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR("ERROR [wrong size read on register]"); + INFO_LOG(SH4, "ERROR [wrong size read on register]"); } #endif // if ((sb_regs[offset].flags& REG_NOT_IMPL)) @@ -120,7 +120,7 @@ void sh4_rio_write(Array& sb_regs, u32 addr, u32 data) #ifdef TRACE if (offset & 3/*(size-1)*/) //4 is min align size { - EMUERROR("Unaligned System bus register write"); + INFO_LOG(SH4, "Unaligned System bus register write"); } #endif offset>>=2; @@ -165,10 +165,10 @@ offset>>=2; else { if (!(sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR4("ERROR: Wrong size write on register - offset=%x, data=%x, size=%d",offset,data,sz); + INFO_LOG(SH4, "ERROR: Wrong size write on register - offset=%x, data=%x, size=%d",offset,data,sz); } if ((sb_regs[offset].flags& REG_NOT_IMPL)) - EMUERROR3("Write to System Control Regs, not implemented - addr=%x, data=%x",addr,data); + INFO_LOG(SH4, "Write to System Control Regs, not implemented - addr=%x, data=%x",addr,data); #endif } @@ -190,7 +190,7 @@ T DYNACALL ReadMem_P4(u32 addr) case 0xE1: case 0xE2: case 0xE3: - EMUERROR("Unhandled p4 read [Store queue] 0x%x",addr); + INFO_LOG(SH4, "Unhandled p4 read [Store queue] 0x%x", addr); return 0; break; @@ -249,15 +249,14 @@ T DYNACALL ReadMem_P4(u32 addr) break; case 0xFF: - EMUERROR("Unhandled p4 read [area7] 0x%x",addr); + INFO_LOG(SH4, "Unhandled p4 read [area7] 0x%x", addr); break; default: - EMUERROR("Unhandled p4 read [Reserved] 0x%x",addr); + INFO_LOG(SH4, "Unhandled p4 read [Reserved] 0x%x", addr); break; } - EMUERROR("Read from P4 not implemented - addr=%x",addr); return 0; } @@ -279,7 +278,7 @@ void DYNACALL WriteMem_P4(u32 addr,T data) case 0xE1: case 0xE2: case 0xE3: - EMUERROR("Unhandled p4 Write [Store queue] 0x%x",addr); + INFO_LOG(SH4, "Unhandled p4 Write [Store queue] 0x%x", addr); break; case 0xF0: @@ -337,7 +336,7 @@ void DYNACALL WriteMem_P4(u32 addr,T data) if (addr&0x80) { #ifdef NO_MMU - EMUERROR("Unhandled p4 Write [Unified TLB address array, Associative Write] 0x%x = %x",addr,data); + INFO_LOG(SH4, "Unhandled p4 Write [Unified TLB address array, Associative Write] 0x%x = %x", addr, data); #endif CCN_PTEH_type t; @@ -398,15 +397,13 @@ void DYNACALL WriteMem_P4(u32 addr,T data) } case 0xFF: - EMUERROR("Unhandled p4 Write [area7] 0x%x = %x",addr,data); + INFO_LOG(SH4, "Unhandled p4 Write [area7] 0x%x = %x", addr, data); break; default: - EMUERROR("Unhandled p4 Write [Reserved] 0x%x",addr); + INFO_LOG(SH4, "Unhandled p4 Write [Reserved] 0x%x", addr); break; } - - EMUERROR3("Write to P4 not implemented - addr=%x, data=%x",addr,data); } @@ -420,7 +417,7 @@ T DYNACALL ReadMem_sq(u32 addr) { if (sz!=4) { - EMUERROR("Store Queue Error - only 4 byte read are possible[x%X]",addr); + INFO_LOG(SH4, "Store Queue Error - only 4 byte read are possible[x%X]", addr); return 0xDE; } @@ -435,7 +432,7 @@ template void DYNACALL WriteMem_sq(u32 addr,T data) { if (sz!=4) - EMUERROR("Store Queue Error - only 4 byte writes are possible[x%X=0x%X]",addr,data); + INFO_LOG(SH4, "Store Queue Error - only 4 byte writes are possible[x%X=0x%X]", addr, data); u32 united_offset=addr & 0x3C; @@ -481,7 +478,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -492,7 +489,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -504,16 +501,16 @@ T DYNACALL ReadMem_area7(u32 addr) else if ((addr>=BSC_SDMR2_addr) && (addr<= 0x1F90FFFF)) { //dram settings 2 / write only - EMUERROR("Read from write-only registers [dram settings 2]"); + INFO_LOG(SH4, "Read from write-only registers [dram settings 2]"); } else if ((addr>=BSC_SDMR3_addr) && (addr<= 0x1F94FFFF)) { //dram settings 3 / write only - EMUERROR("Read from write-only registers [dram settings 3]"); + INFO_LOG(SH4, "Read from write-only registers [dram settings 3]"); } else { - EMUERROR2("Out of range on register index . %x",addr); + INFO_LOG(SH4, "Out of range on register index . %x", addr); } break; @@ -526,7 +523,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -537,7 +534,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -548,7 +545,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -559,7 +556,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -570,7 +567,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -581,7 +578,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -592,7 +589,7 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -613,7 +610,7 @@ T DYNACALL ReadMem_area7(u32 addr) } - //EMUERROR2("Unknown Read from Area7 - addr=%x",addr); + //INFO_LOG(SH4, "Unknown Read from Area7 - addr=%x", addr); return 0; } @@ -647,7 +644,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -659,7 +656,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -681,7 +678,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -695,7 +692,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -707,7 +704,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -719,7 +716,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -731,7 +728,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -743,7 +740,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -755,7 +752,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -767,7 +764,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) } else { - EMUERROR2("Out of range on register index %x",addr); + INFO_LOG(SH4, "Out of range on register index %x", addr); } break; @@ -808,13 +805,13 @@ T DYNACALL ReadMem_area7_OCR_T(u32 addr) return (T)*(u32*)&OnChipRAM[addr&OnChipRAM_MASK]; else { - EMUERROR("ReadMem_area7_OCR_T: template SZ is wrong = %d",sz); + ERROR_LOG(SH4, "ReadMem_area7_OCR_T: template SZ is wrong = %d", sz); return 0xDE; } } else { - EMUERROR("On Chip Ram Read, but OCR is disabled"); + INFO_LOG(SH4, "On Chip Ram Read, but OCR is disabled"); return 0xDE; } } @@ -833,12 +830,12 @@ void DYNACALL WriteMem_area7_OCR_T(u32 addr,T data) *(u32*)&OnChipRAM[addr&OnChipRAM_MASK]=data; else { - EMUERROR("WriteMem_area7_OCR_T: template SZ is wrong = %d",sz); + ERROR_LOG(SH4, "WriteMem_area7_OCR_T: template SZ is wrong = %d", sz); } } else { - EMUERROR("On Chip Ram Write, but OCR is disabled"); + INFO_LOG(SH4, "On Chip Ram Write, but OCR is disabled"); } } diff --git a/core/hw/sh4/sh4_opcode_list.cpp b/core/hw/sh4/sh4_opcode_list.cpp index 7ae9b64ef..916853894 100644 --- a/core/hw/sh4/sh4_opcode_list.cpp +++ b/core/hw/sh4/sh4_opcode_list.cpp @@ -608,7 +608,7 @@ std::string disassemble_op(const char* tx1, u32 pc, u16 opcode) ti++; } - printf("Sh4Dissasm : Tag not known\"%s\"\n",tx1); + DEBUG_LOG(SH4, "Sh4Dissasm : Tag not known\"%s\"", tx1); buf[0] = '<'; buf[1] = *tx1; diff --git a/core/log/Log.h b/core/log/Log.h index dc35e1615..f046c1f93 100644 --- a/core/log/Log.h +++ b/core/log/Log.h @@ -28,6 +28,7 @@ enum LOG_TYPE PVR, RENDERER, SAVESTATE, + SH4, NUMBER_OF_LOGS // Must be last }; diff --git a/core/log/LogManager.cpp b/core/log/LogManager.cpp index bf2ccefc2..051f9eee7 100644 --- a/core/log/LogManager.cpp +++ b/core/log/LogManager.cpp @@ -111,6 +111,7 @@ LogManager::LogManager() m_log[LogTypes::PVR] = {"PVR", "PowerVR GPU"}; m_log[LogTypes::RENDERER] = {"RENDERER", "OpenGL Renderer"}; m_log[LogTypes::SAVESTATE] = {"SAVESTATE", "Save States"}; + m_log[LogTypes::SH4] = {"SH4", "SH4 Modules"}; RegisterListener(LogListener::FILE_LISTENER, new FileLogListener("flycast.log")); RegisterListener(LogListener::CONSOLE_LISTENER, new ConsoleListener()); From b388fa43779399568376fae257c7c904f86e13ef Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 16:10:28 +0200 Subject: [PATCH 116/158] imgread: use new logging --- core/hw/gdrom/gdromv3.cpp | 78 +++++++++++++++++---------------------- core/imgread/cdi.cpp | 7 ++-- core/imgread/chd.cpp | 12 +++--- core/imgread/common.cpp | 26 ++++++------- core/imgread/common.h | 6 +-- core/imgread/cue.cpp | 14 +++---- core/imgread/gdi.cpp | 4 +- core/nullDC.cpp | 8 ++-- 8 files changed, 72 insertions(+), 83 deletions(-) diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index d41036597..cf675d953 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -307,7 +307,7 @@ u32 GetFAD(u8* data, bool msf) { if(msf) { - printf("GDROM: MSF FORMAT"); + INFO_LOG(GDROM, "GDROM: MSF FORMAT"); return ((data[0]*60*75) + (data[1]*75) + (data[2])); } else @@ -399,8 +399,7 @@ void gd_process_ata_cmd() break; case ATA_EXEC_DIAG: - printf_ata("ATA_EXEC_DIAG"); - printf("ATA_EXEC_DIAG -- not implemented"); + printf_ata("ATA_EXEC_DIAG -- not implemented"); break; case ATA_SPI_PACKET: @@ -475,7 +474,7 @@ void gd_process_spi_cmd() if (readcmd.head ==1 && readcmd.subh==1 && readcmd.data==1 && readcmd.expdtype==3 && readcmd.other==0) sector_type=2340; else if(readcmd.head ||readcmd.subh || readcmd.other || (!readcmd.data)) // assert - printf("GDROM: *FIXME* ADD MORE CD READ SETTINGS %d %d %d %d 0x%01X",readcmd.head,readcmd.subh,readcmd.other,readcmd.data,readcmd.expdtype); + WARN_LOG(GDROM, "GDROM: *FIXME* ADD MORE CD READ SETTINGS %d %d %d %d 0x%01X",readcmd.head,readcmd.subh,readcmd.other,readcmd.data,readcmd.expdtype); u32 start_sector = GetFAD(&readcmd.b[2],readcmd.prmtype); u32 sector_count = (readcmd.b[8]<<16) | (readcmd.b[9]<<8) | (readcmd.b[10]); @@ -554,8 +553,7 @@ void gd_process_spi_cmd() break; case SPI_CD_READ2: - printf_spicmd("SPI_CD_READ2"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_READ2"); + printf_spicmd("SPI_CD_READ2 Unhandled"); gd_set_state(gds_procpacketdone); break; @@ -564,7 +562,6 @@ void gd_process_spi_cmd() case SPI_REQ_STAT: { printf_spicmd("SPI_REQ_STAT"); - //printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_STAT\n"); u8 stat[10]; //0 0 0 0 0 STATUS @@ -596,7 +593,6 @@ void gd_process_spi_cmd() case SPI_REQ_ERROR: printf_spicmd("SPI_REQ_ERROR"); - //printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n"); u8 resp[10]; resp[0]=0xF0; @@ -624,9 +620,7 @@ void gd_process_spi_cmd() break; case SPI_CD_OPEN: - printf_spicmd("SPI_CD_OPEN"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_OPEN\n"); - + printf_spicmd("SPI_CD_OPEN Unhandled"); gd_set_state(gds_procpacketdone); break; @@ -634,14 +628,13 @@ void gd_process_spi_cmd() case SPI_CD_PLAY: { printf_spicmd("SPI_CD_PLAY"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_PLAY\n"); //cdda.CurrAddr.FAD=60000; cdda.playing=true; SecNumber.Status=GD_PLAY; u32 param_type=packet_cmd.data_8[1]&0x7; - printf("param_type=%d\n",param_type); + DEBUG_LOG(GDROM, "param_type=%d", param_type); if (param_type==1) { cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],0); @@ -663,11 +656,11 @@ void gd_process_spi_cmd() die("SPI_CD_SEEK : not known parameter.."); } cdda.repeats=packet_cmd.data_8[6]&0xF; - printf("cdda.StartAddr=%d\n",cdda.StartAddr.FAD); - printf("cdda.EndAddr=%d\n",cdda.EndAddr.FAD); - printf("cdda.repeats=%d\n",cdda.repeats); - printf("cdda.playing=%d\n",cdda.playing); - printf("cdda.CurrAddr=%d\n",cdda.CurrAddr.FAD); + DEBUG_LOG(GDROM, "cdda.StartAddr=%d",cdda.StartAddr.FAD); + DEBUG_LOG(GDROM, "cdda.EndAddr=%d",cdda.EndAddr.FAD); + DEBUG_LOG(GDROM, "cdda.repeats=%d",cdda.repeats); + DEBUG_LOG(GDROM, "cdda.playing=%d",cdda.playing); + DEBUG_LOG(GDROM, "cdda.CurrAddr=%d",cdda.CurrAddr.FAD); gd_set_state(gds_procpacketdone); } @@ -676,13 +669,12 @@ void gd_process_spi_cmd() case SPI_CD_SEEK: { printf_spicmd("SPI_CD_SEEK"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_SEEK\n"); SecNumber.Status=GD_PAUSE; cdda.playing=false; u32 param_type=packet_cmd.data_8[1]&0x7; - printf("param_type=%d\n",param_type); + DEBUG_LOG(GDROM, "param_type=%d",param_type); if (param_type==1) { cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],0); @@ -709,11 +701,11 @@ void gd_process_spi_cmd() die("SPI_CD_SEEK : not known parameter.."); } - printf("cdda.StartAddr=%d\n",cdda.StartAddr.FAD); - printf("cdda.EndAddr=%d\n",cdda.EndAddr.FAD); - printf("cdda.repeats=%d\n",cdda.repeats); - printf("cdda.playing=%d\n",cdda.playing); - printf("cdda.CurrAddr=%d\n",cdda.CurrAddr.FAD); + DEBUG_LOG(GDROM, "cdda.StartAddr=%d",cdda.StartAddr.FAD); + DEBUG_LOG(GDROM, "cdda.EndAddr=%d",cdda.EndAddr.FAD); + DEBUG_LOG(GDROM, "cdda.repeats=%d",cdda.repeats); + DEBUG_LOG(GDROM, "cdda.playing=%d",cdda.playing); + DEBUG_LOG(GDROM, "cdda.CurrAddr=%d",cdda.CurrAddr.FAD); gd_set_state(gds_procpacketdone); @@ -721,8 +713,7 @@ void gd_process_spi_cmd() break; case SPI_CD_SCAN: - printf_spicmd("SPI_CD_SCAN"); - printf("GDROM: Unhandled Sega SPI frame: SPI_CD_SCAN\n"); + printf_spicmd("SPI_CD_SCAN Unhandled"); gd_set_state(gds_procpacketdone); @@ -731,7 +722,6 @@ void gd_process_spi_cmd() case SPI_GET_SCD: { printf_spicmd("SPI_GET_SCD"); - //printf("\nGDROM:\tUnhandled Sega SPI frame: SPI_GET_SCD\n"); u32 format; format=packet_cmd.data_8[1]&0xF; @@ -810,7 +800,7 @@ void gd_process_spi_cmd() break; default: - printf("GDROM: Unhandled Sega SPI frame: %X\n", packet_cmd.data_8[0]); + INFO_LOG(GDROM, "GDROM: Unhandled Sega SPI frame: %X", packet_cmd.data_8[0]); gd_set_state(gds_procpacketdone); break; @@ -841,13 +831,13 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz) case GD_DATA: if(2!=sz) - printf("GDROM: Bad size on DATA REG Read\n"); + INFO_LOG(GDROM, "GDROM: Bad size on DATA REG Read"); //if (gd_state == gds_pio_send_data) //{ if (pio_buff.index == pio_buff.size) { - printf("GDROM: Illegal Read From DATA (underflow)\n"); + INFO_LOG(GDROM, "GDROM: Illegal Read From DATA (underflow)"); } else { @@ -887,7 +877,7 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz) return SecNumber.full; default: - printf("GDROM: Unhandled read from address %X, Size:%X",Addr,sz); + INFO_LOG(GDROM, "GDROM: Unhandled read from address %X, Size:%X",Addr,sz); return 0; } } @@ -910,7 +900,7 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) case GD_DATA: { if(2!=sz) - printf("GDROM: Bad size on DATA REG\n"); + INFO_LOG(GDROM, "GDROM: Bad size on DATA REG"); if (gd_state == gds_waitpacket) { packet_cmd.data_16[packet_cmd.index]=(u16)data; @@ -930,18 +920,18 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) } else { - printf("GDROM: Illegal Write to DATA\n"); + INFO_LOG(GDROM, "GDROM: Illegal Write to DATA"); } return; } case GD_DEVCTRL_Write: - printf("GDROM: Write GD_DEVCTRL (Not implemented on Dreamcast)\n"); + INFO_LOG(GDROM, "GDROM: Write GD_DEVCTRL (Not implemented on Dreamcast)"); break; case GD_DRVSEL: if (data != 0) { - printf("GDROM: Write to GD_DRVSEL, !=0. Value is: %02X\n", data); + INFO_LOG(GDROM, "GDROM: Write to GD_DRVSEL, !=0. Value is: %02X", data); } DriveSel = data; break; @@ -956,12 +946,12 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) break; case GD_SECTCNT_Write: - printf("GDROM: Write to SecCount = %X", data); + DEBUG_LOG(GDROM, "GDROM: Write to SecCount = %X", data); SecCount.full =(u8) data; break; case GD_SECTNUM: - printf("GDROM: Write to SecNum; not possible = %X", data); + INFO_LOG(GDROM, "GDROM: Write to SecNum; not possible = %X", data); break; case GD_COMMAND_Write: @@ -974,7 +964,7 @@ void WriteMem_gdrom(u32 Addr, u32 data, u32 sz) break; default: - printf("\nGDROM:\tUnhandled write to address %X <= %X, Size:%X",Addr,data,sz); + INFO_LOG(GDROM, "GDROM: Unhandled write to address %X <= %X, Size:%X",Addr,data,sz); break; } } @@ -1025,13 +1015,13 @@ int GDRomschd(int i, int c, int j) // do we need to do this for GDROM DMA? if(0x8201 != (dmaor &DMAOR_MASK)) { - printf("\n!\tGDROM: DMAOR has invalid settings (%X) !\n", dmaor); + INFO_LOG(GDROM, "GDROM: DMAOR has invalid settings (%X)", dmaor); //return; } if(len == 0) { - printf("\n!\tGDROM: Len: %X, Abnormal Termination !\n", len); + INFO_LOG(GDROM, "GDROM: Len: %X, Abnormal Termination !", len); } u32 len_backup = len; @@ -1061,7 +1051,7 @@ int GDRomschd(int i, int c, int j) } else { - msgboxf("GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)", MBX_ICONERROR, SB_GDDIR); + WARN_LOG(GDROM, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)", src); } //SB_GDLEN = 0x00000000; //13/5/2k7 -> according to docs these regs are not updated by hardware @@ -1096,7 +1086,7 @@ void GDROM_DmaStart(u32 addr, u32 data) { if (SB_GDEN==0) { - printf("Invalid GD-DMA start, SB_GDEN=0.Ingoring it.\n"); + INFO_LOG(GDROM, "Invalid GD-DMA start, SB_GDEN=0.Ingoring it."); return; } SB_GDST|=data&1; @@ -1105,7 +1095,7 @@ void GDROM_DmaStart(u32 addr, u32 data) { SB_GDSTARD=SB_GDSTAR; SB_GDLEND=0; - //printf("GDROM-DMA start addr %08X len %d\n", SB_GDSTAR, SB_GDLEN); + DEBUG_LOG(GDROM, "GDROM-DMA start addr %08X len %d", SB_GDSTAR, SB_GDLEN); int ticks = getGDROMTicks(); if (ticks < 448) // FIXME #define diff --git a/core/imgread/cdi.cpp b/core/imgread/cdi.cpp index a3d375905..a8840c033 100644 --- a/core/imgread/cdi.cpp +++ b/core/imgread/cdi.cpp @@ -43,7 +43,7 @@ Disc* cdi_parse(const wchar* file) //printf("\nSession %d has %d track(s)\n",image.global_current_session,image.tracks); if (image.tracks == 0) - printf("Open session\n"); + INFO_LOG(GDROM, "Open session"); else { // Clear cuesheet @@ -111,14 +111,13 @@ Disc* cdi_parse(const wchar* file) // if (track.pregap_length != 150) printf("Warning! This track seems to have a non-standard pregap...\n"); if (track.length < 0) - printf( "Negative track size found\n" - "You must extract image with /pregap option"); + WARN_LOG(GDROM, "Negative track size found. You must extract image with /pregap option"); //if (!opts.showinfo) { if (track.total_length < track.length + track.pregap_length) { - printf("\nThis track seems truncated. Skipping...\n"); + WARN_LOG(GDROM, "This track seems truncated. Skipping..."); core_fseek(fsource, track.position, SEEK_SET); core_fseek(fsource, track.total_length, SEEK_CUR); track.position = core_ftell(fsource); diff --git a/core/imgread/chd.cpp b/core/imgread/chd.cpp index 57e6081fb..b51567eb8 100644 --- a/core/imgread/chd.cpp +++ b/core/imgread/chd.cpp @@ -85,11 +85,11 @@ bool CHDDisc::TryOpen(const wchar* file) if (err!=CHDERR_NONE) { - printf("chd: chd_open failed for file %s: %d\n", file, err); + INFO_LOG(GDROM, "chd: chd_open failed for file %s: %d", file, err); return false; } - printf("chd: parsing file %s\n",file); + INFO_LOG(GDROM, "chd: parsing file %s", file); const chd_header* head = chd_get_header(chd); @@ -101,7 +101,7 @@ bool CHDDisc::TryOpen(const wchar* file) if (hunkbytes%(2352+96)!=0) { - printf("chd: hunkbytes is invalid, %d\n",hunkbytes); + INFO_LOG(GDROM, "chd: hunkbytes is invalid, %d\n",hunkbytes); return false; } @@ -149,10 +149,10 @@ bool CHDDisc::TryOpen(const wchar* file) if (tkid!=(tracks.size()+1) || (strcmp(type,"MODE1_RAW")!=0 && strcmp(type,"AUDIO")!=0 && strcmp(type,"MODE1")!=0) || strcmp(subtype,"NONE")!=0 || pregap!=0 || postgap!=0) { - printf("chd: track type %s is not supported\n",type); + INFO_LOG(GDROM, "chd: track type %s is not supported", type); return false; } - printf("%s\n",temp); + DEBUG_LOG(GDROM, "%s", temp); Track t; t.StartFAD = total_frames; total_frames += frames; @@ -173,7 +173,7 @@ bool CHDDisc::TryOpen(const wchar* file) if (total_frames!=549300 || tracks.size()<3) { - printf("WARNING: chd: Total frames is wrong: %u frames in %u tracks\n",total_frames,tracks.size()); + WARN_LOG(GDROM, "WARNING: chd: Total frames is wrong: %u frames in %zu tracks", total_frames, tracks.size()); #ifndef NOT_REICAST msgboxf("This is an improper dump!",MBX_ICONEXCLAMATION); #endif diff --git a/core/imgread/common.cpp b/core/imgread/common.cpp index 0697517fd..9f802e6d1 100644 --- a/core/imgread/common.cpp +++ b/core/imgread/common.cpp @@ -38,7 +38,7 @@ void PatchRegion_0(u8* sector,int size) if (size!=2048) { - printf("PatchRegion_0 -> sector size %d , skipping patch\n",size); + INFO_LOG(GDROM, "PatchRegion_0 -> sector size %d , skipping patch", size); } //patch meta info @@ -58,7 +58,7 @@ void PatchRegion_6(u8* sector,int size) if (size!=2048) { - printf("PatchRegion_6 -> sector size %d , skipping patch\n",size); + INFO_LOG(GDROM, "PatchRegion_6 -> sector size %d , skipping patch", size); } //patch area symbols @@ -124,7 +124,7 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector) } break; default : - printf("Sector conversion from %d to %d not supported \n", from , to); + INFO_LOG(GDROM, "Sector conversion from %d to %d not supported \n", from , to); break; } @@ -139,9 +139,9 @@ Disc* OpenDisc(const wchar* fn) rv = drivers[i](fn); if (rv && cdi_parse == drivers[i]) { - const wchar warn_str[] = "Warning: CDI Image Loaded!\n Many CDI images are known to be defective, GDI, CUE or CHD format is preferred. " + const wchar warn_str[] = "Warning: CDI Image Loaded! Many CDI images are known to be defective, GDI, CUE or CHD format is preferred. " "Please only file bug reports when using images known to be good (GDI, CUE or CHD)."; - printf("%s\n", warn_str); + WARN_LOG(GDROM, "%s", warn_str); break; } @@ -159,7 +159,7 @@ bool InitDrive_(wchar* fn) if (disc!=0) { - printf("gdrom: Opened image \"%s\"\n",fn); + INFO_LOG(GDROM, "gdrom: Opened image \"%s\"", fn); NullDriveDiscType=Busy; #ifndef NOT_REICAST libCore_gdrom_disc_change(); @@ -169,7 +169,7 @@ bool InitDrive_(wchar* fn) } else { - printf("gdrom: Failed to open image \"%s\"\n",fn); + INFO_LOG(GDROM, "gdrom: Failed to open image \"%s\"", fn); NullDriveDiscType=NoDisk; //no disc :) } return false; @@ -180,7 +180,7 @@ bool InitDrive(u32 fileflags) { if (settings.imgread.LoadDefaultImage) { - printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage); + INFO_LOG(GDROM, "Loading default image \"%s\"", settings.imgread.DefaultImage); if (!InitDrive_(settings.imgread.DefaultImage)) { msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR,settings.imgread.DefaultImage); @@ -244,7 +244,7 @@ bool DiscSwap(u32 fileflags) sns_key = 0x6; if (settings.imgread.LoadDefaultImage) { - printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage); + INFO_LOG(GDROM, "Loading default image \"%s\"", settings.imgread.DefaultImage); if (!InitDrive_(settings.imgread.DefaultImage)) { msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR,settings.imgread.DefaultImage); @@ -409,19 +409,19 @@ void GetDriveSessionInfo(u8* to,u8 session) void printtoc(TocInfo* toc,SessionInfo* ses) { - printf("Sessions %d\n",ses->SessionCount); + INFO_LOG(GDROM, "Sessions %d", ses->SessionCount); for (u32 i=0;iSessionCount;i++) { - printf("Session %d: FAD %d,First Track %d\n",i+1,ses->SessionFAD[i],ses->SessionStart[i]); + INFO_LOG(GDROM, "Session %d: FAD %d,First Track %d", i + 1, ses->SessionFAD[i], ses->SessionStart[i]); for (u32 t=toc->FistTrack-1;t<=toc->LastTrack;t++) { if (toc->tracks[t].Session==i+1) { - printf("\tTrack %d : FAD %d CTRL %d ADR %d\n",t,toc->tracks[t].FAD,toc->tracks[t].Control,toc->tracks[t].Addr); + INFO_LOG(GDROM, " Track %d : FAD %d CTRL %d ADR %d", t, toc->tracks[t].FAD, toc->tracks[t].Control, toc->tracks[t].Addr); } } } - printf("Session END: FAD END %d\n",ses->SessionsEndFAD); + INFO_LOG(GDROM, "Session END: FAD END %d", ses->SessionsEndFAD); } DiscType GuessDiscType(bool m1, bool m2, bool da) diff --git a/core/imgread/common.h b/core/imgread/common.h index b793ec96c..194bbf11c 100644 --- a/core/imgread/common.h +++ b/core/imgread/common.h @@ -190,7 +190,7 @@ struct Disc } else if (fmt==2352 && (secfmt==SECFMT_2048_MODE1 || secfmt==SECFMT_2048_MODE2_FORM1 )) { - printf("GDR:fmt=2352;secfmt=2048\n"); + INFO_LOG(GDROM, "GDR:fmt=2352;secfmt=2048"); memcpy(dst,temp,2048); } else if (fmt==2048 && secfmt==SECFMT_2448_MODE2) @@ -200,13 +200,13 @@ struct Disc } else { - printf("ERROR: UNABLE TO CONVERT SECTOR. THIS IS FATAL. Format: %d Sector format: %d\n", fmt, secfmt); + WARN_LOG(GDROM, "ERROR: UNABLE TO CONVERT SECTOR. THIS IS FATAL. Format: %d Sector format: %d", fmt, secfmt); //verify(false); } } else { - printf("Sector Read miss FAD: %d\n", FAD); + INFO_LOG(GDROM, "Sector Read miss FAD: %d", FAD); } dst+=fmt; FAD++; diff --git a/core/imgread/cue.cpp b/core/imgread/cue.cpp index 0b89f7d96..3f8a88d14 100644 --- a/core/imgread/cue.cpp +++ b/core/imgread/cue.cpp @@ -60,7 +60,7 @@ Disc* cue_parse(const wchar* file) if (cue_len >= sizeof(cue_data)) { - printf("CUE parse error: CUE file too big\n"); + WARN_LOG(GDROM, "CUE parse error: CUE file too big"); core_fclose(fsource); return NULL; } @@ -90,10 +90,10 @@ Disc* cue_parse(const wchar* file) current_fad = 45000 + 150; } else if (token != "SINGLE-DENSITY") - printf("CUE parse error: unrecognized REM token %s. Expected SINGLE-DENSITY or HIGH-DENSITY\n", token.c_str()); + WARN_LOG(GDROM, "CUE parse error: unrecognized REM token %s. Expected SINGLE-DENSITY or HIGH-DENSITY", token.c_str()); cuesheet >> token; if (token != "AREA") - printf("CUE parse error: unrecognized REM token %s. Expected AREA\n", token.c_str()); + WARN_LOG(GDROM, "CUE parse error: unrecognized REM token %s. Expected AREA", token.c_str()); } else if (token == "FILE") { @@ -121,7 +121,7 @@ Disc* cue_parse(const wchar* file) } cuesheet >> token; // BINARY if (token != "BINARY") - printf("CUE parse error: unrecognized FILE token %s. Expected BINARY\n", token.c_str()); + WARN_LOG(GDROM, "CUE parse error: unrecognized FILE token %s. Expected BINARY", token.c_str()); } else if (token == "TRACK") { @@ -142,17 +142,17 @@ Disc* cue_parse(const wchar* file) core_file* track_file = core_fopen(path.c_str()); if (track_file == NULL) { - printf("CUE file: cannot open track %d: %s\n", track_number, path.c_str()); + WARN_LOG(GDROM, "CUE file: cannot open track %d: %s", track_number, path.c_str()); return NULL; } u32 sector_size = getSectorSize(track_type); if (sector_size == 0) { - printf("CUE file: track %d has unknown sector type: %s\n", track_number, track_type.c_str()); + WARN_LOG(GDROM, "CUE file: track %d has unknown sector type: %s", track_number, track_type.c_str()); return NULL; } if (core_fsize(track_file) % sector_size != 0) - printf("Warning: Size of track %s is not multiple of sector size %d\n", track_filename.c_str(), sector_size); + WARN_LOG(GDROM, "Warning: Size of track %s is not multiple of sector size %d", track_filename.c_str(), sector_size); current_fad = t.StartFAD + (u32)core_fsize(track_file) / sector_size; //printf("file[%lu] \"%s\": StartFAD:%d, sector_size:%d file_size:%d\n", disc->tracks.size(), diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index 92c896519..40c73feb6 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -87,7 +87,7 @@ Disc* load_gdi(const char* file) istringstream gdi(gdi_data); gdi >> iso_tc; - printf("\nGDI : %d tracks\n",iso_tc); + INFO_LOG(GDROM, "GDI : %d tracks", iso_tc); string basepath = OS_dirname(file); @@ -129,7 +129,7 @@ Disc* load_gdi(const char* file) gdi >> OFFSET; - printf("file[%d] \"%s\": FAD:%d, CTRL:%d, SSIZE:%d, OFFSET:%d\n", TRACK, track_filename.c_str(), FADS, CTRL, SSIZE, OFFSET); + DEBUG_LOG(GDROM, "file[%d] \"%s\": FAD:%d, CTRL:%d, SSIZE:%d, OFFSET:%d", TRACK, track_filename.c_str(), FADS, CTRL, SSIZE, OFFSET); Track t; t.ADDR=0; diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 6814addaf..51ea0b5f6 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -143,7 +143,7 @@ void LoadSpecialSettings() if (reios_windows_ce) { - INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game\n"); + INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); settings.rend.ExtraDepthScale = 0.1; extra_depth_game = true; settings.dreamcast.FullMMU = true; @@ -188,14 +188,14 @@ void LoadSpecialSettings() // Ducati World (PAL) || !strncmp("T-8121D-50", reios_product_number, 10)) { - INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", reios_product_number); settings.dynarec.safemode = 1; safemode_game = true; } // NHL 2K2 if (!strncmp("MK-51182", reios_product_number, 8)) { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); settings.rend.ExtraDepthScale = 10000; extra_depth_game = true; } @@ -218,7 +218,7 @@ void LoadSpecialSettings() // Marionette Company 2 || !strncmp("T5203M", reios_product_number, 6)) { - INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s\n", reios_product_number); + INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", reios_product_number); settings.dynarec.disable_vmem32 = true; disable_vmem32_game = true; } From ad4218d617483f41474571f389fbb8015c510e92 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 17:17:08 +0200 Subject: [PATCH 117/158] audio: use new logging other logging changes --- core/hw/holly/sb_mem.cpp | 1 - core/hw/naomi/naomi_cart.cpp | 2 -- core/input/gamepad_device.cpp | 2 +- core/input/mapping.cpp | 2 +- core/linux-dist/main.cpp | 2 +- core/linux-dist/x11.cpp | 2 +- core/oslib/audiobackend_alsa.cpp | 28 ++++++++--------- core/oslib/audiobackend_directsound.cpp | 2 +- core/oslib/audiobackend_omx.cpp | 40 ++++++++++++------------- core/oslib/audiobackend_oss.cpp | 10 +++---- core/oslib/audiobackend_pulseaudio.cpp | 12 ++++---- core/oslib/audiostream.cpp | 26 ++++++++-------- core/rend/TexCache.cpp | 10 +++---- core/rend/gui.cpp | 6 ++-- core/windows/win_vmem.cpp | 4 +-- core/windows/winmain.cpp | 6 ++-- core/windows/xinput_gamepad.h | 8 ++--- 17 files changed, 80 insertions(+), 83 deletions(-) diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index dae8bae8e..77728c116 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -60,7 +60,6 @@ bool LoadRomFiles(const string& root) } else { - ERROR_LOG(FLASHROM, "Unable to find flash/nvmem in %s. Exiting...", root.c_str()); msgboxf("Unable to find flash/nvmem in \n%s\nExiting...", MBX_ICONERROR, root.c_str()); return false; } diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 5234c420f..a28796e4e 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -166,14 +166,12 @@ static bool naomi_cart_LoadZip(char *filename) #if DC_PLATFORM == DC_PLATFORM_NAOMI if (game->cart_type == AW) { - ERROR_LOG(NAOMI, "Atomiswave cartridges are not supported by NAOMI"); msgboxf("Atomiswave cartridges are not supported by NAOMI", 0); return false; } #else if (game->cart_type != AW) { - ERROR_LOG(NAOMI, "NAOMI cartridges are not supported by Atomiswave"); msgboxf("NAOMI cartridges are not supported by Atomiswave", 0); return false; } diff --git a/core/input/gamepad_device.cpp b/core/input/gamepad_device.cpp index 632eccd30..317ddc4e9 100644 --- a/core/input/gamepad_device.cpp +++ b/core/input/gamepad_device.cpp @@ -385,7 +385,7 @@ void replay_input() { fclose(replay_file); replay_file = NULL; - printf("Input replay terminated\n"); + NOTICE_LOG(INPUT, "Input replay terminated"); do_screenshot = true; break; } diff --git a/core/input/mapping.cpp b/core/input/mapping.cpp index 898e10727..85c2f3cf1 100644 --- a/core/input/mapping.cpp +++ b/core/input/mapping.cpp @@ -183,7 +183,7 @@ bool InputMapping::save(const char *name) FILE *fp = fopen(path.c_str(), "w"); if (fp == NULL) { - printf("Cannot save controller mappings into %s\n", path.c_str()); + WARN_LOG(INPUT, "Cannot save controller mappings into %s", path.c_str()); return false; } ConfigFile mf; diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 633fd1f54..94565b026 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -414,7 +414,7 @@ void os_DebugBreak() #if !defined(TARGET_EMSCRIPTEN) raise(SIGTRAP); #else - printf("DEBUGBREAK!\n"); + ERROR_LOG(COMMON, "DEBUGBREAK!"); exit(-1); #endif } diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp index 27fc430fd..5865dd007 100644 --- a/core/linux-dist/x11.cpp +++ b/core/linux-dist/x11.cpp @@ -429,7 +429,7 @@ void x11_window_create() if (!glXQueryVersion(x11Display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { - printf("Invalid GLX version"); + ERROR_LOG(RENDERER, "Invalid GLX version"); exit(1); } diff --git a/core/oslib/audiobackend_alsa.cpp b/core/oslib/audiobackend_alsa.cpp index 2ac08fe46..c4edb095f 100644 --- a/core/oslib/audiobackend_alsa.cpp +++ b/core/oslib/audiobackend_alsa.cpp @@ -20,7 +20,7 @@ static void alsa_init() int rc = -1; if (device == "" || device == "auto") { - printf("ALSA: trying to determine audio device\n"); + INFO_LOG(AUDIO, "ALSA: trying to determine audio device"); // trying default device device = "default"; @@ -54,7 +54,7 @@ static void alsa_init() } if (rc < 0) - printf("ALSA: unable to automatically determine audio device.\n"); + INFO_LOG(AUDIO, "ALSA: unable to automatically determine audio device."); } else { rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); @@ -62,11 +62,11 @@ static void alsa_init() if (rc < 0) { - fprintf(stderr, "ALSA: unable to open PCM device %s: %s\n", device.c_str(), snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: unable to open PCM device %s: %s", device.c_str(), snd_strerror(rc)); return; } - printf("ALSA: Successfully initialized \"%s\"\n", device.c_str()); + INFO_LOG(AUDIO, "ALSA: Successfully initialized \"%s\"", device.c_str()); /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); @@ -75,7 +75,7 @@ static void alsa_init() rc=snd_pcm_hw_params_any(handle, params); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_any %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_any %s", snd_strerror(rc)); return; } @@ -85,7 +85,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_access %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_access %s", snd_strerror(rc)); return; } @@ -93,7 +93,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_format %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_format %s", snd_strerror(rc)); return; } @@ -101,7 +101,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_channels(handle, params, 2); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_channels %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_channels %s", snd_strerror(rc)); return; } @@ -110,7 +110,7 @@ static void alsa_init() rc=snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_rate_near %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_rate_near %s", snd_strerror(rc)); return; } @@ -119,31 +119,31 @@ static void alsa_init() rc=snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, &dir); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s", snd_strerror(rc)); return; } else { - printf("ALSA: period size set to %ld\n", period_size); + INFO_LOG(AUDIO, "ALSA: period size set to %ld", period_size); } buffer_size = (44100 * 100 /* settings.omx.Audio_Latency */ / 1000 / period_size + 1) * period_size; rc=snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size); if (rc < 0) { - fprintf(stderr, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s", snd_strerror(rc)); return; } else { - printf("ALSA: buffer size set to %ld\n", buffer_size); + INFO_LOG(AUDIO, "ALSA: buffer size set to %ld", buffer_size); } /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { - fprintf(stderr, "ALSA: Unable to set hw parameters: %s\n", snd_strerror(rc)); + WARN_LOG(AUDIO, "ALSA: Unable to set hw parameters: %s", snd_strerror(rc)); return; } } diff --git a/core/oslib/audiobackend_directsound.cpp b/core/oslib/audiobackend_directsound.cpp index f004bdfd2..dbd8b3f11 100644 --- a/core/oslib/audiobackend_directsound.cpp +++ b/core/oslib/audiobackend_directsound.cpp @@ -167,7 +167,7 @@ static u32 directsound_push(void* frame, u32 samples, bool wait) */ while (!directsound_push_nw(frame, samples) && wait) - 0 && printf("FAILED waiting on audio FAILED %d\n", directsound_getusedSamples()); + 0 && INFO_LOG(AUDIO, "FAILED waiting on audio FAILED %d", directsound_getusedSamples()); return 1; } diff --git a/core/oslib/audiobackend_omx.cpp b/core/oslib/audiobackend_omx.cpp index c8c8a6536..4a98e66cb 100644 --- a/core/oslib/audiobackend_omx.cpp +++ b/core/oslib/audiobackend_omx.cpp @@ -70,7 +70,7 @@ static u32 omx_get_latency() OMX_ERRORTYPE error = OMX_GetConfig(omx_handle, OMX_IndexConfigAudioRenderingLatency, ¶m); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to get OMX configuration (OMX_IndexConfigAudioRenderingLatency). Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to get OMX configuration (OMX_IndexConfigAudioRenderingLatency). Error 0x%X", error); return param.nU32 * 1000 / OUTPUT_FREQ; } @@ -82,7 +82,7 @@ static void omx_init() error = OMX_Init(); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: OMX_Init() failed. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: OMX_Init() failed. Error 0x%X", error); return; } @@ -99,7 +99,7 @@ static void omx_init() error = OMX_GetHandle(&omx_handle, (OMX_STRING)"OMX.broadcom.audio_render", NULL, &callbacks); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: OMX_GetHandle() failed. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: OMX_GetHandle() failed. Error 0x%X", error); return; } @@ -114,7 +114,7 @@ static void omx_init() error = OMX_SetParameter(omx_handle, OMX_IndexParamPortDefinition, ¶m); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to set OMX_IndexParamPortDefinition. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to set OMX_IndexParamPortDefinition. Error 0x%X", error); OMX_AUDIO_PARAM_PCMMODETYPE pcm; memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); @@ -133,12 +133,12 @@ static void omx_init() error = OMX_SetParameter(omx_handle, OMX_IndexParamAudioPcm, &pcm); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to set OMX_IndexParamAudioPcm. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to set OMX_IndexParamAudioPcm. Error 0x%X", error); // Disable all ports error = OMX_SendCommand(omx_handle, OMX_CommandPortDisable, PORT_INDEX, NULL); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to do OMX_CommandPortDisable. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortDisable. Error 0x%X", error); OMX_PORT_PARAM_TYPE param2; memset(¶m2, 0, sizeof(OMX_PORT_PARAM_TYPE)); @@ -147,7 +147,7 @@ static void omx_init() error = OMX_GetParameter(omx_handle, OMX_IndexParamOtherInit, ¶m2); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: failed to get OMX_IndexParamOtherInit. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to get OMX_IndexParamOtherInit. Error 0x%X", error); } else { @@ -156,7 +156,7 @@ static void omx_init() u32 port = param2.nStartPortNumber + i; error = OMX_SendCommand(omx_handle, OMX_CommandPortDisable, port, NULL); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to do OMX_CommandPortDisable on port %u. Error 0x%X\n", port, error); + WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortDisable on port %u. Error 0x%X", port, error); } } @@ -164,7 +164,7 @@ static void omx_init() error = OMX_SendCommand(omx_handle, OMX_CommandStateSet, OMX_StateIdle, NULL); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: failed to set OMX_CommandStateSet. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to set OMX_CommandStateSet. Error 0x%X", error); return; } omx_wait_for_state(OMX_StateIdle); @@ -174,17 +174,17 @@ static void omx_init() error = OMX_GetState(omx_handle, &state); if(error != OMX_ErrorNone || !(state == OMX_StateIdle || state == OMX_StateExecuting || state == OMX_StatePause)) { - fprintf(stderr, "OMX: state is incorrect. State 0x%X; Error 0x%X\n", state, error); + WARN_LOG(AUDIO, "OMX: state is incorrect. State 0x%X; Error 0x%X", state, error); return; } // Create audio buffers - fprintf(stderr, "OMX: creating %u buffers\n", buffer_count); + INFO_LOG(AUDIO, "OMX: creating %u buffers", buffer_count); // Enable port error = OMX_SendCommand(omx_handle, OMX_CommandPortEnable, PORT_INDEX, NULL); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to do OMX_CommandPortEnable. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortEnable. Error 0x%X", error); // Free audio buffers if they're allocated if(audio_buffers != NULL) @@ -197,7 +197,7 @@ static void omx_init() error = OMX_AllocateBuffer(omx_handle, &audio_buffers[i], PORT_INDEX, NULL, buffer_size); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: failed to allocate buffer[%u]. Error 0x%X\n", i, error); + WARN_LOG(AUDIO, "OMX: failed to allocate buffer[%u]. Error 0x%X", i, error); return; } } @@ -206,7 +206,7 @@ static void omx_init() error = OMX_SendCommand(omx_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: failed to do OMX_CommandStateSet. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandStateSet. Error 0x%X", error); return; } omx_wait_for_state(OMX_StateExecuting); @@ -220,7 +220,7 @@ static void omx_init() error = OMX_EmptyThisBuffer(omx_handle, audio_buffers[i]); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to empty buffer[%u]. Error 0x%X\n", i, error); + WARN_LOG(AUDIO, "OMX: failed to empty buffer[%u]. Error 0x%X", i, error); } char* output_device = "local"; @@ -236,14 +236,14 @@ static void omx_init() error = OMX_SetConfig(omx_handle, OMX_IndexConfigBrcmAudioDestination, &ar_dest); if(error != OMX_ErrorNone) { - fprintf(stderr, "OMX: failed to set OMX configuration (OMX_IndexConfigBrcmAudioDestination). Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: failed to set OMX configuration (OMX_IndexConfigBrcmAudioDestination). Error 0x%X", error); return; } audio_buffer_idx = 0; buffer_length = 0; - fprintf(stderr, "OMX: audio output to '%s'\n", ar_dest.sName); + INFO_LOG(AUDIO, "OMX: audio output to '%s'", ar_dest.sName); } static u32 omx_push(void* frame, u32 samples, bool wait) @@ -265,7 +265,7 @@ static u32 omx_push(void* frame, u32 samples, bool wait) } else if(latency == 0) { - fprintf(stderr, "OMX: underrun occurred\n"); + WARN_LOG(AUDIO, "OMX: underrun occurred"); } memcpy(audio_buffers[audio_buffer_idx]->pBuffer + buffer_length, frame, copy_size); @@ -279,7 +279,7 @@ static u32 omx_push(void* frame, u32 samples, bool wait) OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_handle, audio_buffers[audio_buffer_idx]); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: failed to empty buffer[%u]. Error 0x%X\n", audio_buffer_idx, error); + WARN_LOG(AUDIO, "OMX: failed to empty buffer[%u]. Error 0x%X", audio_buffer_idx, error); audio_buffer_idx = (audio_buffer_idx + 1) % buffer_count; buffer_length = 0; @@ -299,7 +299,7 @@ static void omx_term() error = OMX_Deinit(); if(error != OMX_ErrorNone) - fprintf(stderr, "OMX: OMX_Deinit() failed. Error 0x%X\n", error); + WARN_LOG(AUDIO, "OMX: OMX_Deinit() failed. Error 0x%X", error); if(audio_buffers != NULL) { diff --git a/core/oslib/audiobackend_oss.cpp b/core/oslib/audiobackend_oss.cpp index b3a48cbd6..d099c9861 100644 --- a/core/oslib/audiobackend_oss.cpp +++ b/core/oslib/audiobackend_oss.cpp @@ -12,21 +12,21 @@ static void oss_init() oss_audio_fd = open("/dev/dsp", O_WRONLY); if (oss_audio_fd < 0) { - printf("Couldn't open /dev/dsp.\n"); + WARN_LOG(AUDIO, "Couldn't open /dev/dsp."); } else { - printf("sound enabled, dsp opened for write\n"); + INFO_LOG(AUDIO, "sound enabled, dsp opened for write"); int tmp=44100; int err_ret; err_ret=ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&tmp); - printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp); + INFO_LOG(AUDIO, "set Frequency to %i, return %i (rate=%i)", 44100, err_ret, tmp); int channels=2; err_ret=ioctl(oss_audio_fd, SNDCTL_DSP_CHANNELS, &channels); - printf("set dsp to stereo (%i => %i)\n", channels, err_ret); + INFO_LOG(AUDIO, "set dsp to stereo (%i => %i)", channels, err_ret); int format=AFMT_S16_LE; err_ret=ioctl(oss_audio_fd, SNDCTL_DSP_SETFMT, &format); - printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed", AFMT_S16_LE, format, err_ret); + INFO_LOG(AUDIO, "set dsp to %s audio (%i/%i => %i)", "16bits signed", AFMT_S16_LE, format, err_ret); } } diff --git a/core/oslib/audiobackend_pulseaudio.cpp b/core/oslib/audiobackend_pulseaudio.cpp index b651b4003..16c0295c2 100644 --- a/core/oslib/audiobackend_pulseaudio.cpp +++ b/core/oslib/audiobackend_pulseaudio.cpp @@ -15,15 +15,15 @@ static void pulseaudio_init() ss.rate = 44100; /* Create a new playback stream */ pulse_stream = pa_simple_new(NULL, "reicast", PA_STREAM_PLAYBACK, NULL, "reicast", &ss, NULL, NULL, NULL); - if (!pulse_stream) { - fprintf(stderr, "PulseAudio: pa_simple_new() failed!\n"); - } + if (!pulse_stream) { + WARN_LOG(AUDIO, "PulseAudio: pa_simple_new() failed!"); + } } static u32 pulseaudio_push(void* frame, u32 samples, bool wait) { if (pa_simple_write(pulse_stream, frame, (size_t) samples*4, NULL) < 0) { - fprintf(stderr, "PulseAudio: pa_simple_write() failed!\n"); + WARN_LOG(AUDIO, stderr, "PulseAudio: pa_simple_write() failed!"); } } @@ -32,8 +32,8 @@ static void pulseaudio_term() { { // Make sure that every single sample was played if (pa_simple_drain(pulse_stream, NULL) < 0) { - fprintf(stderr, "PulseAudio: pa_simple_drain() failed!\n"); - } + WARN_LOG(AUDIO, stderr, "PulseAudio: pa_simple_drain() failed!"); + } pa_simple_free(pulse_stream); } } diff --git a/core/oslib/audiostream.cpp b/core/oslib/audiostream.cpp index d0f1ebeb4..899030bbe 100644 --- a/core/oslib/audiostream.cpp +++ b/core/oslib/audiostream.cpp @@ -44,12 +44,12 @@ bool RegisterAudioBackend(audiobackend_t *backend) // Check if backend is valid if (backend == NULL) { - printf("ERROR: Tried to register invalid audio backend (NULL pointer).\n"); + WARN_LOG(AUDIO, "ERROR: Tried to register invalid audio backend (NULL pointer)."); return false; } if (backend->slug == "auto" || backend->slug == "none") { - printf("ERROR: Tried to register invalid audio backend (slug \"%s\" is a reserved keyword).\n", backend->slug.c_str()); + WARN_LOG(AUDIO, "ERROR: Tried to register invalid audio backend (slug \"%s\" is a reserved keyword).", backend->slug.c_str()); return false; } @@ -63,7 +63,7 @@ bool RegisterAudioBackend(audiobackend_t *backend) // Check for integer overflows if (audiobackends_num_max == UINT_MAX) { - printf("ERROR: Registering audio backend \"%s\" (%s) failed. Cannot register more than %u backends\n", backend->slug.c_str(), backend->name.c_str(), audiobackends_num_max); + WARN_LOG(AUDIO, "ERROR: Registering audio backend \"%s\" (%s) failed. Cannot register more than %u backends", backend->slug.c_str(), backend->name.c_str(), audiobackends_num_max); return false; } audiobackends_num_max++; @@ -71,7 +71,7 @@ bool RegisterAudioBackend(audiobackend_t *backend) // Make sure that allocation worked if (new_ptr == NULL) { - printf("ERROR: Registering audio backend \"%s\" (%s) failed. Cannot allocate additional memory.\n", backend->slug.c_str(), backend->name.c_str()); + WARN_LOG(AUDIO, "ERROR: Registering audio backend \"%s\" (%s) failed. Cannot allocate additional memory.", backend->slug.c_str(), backend->name.c_str()); return false; } audiobackends = new_ptr; @@ -86,7 +86,7 @@ audiobackend_t* GetAudioBackend(std::string slug) { if (slug == "none") { - printf("WARNING: Audio backend set to \"none\"!\n"); + INFO_LOG(AUDIO, "WARNING: Audio backend set to \"none\"!"); } else if (audiobackends_num_registered > 0) { @@ -95,7 +95,7 @@ audiobackend_t* GetAudioBackend(std::string slug) /* FIXME: At some point, one might want to insert some intelligent algorithm for autoselecting the approriate audio backend here. I'm too lazy right now. */ - printf("Auto-selected audio backend \"%s\" (%s).\n", audiobackends[0]->slug.c_str(), audiobackends[0]->name.c_str()); + INFO_LOG(AUDIO, "Auto-selected audio backend \"%s\" (%s).", audiobackends[0]->slug.c_str(), audiobackends[0]->name.c_str()); return audiobackends[0]; } else @@ -107,12 +107,12 @@ audiobackend_t* GetAudioBackend(std::string slug) return audiobackends[i]; } } - printf("WARNING: Audio backend \"%s\" not found!\n", slug.c_str()); + WARN_LOG(AUDIO, "WARNING: Audio backend \"%s\" not found!", slug.c_str()); } } else { - printf("WARNING: No audio backends available!\n"); + WARN_LOG(AUDIO, "WARNING: No audio backends available!"); } return NULL; } @@ -181,14 +181,14 @@ void SortAudioBackends() void InitAudio() { if (cfgLoadInt("audio", "disable", 0)) { - printf("WARNING: Audio disabled in config!\n"); + INFO_LOG(AUDIO, "WARNING: Audio disabled in config!"); return; } cfgSaveInt("audio", "disable", 0); if (audiobackend_current != NULL) { - printf("ERROR: The audio backend \"%s\" (%s) has already been initialized, you need to terminate it before you can call audio_init() again!\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); + WARN_LOG(AUDIO, "ERROR: The audio backend \"%s\" (%s) has already been initialized, you need to terminate it before you can call audio_init() again!", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); return; } @@ -197,11 +197,11 @@ void InitAudio() string audiobackend_slug = settings.audio.backend; audiobackend_current = GetAudioBackend(audiobackend_slug); if (audiobackend_current == NULL) { - printf("WARNING: Running without audio!\n"); + INFO_LOG(AUDIO, "WARNING: Running without audio!"); return; } - printf("Initializing audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); + INFO_LOG(AUDIO, "Initializing audio backend \"%s\" (%s)...", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); audiobackend_current->init(); } @@ -209,7 +209,7 @@ void TermAudio() { if (audiobackend_current != NULL) { audiobackend_current->term(); - printf("Terminating audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); + INFO_LOG(AUDIO, "Terminating audio backend \"%s\" (%s)...", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str()); audiobackend_current = NULL; } } diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index 2fc09c0ac..e6aa10ac0 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -187,13 +187,13 @@ vram_block* libCore_vramlock_Lock(u32 start_offset64,u32 end_offset64,void* user if (end_offset64>(VRAM_SIZE-1)) { - msgboxf("vramlock_Lock_64: end_offset64>(VRAM_SIZE-1) \n Tried to lock area out of vram , possibly bug on the pvr plugin",MBX_OK); + WARN_LOG(PVR, "vramlock_Lock_64: end_offset64>(VRAM_SIZE-1) \n Tried to lock area out of vram , possibly bug on the pvr plugin"); end_offset64=(VRAM_SIZE-1); } if (start_offset64>end_offset64) { - msgboxf("vramlock_Lock_64: start_offset64>end_offset64 \n Tried to lock negative block , possibly bug on the pvr plugin",MBX_OK); + WARN_LOG(PVR, "vramlock_Lock_64: start_offset64>end_offset64 \n Tried to lock negative block , possibly bug on the pvr plugin"); start_offset64=0; } @@ -236,8 +236,8 @@ bool VramLockedWriteOffset(size_t offset) if ((*list)[i]) { - msgboxf("Error : pvr is supposed to remove lock",MBX_OK); - dbgbreak; + ERROR_LOG(PVR, "Error : pvr is supposed to remove lock"); + die("Invalid state"); } } @@ -276,7 +276,7 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block) { //VRAM_SIZE/PAGE_SIZE; if (block->end>VRAM_SIZE) - msgboxf("Error : block end is after vram , skipping unlock",MBX_OK); + WARN_LOG(PVR, "Error : block end is after vram , skipping unlock"); else { if (mmu_enabled()) diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 551b688d9..6d8217149 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -149,7 +149,7 @@ void gui_init() ImGui::GetStyle().ScaleAllSizes(scaling); io.Fonts->AddFontFromMemoryCompressedTTF(roboto_medium_compressed_data, roboto_medium_compressed_size, 17 * scaling); - printf("Screen DPI is %d, size %d x %d. Scaling by %.2f\n", screen_dpi, screen_width, screen_height, scaling); + INFO_LOG(RENDERER, "Screen DPI is %d, size %d x %d. Scaling by %.2f", screen_dpi, screen_width, screen_height, scaling); } void ImGui_Impl_NewFrame() @@ -1170,7 +1170,7 @@ static void gui_display_settings() } } else { - printf("Unknown option\n"); + WARN_LOG(RENDERER, "Unknown option"); } options++; @@ -1690,7 +1690,7 @@ int msgboxf(const wchar* text, unsigned int type, ...) { va_start(args, type); vsnprintf(temp, sizeof(temp), text, args); va_end(args); - printf("%s\n", temp); + ERROR_LOG(COMMON, "%s", temp); gui_display_notification(temp, 2000); diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp index 0e97ce1c6..c5e195746 100644 --- a/core/windows/win_vmem.cpp +++ b/core/windows/win_vmem.cpp @@ -181,7 +181,7 @@ bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code return false; *code_area_rwx = ptr; - printf("Found code area at %p, not too far away from %p\n", *code_area_rwx, &vmem_platform_init); + INFO_LOG(DYNAREC, "Found code area at %p, not too far away from %p", *code_area_rwx, &vmem_platform_init); // We should have found some area in the addrspace, after all size is ~tens of megabytes. // Pages are already RWX, all done @@ -215,7 +215,7 @@ bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code *code_area_rw = ptr_rw; *rx_offset = (char*)ptr_rx - (char*)ptr_rw; - printf("Info: Using NO_RWX mode, rx ptr: %p, rw ptr: %p, offset: %lu\n", ptr_rx, ptr_rw, (unsigned long)*rx_offset); + INFO_LOG(DYNAREC, "Info: Using NO_RWX mode, rx ptr: %p, rw ptr: %p, offset: %lu", ptr_rx, ptr_rw, (unsigned long)*rx_offset); return (ptr_rw != NULL); } diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 60e2fad55..50dc123a3 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -182,7 +182,7 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) #endif else { - printf("[GPF]Unhandled access to : 0x%X\n",(unat)address); + ERROR_LOG(COMMON, "[GPF]Unhandled access to : %p\n", address); } return EXCEPTION_CONTINUE_SEARCH; @@ -642,7 +642,7 @@ _In_opt_ PVOID Context Table[0].BeginAddress = 0;// (CodeCache - (u8*)__ImageBase); Table[0].EndAddress = /*(CodeCache - (u8*)__ImageBase) +*/ CODE_SIZE + TEMP_CODE_SIZE; Table[0].UnwindData = (DWORD)((u8 *)unwind_info - CodeCache); - printf("TABLE CALLBACK\n"); + INFO_LOG(COMMON, "TABLE CALLBACK"); //for (;;); return Table; } @@ -759,7 +759,7 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine #ifndef __GNUC__ __except( ExeptionHandler(GetExceptionInformation()) ) { - printf("Unhandled exception - Emulation thread halted...\n"); + ERROR_LOG(COMMON, "Unhandled exception - Emulation thread halted..."); } #endif SetUnhandledExceptionFilter(0); diff --git a/core/windows/xinput_gamepad.h b/core/windows/xinput_gamepad.h index beb311413..b9051c5c6 100644 --- a/core/windows/xinput_gamepad.h +++ b/core/windows/xinput_gamepad.h @@ -92,7 +92,7 @@ public: } else if (input_mapper != NULL) { - printf("xinput: Controller '%s' on port %d disconnected\n", _name.c_str(), _xinput_port); + INFO_LOG(INPUT, "xinput: Controller '%s' on port %d disconnected", _name.c_str(), _xinput_port); GamepadDevice::Unregister(xinput_gamepads[_xinput_port]); input_mapper = NULL; last_buttons_state = 0; @@ -134,16 +134,16 @@ public: _name = "xinput" + std::to_string(_xinput_port); else _name = joycaps.szPname; - printf("xinput: Opened controller '%s' on port %d ", _name.c_str(), _xinput_port); + INFO_LOG(INPUT, "xinput: Opened controller '%s' on port %d", _name.c_str(), _xinput_port); if (!find_mapping()) { input_mapper = new XInputMapping(); input_mapper->name = _name + " mapping"; save_mapping(); - printf("using default mapping\n"); + INFO_LOG(INPUT, "using default mapping"); } else - printf("using custom mapping '%s'\n", input_mapper->name.c_str()); + INFO_LOG(INPUT, "using custom mapping '%s'n", input_mapper->name.c_str()); GamepadDevice::Register(xinput_gamepads[_xinput_port]); } From 2c8094f98724072d813802e8ae55866806845242 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 17:41:15 +0200 Subject: [PATCH 118/158] renderer,sdl: use new logging --- core/rend/gl4/gles.cpp | 2 +- core/rend/gles/CustomTexture.cpp | 6 +++--- core/rend/gles/gldraw.cpp | 2 +- core/rend/gles/gles.cpp | 2 +- core/rend/gles/gltex.cpp | 28 ++++++++++++++------------- core/rend/gles/imgui_impl_opengl3.cpp | 8 ++++---- core/sdl/sdl.cpp | 4 ++-- core/sdl/sdl_gamepad.h | 10 +++++----- 8 files changed, 32 insertions(+), 30 deletions(-) diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 17bd9c7f4..e1f140a76 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -758,7 +758,7 @@ static bool RenderFrame() gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; - DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f\n", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]); + //DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]); //VERT and RAM fog color constants u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT; diff --git a/core/rend/gles/CustomTexture.cpp b/core/rend/gles/CustomTexture.cpp index 8f062d1b2..59cc12827 100644 --- a/core/rend/gles/CustomTexture.cpp +++ b/core/rend/gles/CustomTexture.cpp @@ -106,7 +106,7 @@ bool CustomTexture::Init() DIR *dir = opendir(textures_path.c_str()); if (dir != NULL) { - printf("Found custom textures directory: %s\n", textures_path.c_str()); + INFO_LOG(RENDERER, "Found custom textures directory: %s", textures_path.c_str()); custom_textures_available = true; closedir(dir); loader_thread.Start(); @@ -176,7 +176,7 @@ void CustomTexture::DumpTexture(u32 hash, int w, int h, GLuint textype, void *te FILE *fp = fopen(path.str().c_str(), "wb"); if (fp == NULL) { - printf("Failed to open %s for writing\n", path.str().c_str()); + WARN_LOG(RENDERER, "Failed to open %s for writing", path.str().c_str()); return; } @@ -228,7 +228,7 @@ void CustomTexture::DumpTexture(u32 hash, int w, int h, GLuint textype, void *te } break; default: - printf("dumpTexture: unsupported picture format %x\n", textype); + WARN_LOG(RENDERER, "dumpTexture: unsupported picture format %x", textype); fclose(fp); free(rows[0]); free(rows); diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 66c208886..2a1b76cd1 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -765,7 +765,7 @@ void GenSorted(int first, int count) glBufferData(GL_ELEMENT_ARRAY_BUFFER, vidx_sort.size() * sizeof(u32), &vidx_sort[0], GL_STREAM_DRAW); glCheck(); - if (tess_gen) printf("Generated %.2fK Triangles !\n",tess_gen/1000.0); + if (tess_gen) DEBUG_LOG(RENDERER, "Generated %.2fK Triangles !", tess_gen / 1000.0); } } diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 9a61ab41e..4f871dd23 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1816,7 +1816,7 @@ bool RenderFrame() ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale; - //printf("scale: %f, %f, %f, %f\n",ShaderUniforms.scale_coefs[0],ShaderUniforms.scale_coefs[1],ShaderUniforms.scale_coefs[2],ShaderUniforms.scale_coefs[3]); + //DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", ShaderUniforms.scale_coefs[0], ShaderUniforms.scale_coefs[1], ShaderUniforms.scale_coefs[2], ShaderUniforms.scale_coefs[3]); //VERT and RAM fog color constants diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index b8d595da8..e83c6a882 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -119,22 +119,24 @@ static void dumpRtTexture(u32 name, u32 w, u32 h) { //Texture Cache :) void TextureCacheData::PrintTextureName() { - printf("Texture: %s ",tex?tex->name:"?format?"); + char str[512]; + sprintf(str, "Texture: %s ", tex ? tex->name : "?format?"); if (tcw.VQ_Comp) - printf(" VQ"); + strcat(str, " VQ"); if (tcw.ScanOrder==0) - printf(" TW"); + strcat(str, " TW"); if (tcw.MipMapped) - printf(" MM"); + strcat(str, " MM"); if (tcw.StrideSel) - printf(" Stride"); + strcat(str, " Stride"); - printf(" %dx%d @ 0x%X",8<PL || tex->PL32)) stride=(TEXT_CONTROL&31)*32; //I think this needs +1 ? - //PrintTextureName(); + PrintTextureName(); u32 original_h = h; if (sa_tex > VRAM_SIZE || size == 0 || sa + size > VRAM_SIZE) { @@ -291,7 +293,7 @@ void TextureCacheData::Update() } else { - printf("Warning: invalid texture. Address %08X %08X size %d\n", sa_tex, sa, size); + WARN_LOG(RENDERER, "Warning: invalid texture. Address %08X %08X size %d", sa_tex, sa, size); return; } } @@ -362,7 +364,7 @@ void TextureCacheData::Update() else { //fill it in with a temp color - printf("UNHANDLED TEXTURE\n"); + WARN_LOG(RENDERER, "UNHANDLED TEXTURE"); pb16.init(w, h); memset(pb16.data(), 0x80, w * h * 2); temp_tex_buffer = pb16.data(); @@ -846,7 +848,7 @@ void killtex() } TexCache.clear(); - printf("Texture cache cleared\n"); + INFO_LOG(RENDERER, "Texture cache cleared"); } void rend_text_invl(vram_block* bl) diff --git a/core/rend/gles/imgui_impl_opengl3.cpp b/core/rend/gles/imgui_impl_opengl3.cpp index 4d2936b10..1620c7fda 100644 --- a/core/rend/gles/imgui_impl_opengl3.cpp +++ b/core/rend/gles/imgui_impl_opengl3.cpp @@ -298,13 +298,13 @@ static bool CheckShader(GLuint handle, const char* desc) glGetShaderiv(handle, GL_COMPILE_STATUS, &status); glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); + WARN_LOG(RENDERER, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!", desc); if (log_length > 0) { ImVector buf; buf.resize((int)(log_length + 1)); glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); + WARN_LOG(RENDERER, "%s", buf.begin()); } return (GLboolean)status == GL_TRUE; } @@ -316,13 +316,13 @@ static bool CheckProgram(GLuint handle, const char* desc) glGetProgramiv(handle, GL_LINK_STATUS, &status); glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); if ((GLboolean)status == GL_FALSE) - fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString); + WARN_LOG(RENDERER, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')", desc, g_GlslVersionString); if (log_length > 0) { ImVector buf; buf.resize((int)(log_length + 1)); glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); - fprintf(stderr, "%s\n", buf.begin()); + WARN_LOG(RENDERER, "%s", buf.begin()); } return (GLboolean)status == GL_TRUE; } diff --git a/core/sdl/sdl.cpp b/core/sdl/sdl.cpp index 348af0521..d8e206cb4 100644 --- a/core/sdl/sdl.cpp +++ b/core/sdl/sdl.cpp @@ -52,7 +52,7 @@ static void sdl_open_joystick(int index) if (pJoystick == NULL) { - printf("SDL: Cannot open joystick %d\n", index + 1); + INFO_LOG(INPUT, "SDL: Cannot open joystick %d", index + 1); return; } std::shared_ptr gamepad = std::make_shared(index < MAPLE_PORTS ? index : -1, pJoystick); @@ -266,7 +266,7 @@ void sdl_window_create() if (!SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(window), &ddpi, &hdpi, &vdpi)) screen_dpi = (int)roundf(max(hdpi, vdpi)); - printf("Created SDL Window (%ix%i) and GL Context successfully\n", window_width, window_height); + INFO_LOG(RENDERER, "Created SDL Window (%ix%i) and GL Context successfully", window_width, window_height); } bool gl_init(void* wind, void* disp) diff --git a/core/sdl/sdl_gamepad.h b/core/sdl/sdl_gamepad.h index ea8321d2e..489d10055 100644 --- a/core/sdl/sdl_gamepad.h +++ b/core/sdl/sdl_gamepad.h @@ -49,7 +49,7 @@ public: { _name = SDL_JoystickName(sdl_joystick); sdl_joystick_instance = SDL_JoystickInstanceID(sdl_joystick); - printf("SDL: Opened joystick on port %d: '%s' ", maple_port, _name.c_str()); + INFO_LOG(INPUT, "SDL: Opened joystick on port %d: '%s'", maple_port, _name.c_str()); SDL_JoystickGUID guid = SDL_JoystickGetGUID(sdl_joystick); char buf[33]; SDL_JoystickGetGUIDString(guid, buf, sizeof(buf)); @@ -62,17 +62,17 @@ public: if (_name == "Microsoft X-Box 360 pad") { input_mapper = new Xbox360InputMapping(); - printf("using Xbox 360 mapping\n"); + INFO_LOG(INPUT, "using Xbox 360 mapping"); } else { input_mapper = new DefaultInputMapping(); - printf("using default mapping\n"); + INFO_LOG(INPUT, "using default mapping"); } save_mapping(); } else - printf("using custom mapping '%s'\n", input_mapper->name.c_str()); + INFO_LOG(INPUT, "using custom mapping '%s'", input_mapper->name.c_str()); sdl_haptic = SDL_HapticOpenFromJoystick(sdl_joystick); if (SDL_HapticRumbleInit(sdl_haptic) != 0) { @@ -108,7 +108,7 @@ public: void close() { - printf("SDL: Joystick '%s' on port %d disconnected\n", _name.c_str(), maple_port()); + INFO_LOG(INPUT, "SDL: Joystick '%s' on port %d disconnected", _name.c_str(), maple_port()); if (sdl_haptic != NULL) SDL_HapticClose(sdl_haptic); SDL_JoystickClose(sdl_joystick); From be5aca66e15c9655c21f713564ab36733684e236 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 18:23:10 +0200 Subject: [PATCH 119/158] cfg,dynarecs,reios: use new logging --- core/cfg/cfg.cpp | 6 ++--- core/cfg/cl.cpp | 25 +++++++++---------- core/cfg/ini.cpp | 2 +- core/log/Log.h | 1 + core/log/LogManager.cpp | 3 ++- core/rec-ARM/rec_arm.cpp | 28 +++++++++------------ core/rec-ARM64/rec_arm64.cpp | 6 ++--- core/rec-cpp/rec_cpp.cpp | 6 ++--- core/rec-x64/rec_x64.cpp | 4 +-- core/reios/gdrom_hle.cpp | 47 ++++++++++++++++++------------------ core/reios/reios.cpp | 40 +++++++++++++++--------------- 11 files changed, 80 insertions(+), 88 deletions(-) diff --git a/core/cfg/cfg.cpp b/core/cfg/cfg.cpp index fda8959b2..3d7db1aa6 100644 --- a/core/cfg/cfg.cpp +++ b/core/cfg/cfg.cpp @@ -21,7 +21,7 @@ void savecfgf() FILE* cfgfile = fopen(cfgPath.c_str(),"wt"); if (!cfgfile) { - printf("Error: Unable to open file '%s' for saving\n", cfgPath.c_str()); + WARN_LOG(COMMON, "Error: Unable to open file '%s' for saving", cfgPath.c_str()); } else { @@ -93,11 +93,11 @@ bool cfgOpen() { // Config file can't be opened int error_code = errno; - printf("Warning: Unable to open the config file '%s' for reading (%s)\n", config_path_read.c_str(), strerror(error_code)); + WARN_LOG(COMMON, "Warning: Unable to open the config file '%s' for reading (%s)", config_path_read.c_str(), strerror(error_code)); if (error_code == ENOENT || cfgPath != config_path_read) { // Config file didn't exist - printf("Creating new empty config file at '%s'\n", cfgPath.c_str()); + INFO_LOG(COMMON, "Creating new empty config file at '%s'", cfgPath.c_str()); savecfgf(); } else diff --git a/core/cfg/cl.cpp b/core/cfg/cl.cpp index 06bf74e31..8f8a2140d 100644 --- a/core/cfg/cl.cpp +++ b/core/cfg/cl.cpp @@ -49,19 +49,19 @@ int setconfig(wchar** arg,int cl) { if (cl<1) { - printf("-config : invalid number of parameters, format is section:key=value\n"); + WARN_LOG(COMMON, "-config : invalid number of parameters, format is section:key=value"); return rv; } wchar* sep=strstr(arg[1],":"); if (sep==0) { - printf("-config : invalid parameter %s, format is section:key=value\n",arg[1]); + WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]); return rv; } wchar* value=strstr(sep+1,"="); if (value==0) { - printf("-config : invalid parameter %s, format is section:key=value\n",arg[1]); + WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]); return rv; } @@ -74,14 +74,14 @@ int setconfig(wchar** arg,int cl) if (sect==0 || key==0) { - printf("-config : invalid parameter, format is section:key=value\n"); + WARN_LOG(COMMON, "-config : invalid parameter, format is section:key=value"); return rv; } const wchar* constval = value; if (constval==0) constval=""; - printf("Virtual cfg %s:%s=%s\n",sect,key,value); + INFO_LOG(COMMON, "Virtual cfg %s:%s=%s", sect, key, value); cfgSetVirtual(sect,key,value); rv++; @@ -101,10 +101,10 @@ int setconfig(wchar** arg,int cl) int showhelp(wchar** arg,int cl) { - printf("\nAvailable commands :\n"); + NOTICE_LOG(COMMON, "Available commands:"); - printf("-config section:key=value [, ..]: add a virtual config value\n Virtual config values won't be saved to the .cfg file\n unless a different value is written to em\nNote :\n You can specify many settings in the xx:yy=zz , gg:hh=jj , ...\n format.The spaces between the values and ',' are needed.\n"); - printf("\n-help: show help info\n"); + NOTICE_LOG(COMMON, "-config section:key=value [, ..]: add a virtual config value\n Virtual config values won't be saved to the .cfg file\n unless a different value is written to em\nNote :\n You can specify many settings in the xx:yy=zz , gg:hh=jj , ...\n format.The spaces between the values and ',' are needed."); + NOTICE_LOG(COMMON, "-help: show help info"); return 0; } @@ -136,28 +136,27 @@ bool ParseCommandLine(int argc,wchar* argv[]) || stricmp(extension, ".gdi") == 0 || stricmp(extension, ".lst") == 0 || stricmp(extension, ".cue") == 0)) { - printf("Using '%s' as cd image\n", *arg); + INFO_LOG(COMMON, "Using '%s' as cd image", *arg); cfgSetVirtual("config", "image", *arg); } else if (extension && stricmp(extension, ".elf") == 0) { - printf("Using '%s' as reios elf file\n", *arg); + INFO_LOG(COMMON, "Using '%s' as reios elf file", *arg); cfgSetVirtual("config", "reios.enabled", "1"); cfgSetVirtual("reios", "ElfFile", *arg); } else { #if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - printf("Using '%s' as rom\n", *arg); + INFO_LOG(COMMON, "Using '%s' as rom", *arg); cfgSetVirtual("config", "image", *arg); #else - printf("wtf %s is supposed to do ?\n",*arg); + WARN_LOG(COMMON, "wtf %s is supposed to do ?",*arg); #endif } } arg++; cl--; } - printf("\n"); return false; } diff --git a/core/cfg/ini.cpp b/core/cfg/ini.cpp index 4cd9d05e5..0eedd8eca 100644 --- a/core/cfg/ini.cpp +++ b/core/cfg/ini.cpp @@ -246,7 +246,7 @@ void ConfigFile::parse(FILE* file) if (!separator) { - printf("Malformed entry on config - ignoring @ %d(%s)\n",cline, tl); + WARN_LOG(COMMON, "Malformed entry on config - ignoring @ %d(%s)", cline, tl); continue; } diff --git a/core/log/Log.h b/core/log/Log.h index f046c1f93..ec3aedb12 100644 --- a/core/log/Log.h +++ b/core/log/Log.h @@ -26,6 +26,7 @@ enum LOG_TYPE MODEM, NAOMI, PVR, + REIOS, RENDERER, SAVESTATE, SH4, diff --git a/core/log/LogManager.cpp b/core/log/LogManager.cpp index 051f9eee7..1f9341bfb 100644 --- a/core/log/LogManager.cpp +++ b/core/log/LogManager.cpp @@ -93,7 +93,7 @@ LogManager::LogManager() // create log containers m_log[LogTypes::AICA] = {"AICA", "AICA Audio Emulation"}; m_log[LogTypes::AICA_ARM] = {"AICA_ARM", "AICA ARM Emulation"}; - m_log[LogTypes::AUDIO] = {"Audio", "Audio Ouput Interface"}; + m_log[LogTypes::AUDIO] = {"AUDIO", "Audio Ouput Interface"}; m_log[LogTypes::BOOT] = {"BOOT", "Boot"}; m_log[LogTypes::COMMON] = {"COMMON", "Common"}; m_log[LogTypes::DYNAREC] = {"DYNAREC", "Dynamic Recompiler"}; @@ -109,6 +109,7 @@ LogManager::LogManager() m_log[LogTypes::MODEM] = {"MODEM", "Modem and Network"}; m_log[LogTypes::NAOMI] = {"NAOMI", "Naomi"}; m_log[LogTypes::PVR] = {"PVR", "PowerVR GPU"}; + m_log[LogTypes::REIOS] = {"REIOS", "HLE BIOS"}; m_log[LogTypes::RENDERER] = {"RENDERER", "OpenGL Renderer"}; m_log[LogTypes::SAVESTATE] = {"SAVESTATE", "Save States"}; m_log[LogTypes::SH4] = {"SH4", "SH4 Modules"}; diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index 250bb75bb..d8dc95aba 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -335,7 +335,7 @@ u32 DynaRBI::Relink() } else { - printf("SLOW COND PATH %d\n", oplist.empty() ? -1 : oplist[oplist.size()-1].op); + INFO_LOG(DYNAREC, "SLOW COND PATH %d", oplist.empty() ? -1 : oplist[oplist.size()-1].op); LoadSh4Reg_mem(r4, reg_sr_T); } } @@ -470,7 +470,7 @@ u32 DynaRBI::Relink() } default: - printf("Error, Relink() Block Type: %X\n", BlockType); + ERROR_LOG(DYNAREC, "Error, Relink() Block Type: %X", BlockType); verify(false); break; } @@ -529,7 +529,7 @@ void ngen_Binary(shil_opcode* op, BinaryOP dtop, BinaryOPImm dtopimm) } else { - printf("ngen_Bin ??? %d \n",op->rs2.type); + ERROR_LOG(DYNAREC, "ngen_Bin ??? %d", op->rs2.type); verify(false); } @@ -894,7 +894,7 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr) if (offs==-1) { - printf("%08X : invalid size\n",ptr[0]); + ERROR_LOG(DYNAREC, "%08X : invalid size", ptr[0]); die("can't decode opcode\n"); } @@ -917,7 +917,7 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr) } else { - printf("fail raddr %08X {@%08X}:(\n",ptr[0].full,regs[1]); + ERROR_LOG(DYNAREC, "fail raddr %08X {@%08X}:(", ptr[0].full, regs[1]); die("Invalid opcode: vmem fixup\n"); } //from mem op @@ -1058,7 +1058,7 @@ eReg GenMemAddr(shil_opcode* op, eReg raddr = r0) } else if (!op->rs3.is_null()) { - printf("rs3: %08X\n",op->rs3.type); + ERROR_LOG(DYNAREC, "rs3: %08X", op->rs3.type); die("invalid rs3"); } else if (op->rs1.is_imm()) @@ -1679,7 +1679,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, } else { - printf("ngen_Bin ??? %d \n",op->rs2.type); + ERROR_LOG(DYNAREC, "ngen_Bin ??? %d", op->rs2.type); verify(false); } @@ -2186,7 +2186,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, break; __default: - printf("@@\tError, Default case (0x%X) in ngen_CompileBlock!\n", op->op); + ERROR_LOG(DYNAREC, "@@ Error, Default case (0x%X) in ngen_CompileBlock!", op->op); verify(false); break; } @@ -2390,7 +2390,7 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, void ngen_ResetBlocks() { - printf("@@\tngen_ResetBlocks()\n"); + INFO_LOG(DYNAREC, "@@ ngen_ResetBlocks()"); } /* SHR .. @@ -2402,7 +2402,7 @@ void ngen_ResetBlocks() */ void ngen_init() { - printf("Initializing the ARM32 dynarec\n"); + INFO_LOG(DYNAREC, "Initializing the ARM32 dynarec"); verify(FPCB_OFFSET == -0x2100000 || FPCB_OFFSET == -0x4100000); verify(rcb_noffs(p_sh4rcb->fpcb) == FPCB_OFFSET); @@ -2472,7 +2472,7 @@ void ngen_init() BX(LR); } - printf("readm helpers: up to %08X\n",EMIT_GET_PTR()); + INFO_LOG(DYNAREC, "readm helpers: up to %08X", EMIT_GET_PTR()); emit_SetBaseAddr(); @@ -2511,10 +2511,4 @@ RuntimeBlockInfo* ngen_AllocateBlock() { return new DynaRBI(); }; - -void CacheFlush() -{ - printf("Flushing cache from %08x to %08x\n", &CodeCache[0], &CodeCache[CODE_SIZE - 1]); - //CacheFlush(&CodeCache[0], &CodeCache[CODE_SIZE - 1]); -} #endif diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 4ce70f8d7..0ed926849 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -155,7 +155,7 @@ void ngen_mainloop(void* v_cntx) void ngen_init() { - LOGI("Initializing the ARM64 dynarec\n"); + INFO_LOG(DYNAREC, "Initializing the ARM64 dynarec"); ngen_FailedToFindBlock = &ngen_FailedToFindBlock_nommu; } @@ -1396,7 +1396,7 @@ public: #if 0 if (rewrite && block != NULL) { - LOGI("BLOCK %08x\n", block->vaddr); + INFO_LOG(DYNAREC, "BLOCK %08x", block->vaddr); Instruction* instr_start = (Instruction*)block->code; // Instruction* instr_end = GetLabelAddress(&code_end); Instruction* instr_end = (Instruction*)((u8 *)block->code + block->host_code_size); @@ -1406,7 +1406,7 @@ public: Instruction* instr; for (instr = instr_start; instr < instr_end; instr += kInstructionSize) { decoder.Decode(instr); - LOGI("VIXL\t %p:\t%s\n", + INFO_LOG(DYNAREC, "VIXL %p: %s", reinterpret_cast(instr), disasm.GetOutput()); } diff --git a/core/rec-cpp/rec_cpp.cpp b/core/rec-cpp/rec_cpp.cpp index a9f15fd5a..a260e9f09 100644 --- a/core/rec-cpp/rec_cpp.cpp +++ b/core/rec-cpp/rec_cpp.cpp @@ -75,7 +75,7 @@ RuntimeBlockInfo* ngen_AllocateBlock() } static void ngen_blockcheckfail(u32 pc) { - printf("REC CPP: SMC invalidation at %08X\n", pc); + INFO_LOG(DYNAREC, "REC CPP: SMC invalidation at %08X", pc); rdv_BlockCheckFail(pc); } @@ -1100,7 +1100,7 @@ opcodeExec* createType(const CC_pars_t& prms, void* fun, shil_opcode* opcode) { if (!funs.count(fun)) { funs[fun] = funs_id_count++; - printf("DEFINE %s: FAST_po(%s)\n", getCTN(&createType).c_str(), shil_opcode_name(opcode->op)); + INFO_LOG(DYNAREC, "DEFINE %s: FAST_po(%s)", getCTN(&createType).c_str(), shil_opcode_name(opcode->op)); } typedef typename CTR::opex thetype; @@ -1556,7 +1556,7 @@ public: ptrsg[opcode_index] = unmap[nm](CC_pars, ccfn, op); } else { - printf("IMPLEMENT CC_CALL CLASS: %s\n", nm.c_str()); + INFO_LOG(DYNAREC, "IMPLEMENT CC_CALL CLASS: %s", nm.c_str()); ptrsg[opcode_index] = new opcodeDie(); } } diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index 1bb975fe2..3cc8810d3 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -2246,14 +2246,14 @@ bool ngen_Rewrite(unat& host_pc, unat, unat) RuntimeBlockInfoPtr block = bm_GetBlock((void *)host_pc); if (block == NULL) { - printf("ngen_Rewrite: Block at %p not found\n", (void *)host_pc); + WARN_LOG(DYNAREC, "ngen_Rewrite: Block at %p not found", (void *)host_pc); return false; } u8 *code_ptr = (u8*)host_pc; auto it = block->memory_accesses.find(code_ptr); if (it == block->memory_accesses.end()) { - printf("ngen_Rewrite: memory access at %p not found (%lu entries)\n", code_ptr, block->memory_accesses.size()); + WARN_LOG(DYNAREC, "ngen_Rewrite: memory access at %p not found (%lu entries)", code_ptr, block->memory_accesses.size()); return false; } u32 opid = it->second; diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index a43fbeb9a..0bc9fe9ae 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -12,8 +12,7 @@ #define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff)) -//#define debugf printf -#define debugf(...) +#define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__) void GDROM_HLE_ReadSES(u32 addr) { @@ -22,7 +21,7 @@ void GDROM_HLE_ReadSES(u32 addr) u32 ba = ReadMem32(addr + 8); u32 bb = ReadMem32(addr + 12); - printf("GDROM_HLE_ReadSES: doing nothing w/ %d, %d, %d, %d\n", s, b, ba, bb); + INFO_LOG(REIOS, "GDROM_HLE_ReadSES: doing nothing w/ %d, %d, %d, %d", s, b, ba, bb); } void GDROM_HLE_ReadTOC(u32 Addr) { @@ -32,7 +31,7 @@ void GDROM_HLE_ReadTOC(u32 Addr) u32* pDst = (u32*)GetMemPtr(b, 0); // - debugf("GDROM READ TOC : %X %X \n\n", s, b); + debugf("GDROM READ TOC : %X %X", s, b); libGDR_GetToc(pDst, s); @@ -97,7 +96,7 @@ void GDCC_HLE_GETSCD(u32 addr) { u32 b = ReadMem32(addr + 0x08); u32 u = ReadMem32(addr + 0x0C); - printf("GDROM: Doing nothing for GETSCD [0]=%d, [1]=%d, [2]=0x%08X, [3]=0x%08X\n", s, n, b, u); + INFO_LOG(REIOS, "GDROM: Doing nothing for GETSCD [0]=%d, [1]=%d, [2]=0x%08X, [3]=0x%08X", s, n, b, u); } #define r Sh4cntx.r @@ -110,7 +109,7 @@ void GD_HLE_Command(u32 cc, u32 prm) switch(cc) { case GDCC_GETTOC: - printf("GDROM:\t*FIXME* CMD GETTOC CC:%X PRM:%X\n",cc,prm); + INFO_LOG(REIOS, "GDROM:\t*FIXME* CMD GETTOC CC:%X PRM:%X",cc,prm); break; case GDCC_GETTOC2: @@ -123,7 +122,7 @@ void GD_HLE_Command(u32 cc, u32 prm) break; case GDCC_INIT: - printf("GDROM:\tCMD INIT CC:%X PRM:%X\n",cc,prm); + INFO_LOG(REIOS, "GDROM:\tCMD INIT CC:%X PRM:%X",cc,prm); break; case GDCC_PIOREAD: @@ -131,26 +130,26 @@ void GD_HLE_Command(u32 cc, u32 prm) break; case GDCC_DMAREAD: - debugf("GDROM:\tCMD DMAREAD CC:%X PRM:%X\n", cc, prm); + debugf("GDROM:\tCMD DMAREAD CC:%X PRM:%X", cc, prm); GDROM_HLE_ReadDMA(r[5]); break; case GDCC_PLAY_SECTOR: - printf("GDROM:\tCMD PLAYSEC? CC:%X PRM:%X\n",cc,prm); + INFO_LOG(REIOS, "GDROM:\tCMD PLAYSEC? CC:%X PRM:%X",cc,prm); break; case GDCC_RELEASE: - printf("GDROM:\tCMD RELEASE? CC:%X PRM:%X\n",cc,prm); + INFO_LOG(REIOS, "GDROM:\tCMD RELEASE? CC:%X PRM:%X",cc,prm); break; - case GDCC_STOP: printf("GDROM:\tCMD STOP CC:%X PRM:%X\n",cc,prm); break; - case GDCC_SEEK: printf("GDROM:\tCMD SEEK CC:%X PRM:%X\n",cc,prm); break; - case GDCC_PLAY: printf("GDROM:\tCMD PLAY CC:%X PRM:%X\n",cc,prm); break; - case GDCC_PAUSE:printf("GDROM:\tCMD PAUSE CC:%X PRM:%X\n",cc,prm); break; + case GDCC_STOP: INFO_LOG(REIOS, "GDROM:\tCMD STOP CC:%X PRM:%X",cc,prm); break; + case GDCC_SEEK: INFO_LOG(REIOS, "GDROM:\tCMD SEEK CC:%X PRM:%X",cc,prm); break; + case GDCC_PLAY: INFO_LOG(REIOS, "GDROM:\tCMD PLAY CC:%X PRM:%X",cc,prm); break; + case GDCC_PAUSE:INFO_LOG(REIOS, "GDROM:\tCMD PAUSE CC:%X PRM:%X",cc,prm); break; case GDCC_READ: - printf("GDROM:\tCMD READ CC:%X PRM:%X\n",cc,prm); + INFO_LOG(REIOS, "GDROM:\tCMD READ CC:%X PRM:%X",cc,prm); break; case GDCC_GETSCD: @@ -158,7 +157,7 @@ void GD_HLE_Command(u32 cc, u32 prm) GDCC_HLE_GETSCD(r[5]); break; - default: printf("GDROM:\tUnknown GDROM CC:%X PRM:%X\n",cc,prm); break; + default: INFO_LOG(REIOS, "GDROM:\tUnknown GDROM CC:%X PRM:%X",cc,prm); break; } } @@ -189,8 +188,8 @@ void gdrom_hle_op() debugf("\nGDROM:\tHLE GDROM_MAIN\n"); break; - case GDROM_INIT: printf("\nGDROM:\tHLE GDROM_INIT\n"); break; - case GDROM_RESET: printf("\nGDROM:\tHLE GDROM_RESET\n"); break; + case GDROM_INIT: INFO_LOG(REIOS, "GDROM:\tHLE GDROM_INIT"); break; + case GDROM_RESET: INFO_LOG(REIOS, "GDROM:\tHLE GDROM_RESET"); break; case GDROM_CHECK_DRIVE: // debugf("\nGDROM:\tHLE GDROM_CHECK_DRIVE r4:%X\n",r[4],r[5]); @@ -200,25 +199,25 @@ void gdrom_hle_op() break; case GDROM_ABORT_COMMAND: // - printf("\nGDROM:\tHLE GDROM_ABORT_COMMAND r4:%X\n",r[4],r[5]); + INFO_LOG(REIOS, "GDROM:\tHLE GDROM_ABORT_COMMAND r4:%X",r[4],r[5]); r[0]=-1; // RET FAILURE break; case GDROM_SECTOR_MODE: // - printf("GDROM:\tHLE GDROM_SECTOR_MODE PTR_r4:%X\n",r[4]); + INFO_LOG(REIOS, "GDROM:\tHLE GDROM_SECTOR_MODE PTR_r4:%X",r[4]); for(int i=0; i<4; i++) { SecMode[i] = ReadMem32(r[4]+(i<<2)); - printf("%08X%s",SecMode[i],((3==i) ? "\n" : "\t")); + INFO_LOG(REIOS, "%08X", SecMode[i]); } r[0]=0; // RET SUCCESS break; - default: printf("\nGDROM:\tUnknown SYSCALL: %X\n",r[7]); break; + default: INFO_LOG(REIOS, "GDROM:\tUnknown SYSCALL: %X",r[7]); break; } } else // MISC { - printf("SYSCALL:\tSYSCALL: %X\n",r[7]); + INFO_LOG(REIOS, "SYSCALL:\tSYSCALL: %X", r[7]); } -} \ No newline at end of file +} diff --git a/core/reios/reios.cpp b/core/reios/reios.cpp index d24852d98..8f901f5c5 100644 --- a/core/reios/reios.cpp +++ b/core/reios/reios.cpp @@ -20,9 +20,7 @@ #include -//#define debugf printf - -#define debugf(...) +#define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__) #define dc_bios_syscall_system 0x8C0000B0 #define dc_bios_syscall_font 0x8C0000B4 @@ -55,13 +53,13 @@ bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") { libGDR_ReadSector(temp, base_fad + 16, 1, 2048); if (memcmp(temp, "\001CD001\001", 7) == 0) { - printf("reios: iso9660 PVD found\n"); + INFO_LOG(REIOS, "reios: iso9660 PVD found"); u32 lba = read_u32bi(&temp[156 + 2]); //make sure to use big endian u32 len = read_u32bi(&temp[156 + 10]); //make sure to use big endian data_len = ((len + 2047) / 2048) *2048; - printf("reios: iso9660 root_directory, FAD: %d, len: %d\n", 150 + lba, data_len); + INFO_LOG(REIOS, "reios: iso9660 root_directory, FAD: %d, len: %d", 150 + lba, data_len); libGDR_ReadSector(temp, 150 + lba, data_len/2048, 2048); } else { @@ -70,14 +68,14 @@ bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") { for (int i = 0; i < (data_len-20); i++) { if (memcmp(temp+i, bootfile, strlen(bootfile)) == 0){ - printf("Found %s at %06X\n", bootfile, i); + INFO_LOG(REIOS, "Found %s at %06X", bootfile, i); u32 lba = read_u32bi(&temp[i - 33 + 2]); //make sure to use big endian u32 len = read_u32bi(&temp[i - 33 + 10]); //make sure to use big endian - printf("filename len: %d\n", temp[i - 1]); - printf("file LBA: %d\n", lba); - printf("file LEN: %d\n", len); + INFO_LOG(REIOS, "filename len: %d", temp[i - 1]); + INFO_LOG(REIOS, "file LBA: %d", lba); + INFO_LOG(REIOS, "file LEN: %d", len); if (descrambl) descrambl_file(lba + 150, len, GetMemPtr(0x8c010000, 0)); @@ -168,7 +166,7 @@ void reios_sys_system() { case 2: //SYSINFO_ICON { - printf("SYSINFO_ICON\n"); + INFO_LOG(REIOS, "SYSINFO_ICON"); /* r4 = icon number (0-9, but only 5-9 seems to really be icons) r5 = destination buffer (704 bytes in size) @@ -187,13 +185,13 @@ void reios_sys_system() { break; default: - printf("unhandled: reios_sys_system\n"); + INFO_LOG(REIOS, "unhandled: reios_sys_system"); break; } } void reios_sys_font() { - printf("reios_sys_font\n"); + INFO_LOG(REIOS, "reios_sys_font"); } void reios_sys_flashrom() { @@ -305,7 +303,7 @@ void reios_sys_flashrom() { break; default: - printf("reios_sys_flashrom: not handled, %d\n", cmd); + INFO_LOG(REIOS, "reios_sys_flashrom: not handled, %d", cmd); } } @@ -359,7 +357,7 @@ void gd_do_bioscall() break; default: - printf("gd_do_bioscall: (%d) %d, %d, %d\n", Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6], Sh4cntx.r[7]); + INFO_LOG(REIOS, "gd_do_bioscall: (%d) %d, %d, %d", Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6], Sh4cntx.r[7]); break; } @@ -367,7 +365,7 @@ void gd_do_bioscall() } void reios_sys_misc() { - printf("reios_sys_misc - r7: 0x%08X, r4 0x%08X, r5 0x%08X, r6 0x%08X\n", Sh4cntx.r[7], Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6]); + INFO_LOG(REIOS, "reios_sys_misc - r7: 0x%08X, r4 0x%08X, r5 0x%08X, r6 0x%08X", Sh4cntx.r[7], Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6]); Sh4cntx.r[0] = 0; } @@ -574,9 +572,9 @@ void reios_setuo_naomi(u32 boot_addr) { sh4rcb.cntx.old_fpscr.full = 0x00040001; } void reios_boot() { - printf("-----------------\n"); - printf("REIOS: Booting up\n"); - printf("-----------------\n"); + NOTICE_LOG(REIOS, "-----------------"); + NOTICE_LOG(REIOS, "REIOS: Booting up"); + NOTICE_LOG(REIOS, "-----------------"); //setup syscalls //find boot file //boot it @@ -609,7 +607,7 @@ void reios_boot() { verify(DC_PLATFORM == DC_PLATFORM_NAOMI); if (CurrentCartridge == NULL) { - printf("No cartridge loaded\n"); + WARN_LOG(REIOS, "No cartridge loaded"); return; } u32 data_size = 4; @@ -657,7 +655,7 @@ u32 hook_addr(hook_fp* fn) { if (hooks_rev.count(fn)) return hooks_rev[fn]; else { - printf("hook_addr: Failed to reverse lookup %p\n", fn); + ERROR_LOG(REIOS, "hook_addr: Failed to reverse lookup %p", fn); verify(false); return 0; } @@ -665,7 +663,7 @@ u32 hook_addr(hook_fp* fn) { bool reios_init(u8* rom, u8* flash) { - printf("reios: Init\n"); + INFO_LOG(REIOS, "reios: Init"); biosrom = rom; flashrom = flash; From 3863d9d2fbec3a4e4dfb759c653e7caa024db6a0 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 1 Jul 2019 18:36:52 +0200 Subject: [PATCH 120/158] android: use new logging --- .../reicast/src/main/jni/src/Android.cpp | 20 ++++++------ .../src/main/jni/src/android_gamepad.h | 9 +++--- .../reicast/src/main/jni/src/utils.cpp | 32 +++++++++---------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index ce7d78956..02e3f3026 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -223,8 +223,8 @@ JNIEXPORT jstring JNICALL Java_com_reicast_emulator_emu_JNIdc_initEnvironment(JN const char* path = homeDirectory != NULL ? env->GetStringUTFChars(homeDirectory, 0) : ""; set_user_config_dir(path); set_user_data_dir(path); - printf("Config dir is: %s\n", get_writable_config_path("").c_str()); - printf("Data dir is: %s\n", get_writable_data_path("").c_str()); + INFO_LOG(BOOT, "Config dir is: %s", get_writable_config_path("").c_str()); + INFO_LOG(BOOT, "Data dir is: %s", get_writable_data_path("").c_str()); if (homeDirectory != NULL) env->ReleaseStringUTFChars(homeDirectory, path); @@ -269,7 +269,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env, const char *P = env->GetStringUTFChars(disk, 0); if (!P) settings.imgread.DefaultImage[0] = '\0'; else { - printf("Boot Disk URI: '%s'\n", P); + INFO_LOG(BOOT, "Boot Disk URI: '%s'", P); strncpy(settings.imgread.DefaultImage,(strlen(P)>=7)&&!memcmp( P,"file://",7)? P+7:P,sizeof(settings.imgread.DefaultImage)); settings.imgread.DefaultImage[sizeof(settings.imgread.DefaultImage) - 1] = '\0'; @@ -283,7 +283,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setGameUri(JNIEnv *en { // Get filename string from Java const char* file_path = env->GetStringUTFChars(fileName, 0); - printf("Game Disk URI: '%s'\n", file_path); + INFO_LOG(BOOT, "Game Disk URI: '%s'", file_path); strncpy(gamedisk, strlen(file_path) >= 7 && !memcmp(file_path, "file://", 7) ? file_path + 7 : file_path, sizeof(gamedisk)); gamedisk[sizeof(gamedisk) - 1] = '\0'; env->ReleaseStringUTFChars(fileName, file_path); @@ -303,7 +303,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_diskSwap(JNIEnv *env, const char *P = env->GetStringUTFChars(disk, 0); if (!P) settings.imgread.DefaultImage[0] = '\0'; else { - printf("Swap Disk URI: '%s'\n", P); + INFO_LOG(GDROM, "Swap Disk URI: '%s'", P); strncpy(settings.imgread.DefaultImage,(strlen(P)>=7)&&!memcmp( P,"file://",7)? P+7:P,sizeof(settings.imgread.DefaultImage)); settings.imgread.DefaultImage[sizeof(settings.imgread.DefaultImage) - 1] = '\0'; @@ -360,19 +360,19 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobj if (param==0) { KillTex=true; - printf("Killing texture cache\n"); + INFO_LOG(RENDERER, "Killing texture cache"); } if (param==1) { settings.pvr.ta_skip^=1; - printf("settings.pvr.ta_skip: %d\n",settings.pvr.ta_skip); + INFO_LOG(RENDERER, "settings.pvr.ta_skip: %d", settings.pvr.ta_skip); } if (param==2) { #if FEAT_SHREC != DYNAREC_NONE print_stats=true; - printf("Storing blocks ...\n"); + INFO_LOG(DYNAREC, "Storing blocks ..."); #endif } } @@ -393,10 +393,10 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env, job { if (id==1) { - printf("Loading symtable (%p,%p,%d,%p)\n",env,obj,id,d); + INFO_LOG(DYNAREC, "Loading symtable (%p,%p,%d,%p)",env,obj,id,d); jsize len=env->GetArrayLength(d); u8* syms=(u8*)malloc((size_t)len); - printf("Loading symtable to %8s, %d\n",syms,len); + INFO_LOG(DYNAREC, "Loading symtable to %8s, %d",syms,len); env->GetByteArrayRegion(d,0,len,(jbyte*)syms); sample_Syms(syms, (size_t)len); } diff --git a/shell/android-studio/reicast/src/main/jni/src/android_gamepad.h b/shell/android-studio/reicast/src/main/jni/src/android_gamepad.h index c1fe2b465..10fb4e977 100644 --- a/shell/android-studio/reicast/src/main/jni/src/android_gamepad.h +++ b/shell/android-studio/reicast/src/main/jni/src/android_gamepad.h @@ -92,7 +92,7 @@ public: { _name = name; _unique_id = unique_id; - printf("Android: Opened joystick %d on port %d: '%s' descriptor '%s'", id, maple_port, _name.c_str(), _unique_id.c_str()); + INFO_LOG(INPUT, "Android: Opened joystick %d on port %d: '%s' descriptor '%s'", id, maple_port, _name.c_str(), _unique_id.c_str()); if (id == VIRTUAL_GAMEPAD_ID) { input_mapper = new IdentityInputMapping(); @@ -104,7 +104,6 @@ public: axis_ranges[DC_AXIS_LT] = 255; axis_min_values[DC_AXIS_RT] = 0; axis_ranges[DC_AXIS_RT] = 255; - printf("\n"); } else if (!find_mapping()) { @@ -113,14 +112,14 @@ public: else input_mapper = new DefaultInputMapping(); save_mapping(); - printf("using default mapping\n"); + INFO_LOG(INPUT, "using default mapping"); } else - printf("using custom mapping '%s'\n", input_mapper->name.c_str()); + INFO_LOG(INPUT, "using custom mapping '%s'", input_mapper->name.c_str()); } virtual ~AndroidGamepadDevice() override { - printf("Android: Joystick '%s' on port %d disconnected\n", _name.c_str(), maple_port()); + INFO_LOG(INPUT, "Android: Joystick '%s' on port %d disconnected", _name.c_str(), maple_port()); } static std::shared_ptr GetAndroidGamepad(int id) diff --git a/shell/android-studio/reicast/src/main/jni/src/utils.cpp b/shell/android-studio/reicast/src/main/jni/src/utils.cpp index 699170708..b8e64b5c1 100644 --- a/shell/android-studio/reicast/src/main/jni/src/utils.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/utils.cpp @@ -3,21 +3,21 @@ zip* APKArchive; void setAPK (const char* apkPath) { - LOGI("Loading APK %s", apkPath); - APKArchive = zip_open(apkPath, 0, NULL); - if (APKArchive == NULL) { - LOGE("Error loading APK"); - return; - } + INFO_LOG(COMMON, "Loading APK %s", apkPath); + APKArchive = zip_open(apkPath, 0, NULL); + if (APKArchive == NULL) { + ERROR_LOG(COMMON, "Error loading APK"); + return; + } - //Just for debug, print APK contents - int numFiles = zip_get_num_files(APKArchive); - for (int i=0; i Date: Mon, 1 Jul 2019 22:45:11 +0200 Subject: [PATCH 121/158] win32 build fix --- core/oslib/audiobackend_directsound.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/oslib/audiobackend_directsound.cpp b/core/oslib/audiobackend_directsound.cpp index dbd8b3f11..b9f47ff5d 100644 --- a/core/oslib/audiobackend_directsound.cpp +++ b/core/oslib/audiobackend_directsound.cpp @@ -167,7 +167,8 @@ static u32 directsound_push(void* frame, u32 samples, bool wait) */ while (!directsound_push_nw(frame, samples) && wait) - 0 && INFO_LOG(AUDIO, "FAILED waiting on audio FAILED %d", directsound_getusedSamples()); + //DEBUG_LOG(AUDIO, "FAILED waiting on audio FAILED %d", directsound_getusedSamples()) + ; return 1; } From b540b437ee56fd7e140b3d12df1a45d88cac45e7 Mon Sep 17 00:00:00 2001 From: flyinghead Date: Thu, 4 Jul 2019 09:36:22 +0200 Subject: [PATCH 122/158] win32: unprotect ram regions individually in blockmanager fixes abort when starting game in windows --- core/hw/sh4/dyna/blockmanager.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 008345abe..1a72a7219 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -408,7 +408,18 @@ void bm_Reset() protected_blocks = 0; unprotected_blocks = 0; - mem_region_unlock(virt_ram_base + 0x0C000000, 0x10000000 - 0x0C000000); + // Windows cannot lock/unlock a region spanning more than one VirtualAlloc or MapViewOfFile + // so we have to unlock each region individually + // No need for this mess in 4GB mode since windows doesn't use it +#if RAM_SIZE == 16 * 1024 * 1024 + mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); +#else + mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); +#endif if (_nvmem_4gb_space()) { mem_region_unlock(virt_ram_base + 0x8C000000, 0x90000000 - 0x8C000000); From 18bcb81682772c2c45b1b7e8f4997d2414d97f16 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 4 Jul 2019 17:33:26 +0200 Subject: [PATCH 123/158] naomi: minimal emulation of 840-0001E comm board makes gunsur2 and gunsur2j boot various minor naomi changes --- core/hw/naomi/awcartridge.cpp | 14 +++--- core/hw/naomi/awcartridge.h | 2 +- core/hw/naomi/gdcartridge.cpp | 5 +- core/hw/naomi/naomi_cart.cpp | 88 +++++++++++++++++++++++++++++++++-- core/hw/naomi/naomi_cart.h | 7 +++ core/hw/naomi/naomi_regs.h | 7 +++ 6 files changed, 110 insertions(+), 13 deletions(-) diff --git a/core/hw/naomi/awcartridge.cpp b/core/hw/naomi/awcartridge.cpp index 136ef4215..68428e8c6 100644 --- a/core/hw/naomi/awcartridge.cpp +++ b/core/hw/naomi/awcartridge.cpp @@ -194,7 +194,7 @@ u32 AWCartridge::ReadMem(u32 address, u32 size) { return retval; } default: - EMUERROR("%X, %d", address, size); + INFO_LOG(NAOMI, "Unhandled awcart read %X, %d", address, size); return 0xffff; } } @@ -209,7 +209,7 @@ void AWCartridge::WriteMem(u32 address, u32 data, u32 size) break; case AW_EPR_OFFSETL_addr: - epr_offset = (epr_offset & 0xffff0000) | data; + epr_offset = (epr_offset & 0xffff0000) | (u16)data; recalc_dma_offset(EPR); break; @@ -229,18 +229,19 @@ void AWCartridge::WriteMem(u32 address, u32 data, u32 size) break; case AW_MPR_FILE_OFFSETL_addr: - mpr_file_offset = (mpr_file_offset & 0xffff0000) | data; + mpr_file_offset = (mpr_file_offset & 0xffff0000) | (u16)data; recalc_dma_offset(MPR_FILE); break; case AW_PIO_DATA_addr: // write to ROM board address space, including FlashROM programming using CFI (TODO) + DEBUG_LOG(NAOMI, "Write to AW_PIO_DATA: %x", data); if (epr_offset == 0x7fffff) mpr_bank = data & 3; break; default: - INFO_LOG(NAOMI, "%X: %d sz %d", address, data, size); + INFO_LOG(NAOMI, "Unhandled awcart write %X: %d sz %d", address, data, size); break; } } @@ -389,10 +390,11 @@ void AWCartridge::recalc_dma_offset(int mode) void *AWCartridge::GetDmaPtr(u32 &limit) { + limit = std::min(std::min(limit, (u32)32), dma_limit - dma_offset); u32 offset = dma_offset / 2; - for (int i = 0; i < 16; i++) + for (int i = 0; i < limit / 2; i++) decrypted_buf[i] = decrypt16(offset + i); - limit = min(limit, (u32)32); + // printf("AWCART Decrypted data @ %08x:\n", dma_offset); // for (int i = 0; i < 16; i++) // { diff --git a/core/hw/naomi/awcartridge.h b/core/hw/naomi/awcartridge.h index f7072dcb5..079be3b77 100644 --- a/core/hw/naomi/awcartridge.h +++ b/core/hw/naomi/awcartridge.h @@ -53,7 +53,7 @@ private: static const u8 permutation_table[4][16]; static const sbox_set sboxes_table[4]; static u16 decrypt(u16 cipherText, u32 address, const u32 key); - u16 decrypt16(u32 address) { return decrypt(((u16 *)RomPtr)[address], address, rombd_key); } + u16 decrypt16(u32 address) { return decrypt(((u16 *)RomPtr)[address % (RomSize / 2)], address, rombd_key); } void set_key(); void recalc_dma_offset(int mode); diff --git a/core/hw/naomi/gdcartridge.cpp b/core/hw/naomi/gdcartridge.cpp index 30385edf6..c57f6ae96 100644 --- a/core/hw/naomi/gdcartridge.cpp +++ b/core/hw/naomi/gdcartridge.cpp @@ -499,7 +499,7 @@ void GDCartridge::device_start() (u64(picdata[0x29]) << 0)); } - DEBUG_LOG(NAOMI, "key is %08x%08x\n", (u32)((key & 0xffffffff00000000ULL)>>32), (u32)(key & 0x00000000ffffffffULL)); + DEBUG_LOG(NAOMI, "key is %08x%08x", (u32)((key & 0xffffffff00000000ULL)>>32), (u32)(key & 0x00000000ffffffffULL)); u8 buffer[2048]; std::string gdrom_path = get_game_basename() + "/" + gdrom_name; @@ -596,7 +596,10 @@ void GDCartridge::device_reset() void *GDCartridge::GetDmaPtr(u32 &size) { if (dimm_data == NULL) + { + size = 0; return NULL; + } dimm_cur_address = DmaOffset & (dimm_data_size-1); size = min(size, dimm_data_size - dimm_cur_address); return dimm_data + dimm_cur_address; diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index a28796e4e..209df28cb 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -1,3 +1,24 @@ +/* + This file is part of reicast. + + reicast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + reicast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with reicast. If not, see . +*/ +// Naomi comm board emulation from mame +// https://github.com/mamedev/mame/blob/master/src/mame/machine/m3comm.cpp +// license:BSD-3-Clause +// copyright-holders:MetalliC + #include "naomi_cart.h" #include "naomi_regs.h" #include "cfg/cfg.h" @@ -779,12 +800,38 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); return reg_dimm_4c; - case 0x18: - DEBUG_LOG(NAOMI, "naomi reg 0x18 : returning random data"); - return 0x4000^rand(); - break; + case NAOMI_COMM2_CTRL_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL read"); + return comm_ctrl; - default: break; + case NAOMI_COMM2_OFFSET_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_OFFSET read"); + return comm_offset; + + case NAOMI_COMM2_DATA_addr & 255: + { + DEBUG_LOG(NAOMI, "NAOMI_COMM2_DATA read @ %04x", comm_offset); + u16 value; + if (comm_ctrl & 1) + value = m68k_ram[comm_offset / 2]; + else { + // TODO u16 *commram = (u16*)membank("comm_ram")->base(); + value = comm_ram[comm_offset / 2]; + } + comm_offset += 2; + return value; + } + + case NAOMI_COMM2_STATUS0_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS0 read"); + return comm_offset_status0; + + case NAOMI_COMM2_STATUS1_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS1 read"); + return comm_offset_status1; + + default: + break; } DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", address, size); @@ -903,6 +950,37 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) DEBUG_LOG(NAOMI, "naomi WriteMem: %X <= %X, %d", address, data, size); return; + case NAOMI_COMM2_CTRL_addr & 255: + comm_ctrl = (u16)data; + DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL set to %x", comm_ctrl); + return; + + case NAOMI_COMM2_OFFSET_addr & 255: + comm_offset = (u16)data; + DEBUG_LOG(NAOMI, "NAOMI_COMM2_OFFSET set to %x", comm_offset); + return; + + case NAOMI_COMM2_DATA_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_DATA written @ %04x %04x", comm_offset, (u16)data); + if (comm_ctrl & 1) + m68k_ram[comm_offset / 2] = (u16)data; + else { + // TODO u16 *commram = (u16*)membank("comm_ram")->base(); + comm_ram[comm_offset / 2] = (u16)data; + } + comm_offset += 2; + return; + + case NAOMI_COMM2_STATUS0_addr & 255: + comm_offset_status0 = (u16)data; + DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS0 set to %x", comm_offset_status0); + return; + + case NAOMI_COMM2_STATUS1_addr & 255: + comm_offset_status1 = (u16)data; + DEBUG_LOG(NAOMI, "NAOMI_COMM2_STATUS1 set to %x", comm_offset_status1); + return; + default: break; } DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", address, data, size); diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h index e189bb107..55eb75461 100644 --- a/core/hw/naomi/naomi_cart.h +++ b/core/hw/naomi/naomi_cart.h @@ -52,6 +52,13 @@ protected: u32 DmaOffset; u32 DmaCount; u32 key; + // Naomi 840-0001E communication board + u16 comm_ctrl = 0xC000; + u16 comm_offset = 0; + u16 comm_offset_status0 = 0; + u16 comm_offset_status1 = 0; + u16 m68k_ram[128 * 1024 / sizeof(u16)]; + u16 comm_ram[64 * 1024 / sizeof(u16)]; }; class DecryptedCartridge : public NaomiCartridge diff --git a/core/hw/naomi/naomi_regs.h b/core/hw/naomi/naomi_regs.h index 6ef41386d..9def08341 100644 --- a/core/hw/naomi/naomi_regs.h +++ b/core/hw/naomi/naomi_regs.h @@ -12,6 +12,13 @@ enum NAOMI_DMA_OFFSETH_addr = 0x5f700C, NAOMI_DMA_OFFSETL_addr = 0x5f7010, NAOMI_DMA_COUNT_addr = 0x5f7014, + // Naomi 840-0001E communication board + NAOMI_COMM2_CTRL_addr = 0x5f7018, + NAOMI_COMM2_OFFSET_addr = 0x5f701C, + NAOMI_COMM2_DATA_addr = 0x5F7020, + NAOMI_COMM2_STATUS0_addr = 0x5F7024, + NAOMI_COMM2_STATUS1_addr = 0x5F7028, + NAOMI_BOARDID_WRITE_addr = 0x5F7078, NAOMI_BOARDID_READ_addr = 0x5F707C, NAOMI_COMM_OFFSET_addr = 0x5F7050, From c3a42b0b220c45d3f798e00e035d9f9cca9184cb Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 7 Jul 2019 20:31:36 +0200 Subject: [PATCH 124/158] wince: online support Use default asyncmap for LCP control packets Delay reading from picotcp ppp stream when connecting Accept [PSH,SYN] as valid tcp connect packet Add PBA Tour Bowling 2001 as wince game Disable vmem32 for StarLancer and Maximum Pool (req'd for online support) --- core/deps/picotcp/include/arch/pico_posix.h | 2 +- core/deps/picotcp/modules/pico_dev_ppp.c | 53 ++++++++++++++------- core/deps/picotcp/modules/pico_tcp.c | 4 +- core/hw/modem/modem.cpp | 37 +++++++------- core/hw/modem/modem_regs.h | 9 ++-- core/nullDC.cpp | 11 ++++- 6 files changed, 74 insertions(+), 42 deletions(-) diff --git a/core/deps/picotcp/include/arch/pico_posix.h b/core/deps/picotcp/include/arch/pico_posix.h index 5ddd1fa6d..de9bab022 100644 --- a/core/deps/picotcp/include/arch/pico_posix.h +++ b/core/deps/picotcp/include/arch/pico_posix.h @@ -16,7 +16,7 @@ #define TIME_PRESCALE #define PICO_SUPPORT_THREADING */ -#ifdef RELEASE +#if defined(RELEASE) && !defined(DEBUGFAST) #define dbg(...) #else #define dbg printf diff --git a/core/deps/picotcp/modules/pico_dev_ppp.c b/core/deps/picotcp/modules/pico_dev_ppp.c index e1ba6384a..bc3902448 100644 --- a/core/deps/picotcp/modules/pico_dev_ppp.c +++ b/core/deps/picotcp/modules/pico_dev_ppp.c @@ -543,7 +543,7 @@ static int ppp_fcs_verify(uint8_t *buf, uint32_t len) } /* Serial send (DTE->DCE) functions */ -static int pico_ppp_ctl_send(struct pico_device *dev, uint16_t code, uint8_t *pkt, uint32_t len) +static int pico_ppp_ctl_send(struct pico_device *dev, uint16_t code, uint8_t *pkt, uint32_t len, uint32_t no_escape) { struct pico_device_ppp *ppp = (struct pico_device_ppp *) dev; uint16_t fcs; @@ -567,7 +567,15 @@ static int pico_ppp_ctl_send(struct pico_device *dev, uint16_t code, uint8_t *pk pkt[len - 3] = (uint8_t)(fcs & 0xFFu); pkt[len - 2] = (uint8_t)((fcs & 0xFF00u) >> 8); pkt[len - 1] = PPPF_FLAG_SEQ; + uint32_t asyncmap; + if (no_escape) + { + asyncmap = ppp->asyncmap; + ppp->asyncmap = 0xffffffff; + } ppp_serial_send_escape(ppp, pkt, (int)len); + if (no_escape) + ppp->asyncmap = asyncmap; return (int)len; } @@ -912,7 +920,8 @@ static void lcp_send_configure_request(struct pico_device_ppp *ppp) sizeof(struct pico_lcp_hdr) + /* LCP HDR */ optsize + /* Actual options size */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1u) /* STOP Byte */ + 1u), /* STOP Byte */ + 1 /* no escape */ ); PICO_FREE(lcpbuf); ppp->timer_val = PICO_PPP_DEFAULT_TIMER; @@ -1007,8 +1016,9 @@ static void lcp_send_configure_ack(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1 /* STOP Byte */ - ); + 1, /* STOP Byte */ + 1 /* no escape */ + ); } static void lcp_send_terminate_request(struct pico_device_ppp *ppp) @@ -1023,7 +1033,8 @@ static void lcp_send_terminate_request(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ sizeof(struct pico_lcp_hdr) + /* Actual options size + hdr (whole lcp packet) */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1 /* STOP Byte */ + 1, /* STOP Byte */ + 1 /* no escape */ ); lcp_timer_start(ppp, PPP_TIMER_ON_LCPTERM); } @@ -1042,7 +1053,8 @@ static void lcp_send_terminate_ack(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1 /* STOP Byte */ + 1, /* STOP Byte */ + 1 /* no escape */ ); } @@ -1088,7 +1100,8 @@ static void lcp_send_configure_nack(struct pico_device_ppp *ppp) sizeof(struct pico_lcp_hdr) + /* LCP HDR */ dstopts_len + /* Actual options size */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1u) /* STOP Byte */ + 1u), /* STOP Byte */ + 1 /* no escape */ ); } @@ -1216,7 +1229,8 @@ static void ipcp_send_ack(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ short_be(ipcpreq->len) + /* Actual options size + hdr (whole ipcp packet) */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1 /* STOP Byte */ + 1, /* STOP Byte */ + 0 /* escape */ ); } @@ -1267,7 +1281,8 @@ static void ipcp_send_req(struct pico_device_ppp *ppp) (uint32_t)(prefix + /* PPP Header, etc. */ (uint32_t)len + /* IPCP Header + options */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1u) /* STOP Byte */ + 1u), /* STOP Byte */ + 0 /* escape */ ); } @@ -1295,7 +1310,8 @@ static void ipcp_reject_vj(struct pico_device_ppp *ppp, uint8_t *comp_req) sizeof(struct pico_ipcp_hdr) + /* LCP HDR */ IPCP_VJ_LEN + /* Actual options size */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1u) /* STOP Byte */ + 1u), /* STOP Byte */ + 0 /* escape */ ); } @@ -1574,8 +1590,9 @@ static void lcp_send_echo_reply(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1 /* STOP Byte */ - ); + 1, /* STOP Byte */ + 0 /* escape */ + ); } static const struct pico_ppp_fsm ppp_lcp_fsm[PPP_LCP_STATE_MAX][PPP_LCP_EVENT_MAX] = { @@ -1618,7 +1635,7 @@ static const struct pico_ppp_fsm ppp_lcp_fsm[PPP_LCP_STATE_MAX][PPP_LCP_EVENT_MA [PPP_LCP_STATE_CLOSED] = { [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_CLOSED, {} }, [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_INITIAL, {} }, - [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request} }, + [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSED, {} }, [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_CLOSED, {} }, [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_CLOSED, {} }, @@ -1871,7 +1888,8 @@ static void auth_req(struct pico_device_ppp *ppp) PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ pap_len + /* Authentication packet len */ PPP_FCS_SIZE + /* FCS */ - 1) /* STOP Byte */ + 1), /* STOP Byte */ + 0 /* escape */ ); PICO_FREE(req); } @@ -1916,7 +1934,8 @@ static void auth_rsp(struct pico_device_ppp *ppp) 1 + /* Value length */ CHAP_MD5_SIZE + /* Actual payload size */ PPP_FCS_SIZE + /* FCS at the end of the frame */ - 1) /* STOP Byte */ + 1), /* STOP Byte */ + 0 /* escape */ ); } @@ -2051,7 +2070,8 @@ static void ipcp_send_nack(struct pico_device_ppp *ppp) ppp_dbg("Sending IPCP CONF NAK\n"); pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_IPCP, ipcp_req, /* Start of PPP packet */ - (uint32_t)sizeof(ipcp_req)); + (uint32_t)sizeof(ipcp_req), + 0); /* escape */ } static void ipcp_bring_up(struct pico_device_ppp *ppp) @@ -2329,6 +2349,7 @@ struct pico_device *pico_ppp_create(void) ppp->lcp_state = PPP_LCP_STATE_INITIAL; ppp->auth_state = PPP_AUTH_STATE_INITIAL; ppp->ipcp_state = PPP_IPCP_STATE_INITIAL; + ppp->asyncmap = 0xffffffff; ppp->timer = pico_timer_add(1000, pico_ppp_tick, ppp); if (!ppp->timer) { diff --git a/core/deps/picotcp/modules/pico_tcp.c b/core/deps/picotcp/modules/pico_tcp.c index 8792e49aa..0384c8f5b 100644 --- a/core/deps/picotcp/modules/pico_tcp.c +++ b/core/deps/picotcp/modules/pico_tcp.c @@ -2770,7 +2770,7 @@ static uint8_t invalid_flags(struct pico_socket *s, uint8_t flags) static const uint8_t valid_flags[PICO_SOCKET_STATE_TCP_ARRAYSIZ][MAX_VALID_FLAGS] = { { /* PICO_SOCKET_STATE_TCP_UNDEF */ 0, }, { /* PICO_SOCKET_STATE_TCP_CLOSED */ 0, }, - { /* PICO_SOCKET_STATE_TCP_LISTEN */ PICO_TCP_SYN }, + { /* PICO_SOCKET_STATE_TCP_LISTEN */ PICO_TCP_SYN, PICO_TCP_SYN | PICO_TCP_PSH }, { /* PICO_SOCKET_STATE_TCP_SYN_SENT */ PICO_TCP_SYNACK, PICO_TCP_RST, PICO_TCP_RSTACK}, { /* PICO_SOCKET_STATE_TCP_SYN_RECV */ PICO_TCP_SYN, PICO_TCP_ACK, PICO_TCP_PSH, PICO_TCP_PSHACK, PICO_TCP_FINACK, PICO_TCP_FINPSHACK, PICO_TCP_RST}, { /* PICO_SOCKET_STATE_TCP_ESTABLISHED*/ PICO_TCP_SYN, PICO_TCP_SYNACK, PICO_TCP_ACK, PICO_TCP_PSH, PICO_TCP_PSHACK, PICO_TCP_FIN, PICO_TCP_FINACK, PICO_TCP_FINPSHACK, PICO_TCP_RST, PICO_TCP_RSTACK}, @@ -2850,7 +2850,7 @@ int pico_tcp_input(struct pico_socket *s, struct pico_frame *f) if(invalid_flags(s, flags)) { pico_tcp_reply_rst(f); } - else if (flags == PICO_TCP_SYN) { + else if (flags == PICO_TCP_SYN || flags == (PICO_TCP_SYN | PICO_TCP_PSH)) { tcp_action_call(action->syn, s, f); } else if (flags == (PICO_TCP_SYN | PICO_TCP_ACK)) { tcp_action_call(action->synack, s, f); diff --git a/core/hw/modem/modem.cpp b/core/hw/modem/modem.cpp index 6ac7541fd..a4f970137 100644 --- a/core/hw/modem/modem.cpp +++ b/core/hw/modem/modem.cpp @@ -121,7 +121,8 @@ static void ControllerTestEnd(); static void DSPTestStart(); static void DSPTestEnd(); -static double last_dial_time; +static u64 last_dial_time; +static u64 connected_time; #ifndef RELEASE static double last_comm_stats; @@ -131,7 +132,7 @@ static FILE *recv_fp; static FILE *sent_fp; #endif -static int modem_sched_func(int tag, int c, int j) +static int modem_sched_func(int tag, int cycles, int jitter) { #ifndef RELEASE if (os_GetSeconds() - last_comm_stats >= 2) @@ -166,7 +167,7 @@ static int modem_sched_func(int tag, int c, int j) switch (connect_state) { case DIALING: - if (last_dial_time != 0 && os_GetSeconds() - last_dial_time > 0.99) + if (last_dial_time != 0 && sh4_sched_now64() - last_dial_time >= SH4_MAIN_CLOCK + jitter) { LOG("Switching to RINGING state"); connect_state = RINGING; @@ -174,7 +175,7 @@ static int modem_sched_func(int tag, int c, int j) } else { - last_dial_time = os_GetSeconds(); + last_dial_time = sh4_sched_now64(); modem_regs.reg1e.TDBE = 1; schedule_callback(1000); // To switch to Ringing state @@ -201,7 +202,7 @@ static int modem_sched_func(int tag, int c, int j) SET_STATUS_BIT(0x0f, modem_regs.reg0f.RI, 0); SET_STATUS_BIT(0x0b, modem_regs.reg0b.ATV25, 0); - callback_cycles = SH4_MAIN_CLOCK / 1000000 * 500; // 500 ms + callback_cycles = SH4_MAIN_CLOCK / 1000 * 500; // 500 ms connect_state = PRE_CONNECTED; break; @@ -214,10 +215,13 @@ static int modem_sched_func(int tag, int c, int j) { // V8 AUTO mode dspram[0x302] |= 1 << 4; // protocol octet received + dspram[0x302] = (dspram[0x302] & 0x1f) | (dspram[0x304] & 0xe0); // Received Call Function dspram[0x301] |= 1 << 4; // JM detected dspram[0x303] |= 0xE0; // Received protocol bits (?) - dspram[0x2e3] |= 5; // Symbol rate 3429 - dspram[0x239] |= 12; // RTD 0 @ 3429 sym rate + dspram[0x2e3] = 5; // Symbol rate 3429 + dspram[0x2e4] = 0xe; // V.34 Receiver Speed 33.6 + dspram[0x2e5] = 0xe; // V.34 Transmitter Speed 33.6 + dspram[0x239] = 12; // RTD 0 @ 3429 sym rate if (modem_regs.reg08.ASYN) { modem_regs.reg12 = 0xce; // CONF V34 - K56flex @@ -253,7 +257,7 @@ static int modem_sched_func(int tag, int c, int j) if (modem_regs.reg02.v0.RTSDE) SET_STATUS_BIT(0x0f, modem_regs.reg0f.RTSDT, 1); - // What is this? This is required for games to detect the connection + // Energy detected. Required for games to detect the connection SET_STATUS_BIT(0x0f, modem_regs.reg0f.FED, 1); // V.34 Remote Modem Data Rate Capability @@ -263,6 +267,7 @@ static int modem_sched_func(int tag, int c, int j) start_pppd(); connect_state = CONNECTED; callback_cycles = SH4_MAIN_CLOCK / 1000000 * 238; // 238 us + connected_time = 0; break; @@ -276,10 +281,13 @@ static int modem_sched_func(int tag, int c, int j) LOG("modem_regs %02x == %02x", i, modem_regs.ptr[i]); } #endif + if (connected_time == 0) + connected_time = sh4_sched_now64(); if (!modem_regs.reg1e.RDBF) { int c = read_pppd(); - if (c >= 0) + // Delay reading from ppp to avoid choking WinCE + if (c >= 0 && sh4_sched_now64() - connected_time >= SH4_MAIN_CLOCK / 4) { //LOG("pppd received %02x", c); #ifndef RELEASE @@ -572,10 +580,7 @@ static void ModemNormalWrite(u32 reg, u32 data) u32 dspram_addr = modem_regs.reg1c_1d.MEMADD_l | (modem_regs.reg1c_1d.MEMADD_h << 8); if (modem_regs.reg1c_1d.MEMW) { - //LOG("DSP mem Write%s address %08x = %x", - // word_dspram_write ? " (w)" : "", - // dspram_addr, - // modem_regs.reg18_19 ); + LOG("DSP mem Write%s address %08x = %x", word_dspram_write ? " (w)" : "", dspram_addr, modem_regs.reg18_19); if (word_dspram_write) { if (dspram_addr & 1) @@ -595,9 +600,7 @@ static void ModemNormalWrite(u32 reg, u32 data) modem_regs.reg18_19 = dspram[dspram_addr] | (dspram[dspram_addr + 1] << 8); else modem_regs.reg18_19 = *(u16*)&dspram[dspram_addr]; - //LOG("DSP mem Read address %08x == %x", - // dspram_addr, - // modem_regs.reg18_19 ); + LOG("DSP mem Read address %08x == %x", dspram_addr, modem_regs.reg18_19 ); } } break; @@ -631,7 +634,7 @@ static void ModemNormalWrite(u32 reg, u32 data) break; default: - //printf("ModemNormalWrite : undef %03X=%X\n",reg,data); + //LOG("ModemNormalWrite : undef %03X = %X", reg, data); break; } update_interrupt(); diff --git a/core/hw/modem/modem_regs.h b/core/hw/modem/modem_regs.h index 2c013e65c..08e739c59 100644 --- a/core/hw/modem/modem_regs.h +++ b/core/hw/modem/modem_regs.h @@ -22,7 +22,7 @@ */ #pragma once -#pragma pack(1) +#pragma pack(push, 1) union modemreg_t { u8 ptr[0x21]; @@ -318,6 +318,7 @@ union modemreg_t } reg1f; }; }; +#pragma pack(pop) u8 regs_write_mask[] = { //00 Receive Data Buffer (RBUFFER)/Voice Receive Data Buffer (VBUFR) @@ -433,7 +434,7 @@ static const u8 por_dspram[] = /* 0x060 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x090 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 0x090 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9F avail mod type (wince): 80, 30, 00? /* 0x0A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0B0 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -458,10 +459,10 @@ static const u8 por_dspram[] = /* 0x1E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 0x200 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 0x200 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 204-5 rate_seq_R2, 208-209 rate_seq_R3 /* 0x210 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0xAD, 0x08, 0x07, 0x99, 0x00, 0x23, 0xA0, /* 0x220 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, -/* 0x230 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 0x230 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 239 Round Trip Far Echo Delay /* 0x240 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 26F Saved Filtered EQM (???) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 51ea0b5f6..a2bedf745 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -141,7 +141,7 @@ void LoadSpecialSettings() full_mmu_game = false; disable_vmem32_game = false; - if (reios_windows_ce) + if (reios_windows_ce || !strncmp("T26702N", reios_product_number, 7)) // PBA Tour Bowling 2001 { INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); settings.rend.ExtraDepthScale = 0.1; @@ -216,7 +216,14 @@ void LoadSpecialSettings() // Marionette Company || !strncmp("T5202M", reios_product_number, 6) // Marionette Company 2 - || !strncmp("T5203M", reios_product_number, 6)) + || !strncmp("T5203M", reios_product_number, 6) + // Maximum Pool (for online support) + || !strncmp("T11010N", reios_product_number, 7) + // StarLancer (US) (for online support) + || !strncmp("T40209N", reios_product_number, 7) + // StarLancer (EU) (for online support) + || !strncmp("T17723D 05", reios_product_number, 10) + ) { INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", reios_product_number); settings.dynarec.disable_vmem32 = true; From 9eef02a1e81ce0244936722bc340b90be49c345c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 7 Jul 2019 22:13:43 +0200 Subject: [PATCH 125/158] pvr: ignore Z Write Disable for punch-through polys? tentative fix for Worms World Party --- core/rend/gl4/gldraw.cpp | 8 +++++++- core/rend/gles/gldraw.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index ee3e72694..cfe1302be 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -245,7 +245,13 @@ template // Depth buffer is updated in pass 0 (and also in pass 1 for OP PT) if (pass < 2) - glcache.DepthMask(!gp->isp.ZWriteDis); + { + // Ignore ZWriteDis for punch-through? fixes Worms World Party + if (Type == ListType_Punch_Through) + glcache.DepthMask(GL_TRUE); + else + glcache.DepthMask(!gp->isp.ZWriteDis); + } else glcache.DepthMask(GL_FALSE); } diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 2a1b76cd1..4f0c746ce 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -263,7 +263,13 @@ __forceinline if (SortingEnabled && !settings.rend.PerStripSorting) glcache.DepthMask(GL_FALSE); else - glcache.DepthMask(!gp->isp.ZWriteDis); + { + // Ignore ZWriteDis for punch-through? fixes Worms World Party + if (Type == ListType_Punch_Through) + glcache.DepthMask(GL_TRUE); + else + glcache.DepthMask(!gp->isp.ZWriteDis); + } } template From dbbc1819e872fc066e1328311d23d2fc28a93792 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 7 Jul 2019 22:56:23 +0200 Subject: [PATCH 126/158] remove NACL --- core/build.h | 2 +- core/linux/common.cpp | 8 +- core/nacl/nacl.cpp | 293 ----------------------- core/nacl/nacl_lin.cpp | 18 -- core/rend/gles/gles.h | 2 +- core/types.h | 6 - shell/cmake/CMakeLists.txt | 1 - shell/nacl/Makefile | 52 ---- shell/nacl/background.js | 40 ---- shell/nacl/common.js | 474 ------------------------------------- shell/nacl/example.js | 19 -- shell/nacl/icon128.png | Bin 9897 -> 0 bytes shell/nacl/index.html | 27 --- shell/nacl_lin/Makefile | 124 ---------- 14 files changed, 5 insertions(+), 1061 deletions(-) delete mode 100644 core/nacl/nacl.cpp delete mode 100644 core/nacl/nacl_lin.cpp delete mode 100644 shell/nacl/Makefile delete mode 100644 shell/nacl/background.js delete mode 100644 shell/nacl/common.js delete mode 100644 shell/nacl/example.js delete mode 100644 shell/nacl/icon128.png delete mode 100644 shell/nacl/index.html delete mode 100644 shell/nacl_lin/Makefile diff --git a/core/build.h b/core/build.h index 2736a0cf9..3ba546c1d 100755 --- a/core/build.h +++ b/core/build.h @@ -211,7 +211,7 @@ #elif defined(TARGET_GCW0) #define HOST_OS OS_LINUX #define HOST_CPU CPU_MIPS -#elif defined(TARGET_NACL32) || defined(TARGET_EMSCRIPTEN) +#elif defined(TARGET_EMSCRIPTEN) #define HOST_OS OS_LINUX #define HOST_CPU CPU_GENERIC #elif defined(TARGET_IPHONE) diff --git a/core/linux/common.cpp b/core/linux/common.cpp index e98e0032e..11f523768 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -7,17 +7,15 @@ #define __USE_GNU 1 #include #endif -#if !defined(TARGET_NACL32) #include #include -#endif #include #include #include #include #include #include -#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_IPHONE) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN) && !defined(TARGET_OSX) && !defined(TARGET_OSX_X64) +#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_IPHONE) && !defined(TARGET_EMSCRIPTEN) && !defined(TARGET_OSX) && !defined(TARGET_OSX_X64) #include #include #endif @@ -177,7 +175,7 @@ void enable_runfast() } void linux_fix_personality() { - #if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_OS_MAC) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN) + #if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_OS_MAC) && !defined(TARGET_EMSCRIPTEN) DEBUG_LOG(BOOT, "Personality: %08X", personality(0xFFFFFFFF)); personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF)); DEBUG_LOG(BOOT, "Updated personality: %08X", personality(0xFFFFFFFF)); @@ -185,7 +183,7 @@ void linux_fix_personality() { } void linux_rpi2_init() { -#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_NACL32) && !defined(TARGET_EMSCRIPTEN) && defined(TARGET_VIDEOCORE) +#if !defined(TARGET_BSD) && !defined(_ANDROID) && !defined(TARGET_EMSCRIPTEN) && defined(TARGET_VIDEOCORE) void* handle; void (*rpi_bcm_init)(void); diff --git a/core/nacl/nacl.cpp b/core/nacl/nacl.cpp deleted file mode 100644 index eb81de6d1..000000000 --- a/core/nacl/nacl.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include -#include -#include -#include -#include "ppapi/cpp/instance.h" -#include "ppapi/cpp/module.h" -#include "ppapi/cpp/var.h" - -#include -#include "nacl_io/ioctl.h" -#include "nacl_io/nacl_io.h" - -#include "ppapi/cpp/graphics_3d.h" -#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h" -#include "ppapi/utility/completion_callback_factory.h" - -#include "types.h" -#include "maple_cfg.h" - -#include - -extern int screen_width,screen_height; -bool rend_single_frame(); -bool gles_init(); -extern "C" int reicast_main(int argc, char* argv[]); - -int msgboxf(const wchar* text,unsigned int type,...) -{ - va_list args; - - wchar temp[2048]; - va_start(args, type); - vsprintf(temp, text, args); - va_end(args); - - puts(temp); - return 0; -} - -int dc_init(int argc,wchar* argv[]); -void dc_run(); - -bool rend_framePending(); - -pthread_t emut; - -void* emuthread(void* ) { - printf("Emu thread starting up"); - char *Args[3]; - Args[0] = "dc"; - - set_user_config_dir("/http"); - set_user_data_dir("/http"); - - dc_init(1,Args); - dc_run(); - - return 0; -} - -namespace hello_world -{ - class HelloWorldInstance; - HelloWorldInstance* rei_instance; -class HelloWorldInstance : public pp::Instance { - public: - explicit HelloWorldInstance(PP_Instance instance) : pp::Instance(instance), callback_factory_(this) { - rei_instance = this; - printf("Reicast NACL loaded\n"); - nacl_io_init_ppapi(instance, pp::Module::Get()->get_browser_interface()); - - umount("/"); - mount("", "/", "memfs", 0, ""); - - mount("", /* source. Use relative URL */ - "/http", /* target */ - "httpfs", /* filesystemtype */ - 0, /* mountflags */ - ""); /* data */ - - - pthread_create(&emut, NULL, emuthread, 0); - } - virtual ~HelloWorldInstance() {} - - pp::CompletionCallbackFactory callback_factory_; - pp::Graphics3D context_; - int32_t width_; - int32_t height_; - - /// Called by the browser to handle the postMessage() call in Javascript. - /// Detects which method is being called from the message contents, and - /// calls the appropriate function. Posts the result back to the browser - /// asynchronously. - /// @param[in] var_message The message posted by the browser. The possible - /// messages are 'fortyTwo' and 'reverseText:Hello World'. Note that - /// the 'reverseText' form contains the string to reverse following a ':' - /// separator. - virtual void HandleMessage(const pp::Var& var_message); - - bool InitGL(int32_t new_width, int32_t new_height) { - if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) { - fprintf(stderr, "Unable to initialize GL PPAPI!\n"); - return false; - } - - const int32_t attrib_list[] = { - PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, - PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, - PP_GRAPHICS3DATTRIB_WIDTH, new_width, - PP_GRAPHICS3DATTRIB_HEIGHT, new_height, - PP_GRAPHICS3DATTRIB_NONE - }; - - context_ = pp::Graphics3D(this, attrib_list); - if (!BindGraphics(context_)) { - fprintf(stderr, "Unable to bind 3d context!\n"); - context_ = pp::Graphics3D(); - glSetCurrentContextPPAPI(0); - return false; - } - - glSetCurrentContextPPAPI(context_.pp_resource()); - return true; - } - - virtual void DidChangeView(const pp::View& view) { - // Pepper specifies dimensions in DIPs (device-independent pixels). To - // generate a context that is at device-pixel resolution on HiDPI devices, - // scale the dimensions by view.GetDeviceScale(). - int32_t new_width = view.GetRect().width() * view.GetDeviceScale(); - int32_t new_height = view.GetRect().height() * view.GetDeviceScale(); - - if (context_.is_null()) { - if (!InitGL(new_width, new_height)) { - // failed. - return; - } - - verify(gles_init() == true); - RenderLoop(0); - } else { - // Resize the buffers to the new size of the module. - int32_t result = context_.ResizeBuffers(new_width, new_height); - if (result < 0) { - printf("Unable to resize buffers to %d x %d!\n"); - return; - } - } - - width_ = new_width; - height_ = new_height; - glViewport(0, 0, width_, height_); - printf("Resize: %d x %d\n", new_width, new_height); - } - - - void RenderLoop(int32_t) { - - screen_width = width_; - screen_height = height_; - - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (rend_framePending()) { - while (!rend_single_frame()) ; - printf("Rendered frame\n"); - } - - printf("Swapping buffers\n"); - context_.SwapBuffers( - callback_factory_.NewCallback(&HelloWorldInstance::RenderLoop)); - } - -}; - -void HelloWorldInstance::HandleMessage(const pp::Var& var_message) { - if (!var_message.is_string()) { - return; - } - - // Post the return result back to the browser. Note that HandleMessage() is - // always called on the main thread, so it's OK to post the return message - // directly from here. The return post is asynhronous: PostMessage returns - // immediately. - - //PostMessage(return_var); -} - -/// The Module class. The browser calls the CreateInstance() method to create -/// an instance of your NaCl module on the web page. The browser creates a new -/// instance for each tag with -/// type="application/x-nacl". -class HelloWorldModule : public pp::Module { - public: - HelloWorldModule() : pp::Module() { - - } - virtual ~HelloWorldModule() {} - - /// Create and return a HelloWorldInstance object. - /// @param[in] instance a handle to a plug-in instance. - /// @return a newly created HelloWorldInstance. - /// @note The browser is responsible for calling @a delete when done. - virtual pp::Instance* CreateInstance(PP_Instance instance) { - return new HelloWorldInstance(instance); - } -}; -} // namespace hello_world - -int nacl_printf(const wchar* text,...) -{ - va_list args; - - wchar temp[2048]; - va_start(args, text); - int rv = vsprintf(temp, text, args); - va_end(args); - - if (hello_world::rei_instance) - hello_world::rei_instance->PostMessage(pp::Var(temp)); - return rv; -} - -namespace pp { -/// Factory function called by the browser when the module is first loaded. -/// The browser keeps a singleton of this module. It calls the -/// CreateInstance() method on the object you return to make instances. There -/// is one instance per tag on the page. This is the main binding -/// point for your NaCl module with the browser. -/// @return new HelloWorldModule. -/// @note The browser is responsible for deleting returned @a Module. -Module* CreateModule() { - return new hello_world::HelloWorldModule(); -} -} // namespace pp - - -u16 kcode[4]; -u32 vks[4]; -s8 joyx[4],joyy[4]; -u8 rt[4],lt[4]; - -int get_mic_data(u8* buffer) { return 0; } -int push_vmu_screen(u8* buffer) { return 0; } - -void os_SetWindowText(const char * text) { - puts(text); -} - -void os_DoEvents() { - -} - -void os_SetupInput() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif -} - -void UpdateInputState(u32 port) { - -} - -void os_CreateWindow() { - -} - -void os_DebugBreak() { - exit(1); -} - -void* libPvr_GetRenderTarget() { - return 0; -} - -void* libPvr_GetRenderSurface() { - return 0; - -} - -bool gl_init(void*, void*) { - return true; -} - -void gl_term() { - -} - -void gl_swap() { - -} diff --git a/core/nacl/nacl_lin.cpp b/core/nacl/nacl_lin.cpp deleted file mode 100644 index a7e3e15ac..000000000 --- a/core/nacl/nacl_lin.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#define PUTS_REAL puts - -#include -#include - -int nacl_printf(const wchar* text,...) -{ - va_list args; - - wchar temp[2048]; - va_start(args, text); - int rv = vsprintf(temp, text, args); - va_end(args); - - PUTS_REAL(temp); - return rv; -} - diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index dec2f287d..430734527 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -3,7 +3,7 @@ #include #include "rend/rend.h" -#if (defined(GLES) && !defined(TARGET_NACL32) && HOST_OS != OS_DARWIN && !defined(USE_SDL)) || defined(_ANDROID) +#if (defined(GLES) && HOST_OS != OS_DARWIN && !defined(USE_SDL)) || defined(_ANDROID) #define USE_EGL #include #include diff --git a/core/types.h b/core/types.h index 94156d2d4..e4a0e3c0b 100644 --- a/core/types.h +++ b/core/types.h @@ -329,12 +329,6 @@ struct maple_device_instance #include #include -#if defined(TARGET_NACL32) - int nacl_printf(const wchar* Text,...); - #define printf nacl_printf - #define puts(X) printf("%s\n", X) -#endif - #if HOST_OS == OS_DARWIN int darw_printf(const wchar* Text,...); #define printf darw_printf diff --git a/shell/cmake/CMakeLists.txt b/shell/cmake/CMakeLists.txt index c5d855c37..aef683440 100644 --- a/shell/cmake/CMakeLists.txt +++ b/shell/cmake/CMakeLists.txt @@ -67,7 +67,6 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL Linux) else() message(FATAL_ERROR "Unknown target") # TODO, TARGET_GCW0 - # TODO, TARGET_NACL32 # TODO, TARGET_IPHONE # TODO, TARGET_PANDORA endif() diff --git a/shell/nacl/Makefile b/shell/nacl/Makefile deleted file mode 100644 index fec9cf250..000000000 --- a/shell/nacl/Makefile +++ /dev/null @@ -1,52 +0,0 @@ - -VALID_TOOLCHAINS := pnacl newlib glibc -CONFIG ?= Debug - -include $(NACL_SDK_ROOT)/tools/common.mk - -LOCAL_PATH := $(call my-dir) -NOT_ARM := 1 -CPP_REC := 1 -#NO_REND := 1 -NO_NIXPROF := 1 - - -RZDCY_SRC_DIR = ../../core - -include $(RZDCY_SRC_DIR)/core.mk - -TARGET = reicast -DEPS = nacl_io -LIBS = ppapi_gles2 ppapi_cpp ppapi pthread nacl_io - -CFLAGS = -Wno-error -Wno-ignored-attributes -CFLAGS += -O3 -fno-strict-aliasing -ffast-math -CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -CFLAGS += -D RELEASE -D TARGET_NO_JIT -D TARGET_NACL32 -DGLES -CFLAGS += -D TARGET_NO_EXCEPTIONS -D TARGET_NO_WEBUI -D TARGET_NO_COREIO_HTTP - -SOURCES = $(RZDCY_FILES) ../../core/nacl/nacl.cpp - -# Project Build flags -WARNINGS ?=-Wno-long-long -Wno-switch-enum -CXXFLAGS += -std=gnu++0x $(WARNINGS) - - -# Build rules generated by macros from common.mk: - -$(foreach dep,$(DEPS),$(eval $(call DEPEND_RULE,$(dep)))) - -$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS)))) - -# The PNaCl workflow uses both an unstripped and finalized/stripped binary. -# On NaCl, only produce a stripped binary for Release configs (not Debug). -ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG)))) -$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS))) -$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped)) -else -$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS))) -endif - -SHELL = sh - -$(eval $(call NMF_RULE,$(TARGET),)) diff --git a/shell/nacl/background.js b/shell/nacl/background.js deleted file mode 100644 index 5c3b1b7c9..000000000 --- a/shell/nacl/background.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -function makeURL(toolchain, config) { - return 'index.html?tc=' + toolchain + '&config=' + config; -} - -function createWindow(url) { - console.log('loading ' + url); - chrome.app.window.create(url, { - width: 1024, - height: 800, - frame: 'none' - }); -} - -function onLaunched(launchData) { - // Send and XHR to get the URL to load from a configuration file. - // Normally you won't need to do this; just call: - // - // chrome.app.window.create('', {...}); - // - // In the SDK we want to be able to load different URLs (for different - // toolchain/config combinations) from the commandline, so we to read - // this information from the file "run_package_config". - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'run_package_config', true); - xhr.onload = function() { - var toolchain_config = this.responseText.split(' '); - createWindow(makeURL.apply(null, toolchain_config)); - }; - xhr.onerror = function() { - // Can't find the config file, just load the default. - createWindow('index.html'); - }; - xhr.send(); -} - -chrome.app.runtime.onLaunched.addListener(onLaunched); diff --git a/shell/nacl/common.js b/shell/nacl/common.js deleted file mode 100644 index a70001551..000000000 --- a/shell/nacl/common.js +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Set to true when the Document is loaded IFF "test=true" is in the query -// string. -var isTest = false; - -// Set to true when loading a "Release" NaCl module, false when loading a -// "Debug" NaCl module. -var isRelease = true; - -// Javascript module pattern: -// see http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Namespaces -// In essence, we define an anonymous function which is immediately called and -// returns a new object. The new object contains only the exported definitions; -// all other definitions in the anonymous function are inaccessible to external -// code. -var common = (function() { - - function isHostToolchain(tool) { - return tool == 'win' || tool == 'linux' || tool == 'mac'; - } - - /** - * Return the mime type for NaCl plugin. - * - * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc. - * @return {string} The mime-type for the kind of NaCl plugin matching - * the given toolchain. - */ - function mimeTypeForTool(tool) { - // For NaCl modules use application/x-nacl. - var mimetype = 'application/x-nacl'; - if (isHostToolchain(tool)) { - // For non-NaCl PPAPI plugins use the x-ppapi-debug/release - // mime type. - if (isRelease) - mimetype = 'application/x-ppapi-release'; - else - mimetype = 'application/x-ppapi-debug'; - } else if (tool == 'pnacl') { - mimetype = 'application/x-pnacl'; - } - return mimetype; - } - - /** - * Check if the browser supports NaCl plugins. - * - * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc. - * @return {bool} True if the browser supports the type of NaCl plugin - * produced by the given toolchain. - */ - function browserSupportsNaCl(tool) { - // Assume host toolchains always work with the given browser. - // The below mime-type checking might not work with - // --register-pepper-plugins. - if (isHostToolchain(tool)) { - return true; - } - var mimetype = mimeTypeForTool(tool); - return navigator.mimeTypes[mimetype] !== undefined; - } - - /** - * Inject a script into the DOM, and call a callback when it is loaded. - * - * @param {string} url The url of the script to load. - * @param {Function} onload The callback to call when the script is loaded. - * @param {Function} onerror The callback to call if the script fails to load. - */ - function injectScript(url, onload, onerror) { - var scriptEl = document.createElement('script'); - scriptEl.type = 'text/javascript'; - scriptEl.src = url; - scriptEl.onload = onload; - if (onerror) { - scriptEl.addEventListener('error', onerror, false); - } - document.head.appendChild(scriptEl); - } - - /** - * Run all tests for this example. - * - * @param {Object} moduleEl The module DOM element. - */ - function runTests(moduleEl) { - console.log('runTests()'); - common.tester = new Tester(); - - // All NaCl SDK examples are OK if the example exits cleanly; (i.e. the - // NaCl module returns 0 or calls exit(0)). - // - // Without this exception, the browser_tester thinks that the module - // has crashed. - common.tester.exitCleanlyIsOK(); - - common.tester.addAsyncTest('loaded', function(test) { - test.pass(); - }); - - if (typeof window.addTests !== 'undefined') { - window.addTests(); - } - - common.tester.waitFor(moduleEl); - common.tester.run(); - } - - /** - * Create the Native Client element as a child of the DOM element - * named "listener". - * - * @param {string} name The name of the example. - * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc. - * @param {string} path Directory name where .nmf file can be found. - * @param {number} width The width to create the plugin. - * @param {number} height The height to create the plugin. - * @param {Object} attrs Dictionary of attributes to set on the module. - */ - function createNaClModule(name, tool, path, width, height, attrs) { - var moduleEl = document.createElement('embed'); - moduleEl.setAttribute('name', 'nacl_module'); - moduleEl.setAttribute('id', 'nacl_module'); - moduleEl.setAttribute('width', width); - moduleEl.setAttribute('height', height); - moduleEl.setAttribute('path', path); - moduleEl.setAttribute('src', path + '/' + name + '.nmf'); - - // Add any optional arguments - if (attrs) { - for (var key in attrs) { - moduleEl.setAttribute(key, attrs[key]); - } - } - - var mimetype = mimeTypeForTool(tool); - moduleEl.setAttribute('type', mimetype); - - // The element is wrapped inside a
, which has both a 'load' - // and a 'message' event listener attached. This wrapping method is used - // instead of attaching the event listeners directly to the element - // to ensure that the listeners are active before the NaCl module 'load' - // event fires. - var listenerDiv = document.getElementById('listener'); - listenerDiv.appendChild(moduleEl); - - // Request the offsetTop property to force a relayout. As of Apr 10, 2014 - // this is needed if the module is being loaded on a Chrome App's - // background page (see crbug.com/350445). - moduleEl.offsetTop; - - // Host plugins don't send a moduleDidLoad message. We'll fake it here. - var isHost = isHostToolchain(tool); - if (isHost) { - window.setTimeout(function() { - moduleEl.readyState = 1; - moduleEl.dispatchEvent(new CustomEvent('loadstart')); - moduleEl.readyState = 4; - moduleEl.dispatchEvent(new CustomEvent('load')); - moduleEl.dispatchEvent(new CustomEvent('loadend')); - }, 100); // 100 ms - } - - // This is code that is only used to test the SDK. - if (isTest) { - var loadNaClTest = function() { - injectScript('nacltest.js', function() { - runTests(moduleEl); - }); - }; - - // Try to load test.js for the example. Whether or not it exists, load - // nacltest.js. - injectScript('test.js', loadNaClTest, loadNaClTest); - } - } - - /** - * Add the default "load" and "message" event listeners to the element with - * id "listener". - * - * The "load" event is sent when the module is successfully loaded. The - * "message" event is sent when the naclModule posts a message using - * PPB_Messaging.PostMessage() (in C) or pp::Instance().PostMessage() (in - * C++). - */ - function attachDefaultListeners() { - var listenerDiv = document.getElementById('listener'); - listenerDiv.addEventListener('load', moduleDidLoad, true); - listenerDiv.addEventListener('message', handleMessage, true); - listenerDiv.addEventListener('error', handleError, true); - listenerDiv.addEventListener('crash', handleCrash, true); - if (typeof window.attachListeners !== 'undefined') { - window.attachListeners(); - } - } - - /** - * Called when the NaCl module fails to load. - * - * This event listener is registered in createNaClModule above. - */ - function handleError(event) { - // We can't use common.naclModule yet because the module has not been - // loaded. - var moduleEl = document.getElementById('nacl_module'); - updateStatus('ERROR [' + moduleEl.lastError + ']'); - } - - /** - * Called when the Browser can not communicate with the Module - * - * This event listener is registered in attachDefaultListeners above. - */ - function handleCrash(event) { - if (common.naclModule.exitStatus == -1) { - updateStatus('CRASHED'); - } else { - updateStatus('EXITED [' + common.naclModule.exitStatus + ']'); - } - if (typeof window.handleCrash !== 'undefined') { - window.handleCrash(common.naclModule.lastError); - } - } - - /** - * Called when the NaCl module is loaded. - * - * This event listener is registered in attachDefaultListeners above. - */ - function moduleDidLoad() { - common.naclModule = document.getElementById('nacl_module'); - updateStatus('RUNNING'); - - if (typeof window.moduleDidLoad !== 'undefined') { - window.moduleDidLoad(); - } - } - - /** - * Hide the NaCl module's embed element. - * - * We don't want to hide by default; if we do, it is harder to determine that - * a plugin failed to load. Instead, call this function inside the example's - * "moduleDidLoad" function. - * - */ - function hideModule() { - // Setting common.naclModule.style.display = "None" doesn't work; the - // module will no longer be able to receive postMessages. - common.naclModule.style.height = '0'; - } - - /** - * Remove the NaCl module from the page. - */ - function removeModule() { - common.naclModule.parentNode.removeChild(common.naclModule); - common.naclModule = null; - } - - /** - * Return true when |s| starts with the string |prefix|. - * - * @param {string} s The string to search. - * @param {string} prefix The prefix to search for in |s|. - */ - function startsWith(s, prefix) { - // indexOf would search the entire string, lastIndexOf(p, 0) only checks at - // the first index. See: http://stackoverflow.com/a/4579228 - return s.lastIndexOf(prefix, 0) === 0; - } - - /** Maximum length of logMessageArray. */ - var kMaxLogMessageLength = 20; - - /** An array of messages to display in the element with id "log". */ - var logMessageArray = []; - - /** - * Add a message to an element with id "log". - * - * This function is used by the default "log:" message handler. - * - * @param {string} message The message to log. - */ - function logMessage(message) { - logMessageArray.push(message); - if (logMessageArray.length > kMaxLogMessageLength) - logMessageArray.shift(); - - document.getElementById('log').textContent = logMessageArray.join('\n'); - console.log(message); - } - - /** - */ - var defaultMessageTypes = { - 'alert': alert, - 'log': logMessage - }; - - /** - * Called when the NaCl module sends a message to JavaScript (via - * PPB_Messaging.PostMessage()) - * - * This event listener is registered in createNaClModule above. - * - * @param {Event} message_event A message event. message_event.data contains - * the data sent from the NaCl module. - */ - function handleMessage(message_event) { - if (typeof message_event.data === 'string') { - for (var type in defaultMessageTypes) { - if (defaultMessageTypes.hasOwnProperty(type)) { - if (startsWith(message_event.data, type + ':')) { - func = defaultMessageTypes[type]; - func(message_event.data.slice(type.length + 1)); - return; - } - } - } - } - - if (typeof window.handleMessage !== 'undefined') { - window.handleMessage(message_event); - return; - } - - logMessage('Unhandled message: ' + message_event.data); - } - - /** - * Called when the DOM content has loaded; i.e. the page's document is fully - * parsed. At this point, we can safely query any elements in the document via - * document.querySelector, document.getElementById, etc. - * - * @param {string} name The name of the example. - * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc. - * @param {string} path Directory name where .nmf file can be found. - * @param {number} width The width to create the plugin. - * @param {number} height The height to create the plugin. - * @param {Object} attrs Optional dictionary of additional attributes. - */ - function domContentLoaded(name, tool, path, width, height, attrs) { - // If the page loads before the Native Client module loads, then set the - // status message indicating that the module is still loading. Otherwise, - // do not change the status message. - updateStatus('Page loaded.'); - if (!browserSupportsNaCl(tool)) { - updateStatus( - 'Browser does not support NaCl (' + tool + '), or NaCl is disabled'); - } else if (common.naclModule == null) { - updateStatus('Creating embed: ' + tool); - - // We use a non-zero sized embed to give Chrome space to place the bad - // plug-in graphic, if there is a problem. - width = typeof width !== 'undefined' ? width : 200; - height = typeof height !== 'undefined' ? height : 200; - attachDefaultListeners(); - createNaClModule(name, tool, path, width, height, attrs); - } else { - // It's possible that the Native Client module onload event fired - // before the page's onload event. In this case, the status message - // will reflect 'SUCCESS', but won't be displayed. This call will - // display the current message. - updateStatus('Waiting.'); - } - } - - /** Saved text to display in the element with id 'statusField'. */ - var statusText = 'NO-STATUSES'; - - /** - * Set the global status message. If the element with id 'statusField' - * exists, then set its HTML to the status message as well. - * - * @param {string} opt_message The message to set. If null or undefined, then - * set element 'statusField' to the message from the last call to - * updateStatus. - */ - function updateStatus(opt_message) { - if (opt_message) { - statusText = opt_message; - } - var statusField = document.getElementById('statusField'); - if (statusField) { - statusField.innerHTML = statusText; - } - } - - // The symbols to export. - return { - /** A reference to the NaCl module, once it is loaded. */ - naclModule: null, - - attachDefaultListeners: attachDefaultListeners, - domContentLoaded: domContentLoaded, - createNaClModule: createNaClModule, - hideModule: hideModule, - removeModule: removeModule, - logMessage: logMessage, - updateStatus: updateStatus - }; - -}()); - -// Listen for the DOM content to be loaded. This event is fired when parsing of -// the page's document has finished. -document.addEventListener('DOMContentLoaded', function() { - var body = document.body; - - // The data-* attributes on the body can be referenced via body.dataset. - if (body.dataset) { - var loadFunction; - if (!body.dataset.customLoad) { - loadFunction = common.domContentLoaded; - } else if (typeof window.domContentLoaded !== 'undefined') { - loadFunction = window.domContentLoaded; - } - - // From https://developer.mozilla.org/en-US/docs/DOM/window.location - var searchVars = {}; - if (window.location.search.length > 1) { - var pairs = window.location.search.substr(1).split('&'); - for (var key_ix = 0; key_ix < pairs.length; key_ix++) { - var keyValue = pairs[key_ix].split('='); - searchVars[unescape(keyValue[0])] = - keyValue.length > 1 ? unescape(keyValue[1]) : ''; - } - } - - if (loadFunction) { - var toolchains = body.dataset.tools.split(' '); - var configs = body.dataset.configs.split(' '); - - var attrs = {}; - if (body.dataset.attrs) { - var attr_list = body.dataset.attrs.split(' '); - for (var key in attr_list) { - var attr = attr_list[key].split('='); - var key = attr[0]; - var value = attr[1]; - attrs[key] = value; - } - } - - var tc = toolchains.indexOf(searchVars.tc) !== -1 ? - searchVars.tc : toolchains[0]; - - // If the config value is included in the search vars, use that. - // Otherwise default to Release if it is valid, or the first value if - // Release is not valid. - if (configs.indexOf(searchVars.config) !== -1) - var config = searchVars.config; - else if (configs.indexOf('Release') !== -1) - var config = 'Release'; - else - var config = configs[0]; - - var pathFormat = body.dataset.path; - var path = pathFormat.replace('{tc}', tc).replace('{config}', config); - - isTest = searchVars.test === 'true'; - isRelease = path.toLowerCase().indexOf('release') != -1; - - loadFunction(body.dataset.name, tc, path, body.dataset.width, - body.dataset.height, attrs); - } - } -}); diff --git a/shell/nacl/example.js b/shell/nacl/example.js deleted file mode 100644 index ed76b9f4c..000000000 --- a/shell/nacl/example.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -function $(id) { - return document.getElementById(id); -} - -// Add event listeners after the NaCl module has loaded. These listeners will -// forward messages to the NaCl module via postMessage() -function attachListeners() { - -} - -// Handle a message coming from the NaCl module. -function handleMessage(event) { - console.log(event.data); - $("status").textContent = event.data; -} diff --git a/shell/nacl/icon128.png b/shell/nacl/icon128.png deleted file mode 100644 index 4e966a7523851af14908b6831473912c24a623f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9897 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 - - - - - - reicast nacl - - - - - -

reicast nacl

-

Status: NO-STATUS

- - -
- - - diff --git a/shell/nacl_lin/Makefile b/shell/nacl_lin/Makefile deleted file mode 100644 index bab2d63af..000000000 --- a/shell/nacl_lin/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -# nacl-simulating linux build -# for debugging - -LOCAL_PATH := $(call my-dir) -FOR_LINUX :=1 -#NOT_ARM := 1 -#X64_REC := 1 -CPP_REC :=1 -#NO_REC := 1 -NO_REND := 1 -WEBUI :=1 -USE_ALSA := 1 -USE_OSS := 1 -#USE_PULSEAUDIO := 1 - -RZDCY_SRC_DIR = ../../core - -include $(RZDCY_SRC_DIR)/core.mk - -RZDCY_FILES += $(RZDCY_SRC_DIR)/nacl/nacl_lin.cpp - -CXX=${CC_PREFIX}g++ -CC=${CC_PREFIX}gcc -AS=${CC_PREFIX}as -STRIP=${CC_PREFIX}strip - -LD=${CC} - -MFLAGS := #-m32 -#-marm -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -funroll-loops -ASFLAGS := -#-march=armv7-a -mfpu=neon -mfloat-abi=softfp - -LDFLAGS := -g -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common - -CFLAGS := -g -O3 -D RELEASE -c -D TARGET_LINUX_x64 -D TARGET_NACL32 -D USES_HOMEDIR -D TARGET_NO_JIT -D NO_REND -std=c++11 -CFLAGS += -frename-registers -fno-strict-aliasing #-fsingle-precision-constant -CFLAGS += -ffast-math -ftree-vectorize - - -#-fprefetch-loop-arrays -#-std=c++0x -CXXFLAGS += $(CFLAGS) $(MFLAGS) -fexceptions -fno-rtti -fpermissive -CXXFLAGS += -fno-operator-names - -ifdef PGO_MAKE - CFLAGS += -fprofile-generate -pg - LDFLAGS += -fprofile-generate -else - CFLAGS += -fomit-frame-pointer -endif - -ifdef PGO_USE - CFLAGS += -fprofile-use -endif - - -ifdef LTO_TEST - CFLAGS += -flto -fwhole-program - LDFLAGS +=-flto -fwhole-program -endif - -INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos - -LIBS := # use system libs -LIBS += -lm -lrt -ldl -LIBS += -lpthread #-lX11 - -ifdef USE_ALSA - CXXFLAGS += -D USE_ALSA - LIBS += -lasound -endif - -ifdef USE_OSS - CXXFLAGS += -D USE_OSS -endif - -ifdef USE_PULSEAUDIO - CXXFLAGS += -D USE_PULSEAUDIO - LIBS += -lpulse-simple -endif - -ifdef USE_GLES - CXXFLAGS += -DGLES - LIBS += -lEGL -lGLESv2 -else - LIBS += -ldl -lGL #for desktop gl -endif - - -OBJECTS=$(RZDCY_FILES:.cpp=.build_obj) -OBJECTS:=$(OBJECTS:.c=.build_obj) -OBJECTS:=$(OBJECTS:.S=.build_obj) -OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS)) - - -EXECUTABLE_STRIPPED=nosym-reicast.elf -EXECUTABLE=reicast.elf - -PACKAGE_FILES=$(EXECUTABLE_STRIPPED) default.gcw0.desktop icon-32.png - -all: $(CPPFILES) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) - -$(EXECUTABLE): $(OBJECTS) - $(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ - -$(EXECUTABLE_STRIPPED): $(EXECUTABLE) - cp $< $@ && $(STRIP) $@ - -obj/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp - mkdir -p $(dir $@) - $(CXX) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $(CXXFLAGS) $< -o $@ - -obj/%.build_obj : $(RZDCY_SRC_DIR)/%.c - mkdir -p $(dir $@) - $(CC) $(EXTRAFLAGS) $(INCS) $(CFLAGS) $< -o $@ - -obj/%.build_obj : $(RZDCY_SRC_DIR)/%.S - mkdir -p $(dir $@) - $(AS) $(ASFLAGS) $(INCS) $< -o $@ - - -clean: - rm $(OBJECTS) $(EXECUTABLE) -f From 75cdd93001c3900f6750b8893a6f5bdb4a2b59d6 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 7 Jul 2019 23:40:13 +0200 Subject: [PATCH 127/158] remove webui, libwebsocket --- WorkDir/webui/debugger.html | 397 ------ WorkDir/webui/favicon.ico | Bin 1406 -> 0 bytes core/core.mk | 9 - core/deps/ifaddrs/README.md | 6 - core/deps/ifaddrs/ifaddrs.c | 658 --------- core/deps/ifaddrs/ifaddrs.h | 56 - core/deps/libwebsocket/LICENSE | 526 -------- core/deps/libwebsocket/README | 20 - core/deps/libwebsocket/base64-decode.c | 93 -- core/deps/libwebsocket/client-handshake.c | 441 ------ core/deps/libwebsocket/client-parser.c | 402 ------ core/deps/libwebsocket/client.c | 953 ------------- core/deps/libwebsocket/config.h | 4 - core/deps/libwebsocket/context.c | 348 ----- .../libwebsocket/extension-deflate-frame.c | 294 ---- .../libwebsocket/extension-deflate-frame.h | 25 - .../libwebsocket/extension-deflate-stream.c | 166 --- .../libwebsocket/extension-deflate-stream.h | 20 - core/deps/libwebsocket/extension.c | 206 --- core/deps/libwebsocket/handshake.c | 171 --- core/deps/libwebsocket/lextable.h | 287 ---- core/deps/libwebsocket/libwebsockets.c | 766 ----------- core/deps/libwebsocket/libwebsockets.h | 1190 ----------------- core/deps/libwebsocket/lws-plat-unix.c | 396 ------ core/deps/libwebsocket/lws-plat-win.c | 365 ----- core/deps/libwebsocket/lws_config.h | 174 --- core/deps/libwebsocket/output.c | 571 -------- core/deps/libwebsocket/parsers.c | 973 -------------- core/deps/libwebsocket/pollfd.c | 239 ---- .../deps/libwebsocket/private-libwebsockets.h | 916 ------------- core/deps/libwebsocket/server-handshake.c | 280 ---- core/deps/libwebsocket/server.c | 868 ------------ core/deps/libwebsocket/service.c | 514 ------- core/deps/libwebsocket/sha-1.c | 299 ----- core/webui/server.cpp | 877 ------------ core/webui/server.h | 1 - .../reicast/src/main/jni/Android.mk | 1 - .../reicast-ios.xcodeproj/project.pbxproj | 2 - .../reicast-osx.xcodeproj/project.pbxproj | 4 - shell/cmake/CMakeLists.txt | 8 - shell/cmake/config.cmake | 27 +- shell/emscripten/Makefile | 2 +- shell/linux/Makefile | 18 +- 43 files changed, 13 insertions(+), 13560 deletions(-) delete mode 100644 WorkDir/webui/debugger.html delete mode 100644 WorkDir/webui/favicon.ico delete mode 100644 core/deps/ifaddrs/README.md delete mode 100644 core/deps/ifaddrs/ifaddrs.c delete mode 100644 core/deps/ifaddrs/ifaddrs.h delete mode 100644 core/deps/libwebsocket/LICENSE delete mode 100644 core/deps/libwebsocket/README delete mode 100644 core/deps/libwebsocket/base64-decode.c delete mode 100644 core/deps/libwebsocket/client-handshake.c delete mode 100644 core/deps/libwebsocket/client-parser.c delete mode 100644 core/deps/libwebsocket/client.c delete mode 100644 core/deps/libwebsocket/config.h delete mode 100644 core/deps/libwebsocket/context.c delete mode 100644 core/deps/libwebsocket/extension-deflate-frame.c delete mode 100644 core/deps/libwebsocket/extension-deflate-frame.h delete mode 100644 core/deps/libwebsocket/extension-deflate-stream.c delete mode 100644 core/deps/libwebsocket/extension-deflate-stream.h delete mode 100644 core/deps/libwebsocket/extension.c delete mode 100644 core/deps/libwebsocket/handshake.c delete mode 100644 core/deps/libwebsocket/lextable.h delete mode 100644 core/deps/libwebsocket/libwebsockets.c delete mode 100644 core/deps/libwebsocket/libwebsockets.h delete mode 100644 core/deps/libwebsocket/lws-plat-unix.c delete mode 100644 core/deps/libwebsocket/lws-plat-win.c delete mode 100644 core/deps/libwebsocket/lws_config.h delete mode 100644 core/deps/libwebsocket/output.c delete mode 100644 core/deps/libwebsocket/parsers.c delete mode 100644 core/deps/libwebsocket/pollfd.c delete mode 100644 core/deps/libwebsocket/private-libwebsockets.h delete mode 100644 core/deps/libwebsocket/server-handshake.c delete mode 100644 core/deps/libwebsocket/server.c delete mode 100644 core/deps/libwebsocket/service.c delete mode 100644 core/deps/libwebsocket/sha-1.c delete mode 100644 core/webui/server.cpp delete mode 100644 core/webui/server.h diff --git a/WorkDir/webui/debugger.html b/WorkDir/webui/debugger.html deleted file mode 100644 index 13a738b6c..000000000 --- a/WorkDir/webui/debugger.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - Minimal Websocket test app - - - - -
-
- -
- -
-
Detected Browser:
...
- -
- -
-
libwebsockets "dumb-increment-protocol"
-
- - - - - -
Not initialized
-
-The incrementing number is coming from the server and is individual for -each connection to the server... try opening a second browser window. -

-The button zeros just this connection's number. -

- -
-
-
-
-
libwebsockets "lws-mirror-protocol"
-
-Use the mouse to draw on the canvas below -- all other browser windows open -on this page see your drawing in realtime and you can see any of theirs as -well. -

-The lws-mirror protocol doesn't interpret what is being sent to it, it just -re-sends it to every other websocket it has a connection with using that -protocol, including the guy who sent the packet. -

-libwebsockets-test-client joins in by spamming circles on to this shared canvas when -run. -
- - - - - - - - -
Drawing color: - -
Not initialized
-
-
-
- -
-Looking for support? http://libwebsockets.org
-Join the mailing list: ​http://ml.libwebsockets.org/mailman/listinfo/libwebsockets - -
- -
- - - - - diff --git a/WorkDir/webui/favicon.ico b/WorkDir/webui/favicon.ico deleted file mode 100644 index c0cc2e3dff34012ba3d4a7848a7ed17579788ec5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406 zcmZQzU<5(|0R}M0U}azs1F|%L7$l?s#Ec9aKoZP=&`9i!<^REA8>%80(yxAC$j<-A zkb5S8;qL6446ipNFl>5#fuVR6L=8goC~GtXMnhmYga9MSfQgBTk&TUw5$JocUP63y z3phA97+G0a8QIy{!BT|y==xb$SQt4uIT@LmnZZ(o_~`mk`Tv1M8w?+DXJCL~kQj^& JqOtKoVgQl$ETjMc diff --git a/core/core.mk b/core/core.mk index 82ff5c045..b7970ce95 100755 --- a/core/core.mk +++ b/core/core.mk @@ -13,15 +13,6 @@ RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \ deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/ deps/xbrz/ \ deps/xxhash/ deps/libzip/ deps/imgui/ archive/ input/ log/ -ifdef WEBUI - RZDCY_MODULES += webui/ - RZDCY_MODULES += deps/libwebsocket/ - - ifdef FOR_ANDROID - RZDCY_MODULES += deps/ifaddrs/ - endif -endif - ifndef NOT_ARM RZDCY_MODULES += rec-ARM/ endif diff --git a/core/deps/ifaddrs/README.md b/core/deps/ifaddrs/README.md deleted file mode 100644 index dc05bdfd3..000000000 --- a/core/deps/ifaddrs/README.md +++ /dev/null @@ -1,6 +0,0 @@ -android-ifaddrs -=============== - -An implementation of getifaddrs() for Android, since the NDK does not natively support it. - -Works just like you would expect on regular Linux. License information is present in each file (BSD license). diff --git a/core/deps/ifaddrs/ifaddrs.c b/core/deps/ifaddrs/ifaddrs.c deleted file mode 100644 index 916f9c2fd..000000000 --- a/core/deps/ifaddrs/ifaddrs.c +++ /dev/null @@ -1,658 +0,0 @@ -/* -Copyright (c) 2013, Kenneth MacKay -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ifaddrs.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct NetlinkList -{ - struct NetlinkList *m_next; - struct nlmsghdr *m_data; - unsigned int m_size; -} NetlinkList; - -static int netlink_socket(void) -{ - int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if(l_socket < 0) - { - return -1; - } - - struct sockaddr_nl l_addr; - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) - { - close(l_socket); - return -1; - } - - return l_socket; -} - -static int netlink_send(int p_socket, int p_request) -{ - char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))]; - memset(l_buffer, 0, sizeof(l_buffer)); - struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer; - struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr); - - l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg)); - l_hdr->nlmsg_type = p_request; - l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - l_hdr->nlmsg_pid = 0; - l_hdr->nlmsg_seq = p_socket; - l_msg->rtgen_family = AF_UNSPEC; - - struct sockaddr_nl l_addr; - memset(&l_addr, 0, sizeof(l_addr)); - l_addr.nl_family = AF_NETLINK; - return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); -} - -static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) -{ - struct msghdr l_msg; - struct iovec l_iov = { p_buffer, p_len }; - struct sockaddr_nl l_addr; - int l_result; - - for(;;) - { - l_msg.msg_name = (void *)&l_addr; - l_msg.msg_namelen = sizeof(l_addr); - l_msg.msg_iov = &l_iov; - l_msg.msg_iovlen = 1; - l_msg.msg_control = NULL; - l_msg.msg_controllen = 0; - l_msg.msg_flags = 0; - int l_result = recvmsg(p_socket, &l_msg, 0); - - if(l_result < 0) - { - if(errno == EINTR) - { - continue; - } - return -2; - } - - if(l_msg.msg_flags & MSG_TRUNC) - { // buffer was too small - return -1; - } - return l_result; - } -} - -static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done) -{ - size_t l_size = 4096; - void *l_buffer = NULL; - - for(;;) - { - free(l_buffer); - l_buffer = malloc(l_size); - if (l_buffer == NULL) - { - return NULL; - } - - int l_read = netlink_recv(p_socket, l_buffer, l_size); - *p_size = l_read; - if(l_read == -2) - { - free(l_buffer); - return NULL; - } - if(l_read >= 0) - { - pid_t l_pid = getpid(); - struct nlmsghdr *l_hdr; - for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - *p_done = 1; - break; - } - - if(l_hdr->nlmsg_type == NLMSG_ERROR) - { - free(l_buffer); - return NULL; - } - } - return l_buffer; - } - - l_size *= 2; - } -} - -static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) -{ - NetlinkList *l_item = malloc(sizeof(NetlinkList)); - if (l_item == NULL) - { - return NULL; - } - - l_item->m_next = NULL; - l_item->m_data = p_data; - l_item->m_size = p_size; - return l_item; -} - -static void freeResultList(NetlinkList *p_list) -{ - NetlinkList *l_cur; - while(p_list) - { - l_cur = p_list; - p_list = p_list->m_next; - free(l_cur->m_data); - free(l_cur); - } -} - -static NetlinkList *getResultList(int p_socket, int p_request) -{ - if(netlink_send(p_socket, p_request) < 0) - { - return NULL; - } - - NetlinkList *l_list = NULL; - NetlinkList *l_end = NULL; - int l_size; - int l_done = 0; - while(!l_done) - { - struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); - if(!l_hdr) - { // error - freeResultList(l_list); - return NULL; - } - - NetlinkList *l_item = newListItem(l_hdr, l_size); - if (!l_item) - { - freeResultList(l_list); - return NULL; - } - if(!l_list) - { - l_list = l_item; - } - else - { - l_end->m_next = l_item; - } - l_end = l_item; - } - return l_list; -} - -static size_t maxSize(size_t a, size_t b) -{ - return (a > b ? a : b); -} - -static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) -{ - switch(p_family) - { - case AF_INET: - return sizeof(struct sockaddr_in); - case AF_INET6: - return sizeof(struct sockaddr_in6); - case AF_PACKET: - return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); - default: - return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); - } -} - -static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) -{ - switch(p_family) - { - case AF_INET: - memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); - break; - case AF_INET6: - memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); - break; - case AF_PACKET: - memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); - ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; - break; - default: - memcpy(p_dest->sa_data, p_data, p_size); - break; - } - p_dest->sa_family = p_family; -} - -static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) -{ - if(!*p_resultList) - { - *p_resultList = p_entry; - } - else - { - struct ifaddrs *l_cur = *p_resultList; - while(l_cur->ifa_next) - { - l_cur = l_cur->ifa_next; - } - l_cur->ifa_next = p_entry; - } -} - -static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) -{ - struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - size_t l_dataSize = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - struct rtattr *l_rta; - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); - break; - case IFLA_IFNAME: - l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); - break; - case IFLA_STATS: - l_dataSize += NLMSG_ALIGN(l_rtaSize); - break; - default: - break; - } - } - - struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = ""; - - char *l_index = ((char *)l_entry) + sizeof(struct ifaddrs); - char *l_name = l_index + sizeof(int); - char *l_addr = l_name + l_nameSize; - char *l_data = l_addr + l_addrSize; - - // save the interface index so we can look it up when handling the addresses. - memcpy(l_index, &l_info->ifi_index, sizeof(int)); - - l_entry->ifa_flags = l_info->ifi_flags; - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFLA_ADDRESS: - case IFLA_BROADCAST: - { - size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); - makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; - ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; - if(l_rta->rta_type == IFLA_ADDRESS) - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFLA_IFNAME: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - case IFLA_STATS: - memcpy(l_data, l_rtaData, l_rtaDataSize); - l_entry->ifa_data = l_data; - break; - default: - break; - } - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks) -{ - int l_num = 0; - struct ifaddrs *l_cur = *p_links; - while(l_cur && l_num < p_numLinks) - { - char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs); - int l_index; - memcpy(&l_index, l_indexPtr, sizeof(int)); - if(l_index == p_index) - { - return l_cur; - } - - l_cur = l_cur->ifa_next; - ++l_num; - } - return NULL; -} - -static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks) -{ - struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); - struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks); - - size_t l_nameSize = 0; - size_t l_addrSize = 0; - - int l_addedNetmask = 0; - - size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - struct rtattr *l_rta; - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - if(l_info->ifa_family == AF_PACKET) - { - continue; - } - - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_LOCAL: - if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) - { // make room for netmask - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - l_addedNetmask = 1; - } - case IFA_BROADCAST: - l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); - break; - case IFA_LABEL: - l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); - break; - default: - break; - } - } - - struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); - if (l_entry == NULL) - { - return -1; - } - memset(l_entry, 0, sizeof(struct ifaddrs)); - l_entry->ifa_name = (l_interface ? l_interface->ifa_name : ""); - - char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs); - char *l_addr = l_name + l_nameSize; - - l_entry->ifa_flags = l_info->ifa_flags; - if(l_interface) - { - l_entry->ifa_flags |= l_interface->ifa_flags; - } - - l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); - for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) - { - void *l_rtaData = RTA_DATA(l_rta); - size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); - switch(l_rta->rta_type) - { - case IFA_ADDRESS: - case IFA_BROADCAST: - case IFA_LOCAL: - { - size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); - makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); - if(l_info->ifa_family == AF_INET6) - { - if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) - { - ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; - } - } - - if(l_rta->rta_type == IFA_ADDRESS) - { // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - } - else if(l_rta->rta_type == IFA_LOCAL) - { - if(l_entry->ifa_addr) - { - l_entry->ifa_dstaddr = l_entry->ifa_addr; - } - l_entry->ifa_addr = (struct sockaddr *)l_addr; - } - else - { - l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; - } - l_addr += NLMSG_ALIGN(l_addrLen); - break; - } - case IFA_LABEL: - strncpy(l_name, l_rtaData, l_rtaDataSize); - l_name[l_rtaDataSize] = '\0'; - l_entry->ifa_name = l_name; - break; - default: - break; - } - } - - if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) - { - unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); - unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); - char l_mask[16] = {0}; - unsigned i; - for(i=0; i<(l_prefix/8); ++i) - { - l_mask[i] = 0xff; - } - if(l_prefix % 8) - { - l_mask[i] = 0xff << (8 - (l_prefix % 8)); - } - - makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); - l_entry->ifa_netmask = (struct sockaddr *)l_addr; - } - - addToEnd(p_resultList, l_entry); - return 0; -} - -static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) -{ - int l_numLinks = 0; - pid_t l_pid = getpid(); - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWLINK) - { - if(interpretLink(l_hdr, p_resultList) == -1) - { - return -1; - } - ++l_numLinks; - } - } - } - return l_numLinks; -} - -static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) -{ - pid_t l_pid = getpid(); - for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) - { - unsigned int l_nlsize = p_netlinkList->m_size; - struct nlmsghdr *l_hdr; - for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) - { - if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) - { - continue; - } - - if(l_hdr->nlmsg_type == NLMSG_DONE) - { - break; - } - - if(l_hdr->nlmsg_type == RTM_NEWADDR) - { - if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1) - { - return -1; - } - } - } - } - return 0; -} - -int getifaddrs(struct ifaddrs **ifap) -{ - if(!ifap) - { - return -1; - } - *ifap = NULL; - - int l_socket = netlink_socket(); - if(l_socket < 0) - { - return -1; - } - - NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK); - if(!l_linkResults) - { - close(l_socket); - return -1; - } - - NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR); - if(!l_addrResults) - { - close(l_socket); - freeResultList(l_linkResults); - return -1; - } - - int l_result = 0; - int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap); - if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1) - { - l_result = -1; - } - - freeResultList(l_linkResults); - freeResultList(l_addrResults); - close(l_socket); - return l_result; -} - -void freeifaddrs(struct ifaddrs *ifa) -{ - struct ifaddrs *l_cur; - while(ifa) - { - l_cur = ifa; - ifa = ifa->ifa_next; - free(l_cur); - } -} diff --git a/core/deps/ifaddrs/ifaddrs.h b/core/deps/ifaddrs/ifaddrs.h deleted file mode 100644 index 7c044c0bc..000000000 --- a/core/deps/ifaddrs/ifaddrs.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 1995, 1999 - * Berkeley Software Design, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp - */ - -#ifndef _IFADDRS_H_ -#define _IFADDRS_H_ - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - struct sockaddr *ifa_dstaddr; - void *ifa_data; -}; - -/* - * This may have been defined in . Note that if is - * to be included it must be included before this header file. - */ -#ifndef ifa_broadaddr -#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ -#endif - -#ifdef _cplusplus -extern "C" { -#endif -extern int getifaddrs(struct ifaddrs **ifap); -extern void freeifaddrs(struct ifaddrs *ifa); -#ifdef _cplusplus -} -#endif - -#endif diff --git a/core/deps/libwebsocket/LICENSE b/core/deps/libwebsocket/LICENSE deleted file mode 100644 index 7c8986558..000000000 --- a/core/deps/libwebsocket/LICENSE +++ /dev/null @@ -1,526 +0,0 @@ -Libwebsockets and included programs are provided under the terms of the GNU -Library General Public License (LGPL) 2.1, with the following exceptions: - -1) Static linking of programs with the libwebsockets library does not -constitute a derivative work and does not require the author to provide -source code for the program, use the shared libwebsockets libraries, or -link their program against a user-supplied version of libwebsockets. - -If you link the program to a modified version of libwebsockets, then the -changes to libwebsockets must be provided under the terms of the LGPL in -sections 1, 2, and 4. - -2) You do not have to provide a copy of the libwebsockets license with -programs that are linked to the libwebsockets library, nor do you have to -identify the libwebsockets license in your program or documentation as -required by section 6 of the LGPL. - -However, programs must still identify their use of libwebsockets. The -following example statement can be included in user documentation to -satisfy this requirement: - -"[program] is based in part on the work of the libwebsockets project -(http://libwebsockets.org)" - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/core/deps/libwebsocket/README b/core/deps/libwebsocket/README deleted file mode 100644 index 37436e83f..000000000 --- a/core/deps/libwebsocket/README +++ /dev/null @@ -1,20 +0,0 @@ -This is the libwebsockets C library for lightweight websocket clients and -servers. For support, visit - - http://libwebsockets.org - -and consider joining the project mailing list at - - http://ml.libwebsockets.org/mailman/listinfo/libwebsockets - -You can get the latest version of the library from git - -http://git.libwebsockets.org -https://github.com/warmcat/libwebsockets - -for more information: - -README.build - information on building the library -README.coding - information for writing code using the library -README.test-apps - information about the test apps built with the library - diff --git a/core/deps/libwebsocket/base64-decode.c b/core/deps/libwebsocket/base64-decode.c deleted file mode 100644 index b89db7ac3..000000000 --- a/core/deps/libwebsocket/base64-decode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This code originally came from here - * - * http://base64.sourceforge.net/b64.c - * - * with the following license: - * - * LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the - * Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS - * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * VERSION HISTORY: - * Bob Trower 08/04/01 -- Create Version 0.00.00B - * - * I cleaned it up quite a bit to match the (linux kernel) style of the rest - * of libwebsockets; this version is under LGPL2 like the rest of libwebsockets - * since he explictly allows sublicensing, but I give the URL above so you can - * get the original with Bob's super-liberal terms directly if you prefer. - */ - - -#include -#include -#include "private-libwebsockets.h" - -static const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" - "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; - -LWS_VISIBLE int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) -{ - unsigned char triple[3]; - int i; - int len; - int line = 0; - int done = 0; - - while (in_len) { - len = 0; - for (i = 0; i < 3; i++) { - if (in_len) { - triple[i] = *in++; - len++; - in_len--; - } else - triple[i] = 0; - } - if (!len) - continue; - - if (done + 4 >= out_size) - return -1; - - *out++ = encode[triple[0] >> 2]; - *out++ = encode[((triple[0] & 0x03) << 4) | - ((triple[1] & 0xf0) >> 4)]; - *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | - ((triple[2] & 0xc0) >> 6)] : '='); - *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); - - done += 4; - line += 4; - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; -} diff --git a/core/deps/libwebsocket/client-handshake.c b/core/deps/libwebsocket/client-handshake.c deleted file mode 100644 index 2e51bb4d1..000000000 --- a/core/deps/libwebsocket/client-handshake.c +++ /dev/null @@ -1,441 +0,0 @@ -#include "private-libwebsockets.h" - -struct libwebsocket *libwebsocket_client_connect_2( - struct libwebsocket_context *context, - struct libwebsocket *wsi -) { - struct libwebsocket_pollfd pfd; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 server_addr6; - struct sockaddr_in6 client_addr6; - struct addrinfo hints, *result; -#endif - struct sockaddr_in server_addr4; - struct sockaddr_in client_addr4; - struct hostent *server_hostent; - - struct sockaddr *v; - int n; - int plen = 0; - const char *ads; - - lwsl_client("libwebsocket_client_connect_2\n"); - - /* - * proxy? - */ - - if (context->http_proxy_port) { - plen = sprintf((char *)context->service_buffer, - "CONNECT %s:%u HTTP/1.0\x0d\x0a" - "User-agent: libwebsockets\x0d\x0a" -/*Proxy-authorization: basic aGVsbG86d29ybGQ= */ - "\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS), - wsi->u.hdr.ah->c_port); - ads = context->http_proxy_address; - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) - server_addr6.sin6_port = htons(context->http_proxy_port); - else -#endif - server_addr4.sin_port = htons(context->http_proxy_port); - - } else { - ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) - server_addr6.sin6_port = htons(wsi->u.hdr.ah->c_port); - else -#endif - server_addr4.sin_port = htons(wsi->u.hdr.ah->c_port); - } - - /* - * prepare the actual connection (to the proxy, if any) - */ - lwsl_client("libwebsocket_client_connect_2: address %s\n", ads); - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - memset(&hints, 0, sizeof(struct addrinfo)); - n = getaddrinfo(ads, NULL, &hints, &result); - if (n) { -#ifdef _WIN32 - lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n)); -#else - lwsl_err("getaddrinfo: %s\n", gai_strerror(n)); -#endif - goto oom4; - } - - server_addr6.sin6_family = AF_INET6; - switch (result->ai_family) { - case AF_INET: - /* map IPv4 to IPv6 */ - bzero((char *)&server_addr6.sin6_addr, - sizeof(struct in6_addr)); - server_addr6.sin6_addr.s6_addr[10] = 0xff; - server_addr6.sin6_addr.s6_addr[11] = 0xff; - memcpy(&server_addr6.sin6_addr.s6_addr[12], - &((struct sockaddr_in *)result->ai_addr)->sin_addr, - sizeof(struct in_addr)); - break; - case AF_INET6: - memcpy(&server_addr6.sin6_addr, - &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr, - sizeof(struct in6_addr)); - break; - default: - lwsl_err("Unknown address family\n"); - freeaddrinfo(result); - goto oom4; - } - - freeaddrinfo(result); - } else -#endif - { - server_hostent = gethostbyname(ads); - if (!server_hostent) { - lwsl_err("Unable to get host name from %s\n", ads); - goto oom4; - } - - server_addr4.sin_family = AF_INET; - server_addr4.sin_addr = - *((struct in_addr *)server_hostent->h_addr); - bzero(&server_addr4.sin_zero, 8); - } - - if (wsi->sock < 0) { - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) - wsi->sock = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - wsi->sock = socket(AF_INET, SOCK_STREAM, 0); - - if (wsi->sock < 0) { - lwsl_warn("Unable to open socket\n"); - goto oom4; - } - - if (lws_plat_set_socket_options(context, wsi->sock)) { - lwsl_err("Failed to set wsi socket options\n"); - compatible_close(wsi->sock); - goto oom4; - } - - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT; - - insert_wsi_socket_into_fds(context, wsi); - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - AWAITING_TIMEOUT); -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&client_addr6; - n = sizeof(client_addr6); - bzero((char *)v, n); - client_addr6.sin6_family = AF_INET6; - } else -#endif - { - v = (struct sockaddr *)&client_addr4; - n = sizeof(client_addr4); - bzero((char *)v, n); - client_addr4.sin_family = AF_INET; - } - - if (context->iface) { - if (interface_to_sa(context, context->iface, - (struct sockaddr_in *)v, n) < 0) { - lwsl_err("Unable to find interface %s\n", - context->iface); - compatible_close(wsi->sock); - goto failed; - } - - if (bind(wsi->sock, v, n) < 0) { - lwsl_err("Error binding to interface %s", - context->iface); - compatible_close(wsi->sock); - goto failed; - } - } - } - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&server_addr6; - n = sizeof(struct sockaddr_in6); - } else -#endif - { - v = (struct sockaddr *)&server_addr4; - n = sizeof(struct sockaddr); - } - - if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) { - - if (LWS_ERRNO == LWS_EALREADY || LWS_ERRNO == LWS_EINPROGRESS - || LWS_ERRNO == LWS_EWOULDBLOCK) { - lwsl_client("nonblocking connect retry\n"); - - /* - * must do specifically a POLLOUT poll to hear - * about the connect completion - */ - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) - goto oom4; - - return wsi; - } - - if (LWS_ERRNO != LWS_EISCONN) { - lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO); - goto failed; - } - } - - lwsl_client("connected\n"); - - /* we are connected to server, or proxy */ - - if (context->http_proxy_port) { - - /* OK from now on we talk via the proxy, so connect to that */ - - /* - * (will overwrite existing pointer, - * leaving old string/frag there but unreferenced) - */ - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, - context->http_proxy_address)) - goto failed; - wsi->u.hdr.ah->c_port = context->http_proxy_port; - - n = send(wsi->sock, context->service_buffer, plen, MSG_NOSIGNAL); - if (n < 0) { - lwsl_debug("ERROR writing to proxy socket\n"); - goto failed; - } - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - AWAITING_TIMEOUT); - - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY; - - return wsi; - } - - /* - * provoke service to issue the handshake directly - * we need to do it this way because in the proxy case, this is the - * next state and executed only if and when we get a good proxy - * response inside the state machine... but notice in SSL case this - * may not have sent anything yet with 0 return, and won't until some - * many retries from main loop. To stop that becoming endless, - * cover with a timeout. - */ - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, AWAITING_TIMEOUT); - - wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE; - pfd.fd = wsi->sock; - pfd.revents = LWS_POLLIN; - - n = libwebsocket_service_fd(context, &pfd); - - if (n < 0) - goto failed; - - if (n) /* returns 1 on failure after closing wsi */ - return NULL; - - return wsi; - -oom4: - free(wsi->u.hdr.ah); - free(wsi); - return NULL; - -failed: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return NULL; -} - -/** - * libwebsocket_client_connect() - Connect to another websocket server - * @context: Websocket context - * @address: Remote server address, eg, "myserver.com" - * @port: Port to connect to on the remote server, eg, 80 - * @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self - * signed certs - * @path: Websocket path on server - * @host: Hostname on server - * @origin: Socket origin name - * @protocol: Comma-separated list of protocols being asked for from - * the server, or just one. The server will pick the one it - * likes best. - * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest - * protocol supported, or the specific protocol ordinal - * - * This function creates a connection to a remote server - */ - -LWS_VISIBLE struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *context, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one) -{ - struct libwebsocket *wsi; - - wsi = (struct libwebsocket *) malloc(sizeof(struct libwebsocket)); - if (wsi == NULL) - goto bail; - - memset(wsi, 0, sizeof(*wsi)); - wsi->sock = -1; - - /* -1 means just use latest supported */ - - if (ietf_version_or_minus_one == -1) - ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED; - - wsi->ietf_spec_revision = ietf_version_or_minus_one; - wsi->user_space = NULL; - wsi->state = WSI_STATE_CLIENT_UNCONNECTED; - wsi->protocol = NULL; - wsi->pending_timeout = NO_PENDING_TIMEOUT; - -#ifdef LWS_OPENSSL_SUPPORT - wsi->use_ssl = ssl_connection; -#else - if (ssl_connection) { - lwsl_err("libwebsockets not configured for ssl\n"); - goto bail; - } -#endif - - if (lws_allocate_header_table(wsi)) - goto bail; - - /* - * we're not necessarily in a position to action these right away, - * stash them... we only need during connect phase so u.hdr is fine - */ - wsi->u.hdr.ah->c_port = port; - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) - goto bail1; - - /* these only need u.hdr lifetime as well */ - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path)) - goto bail1; - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host)) - goto bail1; - - if (origin) - if (lws_hdr_simple_create(wsi, - _WSI_TOKEN_CLIENT_ORIGIN, origin)) - goto bail1; - /* - * this is a list of protocols we tell the server we're okay with - * stash it for later when we compare server response with it - */ - if (protocol) - if (lws_hdr_simple_create(wsi, - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, protocol)) - goto bail1; - - wsi->protocol = &context->protocols[0]; - - /* - * Check with each extension if it is able to route and proxy this - * connection for us. For example, an extension like x-google-mux - * can handle this and then we don't need an actual socket for this - * connection. - */ - - if (lws_ext_callback_for_each_extension_type(context, wsi, - LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - (void *)address, port) > 0) { - lwsl_client("libwebsocket_client_connect: ext handling conn\n"); - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - AWAITING_TIMEOUT); - - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT; - return wsi; - } - lwsl_client("libwebsocket_client_connect: direct conn\n"); - - return libwebsocket_client_connect_2(context, wsi); - -bail1: - free(wsi->u.hdr.ah); -bail: - free(wsi); - - return NULL; -} - - -/** - * libwebsocket_client_connect_extended() - Connect to another websocket server - * @context: Websocket context - * @address: Remote server address, eg, "myserver.com" - * @port: Port to connect to on the remote server, eg, 80 - * @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self - * signed certs - * @path: Websocket path on server - * @host: Hostname on server - * @origin: Socket origin name - * @protocol: Comma-separated list of protocols being asked for from - * the server, or just one. The server will pick the one it - * likes best. - * @ietf_version_or_minus_one: -1 to ask to connect using the default, latest - * protocol supported, or the specific protocol ordinal - * @userdata: Pre-allocated user data - * - * This function creates a connection to a remote server - */ - -LWS_VISIBLE struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *context, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata) -{ - struct libwebsocket *ws = - libwebsocket_client_connect(context, address, port, - ssl_connection, path, host, origin, protocol, - ietf_version_or_minus_one); - - if (ws && !ws->user_space && userdata) - ws->user_space = userdata ; - - return ws ; -} diff --git a/core/deps/libwebsocket/client-parser.c b/core/deps/libwebsocket/client-parser.c deleted file mode 100644 index d7b97cc3e..000000000 --- a/core/deps/libwebsocket/client-parser.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c) -{ - int callback_action = LWS_CALLBACK_CLIENT_RECEIVE; - int handled; - struct lws_tokens eff_buf; - int m; - - switch (wsi->lws_rx_parse_state) { - case LWS_RXPS_NEW: - - switch (wsi->ietf_spec_revision) { - - case 13: - wsi->u.ws.opcode = c & 0xf; - wsi->u.ws.rsv = (c & 0x70); - wsi->u.ws.final = !!((c >> 7) & 1); - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - wsi->u.ws.frame_is_binary = wsi->u.ws.opcode == - LWS_WS_OPCODE_07__BINARY_FRAME; - break; - } - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; - break; - - default: - lwsl_err("unknown spec version %02d\n", - wsi->ietf_spec_revision); - break; - } - break; - - - case LWS_RXPS_04_FRAME_HDR_LEN: - - wsi->u.ws.this_frame_masked = !!(c & 0x80); - - switch (c & 0x7f) { - case 126: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; - break; - case 127: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; - break; - default: - wsi->u.ws.rx_packet_length = c; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (c) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->u.ws.rx_packet_length = c << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->u.ws.rx_packet_length |= c; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (wsi->u.ws.rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_8: - if (c & 0x80) { - lwsl_warn("b63 of length must be zero\n"); - /* kill the connection */ - return -1; - } -#if defined __LP64__ - wsi->u.ws.rx_packet_length = ((size_t)c) << 56; -#else - wsi->u.ws.rx_packet_length = 0; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_7: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 48; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_6: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 40; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_5: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 32; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 24; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 16; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->u.ws.rx_packet_length |= (size_t)c; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (wsi->u.ws.rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->u.ws.frame_masking_nonce_04[0] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->u.ws.frame_masking_nonce_04[1] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->u.ws.frame_masking_nonce_04[2] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->u.ws.frame_masking_nonce_04[3] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - - if (wsi->u.ws.rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - - case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - - if (!wsi->u.ws.rx_user_buffer) - lwsl_err("NULL client rx_user_buffer\n"); - - if ((!wsi->u.ws.this_frame_masked) || wsi->u.ws.all_zero_nonce) - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = c; - else - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = - c ^ wsi->u.ws.frame_masking_nonce_04[ - (wsi->u.ws.frame_mask_index++) & 3]; - - if (--wsi->u.ws.rx_packet_length == 0) { - /* spill because we have the whole frame */ - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - - /* - * if there's no protocol max frame size given, we are - * supposed to default to LWS_MAX_SOCKET_IO_BUF - */ - - if (!wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - LWS_MAX_SOCKET_IO_BUF) - break; - else - if (wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - wsi->protocol->rx_buffer_size) - break; - - /* spill because we filled our rx buffer */ -spill: - - handled = 0; - - /* - * is this frame a control packet we should take care of at this - * layer? If so service it and hide it from the user callback - */ - - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__CLOSE: - /* is this an acknowledgement of our close? */ - if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) { - /* - * fine he has told us he is closing too, let's - * finish our close - */ - lwsl_parser("seen server's close ack\n"); - return -1; - } - lwsl_parser("client sees server close len = %d\n", - wsi->u.ws.rx_user_buffer_head); - /* - * parrot the close packet payload back - * we do not care about how it went, we are closing - * immediately afterwards - */ - libwebsocket_write(wsi, (unsigned char *) - &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head, LWS_WRITE_CLOSE); - wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY; - /* close the connection */ - return -1; - - case LWS_WS_OPCODE_07__PING: - lwsl_info("client received ping, doing pong\n"); - /* - * parrot the ping packet payload back as a pong - * !!! this may block or have partial write or fail - * !!! very unlikely if the ping size is small - */ - libwebsocket_write(wsi, (unsigned char *) - &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head, - LWS_WRITE_PONG); - handled = 1; - break; - - case LWS_WS_OPCODE_07__PONG: - lwsl_info("client receied pong\n"); - lwsl_hexdump(&wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head); - - /* issue it */ - callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG; - break; - - case LWS_WS_OPCODE_07__CONTINUATION: - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - break; - - default: - - lwsl_parser("Reserved opc 0x%2X\n", wsi->u.ws.opcode); - - /* - * It's something special we can't understand here. - * Pass the payload up to the extension's parsing - * state machine. - */ - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - &eff_buf, 0) <= 0) { /* not handle or fail */ - - lwsl_ext("Unhandled ext opc 0x%x\n", - wsi->u.ws.opcode); - wsi->u.ws.rx_user_buffer_head = 0; - - return 0; - } - handled = 1; - break; - } - - /* - * No it's real payload, pass it up to the user callback. - * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using libwebsocket_write - */ - if (handled) - goto already_done; - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_RX, - &eff_buf, 0) < 0) /* fail */ - return -1; - - if (eff_buf.token_len <= 0 && - callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG) - goto already_done; - - eff_buf.token[eff_buf.token_len] = '\0'; - - if (!wsi->protocol->callback) - goto already_done; - - if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG) - lwsl_info("Client doing pong callback\n"); - - m = wsi->protocol->callback( - wsi->protocol->owning_server, - wsi, - (enum libwebsocket_callback_reasons)callback_action, - wsi->user_space, - eff_buf.token, - eff_buf.token_len); - - /* if user code wants to close, let caller know */ - if (m) - return 1; - -already_done: - wsi->u.ws.rx_user_buffer_head = 0; - break; - default: - lwsl_err("client rx illegal state\n"); - return 1; - } - - return 0; - -illegal_ctl_length: - - lwsl_warn("Control frame asking for extended length is illegal\n"); - /* kill the connection */ - return -1; -} - - diff --git a/core/deps/libwebsocket/client.c b/core/deps/libwebsocket/client.c deleted file mode 100644 index ffad490ac..000000000 --- a/core/deps/libwebsocket/client.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len) -{ - int n; - - switch (wsi->mode) { - case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY: - case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE: - case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY: - case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT: - case LWS_CONNMODE_WS_CLIENT: - for (n = 0; n < len; n++) - if (libwebsocket_client_rx_sm(wsi, *(*buf)++)) { - lwsl_debug("client_rx_sm failed\n"); - return 1; - } - return 0; - default: - break; - } - return 0; -} - -int lws_client_socket_service(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) -{ - int n; - char *p = (char *)&context->service_buffer[0]; - int len; - unsigned char c; - - switch (wsi->mode) { - - case LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT: - - /* - * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE - * timeout protection set in client-handshake.c - */ - - if (libwebsocket_client_connect_2(context, wsi) == NULL) { - /* closed */ - lwsl_client("closed\n"); - return -1; - } - - /* either still pending connection, or changed mode */ - return 0; - - case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY: - - /* handle proxy hung up on us */ - - if (pollfd->revents & LWS_POLLHUP) { - - lwsl_warn("Proxy connection %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; - } - - n = recv(wsi->sock, context->service_buffer, - sizeof(context->service_buffer), 0); - if (n < 0) { - - if (LWS_ERRNO == LWS_EAGAIN) { - lwsl_debug( - "Proxy read returned EAGAIN... retrying\n"); - return 0; - } - - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - lwsl_err("ERROR reading from proxy socket\n"); - return 0; - } - - context->service_buffer[13] = '\0'; - if (strcmp((char *)context->service_buffer, "HTTP/1.0 200 ")) { - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - lwsl_err("ERROR proxy: %s\n", context->service_buffer); - return 0; - } - - /* clear his proxy connection timeout */ - - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* fallthru */ - - case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE: - - /* - * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE - * timeout protection set in client-handshake.c - */ - - /* - * take care of our libwebsocket_callback_on_writable - * happening at a time when there's no real connection yet - */ - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) - return -1; - -#ifdef LWS_OPENSSL_SUPPORT - /* we can retry this... just cook the SSL BIO the first time */ - - if (wsi->use_ssl && !wsi->ssl) { - const char *hostname = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS); - - wsi->ssl = SSL_new(context->ssl_client_ctx); -#ifndef USE_CYASSL - SSL_set_mode(wsi->ssl, - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); -#endif - /* - * use server name indication (SNI), if supported, - * when establishing connection - */ -#ifdef USE_CYASSL -#ifdef CYASSL_SNI_HOST_NAME - CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME, - hostname, strlen(hostname)); -#endif -#else - SSL_set_tlsext_host_name(wsi->ssl, hostname); -#endif - -#ifdef USE_CYASSL - /* - * CyaSSL does certificate verification differently - * from OpenSSL. - * If we should ignore the certificate, we need to set - * this before SSL_new and SSL_connect is called. - * Otherwise the connect will simply fail with error - * code -155 - */ - if (wsi->use_ssl == 2) - CyaSSL_set_verify(wsi->ssl, - SSL_VERIFY_NONE, NULL); -#endif /* USE_CYASSL */ - - wsi->client_bio = - BIO_new_socket(wsi->sock, BIO_NOCLOSE); - SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio); - -#ifdef USE_CYASSL - CyaSSL_set_using_nonblock(wsi->ssl, 1); -#else - BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */ -#endif - - SSL_set_ex_data(wsi->ssl, - openssl_websocket_private_data_index, - context); - } - - if (wsi->use_ssl) { - lws_latency_pre(context, wsi); - n = SSL_connect(wsi->ssl); - lws_latency(context, wsi, - "SSL_connect LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE", - n, n > 0); - - if (n < 0) { - n = SSL_get_error(wsi->ssl, n); - - if (n == SSL_ERROR_WANT_READ || - n == SSL_ERROR_WANT_WRITE) { - /* - * wants us to retry connect due to - * state of the underlying ssl layer... - * but since it may be stalled on - * blocked write, no incoming data may - * arrive to trigger the retry. - * Force (possibly many times if the SSL - * state persists in returning the - * condition code, but other sockets - * are getting serviced inbetweentimes) - * us to get called back when writable. - */ - - lwsl_info( - "SSL_connect WANT_... retrying\n"); - libwebsocket_callback_on_writable( - context, wsi); - - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL; - - return 0; /* no error */ - } - n = -1; - } - - if (n <= 0) { - /* - * retry if new data comes until we - * run into the connection timeout or win - */ - - n = ERR_get_error(); - if (n != SSL_ERROR_NONE) { - lwsl_err("SSL connect error %lu: %s\n", - n, - ERR_error_string(n, - (char *)context->service_buffer)); - return 0; - } - } - } else - wsi->ssl = NULL; - - /* fallthru */ - - case LWS_CONNMODE_WS_CLIENT_WAITING_SSL: - - if (wsi->use_ssl) { - - if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SSL) { - lws_latency_pre(context, wsi); - n = SSL_connect(wsi->ssl); - lws_latency(context, wsi, - "SSL_connect LWS_CONNMODE_WS_CLIENT_WAITING_SSL", - n, n > 0); - - if (n < 0) { - n = SSL_get_error(wsi->ssl, n); - - if (n == SSL_ERROR_WANT_READ || - n == SSL_ERROR_WANT_WRITE) { - /* - * wants us to retry connect due to - * state of the underlying ssl layer... - * but since it may be stalled on - * blocked write, no incoming data may - * arrive to trigger the retry. - * Force (possibly many times if the SSL - * state persists in returning the - * condition code, but other sockets - * are getting serviced inbetweentimes) - * us to get called back when writable. - */ - - lwsl_info( - "SSL_connect WANT_... retrying\n"); - libwebsocket_callback_on_writable( - context, wsi); - - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL; - - return 0; /* no error */ - } - n = -1; - } - - if (n <= 0) { - /* - * retry if new data comes until we - * run into the connection timeout or win - */ - n = ERR_get_error(); - if (n != SSL_ERROR_NONE) { - lwsl_err("SSL connect error %lu: %s\n", - n, - ERR_error_string(n, - (char *)context->service_buffer)); - return 0; - } - } - } - - #ifndef USE_CYASSL - /* - * See comment above about CyaSSL certificate - * verification - */ - lws_latency_pre(context, wsi); - n = SSL_get_verify_result(wsi->ssl); - lws_latency(context, wsi, - "SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", - n, n > 0); - if ((n != X509_V_OK) && ( - n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || - wsi->use_ssl != 2)) { - - lwsl_err( - "server's cert didn't look good %d\n", n); - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS); - return 0; - } -#endif /* USE_CYASSL */ - } else - wsi->ssl = NULL; -#endif - - wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2; - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, - AWAITING_TIMEOUT); - - /* fallthru */ - - case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2: - p = libwebsockets_generate_client_handshake(context, wsi, p); - if (p == NULL) { - lwsl_err("Failed to generate handshake for client\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; - } - - /* send our request to the server */ - - lws_latency_pre(context, wsi); - - n = lws_ssl_capable_write(wsi, context->service_buffer, p - (char *)context->service_buffer); - lws_latency(context, wsi, "send lws_issue_raw", n, n == p - (char *)context->service_buffer); - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - lwsl_debug("ERROR writing to client socket\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; - case LWS_SSL_CAPABLE_MORE_SERVICE: - libwebsocket_callback_on_writable(context, wsi); - break; - } - - wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; - wsi->u.hdr.lextable_pos = 0; - wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY; - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - AWAITING_TIMEOUT); - break; - - case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY: - - /* handle server hung up on us */ - - if (pollfd->revents & LWS_POLLHUP) { - - lwsl_debug("Server connection %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - goto bail3; - } - - if (!(pollfd->revents & LWS_POLLIN)) - break; - - /* interpret the server response */ - - /* - * HTTP/1.1 101 Switching Protocols - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo= - * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC== - * Sec-WebSocket-Protocol: chat - */ - - /* - * we have to take some care here to only take from the - * socket bytewise. The browser may (and has been seen to - * in the case that onopen() performs websocket traffic) - * coalesce both handshake response and websocket traffic - * in one packet, since at that point the connection is - * definitively ready from browser pov. - */ - len = 1; - while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) { - n = lws_ssl_capable_read(wsi, &c, 1); - lws_latency(context, wsi, "send lws_issue_raw", n, n == 1); - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - goto bail3; - case LWS_SSL_CAPABLE_MORE_SERVICE: - return 0; - } - - if (libwebsocket_parse(wsi, c)) { - lwsl_warn("problems parsing header\n"); - goto bail3; - } - } - - /* - * hs may also be coming in multiple packets, there is a 5-sec - * libwebsocket timeout still active here too, so if parsing did - * not complete just wait for next packet coming in this state - */ - - if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) - break; - - /* - * otherwise deal with the handshake. If there's any - * packet traffic already arrived we'll trigger poll() again - * right away and deal with it that way - */ - - return lws_client_interpret_server_handshake(context, wsi); - -bail3: - lwsl_info( - "closing connection at LWS_CONNMODE...SERVER_REPLY\n"); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return -1; - - case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT: - lwsl_ext("LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT\n"); - break; - - case LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD: - lwsl_ext("LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD\n"); - break; - default: - break; - } - - return 0; -} - - -/* - * In-place str to lower case - */ - -static void -strtolower(char *s) -{ - while (*s) { - *s = tolower((int)*s); - s++; - } -} - -int -lws_client_interpret_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - const char *pc; - int okay = 0; - char *p; - int len; -#ifndef LWS_NO_EXTENSIONS - char ext_name[128]; - struct libwebsocket_extension *ext; - void *v; - int more = 1; - const char *c; -#endif - int n; - int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR; - - /* - * well, what the server sent looked reasonable for syntax. - * Now let's confirm it sent all the necessary headers - */ - - if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { - lwsl_info("no ACCEPT\n"); - goto bail3; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP); - if (!p) { - lwsl_info("no URI\n"); - goto bail3; - } - if (p && strncmp(p, "101", 3)) { - lwsl_warn( - "lws_client_handshake: got bad HTTP response '%s'\n", p); - goto bail3; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE); - if (!p) { - lwsl_info("no UPGRADE\n"); - goto bail3; - } - strtolower(p); - if (strcmp(p, "websocket")) { - lwsl_warn( - "lws_client_handshake: got bad Upgrade header '%s'\n", p); - goto bail3; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION); - if (!p) { - lwsl_info("no Connection hdr\n"); - goto bail3; - } - strtolower(p); - if (strcmp(p, "upgrade")) { - lwsl_warn("lws_client_int_s_hs: bad header %s\n", p); - goto bail3; - } - - pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); - if (pc == NULL) - lwsl_parser("lws_client_int_s_hs: no protocol list\n"); - else - lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc); - - /* - * confirm the protocol the server wants to talk was in the list - * of protocols we offered - */ - - len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL); - if (!len) { - - lwsl_info("lws_client_int_s_hs: WSI_TOKEN_PROTOCOL is null\n"); - /* - * no protocol name to work from, - * default to first protocol - */ - wsi->protocol = &context->protocols[0]; - goto check_extensions; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL); - len = strlen(p); - - while (*pc && !okay) { - if (!strncmp(pc, p, len) && - (pc[len] == ',' || pc[len] == '\0')) { - okay = 1; - continue; - } - while (*pc && *pc != ',') - pc++; - while (*pc && *pc != ' ') - pc++; - } - - if (!okay) { - lwsl_err("lws_client_int_s_hs: got bad protocol %s\n", p); - goto bail2; - } - - /* - * identify the selected protocol struct and set it - */ - n = 0; - wsi->protocol = NULL; - while (context->protocols[n].callback && !wsi->protocol) { - if (strcmp(p, context->protocols[n].name) == 0) { - wsi->protocol = &context->protocols[n]; - break; - } - n++; - } - - if (wsi->protocol == NULL) { - lwsl_err("lws_client_int_s_hs: fail protocol %s\n", p); - goto bail2; - } - - -check_extensions: -#ifndef LWS_NO_EXTENSIONS - /* instantiate the accepted extensions */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) { - lwsl_ext("no client extenstions allowed by server\n"); - goto check_accept; - } - - /* - * break down the list of server accepted extensions - * and go through matching them or identifying bogons - */ - - if (lws_hdr_copy(wsi, (char *)context->service_buffer, - sizeof(context->service_buffer), WSI_TOKEN_EXTENSIONS) < 0) { - lwsl_warn("ext list from server failed to copy\n"); - goto bail2; - } - - c = (char *)context->service_buffer; - n = 0; - while (more) { - - if (*c && (*c != ',' && *c != ' ' && *c != '\t')) { - ext_name[n] = *c++; - if (n < sizeof(ext_name) - 1) - n++; - continue; - } - ext_name[n] = '\0'; - if (!*c) - more = 0; - else { - c++; - if (!n) - continue; - } - - /* check we actually support it */ - - lwsl_ext("checking client ext %s\n", ext_name); - - n = 0; - ext = wsi->protocol->owning_server->extensions; - while (ext && ext->callback) { - - if (strcmp(ext_name, ext->name)) { - ext++; - continue; - } - - n = 1; - - lwsl_ext("instantiating client ext %s\n", ext_name); - - /* instantiate the extension on this conn */ - - wsi->active_extensions_user[ - wsi->count_active_extensions] = - malloc(ext->per_session_data_size); - if (wsi->active_extensions_user[ - wsi->count_active_extensions] == NULL) { - lwsl_err("Out of mem\n"); - goto bail2; - } - memset(wsi->active_extensions_user[ - wsi->count_active_extensions], 0, - ext->per_session_data_size); - wsi->active_extensions[ - wsi->count_active_extensions] = ext; - - /* allow him to construct his context */ - - ext->callback(wsi->protocol->owning_server, - ext, wsi, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - wsi->active_extensions_user[ - wsi->count_active_extensions], - NULL, 0); - - wsi->count_active_extensions++; - - ext++; - } - - if (n == 0) { - lwsl_warn("Unknown ext '%s'!\n", ext_name); - goto bail2; - } - - n = 0; - } - -check_accept: -#endif - - /* - * Confirm his accept token is the one we precomputed - */ - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT); - if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) { - lwsl_warn("lws_client_int_s_hs: accept %s wrong vs %s\n", p, - wsi->u.hdr.ah->initial_handshake_hash_base64); - goto bail2; - } - - /* allocate the per-connection user memory (if any) */ - if (libwebsocket_ensure_user_space(wsi)) { - lwsl_err("Problem allocating wsi user mem\n"); - goto bail2; - } - - /* - * we seem to be good to go, give client last chance to check - * headers and OK it - */ - - wsi->protocol->callback(context, wsi, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - wsi->user_space, NULL, 0); - - /* clear his proxy connection timeout */ - - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* free up his parsing allocations */ - if (wsi->u.hdr.ah) - free(wsi->u.hdr.ah); - - /* mark him as being alive */ - - wsi->state = WSI_STATE_ESTABLISHED; - wsi->mode = LWS_CONNMODE_WS_CLIENT; - - /* union transition */ - - memset(&wsi->u, 0, sizeof(wsi->u)); - - wsi->u.ws.rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* - * create the frame buffer for this connection according to the - * size mentioned in the protocol definition. If 0 there, then - * use a big default for compatibility - */ - - n = wsi->protocol->rx_buffer_size; - if (!n) - n = LWS_MAX_SOCKET_IO_BUF; - n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING; - wsi->u.ws.rx_user_buffer = malloc(n); - if (!wsi->u.ws.rx_user_buffer) { - lwsl_err("Out of Mem allocating rx buffer %d\n", n); - goto bail2; - } - lwsl_info("Allocating client RX buffer %d\n", n); - - if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { - lwsl_warn("Failed to set SNDBUF to %d", n); - goto bail3; - } - - lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name); - - /* call him back to inform him he is up */ - - wsi->protocol->callback(context, wsi, - LWS_CALLBACK_CLIENT_ESTABLISHED, - wsi->user_space, NULL, 0); -#ifndef LWS_NO_EXTENSIONS - /* - * inform all extensions, not just active ones since they - * already know - */ - - ext = context->extensions; - - while (ext && ext->callback) { - v = NULL; - for (n = 0; n < wsi->count_active_extensions; n++) - if (wsi->active_extensions[n] == ext) - v = wsi->active_extensions_user[n]; - - ext->callback(context, ext, wsi, - LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, v, NULL, 0); - ext++; - } -#endif - - return 0; - -bail3: - free(wsi->u.ws.rx_user_buffer); - wsi->u.ws.rx_user_buffer = NULL; - close_reason = LWS_CLOSE_STATUS_NOSTATUS; - -bail2: - if (wsi->protocol) - wsi->protocol->callback(context, wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, NULL, 0); - - lwsl_info("closing connection due to bail2 connection error\n"); - - /* free up his parsing allocations */ - - if (wsi->u.hdr.ah) - free(wsi->u.hdr.ah); - - libwebsocket_close_and_free_session(context, wsi, close_reason); - - return 1; -} - - -char * -libwebsockets_generate_client_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char *pkt) -{ - char buf[128]; - char hash[20]; - char key_b64[40]; - char *p = pkt; - int n; -#ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension *ext; - int ext_count = 0; -#endif - - /* - * create the random key - */ - - n = libwebsockets_get_random(context, hash, 16); - if (n != 16) { - lwsl_err("Unable to read from random dev %s\n", - SYSTEM_RANDOM_FILEPATH); - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return NULL; - } - - lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64)); - - /* - * 00 example client handshake - * - * GET /socket.io/websocket HTTP/1.1 - * Upgrade: WebSocket - * Connection: Upgrade - * Host: 127.0.0.1:9999 - * Origin: http://127.0.0.1 - * Sec-WebSocket-Key1: 1 0 2#0W 9 89 7 92 ^ - * Sec-WebSocket-Key2: 7 7Y 4328 B2v[8(z1 - * Cookie: socketio=websocket - * - * (Á®Ä0¶†≥ - * - * 04 example client handshake - * - * GET /chat HTTP/1.1 - * Host: server.example.com - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== - * Sec-WebSocket-Origin: http://example.com - * Sec-WebSocket-Protocol: chat, superchat - * Sec-WebSocket-Version: 4 - */ - - p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI)); - - p += sprintf(p, - "Pragma: no-cache\x0d\x0a""Cache-Control: no-cache\x0d\x0a"); - - p += sprintf(p, "Host: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST)); - p += sprintf(p, -"Upgrade: websocket\x0d\x0a""Connection: Upgrade\x0d\x0a""Sec-WebSocket-Key: "); - strcpy(p, key_b64); - p += strlen(key_b64); - p += sprintf(p, "\x0d\x0a"); - if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)) - p += sprintf(p, "Origin: http://%s\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)); - - if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS)) - p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS)); - - /* tell the server what extensions we could support */ - - p += sprintf(p, "Sec-WebSocket-Extensions: "); -#ifndef LWS_NO_EXTENSIONS - ext = context->extensions; - while (ext && ext->callback) { - - n = lws_ext_callback_for_each_extension_type(context, wsi, - LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - (char *)ext->name, 0); - if (n) { /* an extension vetos us */ - lwsl_ext("ext %s vetoed\n", (char *)ext->name); - ext++; - continue; - } - - n = context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - wsi->user_space, (char *)ext->name, 0); - - /* - * zero return from callback means - * go ahead and allow the extension, - * it's what we get if the callback is - * unhandled - */ - - if (n) { - ext++; - continue; - } - - /* apply it */ - - if (ext_count) - *p++ = ','; - p += sprintf(p, "%s", ext->name); - ext_count++; - - ext++; - } -#endif - p += sprintf(p, "\x0d\x0a"); - - if (wsi->ietf_spec_revision) - p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", - wsi->ietf_spec_revision); - - /* give userland a chance to append, eg, cookies */ - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - NULL, &p, (pkt + sizeof(context->service_buffer)) - p - 12); - - p += sprintf(p, "\x0d\x0a"); - - /* prepare the expected server accept response */ - - key_b64[39] = '\0'; /* enforce composed length below buf sizeof */ - n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key_b64); - - SHA1((unsigned char *)buf, n, (unsigned char *)hash); - - lws_b64_encode_string(hash, 20, - wsi->u.hdr.ah->initial_handshake_hash_base64, - sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64)); - - return p; -} - diff --git a/core/deps/libwebsocket/config.h b/core/deps/libwebsocket/config.h deleted file mode 100644 index 67d08541f..000000000 --- a/core/deps/libwebsocket/config.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "build.h" - -#define LWS_BUILTIN_GETIFADDRS -#define LWS_NO_DAEMONIZE \ No newline at end of file diff --git a/core/deps/libwebsocket/context.c b/core/deps/libwebsocket/context.c deleted file mode 100644 index c63ab271c..000000000 --- a/core/deps/libwebsocket/context.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -#ifndef LWS_BUILD_HASH -#define LWS_BUILD_HASH "unknown-build-hash" -#endif - -#ifdef WIN32 -#define getdtablesize() 30000 -#endif - -static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH; - -/** - * lws_get_library_version: get version and git hash library built from - * - * returns a const char * to a string like "1.1 178d78c" - * representing the library version followed by the git head hash it - * was built from - */ - -LWS_VISIBLE const char * -lws_get_library_version(void) -{ - return library_version; -} - -/** - * libwebsocket_create_context() - Create the websocket handler - * @info: pointer to struct with parameters - * - * This function creates the listening socket (if serving) and takes care - * of all initialization in one step. - * - * After initialization, it returns a struct libwebsocket_context * that - * represents this server. After calling, user code needs to take care - * of calling libwebsocket_service() with the context pointer to get the - * server's sockets serviced. This must be done in the same process - * context as the initialization call. - * - * The protocol callback functions are called for a handful of events - * including http requests coming in, websocket connections becoming - * established, and data arriving; it's also called periodically to allow - * async transmission. - * - * HTTP requests are sent always to the FIRST protocol in @protocol, since - * at that time websocket protocol has not been negotiated. Other - * protocols after the first one never see any HTTP callack activity. - * - * The server created is a simple http server by default; part of the - * websocket standard is upgrading this http connection to a websocket one. - * - * This allows the same server to provide files like scripts and favicon / - * images or whatever over http and dynamic data over websockets all in - * one place; they're all handled in the user callback. - */ - -LWS_VISIBLE struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info) -{ - struct libwebsocket_context *context = NULL; - char *p; - - int pid_daemon = get_daemonize_pid(); - - lwsl_notice("Initial logging level %d\n", log_level); - lwsl_notice("Library version: %s\n", library_version); -#ifdef LWS_USE_IPV6 - if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6)) - lwsl_notice("IPV6 compiled in and enabled\n"); - else - lwsl_notice("IPV6 compiled in but disabled\n"); -#else - lwsl_notice("IPV6 not compiled in\n"); -#endif - lws_feature_status_libev(info); - lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN); - lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS); - - lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED); - lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT); - lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH); - lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER); - - if (lws_plat_context_early_init()) - return NULL; - - context = (struct libwebsocket_context *) - malloc(sizeof(struct libwebsocket_context)); - if (!context) { - lwsl_err("No memory for websocket context\n"); - return NULL; - } - memset(context, 0, sizeof(*context)); - - if (pid_daemon) { - context->started_with_parent = pid_daemon; - lwsl_notice(" Started with daemon pid %d\n", pid_daemon); - } - - context->listen_service_extraseen = 0; - context->protocols = info->protocols; - context->listen_port = info->port; - context->http_proxy_port = 0; - context->http_proxy_address[0] = '\0'; - context->options = info->options; - context->iface = info->iface; - /* to reduce this allocation, */ -#ifdef WIN32 - context->max_fds = getdtablesize (); -#else - context->max_fds = sysconf(_SC_OPEN_MAX); -#endif - lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n", - sizeof(struct libwebsocket_context), - sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *), - context->max_fds, - sizeof(struct libwebsocket_context) + - ((sizeof(struct libwebsocket_pollfd) + - sizeof(struct libwebsocket *)) * - context->max_fds)); - - context->fds = (struct libwebsocket_pollfd *) - malloc(sizeof(struct libwebsocket_pollfd) * - context->max_fds); - if (context->fds == NULL) { - lwsl_err("Unable to allocate fds array for %d connections\n", - context->max_fds); - free(context); - return NULL; - } - - context->lws_lookup = (struct libwebsocket **) - malloc(sizeof(struct libwebsocket *) * context->max_fds); - if (context->lws_lookup == NULL) { - lwsl_err( - "Unable to allocate lws_lookup array for %d connections\n", - context->max_fds); - free(context->fds); - free(context); - return NULL; - } - memset(context->lws_lookup, 0, sizeof(struct libwebsocket *) * - context->max_fds); - - if (lws_plat_init_fd_tables(context)) { - free(context->lws_lookup); - free(context->fds); - free(context); - return NULL; - } - - lws_context_init_extensions(info, context); - - context->user_space = info->user; - - strcpy(context->canonical_hostname, "unknown"); - - lws_server_get_canonical_hostname(context, info); - - /* split the proxy ads:port if given */ - - if (info->http_proxy_address) { - strncpy(context->http_proxy_address, info->http_proxy_address, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - context->http_proxy_port = info->http_proxy_port; - } else { -#ifdef HAVE_GETENV - p = getenv("http_proxy"); - if (p) { - strncpy(context->http_proxy_address, p, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - - p = strchr(context->http_proxy_address, ':'); - if (p == NULL) { - lwsl_err("http_proxy needs to be ads:port\n"); - goto bail; - } - *p = '\0'; - context->http_proxy_port = atoi(p + 1); - } -#endif - } - - if (context->http_proxy_address[0]) - lwsl_notice(" Proxy %s:%u\n", - context->http_proxy_address, - context->http_proxy_port); - - lwsl_notice( - " per-conn mem: %u + %u headers + protocol rx buf\n", - sizeof(struct libwebsocket), - sizeof(struct allocated_headers)); - - if (lws_context_init_server_ssl(info, context)) - goto bail; - - if (lws_context_init_client_ssl(info, context)) - goto bail; - - if (lws_context_init_server(info, context)) - goto bail; - - /* - * drop any root privs for this process - * to listen on port < 1023 we would have needed root, but now we are - * listening, we don't want the power for anything else - */ - lws_plat_drop_app_privileges(info); - - /* initialize supported protocols */ - - for (context->count_protocols = 0; - info->protocols[context->count_protocols].callback; - context->count_protocols++) { - - lwsl_parser(" Protocol: %s\n", - info->protocols[context->count_protocols].name); - - info->protocols[context->count_protocols].owning_server = - context; - info->protocols[context->count_protocols].protocol_index = - context->count_protocols; - - /* - * inform all the protocols that they are doing their one-time - * initialization if they want to - */ - info->protocols[context->count_protocols].callback(context, - NULL, LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0); - } - - /* - * give all extensions a chance to create any per-context - * allocations they need - */ - - if (info->port != CONTEXT_PORT_NO_LISTEN) { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - NULL, 0) < 0) - goto bail; - } else - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - NULL, 0) < 0) - goto bail; - - return context; - -bail: - libwebsocket_context_destroy(context); - return NULL; -} - -/** - * libwebsocket_context_destroy() - Destroy the websocket context - * @context: Websocket context - * - * This function closes any active connections and then frees the - * context. After calling this, any further use of the context is - * undefined. - */ -LWS_VISIBLE void -libwebsocket_context_destroy(struct libwebsocket_context *context) -{ - int n; - struct libwebsocket_protocols *protocol = context->protocols; - - lwsl_notice("%s\n", __func__); - -#ifdef LWS_LATENCY - if (context->worst_latency_info[0]) - lwsl_notice("Worst latency: %s\n", context->worst_latency_info); -#endif - - for (n = 0; n < context->fds_count; n++) { - struct libwebsocket *wsi = - context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS /* no protocol close */); - n--; - } - - /* - * give all extensions a chance to clean up any per-context - * allocations they might have made - */ - if (context->listen_port) { - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0) - return; - } else - if (lws_ext_callback_for_each_extension_type(context, NULL, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0) - return; - - /* - * inform all the protocols that they are done and will have no more - * callbacks - */ - - while (protocol->callback) { - protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY, - NULL, NULL, 0); - protocol++; - } - - lws_plat_context_early_destroy(context); - - lws_ssl_context_destroy(context); - - if (context->fds) - free(context->fds); - if (context->lws_lookup) - free(context->lws_lookup); - - lws_plat_context_late_destroy(context); - - free(context); -} diff --git a/core/deps/libwebsocket/extension-deflate-frame.c b/core/deps/libwebsocket/extension-deflate-frame.c deleted file mode 100644 index 6cf6ac016..000000000 --- a/core/deps/libwebsocket/extension-deflate-frame.c +++ /dev/null @@ -1,294 +0,0 @@ -#include "private-libwebsockets.h" -#include "extension-deflate-frame.h" -#include -#include -#include - -#define LWS_ZLIB_WINDOW_BITS 15 -#define LWS_ZLIB_MEMLEVEL 8 - -int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ext_deflate_frame_conn *conn = - (struct lws_ext_deflate_frame_conn *)user; - struct lws_tokens *eff_buf = (struct lws_tokens *)in; - size_t current_payload, remaining_payload, total_payload; - int n; - size_t len_so_far; - - switch (reason) { - - /* - * for deflate-frame, both client and server sides act the same - */ - - case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: - case LWS_EXT_CALLBACK_CONSTRUCT: - conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL; - conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL; - conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL; - n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS); - if (n != Z_OK) { - lwsl_ext("deflateInit returned %d\n", n); - return 1; - } - n = deflateInit2(&conn->zs_out, - (context->listen_port ? - DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER : - DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT), - Z_DEFLATED, - -LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL, - Z_DEFAULT_STRATEGY); - if (n != Z_OK) { - lwsl_ext("deflateInit2 returned %d\n", n); - return 1; - } - conn->buf_pre_used = 0; - conn->buf_pre_length = 0; - conn->buf_in_length = sizeof(conn->buf_in); - conn->buf_out_length = sizeof(conn->buf_out); - conn->compressed_out = 0; - conn->buf_pre = NULL; - conn->buf_in = (unsigned char *) - malloc(LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_in_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_in) - goto bail; - conn->buf_out = (unsigned char *) - malloc(LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_out_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_out) - goto bail; - lwsl_ext("zlibs constructed\n"); - break; -bail: - lwsl_err("Out of mem\n"); - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - return -1; - - case LWS_EXT_CALLBACK_DESTROY: - if (conn->buf_pre) - free(conn->buf_pre); - free(conn->buf_in); - free(conn->buf_out); - conn->buf_pre_used = 0; - conn->buf_pre_length = 0; - conn->buf_in_length = 0; - conn->buf_out_length = 0; - conn->compressed_out = 0; - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - lwsl_ext("zlibs destructed\n"); - break; - - case LWS_EXT_CALLBACK_PAYLOAD_RX: - if (!(wsi->u.ws.rsv & 0x40)) - return 0; - - /* - * inflate the incoming payload - */ - current_payload = eff_buf->token_len; - - remaining_payload = wsi->u.ws.rx_packet_length; - if (remaining_payload) { - total_payload = conn->buf_pre_used + - current_payload + - remaining_payload; - - if (conn->buf_pre_length < total_payload) { - conn->buf_pre_length = total_payload; - if (conn->buf_pre) - free(conn->buf_pre); - conn->buf_pre = - (unsigned char *)malloc(total_payload + 4); - if (!conn->buf_pre) { - lwsl_err("Out of memory\n"); - return -1; - } - } - - memcpy(conn->buf_pre + conn->buf_pre_used, - eff_buf->token, current_payload); - conn->buf_pre_used += current_payload; - - eff_buf->token = NULL; - eff_buf->token_len = 0; - - return 0; - } - if (conn->buf_pre_used) { - total_payload = conn->buf_pre_used + - current_payload; - - memcpy(conn->buf_pre + conn->buf_pre_used, - eff_buf->token, current_payload); - conn->buf_pre_used = 0; - - conn->zs_in.next_in = conn->buf_pre; - } else { - total_payload = current_payload; - - conn->zs_in.next_in = (unsigned char *)eff_buf->token; - } - - conn->zs_in.next_in[total_payload + 0] = 0; - conn->zs_in.next_in[total_payload + 1] = 0; - conn->zs_in.next_in[total_payload + 2] = 0xff; - conn->zs_in.next_in[total_payload + 3] = 0xff; - - conn->zs_in.avail_in = total_payload + 4; - - conn->zs_in.next_out = - conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING; - conn->zs_in.avail_out = conn->buf_in_length; - - while (1) { - n = inflate(&conn->zs_in, Z_SYNC_FLUSH); - switch (n) { - case Z_NEED_DICT: - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - /* - * screwed.. close the connection... - * we will get a destroy callback to take care - * of closing nicely - */ - lwsl_info("zlib error inflate %d: %s\n", - n, conn->zs_in.msg); - return -1; - } - - if (conn->zs_in.avail_out) - break; - - len_so_far = conn->zs_in.next_out - - (conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING); - - conn->buf_in_length *= 2; - if (conn->buf_in_length > LWS_MAX_ZLIB_CONN_BUFFER) { - lwsl_ext("zlib in buffer hit limit %u\n", - LWS_MAX_ZLIB_CONN_BUFFER); - return -1; - } - conn->buf_in = (unsigned char *)realloc(conn->buf_in, - LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_in_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_in) { - lwsl_err("Out of memory\n"); - return -1; - } - lwsl_debug( - "deflate-frame ext RX did realloc to %ld\n", - conn->buf_in_length); - conn->zs_in.next_out = conn->buf_in + - LWS_SEND_BUFFER_PRE_PADDING + len_so_far; - conn->zs_in.avail_out = - conn->buf_in_length - len_so_far; - } - - /* rewrite the buffer pointers and length */ - eff_buf->token = - (char *)(conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING); - eff_buf->token_len = (int)(conn->zs_in.next_out - - (conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING)); - - return 0; - - case LWS_EXT_CALLBACK_PAYLOAD_TX: - /* - * deflate the outgoing payload - */ - current_payload = eff_buf->token_len; - - conn->zs_out.next_in = (unsigned char *)eff_buf->token; - conn->zs_out.avail_in = current_payload; - - conn->zs_out.next_out = - conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING; - conn->zs_out.avail_out = conn->buf_out_length; - - while (1) { - n = deflate(&conn->zs_out, Z_SYNC_FLUSH); - if (n == Z_STREAM_ERROR) { - /* - * screwed.. close the connection... we will - * get a destroy callback to take care of - * closing nicely - */ - lwsl_ext("zlib error deflate\n"); - - return -1; - } - - if (conn->zs_out.avail_out) - break; - - len_so_far = (conn->zs_out.next_out - - (conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING)); - conn->buf_out_length *= 2; - if (conn->buf_out_length > LWS_MAX_ZLIB_CONN_BUFFER) { - lwsl_ext("zlib out hit limit %u\n", - LWS_MAX_ZLIB_CONN_BUFFER); - return -1; - } - conn->buf_out = (unsigned char *)realloc( - conn->buf_out, - LWS_SEND_BUFFER_PRE_PADDING + - conn->buf_out_length + - LWS_SEND_BUFFER_POST_PADDING); - if (!conn->buf_out) { - lwsl_err("Out of memory\n"); - return -1; - } - lwsl_debug( - "deflate-frame ext TX did realloc to %ld\n", - conn->buf_in_length); - - conn->zs_out.next_out = (conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING + len_so_far); - conn->zs_out.avail_out = - (conn->buf_out_length - len_so_far); - } - - conn->compressed_out = 1; - - /* rewrite the buffer pointers and length */ - eff_buf->token = (char *)(conn->buf_out + - LWS_SEND_BUFFER_PRE_PADDING); - eff_buf->token_len = (int)(conn->zs_out.next_out - - (conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING)) - 4; - - return 0; - - case LWS_EXT_CALLBACK_PACKET_TX_PRESEND: - if (conn->compressed_out) { - conn->compressed_out = 0; - *((unsigned char *)eff_buf->token) |= 0x40; - } - break; - - case LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION: - /* Avoid x-webkit-deflate-frame extension on client */ - if (!strcmp((char *)in, "x-webkit-deflate-frame")) - return 1; - break; - - default: - break; - } - - return 0; -} - diff --git a/core/deps/libwebsocket/extension-deflate-frame.h b/core/deps/libwebsocket/extension-deflate-frame.h deleted file mode 100644 index 685cdebf9..000000000 --- a/core/deps/libwebsocket/extension-deflate-frame.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "deps/zlib/zlib.h" - -#define DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER 1 -#define DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT Z_DEFAULT_COMPRESSION - -struct lws_ext_deflate_frame_conn { - z_stream zs_in; - z_stream zs_out; - size_t buf_pre_used; - size_t buf_pre_length; - size_t buf_in_length; - size_t buf_out_length; - int compressed_out; - unsigned char *buf_pre; - unsigned char *buf_in; - unsigned char *buf_out; -}; - -extern int lws_extension_callback_deflate_frame( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); diff --git a/core/deps/libwebsocket/extension-deflate-stream.c b/core/deps/libwebsocket/extension-deflate-stream.c deleted file mode 100644 index addaa2c7e..000000000 --- a/core/deps/libwebsocket/extension-deflate-stream.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "private-libwebsockets.h" -#include "extension-deflate-stream.h" -#include -#include -#include - -#define LWS_ZLIB_WINDOW_BITS 15 -#define LWS_ZLIB_MEMLEVEL 8 - -int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ext_deflate_stream_conn *conn = - (struct lws_ext_deflate_stream_conn *)user; - int n; - struct lws_tokens *eff_buf = (struct lws_tokens *)in; - - switch (reason) { - - /* - * for deflate-stream, both client and server sides act the same - */ - - case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: - case LWS_EXT_CALLBACK_CONSTRUCT: - conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL; - conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL; - conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL; - n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS); - if (n != Z_OK) { - lwsl_err("deflateInit returned %d\n", n); - return 1; - } - n = deflateInit2(&conn->zs_out, - DEFLATE_STREAM_COMPRESSION_LEVEL, Z_DEFLATED, - -LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL, - Z_DEFAULT_STRATEGY); - if (n != Z_OK) { - lwsl_err("deflateInit returned %d\n", n); - return 1; - } - lwsl_ext("zlibs constructed\n"); - conn->remaining_in = 0; - break; - - case LWS_EXT_CALLBACK_DESTROY: - (void)inflateEnd(&conn->zs_in); - (void)deflateEnd(&conn->zs_out); - lwsl_ext("zlibs destructed\n"); - break; - - case LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: - - /* - * inflate the incoming compressed data - * Notice, length may be 0 and pointer NULL - * in the case we are flushing with nothing new coming in - */ - if (conn->remaining_in) { - conn->zs_in.next_in = conn->buf_in; - conn->zs_in.avail_in = conn->remaining_in; - conn->remaining_in = 0; - } else { - conn->zs_in.next_in = (unsigned char *)eff_buf->token; - conn->zs_in.avail_in = eff_buf->token_len; - } - - conn->zs_in.next_out = conn->buf_out; - conn->zs_in.avail_out = sizeof(conn->buf_out); - - n = inflate(&conn->zs_in, Z_SYNC_FLUSH); - switch (n) { - case Z_NEED_DICT: - case Z_DATA_ERROR: - case Z_MEM_ERROR: - /* - * screwed.. close the connection... we will get a - * destroy callback to take care of closing nicely - */ - lwsl_err("zlib error inflate %d\n", n); - return -1; - } - - /* rewrite the buffer pointers and length */ - - eff_buf->token = (char *)conn->buf_out; - eff_buf->token_len = - sizeof(conn->buf_out) - conn->zs_in.avail_out; - - /* copy avail data if not consumed */ - if (conn->zs_in.avail_in > 0) { - conn->remaining_in = conn->zs_in.avail_in; - memcpy(conn->buf_in, conn->zs_in.next_in, - conn->zs_in.avail_in); - return 1; - } - - /* - * if we filled the output buffer, signal that we likely have - * more and need to be called again - */ - - if (eff_buf->token_len == sizeof(conn->buf_out)) - return 1; - - /* we don't need calling again until new input data comes */ - - return 0; - - case LWS_EXT_CALLBACK_FLUSH_PENDING_TX: - case LWS_EXT_CALLBACK_PACKET_TX_PRESEND: - - /* - * deflate the outgoing compressed data - */ - - conn->zs_out.next_in = (unsigned char *)eff_buf->token; - conn->zs_out.avail_in = eff_buf->token_len; - - conn->zs_out.next_out = conn->buf_out; - conn->zs_out.avail_out = sizeof(conn->buf_out); - - n = Z_PARTIAL_FLUSH; - if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX) - n = Z_FULL_FLUSH; - - n = deflate(&conn->zs_out, n); - if (n == Z_STREAM_ERROR) { - /* - * screwed.. close the connection... we will get a - * destroy callback to take care of closing nicely - */ - lwsl_ext("zlib error deflate\n"); - - return -1; - } - - /* rewrite the buffer pointers and length */ - - eff_buf->token = (char *)conn->buf_out; - eff_buf->token_len = - sizeof(conn->buf_out) - conn->zs_out.avail_out; - - /* - * if we filled the output buffer, signal that we likely have - * more and need to be called again... even in deflate case - * we might sometimes need to spill more than came in - */ - - if (eff_buf->token_len == sizeof(conn->buf_out)) - return 1; - - /* we don't need calling again until new input data comes */ - - return 0; - - default: - break; - } - - return 0; -} diff --git a/core/deps/libwebsocket/extension-deflate-stream.h b/core/deps/libwebsocket/extension-deflate-stream.h deleted file mode 100644 index ff17741fd..000000000 --- a/core/deps/libwebsocket/extension-deflate-stream.h +++ /dev/null @@ -1,20 +0,0 @@ - -#include "deps/zlib/zlib.h" - -#define DEFLATE_STREAM_CHUNK 128 -#define DEFLATE_STREAM_COMPRESSION_LEVEL 1 - -struct lws_ext_deflate_stream_conn { - z_stream zs_in; - z_stream zs_out; - int remaining_in; - unsigned char buf_in[LWS_MAX_SOCKET_IO_BUF]; - unsigned char buf_out[LWS_MAX_SOCKET_IO_BUF]; -}; - -extern int lws_extension_callback_deflate_stream( - struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); diff --git a/core/deps/libwebsocket/extension.c b/core/deps/libwebsocket/extension.c deleted file mode 100644 index 52510a919..000000000 --- a/core/deps/libwebsocket/extension.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "private-libwebsockets.h" - -#include "extension-deflate-frame.h" -#include "extension-deflate-stream.h" - -struct libwebsocket_extension libwebsocket_internal_extensions[] = { -#ifdef LWS_EXT_DEFLATE_STREAM - { - "deflate-stream", - lws_extension_callback_deflate_stream, - sizeof(struct lws_ext_deflate_stream_conn) - }, -#else - { - "x-webkit-deflate-frame", - lws_extension_callback_deflate_frame, - sizeof(struct lws_ext_deflate_frame_conn) - }, - { - "deflate-frame", - lws_extension_callback_deflate_frame, - sizeof(struct lws_ext_deflate_frame_conn) - }, -#endif - { /* terminator */ - NULL, NULL, 0 - } -}; - -LWS_VISIBLE void -lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context) -{ - context->extensions = info->extensions; - lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE); -} - -LWS_VISIBLE struct libwebsocket_extension *libwebsocket_get_internal_extensions() -{ - return libwebsocket_internal_extensions; -} - - -/* 0 = nobody had nonzero return, 1 = somebody had positive return, -1 = fail */ - -int lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, - void *arg, int len) -{ - int n, m, handled = 0; - - for (n = 0; n < wsi->count_active_extensions; n++) { - m = wsi->active_extensions[n]->callback( - wsi->protocol->owning_server, - wsi->active_extensions[n], wsi, - reason, - wsi->active_extensions_user[n], - arg, len); - if (m < 0) { - lwsl_ext( - "Extension '%s' failed to handle callback %d!\n", - wsi->active_extensions[n]->name, reason); - return -1; - } - if (m > handled) - handled = m; - } - - return handled; -} - -int lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, - int reason, void *arg, int len) -{ - int n = 0, m, handled = 0; - struct libwebsocket_extension *ext = context->extensions; - - while (ext && ext->callback && !handled) { - m = ext->callback(context, ext, wsi, reason, - (void *)(long)n, arg, len); - if (m < 0) { - lwsl_ext( - "Extension '%s' failed to handle callback %d!\n", - wsi->active_extensions[n]->name, reason); - return -1; - } - if (m) - handled = 1; - - ext++; - n++; - } - - return 0; -} - -int -lws_issue_raw_ext_access(struct libwebsocket *wsi, - unsigned char *buf, size_t len) -{ - int ret; - struct lws_tokens eff_buf; - int m; - int n; - - eff_buf.token = (char *)buf; - eff_buf.token_len = len; - - /* - * while we have original buf to spill ourselves, or extensions report - * more in their pipeline - */ - - ret = 1; - while (ret == 1) { - - /* default to nobody has more to spill */ - - ret = 0; - - /* show every extension the new incoming data */ - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, &eff_buf, 0); - if (m < 0) - return -1; - if (m) /* handled */ - ret = 1; - - if ((char *)buf != eff_buf.token) - /* - * extension recreated it: - * need to buffer this if not all sent - */ - wsi->u.ws.clean_buffer = 0; - - /* assuming they left us something to send, send it */ - - if (eff_buf.token_len) { - n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - lwsl_info("closing from ext access\n"); - return -1; - } - - /* always either sent it all or privately buffered */ - } - - lwsl_parser("written %d bytes to client\n", eff_buf.token_len); - - /* no extension has more to spill? Then we can go */ - - if (!ret) - break; - - /* we used up what we had */ - - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* - * Did that leave the pipe choked? - * Or we had to hold on to some of it? - */ - - if (!lws_send_pipe_choked(wsi) && !wsi->truncated_send_len) - /* no we could add more, lets's do that */ - continue; - - lwsl_debug("choked\n"); - - /* - * Yes, he's choked. Don't spill the rest now get a callback - * when he is ready to send and take care of it there - */ - libwebsocket_callback_on_writable( - wsi->protocol->owning_server, wsi); - wsi->extension_data_pending = 1; - ret = 0; - } - - return len; -} - -int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, - void *v, size_t len) -{ - int n; - int handled = 0; - - /* maybe an extension will take care of it for us */ - - for (n = 0; n < wsi->count_active_extensions && !handled; n++) { - if (!wsi->active_extensions[n]->callback) - continue; - - handled |= wsi->active_extensions[n]->callback(context, - wsi->active_extensions[n], wsi, - r, wsi->active_extensions_user[n], v, len); - } - - return handled; -} diff --git a/core/deps/libwebsocket/handshake.c b/core/deps/libwebsocket/handshake.c deleted file mode 100644 index 25dd3cc6f..000000000 --- a/core/deps/libwebsocket/handshake.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -/* - * -04 of the protocol (actually the 80th version) has a radically different - * handshake. The 04 spec gives the following idea - * - * The handshake from the client looks as follows: - * - * GET /chat HTTP/1.1 - * Host: server.example.com - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== - * Sec-WebSocket-Origin: http://example.com - * Sec-WebSocket-Protocol: chat, superchat - * Sec-WebSocket-Version: 4 - * - * The handshake from the server looks as follows: - * - * HTTP/1.1 101 Switching Protocols - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo= - * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC== - * Sec-WebSocket-Protocol: chat - */ - -/* - * We have to take care about parsing because the headers may be split - * into multiple fragments. They may contain unknown headers with arbitrary - * argument lengths. So, we parse using a single-character at a time state - * machine that is completely independent of packet size. - */ - -LWS_VISIBLE int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char *buf, size_t len) -{ - size_t n; - - switch (wsi->state) { - - case WSI_STATE_HTTP_BODY: -http_postbody: - while (len--) { - - if (wsi->u.http.content_length_seen >= wsi->u.http.content_length) - break; - - wsi->u.http.post_buffer[wsi->u.http.body_index++] = *buf++; - wsi->u.http.content_length_seen++; - n = wsi->protocol->rx_buffer_size; - if (!n) - n = LWS_MAX_SOCKET_IO_BUF; - - if (wsi->u.http.body_index != n && - wsi->u.http.content_length_seen != wsi->u.http.content_length) - continue; - - if (wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY, - wsi->user_space, wsi->u.http.post_buffer, - wsi->u.http.body_index); - wsi->u.http.body_index = 0; - if (n) - goto bail; - } - - if (wsi->u.http.content_length_seen == wsi->u.http.content_length) { - /* he sent the content in time */ - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - wsi->user_space, NULL, 0); - wsi->u.http.body_index = 0; - if (n) - goto bail; - } - - } - - /* - * we need to spill here so everything is seen in the case - * there is no content-length - */ - if (wsi->u.http.body_index && wsi->protocol->callback) { - n = wsi->protocol->callback( - wsi->protocol->owning_server, wsi, - LWS_CALLBACK_HTTP_BODY, - wsi->user_space, wsi->u.http.post_buffer, - wsi->u.http.body_index); - wsi->u.http.body_index = 0; - if (n) - goto bail; - } - break; - - case WSI_STATE_HTTP_ISSUING_FILE: - case WSI_STATE_HTTP: - wsi->state = WSI_STATE_HTTP_HEADERS; - wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; - wsi->u.hdr.lextable_pos = 0; - /* fallthru */ - case WSI_STATE_HTTP_HEADERS: - - lwsl_parser("issuing %d bytes to parser\n", (int)len); - - if (lws_handshake_client(wsi, &buf, len)) - goto bail; - - switch (lws_handshake_server(context, wsi, &buf, len)) { - case 1: - goto bail; - case 2: - goto http_postbody; - } - break; - - case WSI_STATE_AWAITING_CLOSE_ACK: - case WSI_STATE_ESTABLISHED: - if (lws_handshake_client(wsi, &buf, len)) - goto bail; - switch (wsi->mode) { - case LWS_CONNMODE_WS_SERVING: - - if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) { - lwsl_info("interpret_incoming_packet has bailed\n"); - goto bail; - } - break; - } - break; - default: - lwsl_err("libwebsocket_read: Unhandled state\n"); - break; - } - - return 0; - -bail: - lwsl_debug("closing connection at libwebsocket_read bail:\n"); - - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - - return -1; -} diff --git a/core/deps/libwebsocket/lextable.h b/core/deps/libwebsocket/lextable.h deleted file mode 100644 index 43dbda9ab..000000000 --- a/core/deps/libwebsocket/lextable.h +++ /dev/null @@ -1,287 +0,0 @@ -/* pos 0000: 0 */ 0x67 /* 'g' */, 0x25, 0x00 /* (to 0x0025 state 1) */, - 0x70 /* 'p' */, 0x27, 0x00 /* (to 0x002A state 5) */, - 0x68 /* 'h' */, 0x30, 0x00 /* (to 0x0036 state 10) */, - 0x63 /* 'c' */, 0x39, 0x00 /* (to 0x0042 state 15) */, - 0x73 /* 's' */, 0x54, 0x00 /* (to 0x0060 state 26) */, - 0x75 /* 'u' */, 0x93, 0x00 /* (to 0x00A2 state 56) */, - 0x6F /* 'o' */, 0x99, 0x00 /* (to 0x00AB state 64) */, - 0x0D /* '.' */, 0xA5, 0x00 /* (to 0x00BA state 77) */, - 0x61 /* 'a' */, 0xDC, 0x00 /* (to 0x00F4 state 127) */, - 0x69 /* 'i' */, 0xED, 0x00 /* (to 0x0108 state 134) */, - 0x64 /* 'd' */, 0x5A, 0x01 /* (to 0x0178 state 225) */, - 0x72 /* 'r' */, 0x5D, 0x01 /* (to 0x017E state 230) */, - 0x08, /* fail */ -/* pos 0025: 1 */ 0xE5 /* 'e' -> */, -/* pos 0026: 2 */ 0xF4 /* 't' -> */, -/* pos 0027: 3 */ 0xA0 /* ' ' -> */, -/* pos 0028: 4 */ 0x00, 0x00 /* - terminal marker 0 - */, -/* pos 002a: 5 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0031 state 6) */, - 0x72 /* 'r' */, 0x09, 0x01 /* (to 0x0136 state 171) */, - 0x08, /* fail */ -/* pos 0031: 6 */ 0xF3 /* 's' -> */, -/* pos 0032: 7 */ 0xF4 /* 't' -> */, -/* pos 0033: 8 */ 0xA0 /* ' ' -> */, -/* pos 0034: 9 */ 0x00, 0x01 /* - terminal marker 1 - */, -/* pos 0036: 10 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x003D state 11) */, - 0x74 /* 't' */, 0xB2, 0x00 /* (to 0x00EB state 119) */, - 0x08, /* fail */ -/* pos 003d: 11 */ 0xF3 /* 's' -> */, -/* pos 003e: 12 */ 0xF4 /* 't' -> */, -/* pos 003f: 13 */ 0xBA /* ':' -> */, -/* pos 0040: 14 */ 0x00, 0x02 /* - terminal marker 2 - */, -/* pos 0042: 15 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0049 state 16) */, - 0x61 /* 'a' */, 0xF8, 0x00 /* (to 0x013D state 177) */, - 0x08, /* fail */ -/* pos 0049: 16 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0050 state 17) */, - 0x6F /* 'o' */, 0x0D, 0x01 /* (to 0x0159 state 203) */, - 0x08, /* fail */ -/* pos 0050: 17 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0057 state 18) */, - 0x74 /* 't' */, 0x0C, 0x01 /* (to 0x015F state 208) */, - 0x08, /* fail */ -/* pos 0057: 18 */ 0xE5 /* 'e' -> */, -/* pos 0058: 19 */ 0xE3 /* 'c' -> */, -/* pos 0059: 20 */ 0xF4 /* 't' -> */, -/* pos 005a: 21 */ 0xE9 /* 'i' -> */, -/* pos 005b: 22 */ 0xEF /* 'o' -> */, -/* pos 005c: 23 */ 0xEE /* 'n' -> */, -/* pos 005d: 24 */ 0xBA /* ':' -> */, -/* pos 005e: 25 */ 0x00, 0x03 /* - terminal marker 3 - */, -/* pos 0060: 26 */ 0xE5 /* 'e' -> */, -/* pos 0061: 27 */ 0xE3 /* 'c' -> */, -/* pos 0062: 28 */ 0xAD /* '-' -> */, -/* pos 0063: 29 */ 0xF7 /* 'w' -> */, -/* pos 0064: 30 */ 0xE5 /* 'e' -> */, -/* pos 0065: 31 */ 0xE2 /* 'b' -> */, -/* pos 0066: 32 */ 0xF3 /* 's' -> */, -/* pos 0067: 33 */ 0xEF /* 'o' -> */, -/* pos 0068: 34 */ 0xE3 /* 'c' -> */, -/* pos 0069: 35 */ 0xEB /* 'k' -> */, -/* pos 006a: 36 */ 0xE5 /* 'e' -> */, -/* pos 006b: 37 */ 0xF4 /* 't' -> */, -/* pos 006c: 38 */ 0xAD /* '-' -> */, -/* pos 006d: 39 */ 0x6B /* 'k' */, 0x19, 0x00 /* (to 0x0086 state 40) */, - 0x70 /* 'p' */, 0x28, 0x00 /* (to 0x0098 state 47) */, - 0x64 /* 'd' */, 0x40, 0x00 /* (to 0x00B3 state 71) */, - 0x76 /* 'v' */, 0x49, 0x00 /* (to 0x00BF state 80) */, - 0x6F /* 'o' */, 0x4F, 0x00 /* (to 0x00C8 state 88) */, - 0x65 /* 'e' */, 0x54, 0x00 /* (to 0x00D0 state 95) */, - 0x61 /* 'a' */, 0x5D, 0x00 /* (to 0x00DC state 106) */, - 0x6E /* 'n' */, 0x62, 0x00 /* (to 0x00E4 state 113) */, - 0x08, /* fail */ -/* pos 0086: 40 */ 0xE5 /* 'e' -> */, -/* pos 0087: 41 */ 0xF9 /* 'y' -> */, -/* pos 0088: 42 */ 0x31 /* '1' */, 0x0A, 0x00 /* (to 0x0092 state 43) */, - 0x32 /* '2' */, 0x0A, 0x00 /* (to 0x0095 state 45) */, - 0x3A /* ':' */, 0x2F, 0x00 /* (to 0x00BD state 79) */, - 0x08, /* fail */ -/* pos 0092: 43 */ 0xBA /* ':' -> */, -/* pos 0093: 44 */ 0x00, 0x04 /* - terminal marker 4 - */, -/* pos 0095: 45 */ 0xBA /* ':' -> */, -/* pos 0096: 46 */ 0x00, 0x05 /* - terminal marker 5 - */, -/* pos 0098: 47 */ 0xF2 /* 'r' -> */, -/* pos 0099: 48 */ 0xEF /* 'o' -> */, -/* pos 009a: 49 */ 0xF4 /* 't' -> */, -/* pos 009b: 50 */ 0xEF /* 'o' -> */, -/* pos 009c: 51 */ 0xE3 /* 'c' -> */, -/* pos 009d: 52 */ 0xEF /* 'o' -> */, -/* pos 009e: 53 */ 0xEC /* 'l' -> */, -/* pos 009f: 54 */ 0xBA /* ':' -> */, -/* pos 00a0: 55 */ 0x00, 0x06 /* - terminal marker 6 - */, -/* pos 00a2: 56 */ 0xF0 /* 'p' -> */, -/* pos 00a3: 57 */ 0xE7 /* 'g' -> */, -/* pos 00a4: 58 */ 0xF2 /* 'r' -> */, -/* pos 00a5: 59 */ 0xE1 /* 'a' -> */, -/* pos 00a6: 60 */ 0xE4 /* 'd' -> */, -/* pos 00a7: 61 */ 0xE5 /* 'e' -> */, -/* pos 00a8: 62 */ 0xBA /* ':' -> */, -/* pos 00a9: 63 */ 0x00, 0x07 /* - terminal marker 7 - */, -/* pos 00ab: 64 */ 0xF2 /* 'r' -> */, -/* pos 00ac: 65 */ 0xE9 /* 'i' -> */, -/* pos 00ad: 66 */ 0xE7 /* 'g' -> */, -/* pos 00ae: 67 */ 0xE9 /* 'i' -> */, -/* pos 00af: 68 */ 0xEE /* 'n' -> */, -/* pos 00b0: 69 */ 0xBA /* ':' -> */, -/* pos 00b1: 70 */ 0x00, 0x08 /* - terminal marker 8 - */, -/* pos 00b3: 71 */ 0xF2 /* 'r' -> */, -/* pos 00b4: 72 */ 0xE1 /* 'a' -> */, -/* pos 00b5: 73 */ 0xE6 /* 'f' -> */, -/* pos 00b6: 74 */ 0xF4 /* 't' -> */, -/* pos 00b7: 75 */ 0xBA /* ':' -> */, -/* pos 00b8: 76 */ 0x00, 0x09 /* - terminal marker 9 - */, -/* pos 00ba: 77 */ 0x8A /* '.' -> */, -/* pos 00bb: 78 */ 0x00, 0x0A /* - terminal marker 10 - */, -/* pos 00bd: 79 */ 0x00, 0x0B /* - terminal marker 11 - */, -/* pos 00bf: 80 */ 0xE5 /* 'e' -> */, -/* pos 00c0: 81 */ 0xF2 /* 'r' -> */, -/* pos 00c1: 82 */ 0xF3 /* 's' -> */, -/* pos 00c2: 83 */ 0xE9 /* 'i' -> */, -/* pos 00c3: 84 */ 0xEF /* 'o' -> */, -/* pos 00c4: 85 */ 0xEE /* 'n' -> */, -/* pos 00c5: 86 */ 0xBA /* ':' -> */, -/* pos 00c6: 87 */ 0x00, 0x0C /* - terminal marker 12 - */, -/* pos 00c8: 88 */ 0xF2 /* 'r' -> */, -/* pos 00c9: 89 */ 0xE9 /* 'i' -> */, -/* pos 00ca: 90 */ 0xE7 /* 'g' -> */, -/* pos 00cb: 91 */ 0xE9 /* 'i' -> */, -/* pos 00cc: 92 */ 0xEE /* 'n' -> */, -/* pos 00cd: 93 */ 0xBA /* ':' -> */, -/* pos 00ce: 94 */ 0x00, 0x0D /* - terminal marker 13 - */, -/* pos 00d0: 95 */ 0xF8 /* 'x' -> */, -/* pos 00d1: 96 */ 0xF4 /* 't' -> */, -/* pos 00d2: 97 */ 0xE5 /* 'e' -> */, -/* pos 00d3: 98 */ 0xEE /* 'n' -> */, -/* pos 00d4: 99 */ 0xF3 /* 's' -> */, -/* pos 00d5: 100 */ 0xE9 /* 'i' -> */, -/* pos 00d6: 101 */ 0xEF /* 'o' -> */, -/* pos 00d7: 102 */ 0xEE /* 'n' -> */, -/* pos 00d8: 103 */ 0xF3 /* 's' -> */, -/* pos 00d9: 104 */ 0xBA /* ':' -> */, -/* pos 00da: 105 */ 0x00, 0x0E /* - terminal marker 14 - */, -/* pos 00dc: 106 */ 0xE3 /* 'c' -> */, -/* pos 00dd: 107 */ 0xE3 /* 'c' -> */, -/* pos 00de: 108 */ 0xE5 /* 'e' -> */, -/* pos 00df: 109 */ 0xF0 /* 'p' -> */, -/* pos 00e0: 110 */ 0xF4 /* 't' -> */, -/* pos 00e1: 111 */ 0xBA /* ':' -> */, -/* pos 00e2: 112 */ 0x00, 0x0F /* - terminal marker 15 - */, -/* pos 00e4: 113 */ 0xEF /* 'o' -> */, -/* pos 00e5: 114 */ 0xEE /* 'n' -> */, -/* pos 00e6: 115 */ 0xE3 /* 'c' -> */, -/* pos 00e7: 116 */ 0xE5 /* 'e' -> */, -/* pos 00e8: 117 */ 0xBA /* ':' -> */, -/* pos 00e9: 118 */ 0x00, 0x10 /* - terminal marker 16 - */, -/* pos 00eb: 119 */ 0xF4 /* 't' -> */, -/* pos 00ec: 120 */ 0xF0 /* 'p' -> */, -/* pos 00ed: 121 */ 0xAF /* '/' -> */, -/* pos 00ee: 122 */ 0xB1 /* '1' -> */, -/* pos 00ef: 123 */ 0xAE /* '.' -> */, -/* pos 00f0: 124 */ 0xB1 /* '1' -> */, -/* pos 00f1: 125 */ 0xA0 /* ' ' -> */, -/* pos 00f2: 126 */ 0x00, 0x11 /* - terminal marker 17 - */, -/* pos 00f4: 127 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x00FB state 128) */, - 0x75 /* 'u' */, 0x54, 0x00 /* (to 0x014B state 190) */, - 0x08, /* fail */ -/* pos 00fb: 128 */ 0xE3 /* 'c' -> */, -/* pos 00fc: 129 */ 0xE5 /* 'e' -> */, -/* pos 00fd: 130 */ 0xF0 /* 'p' -> */, -/* pos 00fe: 131 */ 0xF4 /* 't' -> */, -/* pos 00ff: 132 */ 0x3A /* ':' */, 0x07, 0x00 /* (to 0x0106 state 133) */, - 0x2D /* '-' */, 0x19, 0x00 /* (to 0x011B state 152) */, - 0x08, /* fail */ -/* pos 0106: 133 */ 0x00, 0x12 /* - terminal marker 18 - */, -/* pos 0108: 134 */ 0xE6 /* 'f' -> */, -/* pos 0109: 135 */ 0xAD /* '-' -> */, -/* pos 010a: 136 */ 0xED /* 'm' -> */, -/* pos 010b: 137 */ 0xEF /* 'o' -> */, -/* pos 010c: 138 */ 0xE4 /* 'd' -> */, -/* pos 010d: 139 */ 0xE9 /* 'i' -> */, -/* pos 010e: 140 */ 0xE6 /* 'f' -> */, -/* pos 010f: 141 */ 0xE9 /* 'i' -> */, -/* pos 0110: 142 */ 0xE5 /* 'e' -> */, -/* pos 0111: 143 */ 0xE4 /* 'd' -> */, -/* pos 0112: 144 */ 0xAD /* '-' -> */, -/* pos 0113: 145 */ 0xF3 /* 's' -> */, -/* pos 0114: 146 */ 0xE9 /* 'i' -> */, -/* pos 0115: 147 */ 0xEE /* 'n' -> */, -/* pos 0116: 148 */ 0xE3 /* 'c' -> */, -/* pos 0117: 149 */ 0xE5 /* 'e' -> */, -/* pos 0118: 150 */ 0xBA /* ':' -> */, -/* pos 0119: 151 */ 0x00, 0x13 /* - terminal marker 19 - */, -/* pos 011b: 152 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0122 state 153) */, - 0x6C /* 'l' */, 0x0E, 0x00 /* (to 0x012C state 162) */, - 0x08, /* fail */ -/* pos 0122: 153 */ 0xEE /* 'n' -> */, -/* pos 0123: 154 */ 0xE3 /* 'c' -> */, -/* pos 0124: 155 */ 0xEF /* 'o' -> */, -/* pos 0125: 156 */ 0xE4 /* 'd' -> */, -/* pos 0126: 157 */ 0xE9 /* 'i' -> */, -/* pos 0127: 158 */ 0xEE /* 'n' -> */, -/* pos 0128: 159 */ 0xE7 /* 'g' -> */, -/* pos 0129: 160 */ 0xBA /* ':' -> */, -/* pos 012a: 161 */ 0x00, 0x14 /* - terminal marker 20 - */, -/* pos 012c: 162 */ 0xE1 /* 'a' -> */, -/* pos 012d: 163 */ 0xEE /* 'n' -> */, -/* pos 012e: 164 */ 0xE7 /* 'g' -> */, -/* pos 012f: 165 */ 0xF5 /* 'u' -> */, -/* pos 0130: 166 */ 0xE1 /* 'a' -> */, -/* pos 0131: 167 */ 0xE7 /* 'g' -> */, -/* pos 0132: 168 */ 0xE5 /* 'e' -> */, -/* pos 0133: 169 */ 0xBA /* ':' -> */, -/* pos 0134: 170 */ 0x00, 0x15 /* - terminal marker 21 - */, -/* pos 0136: 171 */ 0xE1 /* 'a' -> */, -/* pos 0137: 172 */ 0xE7 /* 'g' -> */, -/* pos 0138: 173 */ 0xED /* 'm' -> */, -/* pos 0139: 174 */ 0xE1 /* 'a' -> */, -/* pos 013a: 175 */ 0xBA /* ':' -> */, -/* pos 013b: 176 */ 0x00, 0x16 /* - terminal marker 22 - */, -/* pos 013d: 177 */ 0xE3 /* 'c' -> */, -/* pos 013e: 178 */ 0xE8 /* 'h' -> */, -/* pos 013f: 179 */ 0xE5 /* 'e' -> */, -/* pos 0140: 180 */ 0xAD /* '-' -> */, -/* pos 0141: 181 */ 0xE3 /* 'c' -> */, -/* pos 0142: 182 */ 0xEF /* 'o' -> */, -/* pos 0143: 183 */ 0xEE /* 'n' -> */, -/* pos 0144: 184 */ 0xF4 /* 't' -> */, -/* pos 0145: 185 */ 0xF2 /* 'r' -> */, -/* pos 0146: 186 */ 0xEF /* 'o' -> */, -/* pos 0147: 187 */ 0xEC /* 'l' -> */, -/* pos 0148: 188 */ 0xBA /* ':' -> */, -/* pos 0149: 189 */ 0x00, 0x17 /* - terminal marker 23 - */, -/* pos 014b: 190 */ 0xF4 /* 't' -> */, -/* pos 014c: 191 */ 0xE8 /* 'h' -> */, -/* pos 014d: 192 */ 0xEF /* 'o' -> */, -/* pos 014e: 193 */ 0xF2 /* 'r' -> */, -/* pos 014f: 194 */ 0xE9 /* 'i' -> */, -/* pos 0150: 195 */ 0xFA /* 'z' -> */, -/* pos 0151: 196 */ 0xE1 /* 'a' -> */, -/* pos 0152: 197 */ 0xF4 /* 't' -> */, -/* pos 0153: 198 */ 0xE9 /* 'i' -> */, -/* pos 0154: 199 */ 0xEF /* 'o' -> */, -/* pos 0155: 200 */ 0xEE /* 'n' -> */, -/* pos 0156: 201 */ 0xBA /* ':' -> */, -/* pos 0157: 202 */ 0x00, 0x18 /* - terminal marker 24 - */, -/* pos 0159: 203 */ 0xEB /* 'k' -> */, -/* pos 015a: 204 */ 0xE9 /* 'i' -> */, -/* pos 015b: 205 */ 0xE5 /* 'e' -> */, -/* pos 015c: 206 */ 0xBA /* ':' -> */, -/* pos 015d: 207 */ 0x00, 0x19 /* - terminal marker 25 - */, -/* pos 015f: 208 */ 0xE5 /* 'e' -> */, -/* pos 0160: 209 */ 0xEE /* 'n' -> */, -/* pos 0161: 210 */ 0xF4 /* 't' -> */, -/* pos 0162: 211 */ 0xAD /* '-' -> */, -/* pos 0163: 212 */ 0x6C /* 'l' */, 0x07, 0x00 /* (to 0x016A state 213) */, - 0x74 /* 't' */, 0x0C, 0x00 /* (to 0x0172 state 220) */, - 0x08, /* fail */ -/* pos 016a: 213 */ 0xE5 /* 'e' -> */, -/* pos 016b: 214 */ 0xEE /* 'n' -> */, -/* pos 016c: 215 */ 0xE7 /* 'g' -> */, -/* pos 016d: 216 */ 0xF4 /* 't' -> */, -/* pos 016e: 217 */ 0xE8 /* 'h' -> */, -/* pos 016f: 218 */ 0xBA /* ':' -> */, -/* pos 0170: 219 */ 0x00, 0x1A /* - terminal marker 26 - */, -/* pos 0172: 220 */ 0xF9 /* 'y' -> */, -/* pos 0173: 221 */ 0xF0 /* 'p' -> */, -/* pos 0174: 222 */ 0xE5 /* 'e' -> */, -/* pos 0175: 223 */ 0xBA /* ':' -> */, -/* pos 0176: 224 */ 0x00, 0x1B /* - terminal marker 27 - */, -/* pos 0178: 225 */ 0xE1 /* 'a' -> */, -/* pos 0179: 226 */ 0xF4 /* 't' -> */, -/* pos 017a: 227 */ 0xE5 /* 'e' -> */, -/* pos 017b: 228 */ 0xBA /* ':' -> */, -/* pos 017c: 229 */ 0x00, 0x1C /* - terminal marker 28 - */, -/* pos 017e: 230 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0185 state 231) */, - 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x018B state 236) */, - 0x08, /* fail */ -/* pos 0185: 231 */ 0xEE /* 'n' -> */, -/* pos 0186: 232 */ 0xE7 /* 'g' -> */, -/* pos 0187: 233 */ 0xE5 /* 'e' -> */, -/* pos 0188: 234 */ 0xBA /* ':' -> */, -/* pos 0189: 235 */ 0x00, 0x1D /* - terminal marker 29 - */, -/* pos 018b: 236 */ 0xE6 /* 'f' -> */, -/* pos 018c: 237 */ 0xE5 /* 'e' -> */, -/* pos 018d: 238 */ 0xF2 /* 'r' -> */, -/* pos 018e: 239 */ 0xE5 /* 'e' -> */, -/* pos 018f: 240 */ 0xF2 /* 'r' -> */, -/* pos 0190: 241 */ 0xBA /* ':' -> */, -/* pos 0191: 242 */ 0x00, 0x1E /* - terminal marker 30 - */, -/* total size 403 bytes */ diff --git a/core/deps/libwebsocket/libwebsockets.c b/core/deps/libwebsocket/libwebsockets.c deleted file mode 100644 index 3e02529eb..000000000 --- a/core/deps/libwebsocket/libwebsockets.c +++ /dev/null @@ -1,766 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - - -#include "private-libwebsockets.h" - -#if HOST_OS == OS_WINDOWS - #pragma comment(lib, "Ws2_32.lib") -#endif - -int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE; -static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr; - -static const char * const log_level_names[] = { - "ERR", - "WARN", - "NOTICE", - "INFO", - "DEBUG", - "PARSER", - "HEADER", - "EXTENSION", - "CLIENT", - "LATENCY", -}; - - -void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status reason) -{ - int n, m, ret; - int old_state; - unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 + - LWS_SEND_BUFFER_POST_PADDING]; - struct lws_tokens eff_buf; - - if (!wsi) - return; - - old_state = wsi->state; - - switch (old_state) { - case WSI_STATE_DEAD_SOCKET: - return; - - /* we tried the polite way... */ - case WSI_STATE_AWAITING_CLOSE_ACK: - goto just_kill_connection; - - case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE: - if (wsi->truncated_send_len) { - libwebsocket_callback_on_writable(context, wsi); - return; - } - lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); - goto just_kill_connection; - default: - if (wsi->truncated_send_len) { - lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi); - wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE; - return; - } - break; - } - - wsi->u.ws.close_reason = reason; - - if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT || - wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) { - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, NULL, NULL, 0); - - free(wsi->u.hdr.ah); - goto just_kill_connection; - } - - if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { - if (wsi->u.http.post_buffer) { - free(wsi->u.http.post_buffer); - wsi->u.http.post_buffer = NULL; - } - if (wsi->u.http.fd != LWS_INVALID_FILE) { - lwsl_debug("closing http file\n"); - compatible_file_close(wsi->u.http.fd); - wsi->u.http.fd = LWS_INVALID_FILE; - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); - } - } - - /* - * are his extensions okay with him closing? Eg he might be a mux - * parent and just his ch1 aspect is closing? - */ - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) { - lwsl_ext("extension vetoed close\n"); - return; - } - - /* - * flush any tx pending from extensions, since we may send close packet - * if there are problems with send, just nuke the connection - */ - - do { - ret = 0; - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* show every extension the new incoming data */ - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0); - if (m < 0) { - lwsl_ext("Extension reports fatal error\n"); - goto just_kill_connection; - } - if (m) - /* - * at least one extension told us he has more - * to spill, so we will go around again after - */ - ret = 1; - - /* assuming they left us something to send, send it */ - - if (eff_buf.token_len) - if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len) != eff_buf.token_len) { - lwsl_debug("close: ext spill failed\n"); - goto just_kill_connection; - } - } while (ret); - - /* - * signal we are closing, libsocket_write will - * add any necessary version-specific stuff. If the write fails, - * no worries we are closing anyway. If we didn't initiate this - * close, then our state has been changed to - * WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this. - * - * Likewise if it's a second call to close this connection after we - * sent the close indication to the peer already, we are in state - * WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time. - */ - - if (old_state == WSI_STATE_ESTABLISHED && - reason != LWS_CLOSE_STATUS_NOSTATUS) { - - lwsl_debug("sending close indication...\n"); - - /* make valgrind happy */ - memset(buf, 0, sizeof(buf)); - n = libwebsocket_write(wsi, - &buf[LWS_SEND_BUFFER_PRE_PADDING + 2], - 0, LWS_WRITE_CLOSE); - if (n >= 0) { - /* - * we have sent a nice protocol level indication we - * now wish to close, we should not send anything more - */ - - wsi->state = WSI_STATE_AWAITING_CLOSE_ACK; - - /* - * ...and we should wait for a reply for a bit - * out of politeness - */ - - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_CLOSE_ACK, 1); - - lwsl_debug("sent close indication, awaiting ack\n"); - - return; - } - - lwsl_info("close: sending close packet failed, hanging up\n"); - - /* else, the send failed and we should just hang up */ - } - -just_kill_connection: - - lwsl_debug("close: just_kill_connection\n"); - - /* - * we won't be servicing or receiving anything further from this guy - * delete socket from the internal poll list if still present - */ - - remove_wsi_socket_from_fds(context, wsi); - - wsi->state = WSI_STATE_DEAD_SOCKET; - - if ((old_state == WSI_STATE_ESTABLISHED || - wsi->mode == LWS_CONNMODE_WS_SERVING || - wsi->mode == LWS_CONNMODE_WS_CLIENT)) { - - if (wsi->u.ws.rx_user_buffer) { - free(wsi->u.ws.rx_user_buffer); - wsi->u.ws.rx_user_buffer = NULL; - } - if (wsi->u.ws.rxflow_buffer) { - free(wsi->u.ws.rxflow_buffer); - wsi->u.ws.rxflow_buffer = NULL; - } - if (wsi->truncated_send_malloc) { - /* not going to be completed... nuke it */ - free(wsi->truncated_send_malloc); - wsi->truncated_send_malloc = NULL; - wsi->truncated_send_len = 0; - } - } - - /* tell the user it's all over for this guy */ - - if (wsi->protocol && wsi->protocol->callback && - ((old_state == WSI_STATE_ESTABLISHED) || - (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) || - (old_state == WSI_STATE_AWAITING_CLOSE_ACK))) { - lwsl_debug("calling back CLOSED\n"); - wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED, - wsi->user_space, NULL, 0); - } else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) { - lwsl_debug("calling back CLOSED_HTTP\n"); - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 ); - } else - lwsl_debug("not calling back closed\n"); - - /* deallocate any active extension contexts */ - - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0) - lwsl_warn("extension destruction failed\n"); -#ifndef LWS_NO_EXTENSIONS - for (n = 0; n < wsi->count_active_extensions; n++) - free(wsi->active_extensions_user[n]); -#endif - /* - * inform all extensions in case they tracked this guy out of band - * even though not active on him specifically - */ - if (lws_ext_callback_for_each_extension_type(context, wsi, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0) - lwsl_warn("ext destroy wsi failed\n"); - -/* lwsl_info("closing fd=%d\n", wsi->sock); */ - - if (!lws_ssl_close(wsi) && wsi->sock >= 0) { - n = shutdown(wsi->sock, SHUT_RDWR); - if (n) - lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO); - - n = compatible_close(wsi->sock); - if (n) - lwsl_debug("closing: close ret %d\n", LWS_ERRNO); - } - - /* outermost destroy notification for wsi (user_space still intact) */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0); - - if (wsi->protocol && wsi->protocol->per_session_data_size && - wsi->user_space) /* user code may own */ - free(wsi->user_space); - - free(wsi); -} - -/** - * libwebsockets_get_peer_addresses() - Get client address information - * @context: Libwebsockets context - * @wsi: Local struct libwebsocket associated with - * @fd: Connection socket descriptor - * @name: Buffer to take client address name - * @name_len: Length of client address name buffer - * @rip: Buffer to take client address IP qotted quad - * @rip_len: Length of client address IP buffer - * - * This function fills in @name and @rip with the name and IP of - * the client connected with socket descriptor @fd. Names may be - * truncated if there is not enough room. If either cannot be - * determined, they will be returned as valid zero-length strings. - */ - -LWS_VISIBLE void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, - char *rip, int rip_len) -{ - socklen_t len; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_in sin4; - struct hostent *host; - struct hostent *host1; - char ip[128]; - unsigned char *p; - int n; -#ifdef AF_LOCAL - struct sockaddr_un *un; -#endif - int ret = -1; - - rip[0] = '\0'; - name[0] = '\0'; - - lws_latency_pre(context, wsi); - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - - len = sizeof(sin6); - if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - - if (!lws_plat_inet_ntop(AF_INET6, &sin6.sin6_addr, rip, rip_len)) { - lwsl_err("inet_ntop", strerror(LWS_ERRNO)); - goto bail; - } - - // Strip off the IPv4 to IPv6 header if one exists - if (strncmp(rip, "::ffff:", 7) == 0) - memmove(rip, rip + 7, strlen(rip) - 6); - - getnameinfo((struct sockaddr *)&sin6, - sizeof(struct sockaddr_in6), name, - name_len, NULL, 0, 0); - - } else -#endif - { - len = sizeof(sin4); - if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - host = gethostbyaddr((char *) &sin4.sin_addr, - sizeof(sin4.sin_addr), AF_INET); - if (host == NULL) { - lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - - strncpy(name, host->h_name, name_len); - name[name_len - 1] = '\0'; - - host1 = gethostbyname(host->h_name); - if (host1 == NULL) - goto bail; - p = (unsigned char *)host1; - n = 0; - while (p != NULL) { - p = (unsigned char *)host1->h_addr_list[n++]; - if (p == NULL) - continue; - if ((host1->h_addrtype != AF_INET) -#ifdef AF_LOCAL - && (host1->h_addrtype != AF_LOCAL) -#endif - ) - continue; - - if (host1->h_addrtype == AF_INET) - sprintf(ip, "%u.%u.%u.%u", - p[0], p[1], p[2], p[3]); -#ifdef AF_LOCAL - else { - un = (struct sockaddr_un *)p; - strncpy(ip, un->sun_path, sizeof(ip) - 1); - ip[sizeof(ip) - 1] = '\0'; - } -#endif - p = NULL; - strncpy(rip, ip, rip_len); - rip[rip_len - 1] = '\0'; - } - } - - ret = 0; -bail: - lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1); -} - - - -/** - * libwebsocket_context_user() - get the user data associated with the context - * @context: Websocket context - * - * This returns the optional user allocation that can be attached to - * the context the sockets live in at context_create time. It's a way - * to let all sockets serviced in the same context share data without - * using globals statics in the user code. - */ -LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context) -{ - return context->user_space; -} - - -/** - * libwebsocket_callback_all_protocol() - Callback all connections using - * the given protocol with the given reason - * - * @protocol: Protocol whose connections will get callbacks - * @reason: Callback reason index - */ - -LWS_VISIBLE int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - protocol->callback(context, wsi, - reason, wsi->user_space, NULL, 0); - } - - return 0; -} - -/** - * libwebsocket_set_timeout() - marks the wsi as subject to a timeout - * - * You will not need this unless you are doing something special - * - * @wsi: Websocket connection instance - * @reason: timeout reason - * @secs: how many seconds - */ - -LWS_VISIBLE void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs) -{ - time_t now; - - time(&now); - - wsi->pending_timeout_limit = now + secs; - wsi->pending_timeout = reason; -} - - -/** - * libwebsocket_get_socket_fd() - returns the socket file descriptor - * - * You will not need this unless you are doing something special - * - * @wsi: Websocket connection instance - */ - -LWS_VISIBLE int -libwebsocket_get_socket_fd(struct libwebsocket *wsi) -{ - return wsi->sock; -} - -#ifdef LWS_LATENCY -void -lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, - const char *action, int ret, int completed) -{ - unsigned long long u; - char buf[256]; - - u = time_in_microseconds(); - - if (!action) { - wsi->latency_start = u; - if (!wsi->action_start) - wsi->action_start = u; - return; - } - if (completed) { - if (wsi->action_start == wsi->latency_start) - sprintf(buf, - "Completion first try lat %luus: %p: ret %d: %s\n", - u - wsi->latency_start, - (void *)wsi, ret, action); - else - sprintf(buf, - "Completion %luus: lat %luus: %p: ret %d: %s\n", - u - wsi->action_start, - u - wsi->latency_start, - (void *)wsi, ret, action); - wsi->action_start = 0; - } else - sprintf(buf, "lat %luus: %p: ret %d: %s\n", - u - wsi->latency_start, (void *)wsi, ret, action); - - if (u - wsi->latency_start > context->worst_latency) { - context->worst_latency = u - wsi->latency_start; - strcpy(context->worst_latency_info, buf); - } - lwsl_latency("%s", buf); -} -#endif - - - -/** - * libwebsocket_rx_flow_control() - Enable and disable socket servicing for - * receieved packets. - * - * If the output side of a server process becomes choked, this allows flow - * control for the input side. - * - * @wsi: Websocket connection instance to get callback for - * @enable: 0 = disable read servicing for this connection, 1 = enable - */ - -LWS_VISIBLE int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable) -{ - if (enable == (wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW)) - return 0; - - lwsl_info("libwebsocket_rx_flow_control(0x%p, %d)\n", wsi, enable); - wsi->u.ws.rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable; - - return 0; -} - -/** - * libwebsocket_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive - * - * When the user server code realizes it can accept more input, it can - * call this to have the RX flow restriction removed from all connections using - * the given protocol. - * - * @protocol: all connections using this protocol will be allowed to receive - */ - -LWS_VISIBLE void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - libwebsocket_rx_flow_control(wsi, LWS_RXFLOW_ALLOW); - } -} - - -/** - * libwebsocket_canonical_hostname() - returns this host's hostname - * - * This is typically used by client code to fill in the host parameter - * when making a client connection. You can only call it after the context - * has been created. - * - * @context: Websocket context - */ -LWS_VISIBLE extern const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context) -{ - return (const char *)context->canonical_hostname; -} - -int user_callback_handle_rxflow(callback_function callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len) -{ - int n; - - n = callback_function(context, wsi, reason, user, in, len); - if (!n) - n = _libwebsocket_rx_flow_control(wsi); - - return n; -} - - -/** - * libwebsocket_set_proxy() - Setups proxy to libwebsocket_context. - * @context: pointer to struct libwebsocket_context you want set proxy to - * @proxy: pointer to c string containing proxy in format address:port - * - * Returns 0 if proxy string was parsed and proxy was setup. - * Returns -1 if @proxy is NULL or has incorrect format. - * - * This is only required if your OS does not provide the http_proxy - * enviroment variable (eg, OSX) - * - * IMPORTANT! You should call this function right after creation of the - * libwebsocket_context and before call to connect. If you call this - * function after connect behavior is undefined. - * This function will override proxy settings made on libwebsocket_context - * creation with genenv() call. - */ - -LWS_VISIBLE int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy) -{ - char *p; - - if (!proxy) - return -1; - - strncpy(context->http_proxy_address, proxy, - sizeof(context->http_proxy_address) - 1); - context->http_proxy_address[ - sizeof(context->http_proxy_address) - 1] = '\0'; - - p = strchr(context->http_proxy_address, ':'); - if (!p) { - lwsl_err("http_proxy needs to be ads:port\n"); - - return -1; - } - *p = '\0'; - context->http_proxy_port = atoi(p + 1); - - lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address, - context->http_proxy_port); - - return 0; -} - -/** - * libwebsockets_get_protocol() - Returns a protocol pointer from a websocket - * connection. - * @wsi: pointer to struct websocket you want to know the protocol of - * - * - * Some apis can act on all live connections of a given protocol, - * this is how you can get a pointer to the active protocol if needed. - */ - -LWS_VISIBLE const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi) -{ - return wsi->protocol; -} - -LWS_VISIBLE int -libwebsocket_is_final_fragment(struct libwebsocket *wsi) -{ - return wsi->u.ws.final; -} - -LWS_VISIBLE unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi) -{ - return wsi->u.ws.rsv; -} - -int -libwebsocket_ensure_user_space(struct libwebsocket *wsi) -{ - if (!wsi->protocol) - return 1; - - /* allocate the per-connection user memory (if any) */ - - if (wsi->protocol->per_session_data_size && !wsi->user_space) { - wsi->user_space = malloc( - wsi->protocol->per_session_data_size); - if (wsi->user_space == NULL) { - lwsl_err("Out of memory for conn user space\n"); - return 1; - } - memset(wsi->user_space, 0, - wsi->protocol->per_session_data_size); - } - return 0; -} - -LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line) -{ - char buf[300]; - unsigned long long now; - int n; - - buf[0] = '\0'; - for (n = 0; n < LLL_COUNT; n++) - if (level == (1 << n)) { - now = time_in_microseconds() / 100; - sprintf(buf, "[%lu:%04d] %s: ", (unsigned long) now / 10000, - (int)(now % 10000), log_level_names[n]); - break; - } - - fprintf(stderr, "%s%s", buf, line); -} - - -LWS_VISIBLE void _lws_log(int filter, const char *format, ...) -{ - char buf[256]; - va_list ap; - - if (!(log_level & filter)) - return; - - va_start(ap, format); - vsnprintf(buf, sizeof(buf), format, ap); - buf[sizeof(buf) - 1] = '\0'; - va_end(ap); - - lwsl_emit(filter, buf); -} - -/** - * lws_set_log_level() - Set the logging bitfield - * @level: OR together the LLL_ debug contexts you want output from - * @log_emit_function: NULL to leave it as it is, or a user-supplied - * function to perform log string emission instead of - * the default stderr one. - * - * log level defaults to "err", "warn" and "notice" contexts enabled and - * emission on stderr. - */ - -LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level, - const char *line)) -{ - log_level = level; - if (log_emit_function) - lwsl_emit = log_emit_function; -} \ No newline at end of file diff --git a/core/deps/libwebsocket/libwebsockets.h b/core/deps/libwebsocket/libwebsockets.h deleted file mode 100644 index 27051bf17..000000000 --- a/core/deps/libwebsocket/libwebsockets.h +++ /dev/null @@ -1,1190 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C -#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef CMAKE_BUILD -#include "lws_config.h" -#endif - -#if defined(WIN32) || defined(_WIN32) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include -#include -#include -#include - -#define strcasecmp stricmp -#define getdtablesize() 30000 - -#define LWS_VISIBLE - -#ifdef LWS_DLL -#ifdef LWS_INTERNAL -#define LWS_EXTERN extern __declspec(dllexport) -#else -#define LWS_EXTERN extern __declspec(dllimport) -#endif -#else -#define LWS_EXTERN -#endif - -#else // NOT WIN32 - -#include -#include - -#if defined(__GNUC__) -#define LWS_VISIBLE __attribute__((visibility("default"))) -#else -#define LWS_VISIBLE -#endif - -#endif - -#ifdef LWS_USE_LIBEV -#include -#endif /* LWS_USE_LIBEV */ - -#include - -#ifndef LWS_EXTERN -#define LWS_EXTERN extern -#endif - -#ifdef _WIN32 -#define random rand -#else -#include -#include -#endif - -#define CONTEXT_PORT_NO_LISTEN -1 -#define MAX_MUX_RECURSION 2 - -enum lws_log_levels { - LLL_ERR = 1 << 0, - LLL_WARN = 1 << 1, - LLL_NOTICE = 1 << 2, - LLL_INFO = 1 << 3, - LLL_DEBUG = 1 << 4, - LLL_PARSER = 1 << 5, - LLL_HEADER = 1 << 6, - LLL_EXT = 1 << 7, - LLL_CLIENT = 1 << 8, - LLL_LATENCY = 1 << 9, - - LLL_COUNT = 10 /* set to count of valid flags */ -}; - -LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...); - -/* notice, warn and log are always compiled in */ -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) -/* - * weaker logging can be deselected at configure time using --disable-debug - * that gets rid of the overhead of checking while keeping _warn and _err - * active - */ -#ifdef _DEBUG - -#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) -#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) -#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) -#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) -#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) -#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) -#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) -LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len); - -#else /* no debug */ - -#define lwsl_info(...) -#define lwsl_debug(...) -#define lwsl_parser(...) -#define lwsl_header(...) -#define lwsl_ext(...) -#define lwsl_client(...) -#define lwsl_latency(...) -#define lwsl_hexdump(a, b) - -#endif - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -enum libwebsocket_context_options { - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2, - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4, - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8, - LWS_SERVER_OPTION_LIBEV = 16, - LWS_SERVER_OPTION_DISABLE_IPV6 = 32, -}; - -enum libwebsocket_callback_reasons { - LWS_CALLBACK_ESTABLISHED, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - LWS_CALLBACK_CLIENT_ESTABLISHED, - LWS_CALLBACK_CLOSED, - LWS_CALLBACK_CLOSED_HTTP, - LWS_CALLBACK_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE, - LWS_CALLBACK_CLIENT_RECEIVE_PONG, - LWS_CALLBACK_CLIENT_WRITEABLE, - LWS_CALLBACK_SERVER_WRITEABLE, - LWS_CALLBACK_HTTP, - LWS_CALLBACK_HTTP_BODY, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - LWS_CALLBACK_HTTP_WRITEABLE, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, - LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - LWS_CALLBACK_PROTOCOL_INIT, - LWS_CALLBACK_PROTOCOL_DESTROY, - LWS_CALLBACK_WSI_CREATE, /* always protocol[0] */ - LWS_CALLBACK_WSI_DESTROY, /* always protocol[0] */ - LWS_CALLBACK_GET_THREAD_ID, - - /* external poll() management support */ - LWS_CALLBACK_ADD_POLL_FD, - LWS_CALLBACK_DEL_POLL_FD, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - LWS_CALLBACK_LOCK_POLL, - LWS_CALLBACK_UNLOCK_POLL, - - LWS_CALLBACK_USER = 1000, /* user code can use any including / above */ -}; - -// argument structure for all external poll related calls -// passed in via 'in' -struct libwebsocket_pollargs { - int fd; // applicable file descriptor - int events; // the new event mask - int prev_events; // the previous event mask -}; - -#ifdef _WIN32 -struct libwebsocket_pollfd { - SOCKET fd; - SHORT events; - SHORT revents; -}; -#else -#define libwebsocket_pollfd pollfd -#endif - -enum libwebsocket_extension_callback_reasons { - LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, - LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, - LWS_EXT_CALLBACK_CONSTRUCT, - LWS_EXT_CALLBACK_CLIENT_CONSTRUCT, - LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, - LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION, - LWS_EXT_CALLBACK_DESTROY, - LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, - LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - LWS_EXT_CALLBACK_FLUSH_PENDING_TX, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION, - LWS_EXT_CALLBACK_1HZ, - LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, - LWS_EXT_CALLBACK_IS_WRITEABLE, - LWS_EXT_CALLBACK_PAYLOAD_TX, - LWS_EXT_CALLBACK_PAYLOAD_RX, -}; - -enum libwebsocket_write_protocol { - LWS_WRITE_TEXT, - LWS_WRITE_BINARY, - LWS_WRITE_CONTINUATION, - LWS_WRITE_HTTP, - - /* special 04+ opcodes */ - - LWS_WRITE_CLOSE, - LWS_WRITE_PING, - LWS_WRITE_PONG, - - /* flags */ - - LWS_WRITE_NO_FIN = 0x40, - /* - * client packet payload goes out on wire unmunged - * only useful for security tests since normal servers cannot - * decode the content if used - */ - LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 -}; - -/* - * you need these to look at headers that have been parsed if using the - * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum - * list below is absent, .token = NULL and token_len = 0. Otherwise .token - * points to .token_len chars containing that header content. - */ - -struct lws_tokens { - char *token; - int token_len; -}; - -enum lws_token_indexes { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_HOST, - WSI_TOKEN_CONNECTION, - WSI_TOKEN_KEY1, - WSI_TOKEN_KEY2, - WSI_TOKEN_PROTOCOL, - WSI_TOKEN_UPGRADE, - WSI_TOKEN_ORIGIN, - WSI_TOKEN_DRAFT, - WSI_TOKEN_CHALLENGE, - - /* new for 04 */ - WSI_TOKEN_KEY, - WSI_TOKEN_VERSION, - WSI_TOKEN_SWORIGIN, - - /* new for 05 */ - WSI_TOKEN_EXTENSIONS, - - /* client receives these */ - WSI_TOKEN_ACCEPT, - WSI_TOKEN_NONCE, - WSI_TOKEN_HTTP, - - /* http-related */ - WSI_TOKEN_HTTP_ACCEPT, - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, - WSI_TOKEN_HTTP_ACCEPT_ENCODING, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE, - WSI_TOKEN_HTTP_PRAGMA, - WSI_TOKEN_HTTP_CACHE_CONTROL, - WSI_TOKEN_HTTP_AUTHORIZATION, - WSI_TOKEN_HTTP_COOKIE, - WSI_TOKEN_HTTP_CONTENT_LENGTH, - WSI_TOKEN_HTTP_CONTENT_TYPE, - WSI_TOKEN_HTTP_DATE, - WSI_TOKEN_HTTP_RANGE, - WSI_TOKEN_HTTP_REFERER, - WSI_TOKEN_HTTP_URI_ARGS, - - - WSI_TOKEN_MUXURL, - - /* use token storage to stash these */ - - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - _WSI_TOKEN_CLIENT_URI, - _WSI_TOKEN_CLIENT_HOST, - _WSI_TOKEN_CLIENT_ORIGIN, - - /* always last real token index*/ - WSI_TOKEN_COUNT, - /* parser state additions */ - WSI_TOKEN_NAME_PART, - WSI_TOKEN_SKIPPING, - WSI_TOKEN_SKIPPING_SAW_CR, - WSI_PARSING_COMPLETE, - WSI_INIT_TOKEN_MUXURL, -}; - -/* - * From RFC 6455 - 1000 - - 1000 indicates a normal closure, meaning that the purpose for - which the connection was established has been fulfilled. - - 1001 - - 1001 indicates that an endpoint is "going away", such as a server - going down or a browser having navigated away from a page. - - 1002 - - 1002 indicates that an endpoint is terminating the connection due - to a protocol error. - - 1003 - - 1003 indicates that an endpoint is terminating the connection - because it has received a type of data it cannot accept (e.g., an - endpoint that understands only text data MAY send this if it - receives a binary message). - - 1004 - - Reserved. The specific meaning might be defined in the future. - - 1005 - - 1005 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that no status - code was actually present. - - 1006 - - 1006 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed abnormally, e.g., without sending or - receiving a Close control frame. - - 1007 - - 1007 indicates that an endpoint is terminating the connection - because it has received data within a message that was not - consistent with the type of the message (e.g., non-UTF-8 [RFC3629] - data within a text message). - - 1008 - - 1008 indicates that an endpoint is terminating the connection - because it has received a message that violates its policy. This - is a generic status code that can be returned when there is no - other more suitable status code (e.g., 1003 or 1009) or if there - is a need to hide specific details about the policy. - - 1009 - - 1009 indicates that an endpoint is terminating the connection - because it has received a message that is too big for it to - process. - - 1010 - - 1010 indicates that an endpoint (client) is terminating the - connection because it has expected the server to negotiate one or - more extension, but the server didn't return them in the response - message of the WebSocket handshake. The list of extensions that - are needed SHOULD appear in the /reason/ part of the Close frame. - Note that this status code is not used by the server, because it - can fail the WebSocket handshake instead. - - 1011 - - 1011 indicates that a server is terminating the connection because - it encountered an unexpected condition that prevented it from - fulfilling the request. - - 1015 - - 1015 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed due to a failure to perform a TLS handshake - (e.g., the server certificate can't be verified). -*/ - -enum lws_close_status { - LWS_CLOSE_STATUS_NOSTATUS = 0, - LWS_CLOSE_STATUS_NORMAL = 1000, - LWS_CLOSE_STATUS_GOINGAWAY = 1001, - LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, - LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, - LWS_CLOSE_STATUS_RESERVED = 1004, - LWS_CLOSE_STATUS_NO_STATUS = 1005, - LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, - LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, - LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, - LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, - LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, - LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, - LWS_CLOSE_STATUS_TLS_FAILURE = 1015, -}; - -enum http_status { - HTTP_STATUS_OK = 200, - - HTTP_STATUS_BAD_REQUEST = 400, - HTTP_STATUS_UNAUTHORIZED, - HTTP_STATUS_PAYMENT_REQUIRED, - HTTP_STATUS_FORBIDDEN, - HTTP_STATUS_NOT_FOUND, - HTTP_STATUS_METHOD_NOT_ALLOWED, - HTTP_STATUS_NOT_ACCEPTABLE, - HTTP_STATUS_PROXY_AUTH_REQUIRED, - HTTP_STATUS_REQUEST_TIMEOUT, - HTTP_STATUS_CONFLICT, - HTTP_STATUS_GONE, - HTTP_STATUS_LENGTH_REQUIRED, - HTTP_STATUS_PRECONDITION_FAILED, - HTTP_STATUS_REQ_ENTITY_TOO_LARGE, - HTTP_STATUS_REQ_URI_TOO_LONG, - HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, - HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, - HTTP_STATUS_EXPECTATION_FAILED, - - HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, - HTTP_STATUS_NOT_IMPLEMENTED, - HTTP_STATUS_BAD_GATEWAY, - HTTP_STATUS_SERVICE_UNAVAILABLE, - HTTP_STATUS_GATEWAY_TIMEOUT, - HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, -}; - -struct libwebsocket; -struct libwebsocket_context; -/* needed even with extensions disabled for create context */ -struct libwebsocket_extension; - -/** - * callback_function() - User server actions - * @context: Websockets context - * @wsi: Opaque websocket instance pointer - * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library - * @in: Pointer used for some callback reasons - * @len: Length set for some callback reasons - * - * This callback is the way the user controls what is served. All the - * protocol detail is hidden and handled by the library. - * - * For each connection / session there is user data allocated that is - * pointed to by "user". You set the size of this user data area when - * the library is initialized with libwebsocket_create_server. - * - * You get an opportunity to initialize user data when called back with - * LWS_CALLBACK_ESTABLISHED reason. - * - * LWS_CALLBACK_ESTABLISHED: after the server completes a handshake with - * an incoming client - * - * LWS_CALLBACK_CLIENT_CONNECTION_ERROR: the request client connection has - * been unable to complete a handshake with the remote server - * - * LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH: this is the last chance for the - * client user code to examine the http headers - * and decide to reject the connection. If the - * content in the headers is interesting to the - * client (url, etc) it needs to copy it out at - * this point since it will be destroyed before - * the CLIENT_ESTABLISHED call - * - * LWS_CALLBACK_CLIENT_ESTABLISHED: after your client connection completed - * a handshake with the remote server - * - * LWS_CALLBACK_CLOSED: when the websocket session ends - * - * LWS_CALLBACK_CLOSED_HTTP: when a HTTP (non-websocket) session ends - * - * LWS_CALLBACK_RECEIVE: data has appeared for this server endpoint from a - * remote client, it can be found at *in and is - * len bytes long - * - * LWS_CALLBACK_CLIENT_RECEIVE_PONG: if you elected to see PONG packets, - * they appear with this callback reason. PONG - * packets only exist in 04+ protocol - * - * LWS_CALLBACK_CLIENT_RECEIVE: data has appeared from the server for the - * client connection, it can be found at *in and - * is len bytes long - * - * LWS_CALLBACK_HTTP: an http request has come from a client that is not - * asking to upgrade the connection to a websocket - * one. This is a chance to serve http content, - * for example, to send a script to the client - * which will then open the websockets connection. - * @in points to the URI path requested and - * libwebsockets_serve_http_file() makes it very - * simple to send back a file to the client. - * Normally after sending the file you are done - * with the http connection, since the rest of the - * activity will come by websockets from the script - * that was delivered by http, so you will want to - * return 1; to close and free up the connection. - * That's important because it uses a slot in the - * total number of client connections allowed set - * by MAX_CLIENTS. - * - * LWS_CALLBACK_HTTP_BODY: the next @len bytes data from the http - * request body HTTP connection is now available in @in. - * - * LWS_CALLBACK_HTTP_BODY_COMPLETION: the expected amount of http request - * body has been delivered - * - * LWS_CALLBACK_HTTP_WRITEABLE: you can write more down the http protocol - * link now. - * - * LWS_CALLBACK_HTTP_FILE_COMPLETION: a file requested to be send down - * http link has completed. - * - * LWS_CALLBACK_CLIENT_WRITEABLE: - * LWS_CALLBACK_SERVER_WRITEABLE: If you call - * libwebsocket_callback_on_writable() on a connection, you will - * get one of these callbacks coming when the connection socket - * is able to accept another write packet without blocking. - * If it already was able to take another packet without blocking, - * you'll get this callback at the next call to the service loop - * function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE - * and servers get LWS_CALLBACK_SERVER_WRITEABLE. - * - * LWS_CALLBACK_FILTER_NETWORK_CONNECTION: called when a client connects to - * the server at network level; the connection is accepted but then - * passed to this callback to decide whether to hang up immediately - * or not, based on the client IP. @in contains the connection - * socket's descriptor. Since the client connection information is - * not available yet, @wsi still pointing to the main server socket. - * Return non-zero to terminate the connection before sending or - * receiving anything. Because this happens immediately after the - * network connection from the client, there's no websocket protocol - * selected yet so this callback is issued only to protocol 0. - * - * LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED: A new client just had - * been connected, accepted, and instantiated into the pool. This - * callback allows setting any relevant property to it. Because this - * happens immediately after the instantiation of a new client, - * there's no websocket protocol selected yet so this callback is - * issued only to protocol 0. Only @wsi is defined, pointing to the - * new client, and the return value is ignored. - * - * LWS_CALLBACK_FILTER_HTTP_CONNECTION: called when the request has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * @user is a pointer to the connection user space allocation, - * @in is the URI, eg, "/" - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the http - * connection to proceed or to kill the connection. - * - * LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: called when the handshake has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * @user is a pointer to the connection user space allocation, - * @in is the requested protocol name - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the handshake - * to proceed or to kill the connection. - * - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for - * including OpenSSL support, this callback allows your user code - * to perform extra SSL_CTX_load_verify_locations() or similar - * calls to direct OpenSSL where to find certificates the client - * can use to confirm the remote server identity. @user is the - * OpenSSL SSL_CTX* - * - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for - * including OpenSSL support, this callback allows your user code - * to load extra certifcates into the server which allow it to - * verify the validity of certificates returned by clients. @user - * is the server's OpenSSL SSL_CTX* - * - * LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the - * libwebsockets context was created with the option - * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this - * callback is generated during OpenSSL verification of the cert - * sent from the client. It is sent to protocol[0] callback as - * no protocol has been negotiated on the connection yet. - * Notice that the libwebsockets context and wsi are both NULL - * during this callback. See - * http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html - * to understand more detail about the OpenSSL callback that - * generates this libwebsockets callback and the meanings of the - * arguments passed. In this callback, @user is the x509_ctx, - * @in is the ssl pointer and @len is preverify_ok - * Notice that this callback maintains libwebsocket return - * conventions, return 0 to mean the cert is OK or 1 to fail it. - * This also means that if you don't handle this callback then - * the default callback action of returning 0 allows the client - * certificates. - * - * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: this callback happens - * when a client handshake is being compiled. @user is NULL, - * @in is a char **, it's pointing to a char * which holds the - * next location in the header buffer where you can add - * headers, and @len is the remaining space in the header buffer, - * which is typically some hundreds of bytes. So, to add a canned - * cookie, your handler code might look similar to: - * - * char **p = (char **)in; - * - * if (len < 100) - * return 1; - * - * *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); - * - * return 0; - * - * Notice if you add anything, you just have to take care about - * the CRLF on the line you added. Obviously this callback is - * optional, if you don't handle it everything is fine. - * - * Notice the callback is coming to protocols[0] all the time, - * because there is no specific protocol handshook yet. - * - * LWS_CALLBACK_CONFIRM_EXTENSION_OKAY: When the server handshake code - * sees that it does support a requested extension, before - * accepting the extension by additing to the list sent back to - * the client it gives this callback just to check that it's okay - * to use that extension. It calls back to the requested protocol - * and with @in being the extension name, @len is 0 and @user is - * valid. Note though at this time the ESTABLISHED callback hasn't - * happened yet so if you initialize @user content there, @user - * content during this callback might not be useful for anything. - * Notice this callback comes to protocols[0]. - * - * LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED: When a client - * connection is being prepared to start a handshake to a server, - * each supported extension is checked with protocols[0] callback - * with this reason, giving the user code a chance to suppress the - * claim to support that extension by returning non-zero. If - * unhandled, by default 0 will be returned and the extension - * support included in the header to the server. Notice this - * callback comes to protocols[0]. - * - * LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can - * do initial setup / allocations etc - * - * LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating - * this protocol won't get used at all after this callback, the - * context is getting destroyed. Take the opportunity to - * deallocate everything that was allocated by the protocol. - * - * LWS_CALLBACK_WSI_CREATE: outermost (earliest) wsi create notification - * - * LWS_CALLBACK_WSI_DESTROY: outermost (latest) wsi destroy notification - * - * The next five reasons are optional and only need taking care of if you - * will be integrating libwebsockets sockets into an external polling - * array. - * - * For these calls, @in points to a struct libwebsocket_pollargs that - * contains @fd, @events and @prev_events members - * - * LWS_CALLBACK_ADD_POLL_FD: libwebsocket deals with its poll() loop - * internally, but in the case you are integrating with another - * server you will need to have libwebsocket sockets share a - * polling array with the other server. This and the other - * POLL_FD related callbacks let you put your specialized - * poll array interface code in the callback for protocol 0, the - * first protocol you support, usually the HTTP protocol in the - * serving case. - * This callback happens when a socket needs to be - * added to the polling loop: @in points to a struct - * libwebsocket_pollargs; the @fd member of the struct is the file - * descriptor, and @events contains the active events. - * - * If you are using the internal polling loop (the "service" - * callback), you can just ignore these callbacks. - * - * LWS_CALLBACK_DEL_POLL_FD: This callback happens when a socket descriptor - * needs to be removed from an external polling array. @in is - * again the struct libwebsocket_pollargs containing the @fd member - * to be removed. If you are using the internal polling - * loop, you can just ignore it. - * - * LWS_CALLBACK_CHANGE_MODE_POLL_FD: This callback happens when - * libwebsockets wants to modify the events for a connectiion. - * @in is the struct libwebsocket_pollargs with the @fd to change. - * The new event mask is in @events member and the old mask is in - * the @prev_events member. - * If you are using the internal polling loop, you can just ignore - * it. - * - * LWS_CALLBACK_LOCK_POLL: - * LWS_CALLBACK_UNLOCK_POLL: These allow the external poll changes driven - * by libwebsockets to participate in an external thread locking - * scheme around the changes, so the whole thing is threadsafe. - */ -LWS_VISIBLE LWS_EXTERN int callback(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -typedef int (callback_function)(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -#ifndef LWS_NO_EXTENSIONS -/** - * extension_callback_function() - Hooks to allow extensions to operate - * @context: Websockets context - * @ext: This extension - * @wsi: Opaque websocket instance pointer - * @reason: The reason for the call - * @user: Pointer to per-session user data allocated by library - * @in: Pointer used for some callback reasons - * @len: Length set for some callback reasons - * - * Each extension that is active on a particular connection receives - * callbacks during the connection lifetime to allow the extension to - * operate on websocket data and manage itself. - * - * Libwebsockets takes care of allocating and freeing "user" memory for - * each active extension on each connection. That is what is pointed to - * by the @user parameter. - * - * LWS_EXT_CALLBACK_CONSTRUCT: called when the server has decided to - * select this extension from the list provided by the client, - * just before the server will send back the handshake accepting - * the connection with this extension active. This gives the - * extension a chance to initialize its connection context found - * in @user. - * - * LWS_EXT_CALLBACK_CLIENT_CONSTRUCT: same as LWS_EXT_CALLBACK_CONSTRUCT - * but called when client is instantiating this extension. Some - * extensions will work the same on client and server side and then - * you can just merge handlers for both CONSTRUCTS. - * - * LWS_EXT_CALLBACK_DESTROY: called when the connection the extension was - * being used on is about to be closed and deallocated. It's the - * last chance for the extension to deallocate anything it has - * allocated in the user data (pointed to by @user) before the - * user data is deleted. This same callback is used whether you - * are in client or server instantiation context. - * - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE: when this extension was active on - * a connection, and a packet of data arrived at the connection, - * it is passed to this callback to give the extension a chance to - * change the data, eg, decompress it. @user is pointing to the - * extension's private connection context data, @in is pointing - * to an lws_tokens struct, it consists of a char * pointer called - * token, and an int called token_len. At entry, these are - * set to point to the received buffer and set to the content - * length. If the extension will grow the content, it should use - * a new buffer allocated in its private user context data and - * set the pointed-to lws_tokens members to point to its buffer. - * - * LWS_EXT_CALLBACK_PACKET_TX_PRESEND: this works the same way as - * LWS_EXT_CALLBACK_PACKET_RX_PREPARSE above, except it gives the - * extension a chance to change websocket data just before it will - * be sent out. Using the same lws_token pointer scheme in @in, - * the extension can change the buffer and the length to be - * transmitted how it likes. Again if it wants to grow the - * buffer safely, it should copy the data into its own buffer and - * set the lws_tokens token pointer to it. - */ -LWS_VISIBLE LWS_EXTERN int extension_callback(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); - -typedef int (extension_callback_function)(struct libwebsocket_context *context, - struct libwebsocket_extension *ext, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons reason, - void *user, void *in, size_t len); -#endif - -/** - * struct libwebsocket_protocols - List of protocols and handlers server - * supports. - * @name: Protocol name that must match the one given in the client - * Javascript new WebSocket(url, 'protocol') name - * @callback: The service callback used for this protocol. It allows the - * service action for an entire protocol to be encapsulated in - * the protocol-specific callback - * @per_session_data_size: Each new connection using this protocol gets - * this much memory allocated on connection establishment and - * freed on connection takedown. A pointer to this per-connection - * allocation is passed into the callback in the 'user' parameter - * @rx_buffer_size: if you want atomic frames delivered to the callback, you - * should set this to the size of the biggest legal frame that - * you support. If the frame size is exceeded, there is no - * error, but the buffer will spill to the user callback when - * full, which you can detect by using - * libwebsockets_remaining_packet_payload(). Notice that you - * just talk about frame size here, the LWS_SEND_BUFFER_PRE_PADDING - * and post-padding are automatically also allocated on top. - * @no_buffer_all_partial_tx: Leave at zero if you want the library to take - * care of all partial tx for you. It's useful if you only have - * small tx packets and the chance of any truncated send is small - * enough any additional malloc / buffering overhead is less - * painful than writing the code to deal with partial sends. For - * protocols where you stream big blocks, set to nonzero and use - * the return value from libwebsocket_write() to manage how much - * got send yourself. - * @owning_server: the server init call fills in this opaque pointer when - * registering this protocol with the server. - * @protocol_index: which protocol we are starting from zero - * - * This structure represents one protocol supported by the server. An - * array of these structures is passed to libwebsocket_create_server() - * allows as many protocols as you like to be handled by one server. - */ - -struct libwebsocket_protocols { - const char *name; - callback_function *callback; - size_t per_session_data_size; - size_t rx_buffer_size; - int no_buffer_all_partial_tx; - - /* - * below are filled in on server init and can be left uninitialized, - * no need for user to use them directly either - */ - - struct libwebsocket_context *owning_server; - int protocol_index; -}; - -#ifndef LWS_NO_EXTENSIONS -/** - * struct libwebsocket_extension - An extension we know how to cope with - * - * @name: Formal extension name, eg, "deflate-stream" - * @callback: Service callback - * @per_session_data_size: Libwebsockets will auto-malloc this much - * memory for the use of the extension, a pointer - * to it comes in the @user callback parameter - * @per_context_private_data: Optional storage for this extension that - * is per-context, so it can track stuff across - * all sessions, etc, if it wants - */ - -struct libwebsocket_extension { - const char *name; - extension_callback_function *callback; - size_t per_session_data_size; - void *per_context_private_data; -}; -#endif - -/** - * struct lws_context_creation_info: parameters to create context with - * - * @port: Port to listen on... you can use 0 to suppress listening on - * any port, that's what you want if you are not running a - * websocket server at all but just using it as a client - * @iface: NULL to bind the listen socket to all interfaces, or the - * interface name, eg, "eth2" - * @protocols: Array of structures listing supported protocols and a protocol- - * specific callback for each one. The list is ended with an - * entry that has a NULL callback pointer. - * It's not const because we write the owning_server member - * @extensions: NULL or array of libwebsocket_extension structs listing the - * extensions this context supports. If you configured with - * --without-extensions, you should give NULL here. - * @ssl_cert_filepath: If libwebsockets was compiled to use ssl, and you want - * to listen using SSL, set to the filepath to fetch the - * server cert from, otherwise NULL for unencrypted - * @ssl_private_key_filepath: filepath to private key if wanting SSL mode, - * else ignored - * @ssl_ca_filepath: CA certificate filepath or NULL - * @ssl_cipher_list: List of valid ciphers to use (eg, - * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - * or you can leave it as NULL to get "DEFAULT" - * @gid: group id to change to after setting listen socket, or -1. - * @uid: user id to change to after setting listen socket, or -1. - * @options: 0, or LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK - * @user: optional user pointer that can be recovered via the context - * pointer using libwebsocket_context_user - * @ka_time: 0 for no keepalive, otherwise apply this keepalive timeout to - * all libwebsocket sockets, client or server - * @ka_probes: if ka_time was nonzero, after the timeout expires how many - * times to try to get a response from the peer before giving up - * and killing the connection - * @ka_interval: if ka_time was nonzero, how long to wait before each ka_probes - * attempt - */ - -struct lws_context_creation_info { - int port; - const char *iface; - struct libwebsocket_protocols *protocols; - struct libwebsocket_extension *extensions; - const char *ssl_cert_filepath; - const char *ssl_private_key_filepath; - const char *ssl_ca_filepath; - const char *ssl_cipher_list; - const char *http_proxy_address; - unsigned int http_proxy_port; - int gid; - int uid; - unsigned int options; - void *user; - int ka_time; - int ka_probes; - int ka_interval; - -}; - -LWS_VISIBLE LWS_EXTERN -void lws_set_log_level(int level, - void (*log_emit_function)(int level, const char *line)); - -LWS_VISIBLE LWS_EXTERN void -lwsl_emit_syslog(int level, const char *line); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket_context * -libwebsocket_create_context(struct lws_context_creation_info *info); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_context_destroy(struct libwebsocket_context *context); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_cancel_service(struct libwebsocket_context *context); - -#ifdef LWS_USE_LIBEV -LWS_VISIBLE LWS_EXTERN int -libwebsocket_initloop( - struct libwebsocket_context *context, struct ev_loop *loop); - -LWS_VISIBLE void -libwebsocket_sigint_cb( - struct ev_loop *loop, struct ev_signal *watcher, int revents); -#endif /* LWS_USE_LIBEV */ - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd); - -LWS_VISIBLE LWS_EXTERN void * -libwebsocket_context_user(struct libwebsocket_context *context); - -enum pending_timeout { - NO_PENDING_TIMEOUT = 0, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - PENDING_TIMEOUT_AWAITING_PING, - PENDING_TIMEOUT_CLOSE_ACK, - PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, - PENDING_TIMEOUT_SSL_ACCEPT, - PENDING_TIMEOUT_HTTP_CONTENT, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, -}; - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_set_timeout(struct libwebsocket *wsi, - enum pending_timeout reason, int secs); - -/* - * IMPORTANT NOTICE! - * - * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY) - * the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE - * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len). - * - * This allows us to add protocol info before and after the data, and send as - * one packet on the network without payload copying, for maximum efficiency. - * - * So for example you need this kind of code to use libwebsocket_write with a - * 128-byte payload - * - * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING]; - * - * // fill your part of the buffer... for example here it's all zeros - * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128); - * - * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128, - * LWS_WRITE_TEXT); - * - * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just - * use the whole buffer without taking care of the above. - */ - -/* - * this is the frame nonce plus two header plus 8 length - * there's an additional two for mux extension per mux nesting level - * 2 byte prepend on close will already fit because control frames cannot use - * the big length style - */ - -#define LWS_SEND_BUFFER_PRE_PADDING (4 + 10 + (2 * MAX_MUX_RECURSION)) -#define LWS_SEND_BUFFER_POST_PADDING 4 - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, - enum libwebsocket_write_protocol protocol); - -/* helper for case where buffer may be const */ -#define libwebsocket_write_http(wsi, buf, len) \ - libwebsocket_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) - -LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers); -LWS_VISIBLE LWS_EXTERN int -libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int libwebsockets_return_http_status( - struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int code, - const char *html_body); - -LWS_VISIBLE LWS_EXTERN const struct libwebsocket_protocols * -libwebsockets_get_protocol(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_callback_all_protocol( - const struct libwebsocket_protocols *protocol, int reason); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_get_socket_fd(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_is_final_fragment(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN unsigned char -libwebsocket_get_reserved_bits(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable); - -LWS_VISIBLE LWS_EXTERN void -libwebsocket_rx_flow_allow_all_protocol( - const struct libwebsocket_protocols *protocol); - -LWS_VISIBLE LWS_EXTERN size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one); - -LWS_VISIBLE LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_extended(struct libwebsocket_context *clients, - const char *address, - int port, - int ssl_connection, - const char *path, - const char *host, - const char *origin, - const char *protocol, - int ietf_version_or_minus_one, - void *userdata); - -LWS_VISIBLE LWS_EXTERN const char * -libwebsocket_canonical_hostname(struct libwebsocket_context *context); - - -LWS_VISIBLE LWS_EXTERN void -libwebsockets_get_peer_addresses(struct libwebsocket_context *context, - struct libwebsocket *wsi, int fd, char *name, int name_len, - char *rip, int rip_len); - -LWS_VISIBLE LWS_EXTERN int -libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len); - -LWS_VISIBLE LWS_EXTERN int -lws_daemonize(const char *_lock_path); - -LWS_VISIBLE LWS_EXTERN int -lws_send_pipe_choked(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_frame_is_binary(struct libwebsocket *wsi); - -LWS_VISIBLE LWS_EXTERN unsigned char * -libwebsockets_SHA1(const unsigned char *d, size_t n, unsigned char *md); - -LWS_VISIBLE LWS_EXTERN int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); - -LWS_VISIBLE LWS_EXTERN int -lws_b64_decode_string(const char *in, char *out, int out_size); - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_library_version(void); - -/* access to headers... only valid while headers valid */ - -LWS_VISIBLE LWS_EXTERN int -lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h); - -LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h); - -/* - * Note: this is not normally needed as a user api. It's provided in case it is - * useful when integrating with other app poll loop service code. - */ - -LWS_VISIBLE LWS_EXTERN int -libwebsocket_read(struct libwebsocket_context *context, - struct libwebsocket *wsi, - unsigned char *buf, size_t len); - -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions(); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/deps/libwebsocket/lws-plat-unix.c b/core/deps/libwebsocket/lws-plat-unix.c deleted file mode 100644 index ebec155d7..000000000 --- a/core/deps/libwebsocket/lws-plat-unix.c +++ /dev/null @@ -1,396 +0,0 @@ -#include "private-libwebsockets.h" - -#include "build.h" - -#if HOST_OS != OS_WINDOWS -/* - * included from libwebsockets.c for unix builds - */ - -unsigned long long time_in_microseconds(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000000) + tv.tv_usec; -} - -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len) -{ - return read(context->fd_random, (char *)buf, len); -} - -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) -{ - struct libwebsocket_pollfd fds; - - /* treat the fact we got a truncated send pending as if we're choked */ - if (wsi->truncated_send_len) - return 1; - - fds.fd = wsi->sock; - fds.events = POLLOUT; - fds.revents = 0; - - if (poll(&fds, 1, 0) != 1) - return 1; - - if ((fds.revents & POLLOUT) == 0) - return 1; - - /* okay to send another packet without blocking */ - - return 0; -} - -LWS_VISIBLE int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd) -{ - return poll(fd, 1, 0); -} - -/* - * This is just used to interrupt poll waiting - * we don't have to do anything with it. - */ -static void lws_sigusr2(int sig) -{ -} - -/** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity - * @context: Websocket context - * - * This function let a call to libwebsocket_service() waiting for a timeout - * immediately return. - */ -LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) -{ - char buf = 0; - - if (write(context->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1) - lwsl_err("Cannot write to dummy pipe"); -} - -LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) -{ -/* - int syslog_level = LOG_DEBUG; - - switch (level) { - case LLL_ERR: - syslog_level = LOG_ERR; - break; - case LLL_WARN: - syslog_level = LOG_WARNING; - break; - case LLL_NOTICE: - syslog_level = LOG_NOTICE; - break; - case LLL_INFO: - syslog_level = LOG_INFO; - break; - } - */ - printf("%s", line); -} - -LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) -{ - int n; - int m; - char buf; - - /* stay dead once we are dead */ - - if (!context) - return 1; - - lws_libev_run(context); - - context->service_tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - - n = poll(context->fds, context->fds_count, timeout_ms); - context->service_tid = 0; - - if (n == 0) /* poll timeout */ { - libwebsocket_service_fd(context, NULL); - return 0; - } - - if (n < 0) { - if (LWS_ERRNO != LWS_EINTR) - return -1; - return 0; - } - - /* any socket with events to service? */ - - for (n = 0; n < context->fds_count; n++) { - if (!context->fds[n].revents) - continue; - - if (context->fds[n].fd == context->dummy_pipe_fds[0]) { - if (read(context->fds[n].fd, &buf, 1) != 1) - lwsl_err("Cannot read from dummy pipe."); - continue; - } - - m = libwebsocket_service_fd(context, &context->fds[n]); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } - - return 0; -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd) -{ - int optval = 1; - socklen_t optlen = sizeof(optval); - -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) - struct protoent *tcp_proto; -#endif - - if (context->ka_time) { - /* enable keepalive on this socket */ - optval = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *)&optval, optlen) < 0) - return 1; - -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__) - - /* - * didn't find a way to set these per-socket, need to - * tune kernel systemwide values - */ -#else - /* set the keepalive conditions we want on it too */ - optval = context->ka_time; - if (setsockopt(fd, IPPROTO_IP, TCP_KEEPIDLE, - (const void *)&optval, optlen) < 0) - return 1; - - optval = context->ka_interval; - if (setsockopt(fd, IPPROTO_IP, TCP_KEEPINTVL, - (const void *)&optval, optlen) < 0) - return 1; - - optval = context->ka_probes; - if (setsockopt(fd, IPPROTO_IP, TCP_KEEPCNT, - (const void *)&optval, optlen) < 0) - return 1; -#endif - } - - /* Disable Nagle */ - optval = 1; -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__) - setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen); -#else - tcp_proto = getprotobyname("TCP"); - setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen); -#endif - - /* We are nonblocking... */ - fcntl(fd, F_SETFL, O_NONBLOCK); - - return 0; -} - -LWS_VISIBLE void -lws_plat_drop_app_privileges(struct lws_context_creation_info *info) -{ - if (info->gid != -1) - if (setgid(info->gid)) - lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO)); - if (info->uid != -1) - if (setuid(info->uid)) - lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO)); -} - -LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) -{ - if (lws_libev_init_fd_table(context)) - /* libev handled it instead */ - return 0; - - if (pipe(context->dummy_pipe_fds)) { - lwsl_err("Unable to create pipe\n"); - return 1; - } - - /* use the read end of pipe as first item */ - context->fds[0].fd = context->dummy_pipe_fds[0]; - context->fds[0].events = LWS_POLLIN; - context->fds[0].revents = 0; - context->fds_count = 1; - - context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY); - if (context->fd_random < 0) { - lwsl_err("Unable to open random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, context->fd_random); - return 1; - } - - return 0; -} - -static void sigpipe_handler(int x) -{ -} - - -LWS_VISIBLE int -lws_plat_context_early_init(void) -{ - sigset_t mask; - - signal(SIGUSR2, lws_sigusr2); - sigemptyset(&mask); - sigaddset(&mask, SIGUSR2); - - sigprocmask(SIG_BLOCK, &mask, NULL); - - signal(SIGPIPE, sigpipe_handler); - - return 0; -} - -LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) -{ -} - -LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) -{ - close(context->dummy_pipe_fds[0]); - close(context->dummy_pipe_fds[1]); - close(context->fd_random); -} - -/* cast a struct sockaddr_in6 * into addr for ipv6 */ - -LWS_VISIBLE int -interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen) -{ - int rc = -1; - - struct ifaddrs *ifr; - struct ifaddrs *ifc; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; -#endif - - getifaddrs(&ifr); - for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) { - if (!ifc->ifa_addr) - continue; - - lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname); - - if (strcmp(ifc->ifa_name, ifname)) - continue; - - switch (ifc->ifa_addr->sa_family) { - case AF_INET: -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - /* map IPv4 to IPv6 */ - bzero((char *)&addr6->sin6_addr, - sizeof(struct in6_addr)); - addr6->sin6_addr.s6_addr[10] = 0xff; - addr6->sin6_addr.s6_addr[11] = 0xff; - memcpy(&addr6->sin6_addr.s6_addr[12], - &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr, - sizeof(struct in_addr)); - } else -#endif - memcpy(addr, - (struct sockaddr_in *)ifc->ifa_addr, - sizeof(struct sockaddr_in)); - break; -#ifdef LWS_USE_IPV6 - case AF_INET6: - if (rc >= 0) - break; - memcpy(&addr6->sin6_addr, - &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr, - sizeof(struct in6_addr)); - break; -#endif - default: - continue; - } - rc = 0; - } - - freeifaddrs(ifr); - - return rc; -} - -LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ); - context->fds[context->fds_count++].revents = 0; -} - -LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) -{ -} - -LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) -{ - /* if our parent went down, don't linger around */ - if (context->started_with_parent && - kill(context->started_with_parent, 0) < 0) - kill(getpid(), SIGTERM); -} - -LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) -{ - return 0; -} - -LWS_VISIBLE int -lws_plat_open_file(const char* filename, unsigned long* filelen) -{ - struct stat stat_buf; - int ret = open(filename, O_RDONLY); - - if (ret < 0) - return LWS_INVALID_FILE; - - fstat(ret, &stat_buf); - *filelen = stat_buf.st_size; - return ret; -} - -#ifdef LWS_USE_IPV6 -LWS_VISIBLE const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) -{ - return inet_ntop(af, src, dst, cnt); -} -#endif -#endif \ No newline at end of file diff --git a/core/deps/libwebsocket/lws-plat-win.c b/core/deps/libwebsocket/lws-plat-win.c deleted file mode 100644 index ef25eb0d3..000000000 --- a/core/deps/libwebsocket/lws-plat-win.c +++ /dev/null @@ -1,365 +0,0 @@ -#include "private-libwebsockets.h" - - -#include "build.h" - -#if HOST_OS == OS_WINDOWS - -unsigned long long -time_in_microseconds() -{ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL - FILETIME filetime; - ULARGE_INTEGER datetime; - -#ifdef _WIN32_WCE - GetCurrentFT(&filetime); -#else - GetSystemTimeAsFileTime(&filetime); -#endif - - /* - * As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a - * ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can - * prevent alignment faults on 64-bit Windows). - */ - memcpy(&datetime, &filetime, sizeof(datetime)); - - /* Windows file times are in 100s of nanoseconds. */ - return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10; -} - -#ifdef _WIN32_WCE -time_t time(time_t *t) -{ - time_t ret = time_in_microseconds() / 1000000; - *t = ret; - return ret; -} -#endif - -LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context, - void *buf, int len) -{ - int n; - char *p = (char *)buf; - - for (n = 0; n < len; n++) - p[n] = (unsigned char)rand(); - - return n; -} - -LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi) -{ - return wsi->sock_send_blocking; -} - -LWS_VISIBLE int lws_poll_listen_fd(struct libwebsocket_pollfd *fd) -{ - fd_set readfds; - struct timeval tv = { 0, 0 }; - - assert(fd->events == LWS_POLLIN); - - FD_ZERO(&readfds); - FD_SET(fd->fd, &readfds); - - return select(fd->fd + 1, &readfds, NULL, NULL, &tv); -} - -/** - * libwebsocket_cancel_service() - Cancel servicing of pending websocket activity - * @context: Websocket context - * - * This function let a call to libwebsocket_service() waiting for a timeout - * immediately return. - */ -LWS_VISIBLE void -libwebsocket_cancel_service(struct libwebsocket_context *context) -{ - WSASetEvent(context->events[0]); -} - -LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) -{ - lwsl_emit_stderr(level, line); -} - -LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) -{ - int n; - int i; - DWORD ev; - WSANETWORKEVENTS networkevents; - struct libwebsocket_pollfd *pfd; - - /* stay dead once we are dead */ - - if (context == NULL) - return 1; - - context->service_tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - - for (i = 0; i < context->fds_count; ++i) { - pfd = &context->fds[i]; - if (pfd->fd == context->listen_service_fd) - continue; - - if (pfd->events & LWS_POLLOUT) { - if (context->lws_lookup[pfd->fd]->sock_send_blocking) - continue; - pfd->revents = LWS_POLLOUT; - n = libwebsocket_service_fd(context, pfd); - if (n < 0) - return n; - } - } - - ev = WSAWaitForMultipleEvents(context->fds_count + 1, - context->events, FALSE, timeout_ms, FALSE); - context->service_tid = 0; - - if (ev == WSA_WAIT_TIMEOUT) { - libwebsocket_service_fd(context, NULL); - return 0; - } - - if (ev == WSA_WAIT_EVENT_0) { - WSAResetEvent(context->events[0]); - return 0; - } - - if (ev < WSA_WAIT_EVENT_0 || ev > WSA_WAIT_EVENT_0 + context->fds_count) - return -1; - - pfd = &context->fds[ev - WSA_WAIT_EVENT_0 - 1]; - - if (WSAEnumNetworkEvents(pfd->fd, - context->events[ev - WSA_WAIT_EVENT_0], - &networkevents) == SOCKET_ERROR) { - lwsl_err("WSAEnumNetworkEvents() failed with error %d\n", - LWS_ERRNO); - return -1; - } - - pfd->revents = networkevents.lNetworkEvents; - - if (pfd->revents & LWS_POLLOUT) - context->lws_lookup[pfd->fd]->sock_send_blocking = FALSE; - - return libwebsocket_service_fd(context, pfd); -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd) -{ - int optval = 1; - int optlen = sizeof(optval); - u_long optl = 1; - DWORD dwBytesRet; - struct tcp_keepalive alive; - struct protoent *tcp_proto; - - if (context->ka_time) { - /* enable keepalive on this socket */ - optval = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, - (const char *)&optval, optlen) < 0) - return 1; - - alive.onoff = TRUE; - alive.keepalivetime = context->ka_time; - alive.keepaliveinterval = context->ka_interval; - - if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), - NULL, 0, &dwBytesRet, NULL, NULL)) - return 1; - } - - /* Disable Nagle */ - optval = 1; - tcp_proto = getprotobyname("TCP"); - setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, (const char *)&optval, optlen); - - /* We are nonblocking... */ - ioctlsocket(fd, FIONBIO, &optl); - - return 0; -} - -LWS_VISIBLE void -lws_plat_drop_app_privileges(struct lws_context_creation_info *info) -{ -} - -LWS_VISIBLE int -lws_plat_init_fd_tables(struct libwebsocket_context *context) -{ - context->events = (WSAEVENT *)malloc(sizeof(WSAEVENT) * - (context->max_fds + 1)); - if (context->events == NULL) { - lwsl_err("Unable to allocate events array for %d connections\n", - context->max_fds); - return 1; - } - - context->fds_count = 0; - context->events[0] = WSACreateEvent(); - - context->fd_random = 0; - - return 0; -} - -LWS_VISIBLE int -lws_plat_context_early_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - - /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (!err) - return 0; - /* - * Tell the user that we could not find a usable - * Winsock DLL - */ - lwsl_err("WSAStartup failed with error: %d\n", err); - - return 1; -} - -LWS_VISIBLE void -lws_plat_context_early_destroy(struct libwebsocket_context *context) -{ - if (context->events) { - WSACloseEvent(context->events[0]); - free(context->events); - } -} - -LWS_VISIBLE void -lws_plat_context_late_destroy(struct libwebsocket_context *context) -{ - WSACleanup(); -} - -LWS_VISIBLE int -interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen) -{ - return -1; -} - -LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - context->fds[context->fds_count++].revents = 0; - context->events[context->fds_count] = WSACreateEvent(); - WSAEventSelect(wsi->sock, context->events[context->fds_count], LWS_POLLIN); -} - -LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m) -{ - WSACloseEvent(context->events[m + 1]); - context->events[m + 1] = context->events[context->fds_count + 1]; -} - -LWS_VISIBLE void -lws_plat_service_periodic(struct libwebsocket_context *context) -{ -} - -LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) -{ - long networkevents = LWS_POLLOUT | LWS_POLLHUP; - - if ((pfd->events & LWS_POLLIN)) - networkevents |= LWS_POLLIN; - - if (WSAEventSelect(wsi->sock, - context->events[wsi->position_in_fds_table + 1], - networkevents) != SOCKET_ERROR) - return 0; - - lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO); - - return 1; -} - -LWS_VISIBLE HANDLE -lws_plat_open_file(const char* filename, unsigned long* filelen) -{ - HANDLE ret; - WCHAR buffer[MAX_PATH]; - - MultiByteToWideChar(CP_UTF8, 0, filename, -1, buffer, - sizeof(buffer) / sizeof(buffer[0])); - ret = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (ret != LWS_INVALID_FILE) - *filelen = GetFileSize(ret, NULL); - - return ret; -} - -LWS_VISIBLE const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) -{ - WCHAR *buffer; - DWORD bufferlen = cnt; - BOOL ok = FALSE; - - buffer = malloc(bufferlen); - if (!buffer) { - lwsl_err("Out of memory\n"); - return NULL; - } - - if (af == AF_INET) { - struct sockaddr_in srcaddr; - bzero(&srcaddr, sizeof(srcaddr)); - srcaddr.sin_family = AF_INET; - memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr)); - - if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen)) - ok = TRUE; -#ifdef LWS_USE_IPV6 - } else if (af == AF_INET6) { - struct sockaddr_in6 srcaddr; - bzero(&srcaddr, sizeof(srcaddr)); - srcaddr.sin6_family = AF_INET6; - memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr)); - - if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen)) - ok = TRUE; -#endif - } else - lwsl_err("Unsupported type\n"); - - if (!ok) { - int rv = WSAGetLastError(); - lwsl_err("WSAAddressToString() : %d\n", rv); - } else { - if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0) - ok = FALSE; - } - - free(buffer); - return ok ? dst : NULL; -} - -#endif \ No newline at end of file diff --git a/core/deps/libwebsocket/lws_config.h b/core/deps/libwebsocket/lws_config.h deleted file mode 100644 index fb0743f4d..000000000 --- a/core/deps/libwebsocket/lws_config.h +++ /dev/null @@ -1,174 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -#ifndef WIN32 -#define _DEBUG -#endif - -/* Define to 1 to use CyaSSL as a replacement for OpenSSL. - * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ -/* #undef USE_CYASSL */ - -/* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "1.3" - -/* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "c11b847" - -/* Build with OpenSSL support */ -/* #undef LWS_OPENSSL_SUPPORT */ - -/* The client should load and trust CA root certs it finds in the OS */ -/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */ - -/* Sets the path where the client certs should be installed. */ -#define LWS_OPENSSL_CLIENT_CERTS "../share" - -/* Turn off websocket extensions */ -/* #undef LWS_NO_EXTENSIONS */ - -/* Enable libev io loop */ -/* #undef LWS_USE_LIBEV */ - -/* Build with support for ipv6 */ -/* #undef LWS_USE_IPV6 */ - -/* Build with support for HTTP2 */ -/* #undef LWS_USE_HTTP2 */ - -/* Turn on latency measuring code */ -/* #undef LWS_LATENCY */ - -/* Don't build the daemonizeation api */ -#define LWS_NO_DAEMONIZE - -/* Build without server support */ -/* #undef LWS_NO_SERVER */ - -/* Build without client support */ -/* #undef LWS_NO_CLIENT */ - -/* If we should compile with MinGW support */ -/* #undef LWS_MINGW_SUPPORT */ - -/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */ -#define LWS_BUILTIN_GETIFADDRS - -/* Define to 1 if you have the `bzero' function. */ -/* #undef HAVE_BZERO */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H - -/* Define to 1 if you have the `fork' function. */ -/* #undef HAVE_FORK */ - -/* Define to 1 if you have the `getenv’ function. */ -#define HAVE_GETENV - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IN6ADDR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/* #undef HAVE_LIBSSL */ - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_IN_H */ - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define HAVE_REALLOC - -/* Define to 1 if you have the `socket' function. */ -/* #undef HAVE_SOCKET */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_PRCTL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKET_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define to 1 if you have the `vfork' function. */ -/* #undef HAVE_VFORK */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ZLIB_H */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR // We're not using libtool - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS - -/* Version number of package */ -#define VERSION - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to `int' if does not define. */ -#define pid_t - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to 1 if we have getifaddrs */ -/* #undef HAVE_GETIFADDRS */ - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ - -/* Define if the inline keyword doesn't exist. */ -#define inline diff --git a/core/deps/libwebsocket/output.c b/core/deps/libwebsocket/output.c deleted file mode 100644 index 28e15a6d4..000000000 --- a/core/deps/libwebsocket/output.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -static int -libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi) -{ - int n; - - /* fetch the per-frame nonce */ - - n = libwebsockets_get_random(wsi->protocol->owning_server, - wsi->u.ws.frame_masking_nonce_04, 4); - if (n != 4) { - lwsl_parser("Unable to read from random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, n); - return 1; - } - - /* start masking from first byte of masking key buffer */ - wsi->u.ws.frame_mask_index = 0; - - return 0; -} - -#ifdef _DEBUG - -LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len) -{ - int n; - int m; - int start; - unsigned char *buf = (unsigned char *)vbuf; - char line[80]; - char *p; - - lwsl_parser("\n"); - - for (n = 0; n < len;) { - start = n; - p = line; - - p += sprintf(p, "%04X: ", start); - - for (m = 0; m < 16 && n < len; m++) - p += sprintf(p, "%02X ", buf[n++]); - while (m++ < 16) - p += sprintf(p, " "); - - p += sprintf(p, " "); - - for (m = 0; m < 16 && (start + m) < len; m++) { - if (buf[start + m] >= ' ' && buf[start + m] < 127) - *p++ = buf[start + m]; - else - *p++ = '.'; - } - while (m++ < 16) - *p++ = ' '; - - *p++ = '\n'; - *p = '\0'; - lwsl_debug("%s", line); - } - lwsl_debug("\n"); -} - -#endif - -/* - * notice this returns number of bytes consumed, or -1 - */ - -int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len) -{ - struct libwebsocket_context *context = wsi->protocol->owning_server; - int n; - size_t real_len = len; - int m; - - if (!len) - return 0; - /* just ignore sends after we cleared the truncation buffer */ - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE && - !wsi->truncated_send_len) - return len; - - if (wsi->truncated_send_len && (buf < wsi->truncated_send_malloc || - buf > (wsi->truncated_send_malloc + - wsi->truncated_send_len + - wsi->truncated_send_offset))) { - lwsl_err("****** %x Sending new, pending truncated ...\n", wsi); - assert(0); - } - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, &buf, len); - if (m < 0) - return -1; - if (m) /* handled */ { - n = m; - goto handle_truncated_send; - } - if (wsi->sock < 0) - lwsl_warn("** error invalid sock but expected to send\n"); - - /* - * nope, send it on the socket directly - */ - lws_latency_pre(context, wsi); - n = lws_ssl_capable_write(wsi, buf, len); - lws_latency(context, wsi, "send lws_issue_raw", n, n == len); - - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - return -1; - case LWS_SSL_CAPABLE_MORE_SERVICE: - /* nothing got sent, not fatal, retry the whole thing later */ - n = 0; - break; - } - -handle_truncated_send: - /* - * we were already handling a truncated send? - */ - if (wsi->truncated_send_len) { - lwsl_info("***** %x partial send moved on by %d (vs %d)\n", - wsi, n, real_len); - wsi->truncated_send_offset += n; - wsi->truncated_send_len -= n; - - if (!wsi->truncated_send_len) { - lwsl_info("***** %x partial send completed\n", wsi); - /* done with it, but don't free it */ - n = real_len; - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - lwsl_info("***** %x signalling to close now\n", wsi); - return -1; /* retry closing now */ - } - } - /* always callback on writeable */ - libwebsocket_callback_on_writable( - wsi->protocol->owning_server, wsi); - - return n; - } - - if (n == real_len) - /* what we just sent went out cleanly */ - return n; - - if (n && wsi->u.ws.clean_buffer) - /* - * This buffer unaffected by extension rewriting. - * It means the user code is expected to deal with - * partial sends. (lws knows the header was already - * sent, so on next send will just resume sending - * payload) - */ - return n; - - /* - * Newly truncated send. Buffer the remainder (it will get - * first priority next time the socket is writable) - */ - lwsl_info("***** %x new partial sent %d from %d total\n", - wsi, n, real_len); - - /* - * - if we still have a suitable malloc lying around, use it - * - or, if too small, reallocate it - * - or, if no buffer, create it - */ - if (!wsi->truncated_send_malloc || - real_len - n > wsi->truncated_send_allocation) { - if (wsi->truncated_send_malloc) - free(wsi->truncated_send_malloc); - - wsi->truncated_send_allocation = real_len - n; - wsi->truncated_send_malloc = malloc(real_len - n); - if (!wsi->truncated_send_malloc) { - lwsl_err("truncated send: unable to malloc %d\n", - real_len - n); - return -1; - } - } - wsi->truncated_send_offset = 0; - wsi->truncated_send_len = real_len - n; - memcpy(wsi->truncated_send_malloc, buf + n, real_len - n); - - /* since something buffered, force it to get another chance to send */ - libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi); - - return real_len; -} - -/** - * libwebsocket_write() - Apply protocol then write data to client - * @wsi: Websocket instance (available from user callback) - * @buf: The data to send. For data being sent on a websocket - * connection (ie, not default http), this buffer MUST have - * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer - * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid - * in the buffer after (buf + len). This is so the protocol - * header and trailer data can be added in-situ. - * @len: Count of the data bytes in the payload starting from buf - * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one - * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate - * data on a websockets connection. Remember to allow the extra - * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT - * are used. - * - * This function provides the way to issue data back to the client - * for both http and websocket protocols. - * - * In the case of sending using websocket protocol, be sure to allocate - * valid storage before and after buf as explained above. This scheme - * allows maximum efficiency of sending data and protocol in a single - * packet while not burdening the user code with any protocol knowledge. - * - * Return may be -1 for a fatal error needing connection close, or a - * positive number reflecting the amount of bytes actually sent. This - * can be less than the requested number of bytes due to OS memory - * pressure at any given time. - */ - -LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, - size_t len, enum libwebsocket_write_protocol protocol) -{ - int n; - int pre = 0; - int post = 0; - int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT; - unsigned char *dropmask = NULL; - unsigned char is_masked_bit = 0; - size_t orig_len = len; - struct lws_tokens eff_buf; - - if (len == 0 && protocol != LWS_WRITE_CLOSE && - protocol != LWS_WRITE_PING && protocol != LWS_WRITE_PONG) { - lwsl_warn("zero length libwebsocket_write attempt\n"); - return 0; - } - - if (protocol == LWS_WRITE_HTTP) - goto send_raw; - - /* websocket protocol, either binary or text */ - - if (wsi->state != WSI_STATE_ESTABLISHED) - return -1; - - /* if we are continuing a frame that already had its header done */ - - if (wsi->u.ws.inside_frame) - goto do_more_inside_frame; - - /* if he wants all partials buffered, never have a clean_buffer */ - wsi->u.ws.clean_buffer = !wsi->protocol->no_buffer_all_partial_tx; - - /* - * give a chance to the extensions to modify payload - * pre-TX mangling is not allowed to truncate - */ - eff_buf.token = (char *)buf; - eff_buf.token_len = len; - - switch (protocol) { - case LWS_WRITE_PING: - case LWS_WRITE_PONG: - case LWS_WRITE_CLOSE: - break; - default: - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_TX, &eff_buf, 0) < 0) - return -1; - } - - /* - * an extension did something we need to keep... for example, if - * compression extension, it has already updated its state according - * to this being issued - */ - if ((char *)buf != eff_buf.token) - /* - * extension recreated it: - * need to buffer this if not all sent - */ - wsi->u.ws.clean_buffer = 0; - - buf = (unsigned char *)eff_buf.token; - len = eff_buf.token_len; - - switch (wsi->ietf_spec_revision) { - case 13: - - if (masked7) { - pre += 4; - dropmask = &buf[0 - pre]; - is_masked_bit = 0x80; - } - - switch (protocol & 0xf) { - case LWS_WRITE_TEXT: - n = LWS_WS_OPCODE_07__TEXT_FRAME; - break; - case LWS_WRITE_BINARY: - n = LWS_WS_OPCODE_07__BINARY_FRAME; - break; - case LWS_WRITE_CONTINUATION: - n = LWS_WS_OPCODE_07__CONTINUATION; - break; - - case LWS_WRITE_CLOSE: - n = LWS_WS_OPCODE_07__CLOSE; - - /* - * 06+ has a 2-byte status code in network order - * we can do this because we demand post-buf - */ - - if (wsi->u.ws.close_reason) { - /* reason codes count as data bytes */ - buf -= 2; - buf[0] = wsi->u.ws.close_reason >> 8; - buf[1] = wsi->u.ws.close_reason; - len += 2; - } - break; - case LWS_WRITE_PING: - n = LWS_WS_OPCODE_07__PING; - break; - case LWS_WRITE_PONG: - n = LWS_WS_OPCODE_07__PONG; - break; - default: - lwsl_warn("lws_write: unknown write opc / protocol\n"); - return -1; - } - - if (!(protocol & LWS_WRITE_NO_FIN)) - n |= 1 << 7; - - if (len < 126) { - pre += 2; - buf[-pre] = n; - buf[-pre + 1] = len | is_masked_bit; - } else { - if (len < 65536) { - pre += 4; - buf[-pre] = n; - buf[-pre + 1] = 126 | is_masked_bit; - buf[-pre + 2] = len >> 8; - buf[-pre + 3] = len; - } else { - pre += 10; - buf[-pre] = n; - buf[-pre + 1] = 127 | is_masked_bit; -#if defined __LP64__ - buf[-pre + 2] = (len >> 56) & 0x7f; - buf[-pre + 3] = len >> 48; - buf[-pre + 4] = len >> 40; - buf[-pre + 5] = len >> 32; -#else - buf[-pre + 2] = 0; - buf[-pre + 3] = 0; - buf[-pre + 4] = 0; - buf[-pre + 5] = 0; -#endif - buf[-pre + 6] = len >> 24; - buf[-pre + 7] = len >> 16; - buf[-pre + 8] = len >> 8; - buf[-pre + 9] = len; - } - } - break; - } - -do_more_inside_frame: - - /* - * Deal with masking if we are in client -> server direction and - * the protocol demands it - */ - - if (wsi->mode == LWS_CONNMODE_WS_CLIENT) { - - if (!wsi->u.ws.inside_frame) - if (libwebsocket_0405_frame_mask_generate(wsi)) { - lwsl_err("frame mask generation failed\n"); - return -1; - } - - /* - * in v7, just mask the payload - */ - if (dropmask) { /* never set if already inside frame */ - for (n = 4; n < (int)len + 4; n++) - dropmask[n] = dropmask[n] ^ - wsi->u.ws.frame_masking_nonce_04[ - (wsi->u.ws.frame_mask_index++) & 3]; - - /* copy the frame nonce into place */ - memcpy(dropmask, wsi->u.ws.frame_masking_nonce_04, 4); - } - } - -send_raw: - switch (protocol) { - case LWS_WRITE_CLOSE: -/* lwsl_hexdump(&buf[-pre], len + post); */ - case LWS_WRITE_HTTP: - case LWS_WRITE_PONG: - case LWS_WRITE_PING: - return lws_issue_raw(wsi, (unsigned char *)buf - pre, - len + pre + post); - default: - break; - } - - wsi->u.ws.inside_frame = 1; - - /* - * give any active extensions a chance to munge the buffer - * before send. We pass in a pointer to an lws_tokens struct - * prepared with the default buffer and content length that's in - * there. Rather than rewrite the default buffer, extensions - * that expect to grow the buffer can adapt .token to - * point to their own per-connection buffer in the extension - * user allocation. By default with no extensions or no - * extension callback handling, just the normal input buffer is - * used then so it is efficient. - * - * callback returns 1 in case it wants to spill more buffers - * - * This takes care of holding the buffer if send is incomplete, ie, - * if wsi->u.ws.clean_buffer is 0 (meaning an extension meddled with - * the buffer). If wsi->u.ws.clean_buffer is 1, it will instead - * return to the user code how much OF THE USER BUFFER was consumed. - */ - - n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post); - if (n <= 0) - return n; - - if (n == len + pre + post) { - /* everything in the buffer was handled (or rebuffered...) */ - wsi->u.ws.inside_frame = 0; - return orig_len; - } - - /* - * it is how many bytes of user buffer got sent... may be < orig_len - * in which case callback when writable has already been arranged - * and user code can call libwebsocket_write() again with the rest - * later. - */ - - return n - (pre + post); -} - -LWS_VISIBLE int libwebsockets_serve_http_file_fragment( - struct libwebsocket_context *context, struct libwebsocket *wsi) -{ - int n; - int m; - - while (!lws_send_pipe_choked(wsi)) { - - if (wsi->truncated_send_len) { - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from libwebsockets_serve_http_file_fragment\n"); - return -1; - } - continue; - } - - if (wsi->u.http.filepos == wsi->u.http.filelen) - goto all_sent; - - compatible_file_read(n, wsi->u.http.fd, context->service_buffer, - sizeof(context->service_buffer)); - if (n < 0) - return -1; /* caller will close */ - if (n) { - m = libwebsocket_write(wsi, context->service_buffer, n, - LWS_WRITE_HTTP); - if (m < 0) - return -1; - - wsi->u.http.filepos += m; - if (m != n) - /* adjust for what was not sent */ - compatible_file_seek_cur(wsi->u.http.fd, m - n); - } -all_sent: - if (!wsi->truncated_send_len && - wsi->u.http.filepos == wsi->u.http.filelen) { - wsi->state = WSI_STATE_HTTP; - - if (wsi->protocol->callback) - /* ignore callback returned value */ - user_callback_handle_rxflow( - wsi->protocol->callback, context, wsi, - LWS_CALLBACK_HTTP_FILE_COMPLETION, - wsi->user_space, NULL, 0); - return 1; /* >0 indicates completed */ - } - } - - lwsl_info("choked before able to send whole file (post)\n"); - libwebsocket_callback_on_writable(context, wsi); - - return 0; /* indicates further processing must be done */ -} - -LWS_VISIBLE int -lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) -{ - int n; - - n = recv(wsi->sock, buf, len, 0); - if (n >= 0) - return n; - - lwsl_warn("error on reading from skt\n"); - return LWS_SSL_CAPABLE_ERROR; -} - -LWS_VISIBLE int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) -{ - int n; - - n = send(wsi->sock, buf, len, 0); - if (n >= 0) - return n; - - if (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK || - LWS_ERRNO == LWS_EINTR) { - if (LWS_ERRNO == LWS_EWOULDBLOCK) - lws_set_blocking_send(wsi); - - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - lwsl_debug("ERROR writing len %d to skt %d\n", len, n); - return LWS_SSL_CAPABLE_ERROR; -} diff --git a/core/deps/libwebsocket/parsers.c b/core/deps/libwebsocket/parsers.c deleted file mode 100644 index 00f77bb2c..000000000 --- a/core/deps/libwebsocket/parsers.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -unsigned char lextable[] = { - #include "lextable.h" -}; - -#define FAIL_CHAR 0x08 - -int lextable_decode(int pos, char c) -{ - - c = tolower(c); - - while (1) { - if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */ - if ((lextable[pos] & 0x7f) != c) - return -1; - /* fall thru */ - pos++; - if (lextable[pos] == FAIL_CHAR) - return -1; - return pos; - } - /* b7 = 0, end or 3-byte */ - if (lextable[pos] < FAIL_CHAR) /* terminal marker */ - return pos; - - if (lextable[pos] == c) /* goto */ - return pos + (lextable[pos + 1]) + - (lextable[pos + 2] << 8); - /* fall thru goto */ - pos += 3; - /* continue */ - } -} - -int lws_allocate_header_table(struct libwebsocket *wsi) -{ - wsi->u.hdr.ah = malloc(sizeof(*wsi->u.hdr.ah)); - if (wsi->u.hdr.ah == NULL) { - lwsl_err("Out of memory\n"); - return -1; - } - memset(wsi->u.hdr.ah->frag_index, 0, sizeof(wsi->u.hdr.ah->frag_index)); - wsi->u.hdr.ah->next_frag_index = 0; - wsi->u.hdr.ah->pos = 0; - - return 0; -} - -LWS_VISIBLE int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h) -{ - int n; - int len = 0; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return 0; - do { - len += wsi->u.hdr.ah->frags[n].len; - n = wsi->u.hdr.ah->frags[n].next_frag_index; - } while (n); - - return len; -} - -LWS_VISIBLE int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len, - enum lws_token_indexes h) -{ - int toklen = lws_hdr_total_length(wsi, h); - int n; - - if (toklen >= len) - return -1; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return 0; - - do { - strcpy(dest, - &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]); - dest += wsi->u.hdr.ah->frags[n].len; - n = wsi->u.hdr.ah->frags[n].next_frag_index; - } while (n); - - return toklen; -} - -char *lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h) -{ - int n; - - n = wsi->u.hdr.ah->frag_index[h]; - if (!n) - return NULL; - - return &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]; -} - -int lws_hdr_simple_create(struct libwebsocket *wsi, - enum lws_token_indexes h, const char *s) -{ - wsi->u.hdr.ah->next_frag_index++; - if (wsi->u.hdr.ah->next_frag_index == - sizeof(wsi->u.hdr.ah->frags) / sizeof(wsi->u.hdr.ah->frags[0])) { - lwsl_warn("More hdr frags than we can deal with, dropping\n"); - return -1; - } - - wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->next_frag_index; - - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].next_frag_index = - 0; - - do { - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_err("Ran out of header data space\n"); - return -1; - } - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s; - if (*s) - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].len++; - } while (*s++); - - return 0; -} - -static char char_to_hex(const char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - return -1; -} - -static int issue_char(struct libwebsocket *wsi, unsigned char c) -{ - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_warn("excessive header content\n"); - return -1; - } - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c; - if (c) - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; - - return 0; -} - -int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) -{ - int n; - - switch (wsi->u.hdr.parser_state) { - case WSI_TOKEN_GET_URI: - case WSI_TOKEN_POST_URI: - case WSI_TOKEN_HOST: - case WSI_TOKEN_CONNECTION: - case WSI_TOKEN_KEY1: - case WSI_TOKEN_KEY2: - case WSI_TOKEN_PROTOCOL: - case WSI_TOKEN_UPGRADE: - case WSI_TOKEN_ORIGIN: - case WSI_TOKEN_SWORIGIN: - case WSI_TOKEN_DRAFT: - case WSI_TOKEN_CHALLENGE: - case WSI_TOKEN_KEY: - case WSI_TOKEN_VERSION: - case WSI_TOKEN_ACCEPT: - case WSI_TOKEN_NONCE: - case WSI_TOKEN_EXTENSIONS: - case WSI_TOKEN_HTTP: - case WSI_TOKEN_HTTP_ACCEPT: - case WSI_TOKEN_HTTP_IF_MODIFIED_SINCE: - case WSI_TOKEN_HTTP_ACCEPT_ENCODING: - case WSI_TOKEN_HTTP_ACCEPT_LANGUAGE: - case WSI_TOKEN_HTTP_PRAGMA: - case WSI_TOKEN_HTTP_CACHE_CONTROL: - case WSI_TOKEN_HTTP_AUTHORIZATION: - case WSI_TOKEN_HTTP_COOKIE: - case WSI_TOKEN_HTTP_CONTENT_LENGTH: - case WSI_TOKEN_HTTP_CONTENT_TYPE: - case WSI_TOKEN_HTTP_DATE: - case WSI_TOKEN_HTTP_RANGE: - case WSI_TOKEN_HTTP_REFERER: - - - lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c); - - /* collect into malloc'd buffers */ - /* optional initial space swallow */ - if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->frag_index[ - wsi->u.hdr.parser_state]].len && c == ' ') - break; - - if ((wsi->u.hdr.parser_state != WSI_TOKEN_GET_URI) && (wsi->u.hdr.parser_state != WSI_TOKEN_POST_URI)) - goto check_eol; - - /* special URI processing... end at space */ - - if (c == ' ') { - /* enforce starting with / */ - if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len) - if (issue_char(wsi, '/') < 0) - return -1; - c = '\0'; - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - goto spill; - } - - /* special URI processing... convert %xx */ - - switch (wsi->u.hdr.ues) { - case URIES_IDLE: - if (c == '%') { - wsi->u.hdr.ues = URIES_SEEN_PERCENT; - goto swallow; - } - break; - case URIES_SEEN_PERCENT: - if (char_to_hex(c) < 0) { - /* regurgitate */ - if (issue_char(wsi, '%') < 0) - return -1; - wsi->u.hdr.ues = URIES_IDLE; - /* continue on to assess c */ - break; - } - wsi->u.hdr.esc_stash = c; - wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1; - goto swallow; - - case URIES_SEEN_PERCENT_H1: - if (char_to_hex(c) < 0) { - /* regurgitate */ - issue_char(wsi, '%'); - wsi->u.hdr.ues = URIES_IDLE; - /* regurgitate + assess */ - if (libwebsocket_parse(wsi, wsi->u.hdr.esc_stash) < 0) - return -1; - /* continue on to assess c */ - break; - } - c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) | - char_to_hex(c); - wsi->u.hdr.ues = URIES_IDLE; - break; - } - - /* - * special URI processing... - * convert /.. or /... or /../ etc to / - * convert /./ to / - * convert // or /// etc to / - * leave /.dir or whatever alone - */ - - switch (wsi->u.hdr.ups) { - case URIPS_IDLE: - /* issue the first / always */ - if (c == '/') - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - break; - case URIPS_SEEN_SLASH: - /* swallow subsequent slashes */ - if (c == '/') - goto swallow; - /* track and swallow the first . after / */ - if (c == '.') { - wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT; - goto swallow; - } else - wsi->u.hdr.ups = URIPS_IDLE; - break; - case URIPS_SEEN_SLASH_DOT: - /* swallow second . */ - if (c == '.') { - /* - * back up one dir level if possible - * safe against header fragmentation because - * the method URI can only be in 1 fragment - */ - if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 2) { - wsi->u.hdr.ah->pos--; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--; - do { - wsi->u.hdr.ah->pos--; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--; - } while (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 1 && - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos] != '/'); - } - wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT; - goto swallow; - } - /* change /./ to / */ - if (c == '/') { - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - goto swallow; - } - /* it was like /.dir ... regurgitate the . */ - wsi->u.hdr.ups = URIPS_IDLE; - issue_char(wsi, '.'); - break; - - case URIPS_SEEN_SLASH_DOT_DOT: - /* swallow prior .. chars and any subsequent . */ - if (c == '.') - goto swallow; - /* last issued was /, so another / == // */ - if (c == '/') - goto swallow; - else /* last we issued was / so SEEN_SLASH */ - wsi->u.hdr.ups = URIPS_SEEN_SLASH; - break; - case URIPS_ARGUMENTS: - /* leave them alone */ - break; - } - -check_eol: - - /* bail at EOL */ - if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE && - c == '\x0d') { - c = '\0'; - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - lwsl_parser("*\n"); - } - - if (c == '?') { /* start of URI arguments */ - /* seal off uri header */ - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0'; - - /* move to using WSI_TOKEN_HTTP_URI_ARGS */ - wsi->u.hdr.ah->next_frag_index++; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].next_frag_index = 0; - - wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = - wsi->u.hdr.ah->next_frag_index; - - /* defeat normal uri path processing */ - wsi->u.hdr.ups = URIPS_ARGUMENTS; - goto swallow; - } - -spill: - if (issue_char(wsi, c) < 0) - return -1; -swallow: - /* per-protocol end of headers management */ - - if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - break; - - /* collecting and checking a name part */ - case WSI_TOKEN_NAME_PART: - lwsl_parser("WSI_TOKEN_NAME_PART '%c'\n", c); - - wsi->u.hdr.lextable_pos = - lextable_decode(wsi->u.hdr.lextable_pos, c); - - if (wsi->u.hdr.lextable_pos < 0) { - /* this is not a header we know about */ - if (wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI] || wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] || - wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP]) { - /* - * altready had the method, no idea what - * this crap is, ignore - */ - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - break; - } - /* - * hm it's an unknown http method in fact, - * treat as dangerous - */ - - lwsl_info("Unknown method - dropping\n"); - return -1; - } - if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) { - - /* terminal state */ - - n = (lextable[wsi->u.hdr.lextable_pos] << 8) | lextable[wsi->u.hdr.lextable_pos + 1]; - - lwsl_parser("known hdr %d\n", n); - - if (n == WSI_TOKEN_GET_URI && - wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI]) { - lwsl_warn("Duplicated GET\n"); - return -1; - } else if (n == WSI_TOKEN_POST_URI && - wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI]) { - lwsl_warn("Duplicated POST\n"); - return -1; - } - - /* - * WSORIGIN is protocol equiv to ORIGIN, - * JWebSocket likes to send it, map to ORIGIN - */ - if (n == WSI_TOKEN_SWORIGIN) - n = WSI_TOKEN_ORIGIN; - - wsi->u.hdr.parser_state = (enum lws_token_indexes) - (WSI_TOKEN_GET_URI + n); - if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - - goto start_fragment; - } - break; - -start_fragment: - wsi->u.hdr.ah->next_frag_index++; - if (wsi->u.hdr.ah->next_frag_index == - sizeof(wsi->u.hdr.ah->frags) / - sizeof(wsi->u.hdr.ah->frags[0])) { - lwsl_warn("More hdr frags than we can deal with\n"); - return -1; - } - - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset = - wsi->u.hdr.ah->pos; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0; - wsi->u.hdr.ah->frags[ - wsi->u.hdr.ah->next_frag_index].next_frag_index = 0; - - n = wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state]; - if (!n) { /* first fragment */ - wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state] = - wsi->u.hdr.ah->next_frag_index; - break; - } - /* continuation */ - while (wsi->u.hdr.ah->frags[n].next_frag_index) - n = wsi->u.hdr.ah->frags[n].next_frag_index; - wsi->u.hdr.ah->frags[n].next_frag_index = - wsi->u.hdr.ah->next_frag_index; - - if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) { - lwsl_warn("excessive header content\n"); - return -1; - } - - wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = ' '; - wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++; - break; - - /* skipping arg part of a name we didn't recognize */ - case WSI_TOKEN_SKIPPING: - lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c); - - if (c == '\x0d') - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - break; - - case WSI_TOKEN_SKIPPING_SAW_CR: - lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c); - if (c == '\x0a') { - wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; - wsi->u.hdr.lextable_pos = 0; - } else - wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING; - break; - /* we're done, ignore anything else */ - - case WSI_PARSING_COMPLETE: - lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c); - break; - - default: /* keep gcc happy */ - break; - } - - return 0; - -set_parsing_complete: - - if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) { - if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION)) - wsi->ietf_spec_revision = - atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION)); - - lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision); - } - wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE; - wsi->hdr_parsing_completed = 1; - - return 0; -} - - -/** - * lws_frame_is_binary: true if the current frame was sent in binary mode - * - * @wsi: the connection we are inquiring about - * - * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if - * it's interested to see if the frame it's dealing with was sent in binary - * mode. - */ - -LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi) -{ - return wsi->u.ws.frame_is_binary; -} - -int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) -{ - int n; - struct lws_tokens eff_buf; - int ret = 0; - - switch (wsi->lws_rx_parse_state) { - case LWS_RXPS_NEW: - - switch (wsi->ietf_spec_revision) { - case 13: - /* - * no prepended frame key any more - */ - wsi->u.ws.all_zero_nonce = 1; - goto handle_first; - - default: - lwsl_warn("lws_rx_sm: unknown spec version %d\n", - wsi->ietf_spec_revision); - break; - } - break; - case LWS_RXPS_04_MASK_NONCE_1: - wsi->u.ws.frame_masking_nonce_04[1] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2; - break; - case LWS_RXPS_04_MASK_NONCE_2: - wsi->u.ws.frame_masking_nonce_04[2] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3; - break; - case LWS_RXPS_04_MASK_NONCE_3: - wsi->u.ws.frame_masking_nonce_04[3] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - - /* - * start from the zero'th byte in the XOR key buffer since - * this is the start of a frame with a new key - */ - - wsi->u.ws.frame_mask_index = 0; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1; - break; - - /* - * 04 logical framing from the spec (all this is masked when incoming - * and has to be unmasked) - * - * We ignore the possibility of extension data because we don't - * negotiate any extensions at the moment. - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-------+-+-------------+-------------------------------+ - * |F|R|R|R| opcode|R| Payload len | Extended payload length | - * |I|S|S|S| (4) |S| (7) | (16/63) | - * |N|V|V|V| |V| | (if payload len==126/127) | - * | |1|2|3| |4| | | - * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - * | Extended payload length continued, if payload len == 127 | - * + - - - - - - - - - - - - - - - +-------------------------------+ - * | | Extension data | - * +-------------------------------+ - - - - - - - - - - - - - - - + - * : : - * +---------------------------------------------------------------+ - * : Application data : - * +---------------------------------------------------------------+ - * - * We pass payload through to userland as soon as we get it, ignoring - * FIN. It's up to userland to buffer it up if it wants to see a - * whole unfragmented block of the original size (which may be up to - * 2^63 long!) - */ - - case LWS_RXPS_04_FRAME_HDR_1: -handle_first: - - wsi->u.ws.opcode = c & 0xf; - wsi->u.ws.rsv = c & 0x70; - wsi->u.ws.final = !!((c >> 7) & 1); - - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - wsi->u.ws.frame_is_binary = - wsi->u.ws.opcode == LWS_WS_OPCODE_07__BINARY_FRAME; - break; - } - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN: - - wsi->u.ws.this_frame_masked = !!(c & 0x80); - - switch (c & 0x7f) { - case 126: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; - break; - case 127: - /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; - break; - default: - wsi->u.ws.rx_packet_length = c & 0x7f; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - if (wsi->u.ws.rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->u.ws.rx_packet_length = c << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->u.ws.rx_packet_length |= c; - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_8: - if (c & 0x80) { - lwsl_warn("b63 of length must be zero\n"); - /* kill the connection */ - return -1; - } -#if defined __LP64__ - wsi->u.ws.rx_packet_length = ((size_t)c) << 56; -#else - wsi->u.ws.rx_packet_length = 0; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_7: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 48; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_6: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 40; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_5: -#if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 32; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 24; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 16; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->u.ws.rx_packet_length |= ((size_t)c); - if (wsi->u.ws.this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->u.ws.frame_masking_nonce_04[0] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->u.ws.frame_masking_nonce_04[1] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->u.ws.frame_masking_nonce_04[2] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->u.ws.frame_masking_nonce_04[3] = c; - if (c) - wsi->u.ws.all_zero_nonce = 0; - wsi->lws_rx_parse_state = - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - wsi->u.ws.frame_mask_index = 0; - if (wsi->u.ws.rx_packet_length == 0) { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - - - case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - - if (!wsi->u.ws.rx_user_buffer) - lwsl_err("NULL user buffer...\n"); - - if (wsi->u.ws.all_zero_nonce) - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = c; - else - wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + - (wsi->u.ws.rx_user_buffer_head++)] = - c ^ wsi->u.ws.frame_masking_nonce_04[ - (wsi->u.ws.frame_mask_index++) & 3]; - - if (--wsi->u.ws.rx_packet_length == 0) { - /* spill because we have the whole frame */ - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - - /* - * if there's no protocol max frame size given, we are - * supposed to default to LWS_MAX_SOCKET_IO_BUF - */ - - if (!wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - LWS_MAX_SOCKET_IO_BUF) - break; - else - if (wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_user_buffer_head != - wsi->protocol->rx_buffer_size) - break; - - /* spill because we filled our rx buffer */ -spill: - /* - * is this frame a control packet we should take care of at this - * layer? If so service it and hide it from the user callback - */ - - lwsl_parser("spill on %s\n", wsi->protocol->name); - - switch (wsi->u.ws.opcode) { - case LWS_WS_OPCODE_07__CLOSE: - /* is this an acknowledgement of our close? */ - if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) { - /* - * fine he has told us he is closing too, let's - * finish our close - */ - lwsl_parser("seen client close ack\n"); - return -1; - } - lwsl_parser("server sees client close packet\n"); - /* parrot the close packet payload back */ - n = libwebsocket_write(wsi, (unsigned char *) - &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head, - LWS_WRITE_CLOSE); - if (n < 0) - lwsl_info("write of close ack failed %d\n", n); - wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY; - /* close the connection */ - return -1; - - case LWS_WS_OPCODE_07__PING: - lwsl_info("received %d byte ping, sending pong\n", - wsi->u.ws.rx_user_buffer_head); - lwsl_hexdump(&wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head); - /* parrot the ping packet payload back as a pong */ - n = libwebsocket_write(wsi, (unsigned char *) - &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], - wsi->u.ws.rx_user_buffer_head, LWS_WRITE_PONG); - if (n < 0) - return -1; - /* ... then just drop it */ - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - - case LWS_WS_OPCODE_07__PONG: - /* ... then just drop it */ - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - - case LWS_WS_OPCODE_07__TEXT_FRAME: - case LWS_WS_OPCODE_07__BINARY_FRAME: - case LWS_WS_OPCODE_07__CONTINUATION: - break; - - default: - lwsl_parser("passing opc %x up to exts\n", - wsi->u.ws.opcode); - /* - * It's something special we can't understand here. - * Pass the payload up to the extension's parsing - * state machine. - */ - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX, - &eff_buf, 0) <= 0) /* not handle or fail */ - lwsl_ext("ext opc opcode 0x%x unknown\n", - wsi->u.ws.opcode); - - wsi->u.ws.rx_user_buffer_head = 0; - return 0; - } - - /* - * No it's real payload, pass it up to the user callback. - * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using libwebsocket_write - */ - - eff_buf.token = &wsi->u.ws.rx_user_buffer[ - LWS_SEND_BUFFER_PRE_PADDING]; - eff_buf.token_len = wsi->u.ws.rx_user_buffer_head; - - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PAYLOAD_RX, &eff_buf, 0) < 0) - return -1; - - if (eff_buf.token_len > 0) { - eff_buf.token[eff_buf.token_len] = '\0'; - - if (wsi->protocol->callback) - ret = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi->protocol->owning_server, - wsi, LWS_CALLBACK_RECEIVE, - wsi->user_space, - eff_buf.token, - eff_buf.token_len); - else - lwsl_err("No callback on payload spill!\n"); - } - - wsi->u.ws.rx_user_buffer_head = 0; - break; - } - - return ret; - -illegal_ctl_length: - - lwsl_warn("Control frame with xtended length is illegal\n"); - /* kill the connection */ - return -1; -} - - -/** - * libwebsockets_remaining_packet_payload() - Bytes to come before "overall" - * rx packet is complete - * @wsi: Websocket instance (available from user callback) - * - * This function is intended to be called from the callback if the - * user code is interested in "complete packets" from the client. - * libwebsockets just passes through payload as it comes and issues a buffer - * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE - * callback handler can use this API to find out if the buffer it has just - * been given is the last piece of a "complete packet" from the client -- - * when that is the case libwebsockets_remaining_packet_payload() will return - * 0. - * - * Many protocols won't care becuse their packets are always small. - */ - -LWS_VISIBLE size_t -libwebsockets_remaining_packet_payload(struct libwebsocket *wsi) -{ - return wsi->u.ws.rx_packet_length; -} diff --git a/core/deps/libwebsocket/pollfd.c b/core/deps/libwebsocket/pollfd.c deleted file mode 100644 index 3995a378a..000000000 --- a/core/deps/libwebsocket/pollfd.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; - - if (context->fds_count >= context->max_fds) { - lwsl_err("Too many fds (%d)\n", context->max_fds); - return 1; - } - - if (wsi->sock >= context->max_fds) { - lwsl_err("Socket fd %d is too high (%d)\n", - wsi->sock, context->max_fds); - return 1; - } - - assert(wsi); - assert(wsi->sock >= 0); - - lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n", - wsi, wsi->sock, context->fds_count); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0); - - context->lws_lookup[wsi->sock] = wsi; - wsi->position_in_fds_table = context->fds_count; - context->fds[context->fds_count].fd = wsi->sock; - context->fds[context->fds_count].events = LWS_POLLIN; - - lws_plat_insert_socket_into_fds(context, wsi); - - /* external POLL support via protocol 0 */ - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_ADD_POLL_FD, - wsi->user_space, (void *) &pa, 0); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *)&pa, 0); - - return 0; -} - -int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - int m; - struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 }; - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE); - - if (!--context->fds_count) { - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0); - goto do_ext; - } - - if (wsi->sock > context->max_fds) { - lwsl_err("Socket fd %d too high (%d)\n", - wsi->sock, context->max_fds); - return 1; - } - - lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__, - wsi, wsi->sock, wsi->position_in_fds_table); - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *)&pa, 0); - - m = wsi->position_in_fds_table; /* replace the contents for this */ - - /* have the last guy take up the vacant slot */ - context->fds[m] = context->fds[context->fds_count]; - - lws_plat_delete_socket_from_fds(context, wsi, m); - - /* - * end guy's fds_lookup entry remains unchanged - * (still same fd pointing to same wsi) - */ - /* end guy's "position in fds table" changed */ - context->lws_lookup[context->fds[context->fds_count].fd]-> - position_in_fds_table = m; - /* deletion guy's lws_lookup entry needs nuking */ - context->lws_lookup[wsi->sock] = NULL; - /* removed wsi has no position any more */ - wsi->position_in_fds_table = -1; - -do_ext: - /* remove also from external POLL support via protocol 0 */ - if (wsi->sock) { - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_DEL_POLL_FD, wsi->user_space, - (void *) &pa, 0); - } - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 0); - return 0; -} - -int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) -{ - struct libwebsocket_context *context = wsi->protocol->owning_server; - int tid; - int sampled_tid; - struct libwebsocket_pollfd *pfd; - struct libwebsocket_pollargs pa; - - pfd = &context->fds[wsi->position_in_fds_table]; - pa.fd = wsi->sock; - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0); - - pa.prev_events = pfd->events; - pa.events = pfd->events = (pfd->events & ~_and) | _or; - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - wsi->user_space, (void *) &pa, 0); - - /* - * if we changed something in this pollfd... - * ... and we're running in a different thread context - * than the service thread... - * ... and the service thread is waiting ... - * then cancel it to force a restart with our changed events - */ - if (pa.prev_events != pa.events) { - - if (lws_plat_change_pollfd(context, wsi, pfd)) { - lwsl_info("%s failed\n", __func__); - return 1; - } - - sampled_tid = context->service_tid; - if (sampled_tid) { - tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - if (tid != sampled_tid) - libwebsocket_cancel_service(context); - } - } - - context->protocols[0].callback(context, wsi, - LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0); - - return 0; -} - - -/** - * libwebsocket_callback_on_writable() - Request a callback when this socket - * becomes able to be written to without - * blocking - * - * @context: libwebsockets context - * @wsi: Websocket connection instance to get callback for - */ - -LWS_VISIBLE int -libwebsocket_callback_on_writable(struct libwebsocket_context *context, - struct libwebsocket *wsi) -{ - if (lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, NULL, 0)) - return 1; - - if (wsi->position_in_fds_table < 0) { - lwsl_err("%s: failed to find socket %d\n", __func__, wsi->sock); - return -1; - } - - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) - return -1; - - lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_WRITE); - - return 1; -} - -/** - * libwebsocket_callback_on_writable_all_protocol() - Request a callback for - * all connections using the given protocol when it - * becomes possible to write to each socket without - * blocking in turn. - * - * @protocol: Protocol whose connections will get callbacks - */ - -LWS_VISIBLE int -libwebsocket_callback_on_writable_all_protocol( - const struct libwebsocket_protocols *protocol) -{ - struct libwebsocket_context *context = protocol->owning_server; - int n; - struct libwebsocket *wsi; - - for (n = 0; n < context->fds_count; n++) { - wsi = context->lws_lookup[context->fds[n].fd]; - if (!wsi) - continue; - if (wsi->protocol == protocol) - libwebsocket_callback_on_writable(context, wsi); - } - - return 0; -} diff --git a/core/deps/libwebsocket/private-libwebsockets.h b/core/deps/libwebsocket/private-libwebsockets.h deleted file mode 100644 index 3069f997d..000000000 --- a/core/deps/libwebsocket/private-libwebsockets.h +++ /dev/null @@ -1,916 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -#pragma once -#include "build.h" - -/* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "1.3" - -/* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "c11b847" - - -/* System introspection configs */ -#ifdef CMAKE_BUILD -#include "lws_config.h" -#else -#if HOST_OS == OS_WINDOWS -#define inline __inline -#else /* not WIN32 */ -#include "config.h" - -#endif /* not WIN32 */ -#endif /* not CMAKE */ - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#if defined(WIN32) || defined(_WIN32) -#define LWS_NO_DAEMONIZE -#define LWS_ERRNO WSAGetLastError() -#define LWS_EAGAIN WSAEWOULDBLOCK -#define LWS_EALREADY WSAEALREADY -#define LWS_EINPROGRESS WSAEINPROGRESS -#define LWS_EINTR WSAEINTR -#define LWS_EISCONN WSAEISCONN -#define LWS_EWOULDBLOCK WSAEWOULDBLOCK -#define LWS_POLLHUP (FD_CLOSE) -#define LWS_POLLIN (FD_READ | FD_ACCEPT) -#define LWS_POLLOUT (FD_WRITE) -#define MSG_NOSIGNAL 0 -#define SHUT_RDWR SD_BOTH -#define SOL_TCP IPPROTO_TCP - -#define compatible_close(fd) closesocket(fd) -#define compatible_file_close(fd) CloseHandle(fd) -#define compatible_file_seek_cur(fd, offset) SetFilePointer(fd, offset, NULL, FILE_CURRENT) -#define compatible_file_read(amount, fd, buf, len) {\ - DWORD _amount; \ - if (!ReadFile(fd, buf, len, &_amount, NULL)) \ - amount = -1; \ - else \ - amount = _amount; \ - } -#define lws_set_blocking_send(wsi) wsi->sock_send_blocking = TRUE -#include -#include -#include -#ifdef HAVE_IN6ADDR_H -#include -#endif -#include - -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif - -#ifdef _WIN32_WCE -#define vsnprintf _vsnprintf -#endif - -#define LWS_INVALID_FILE INVALID_HANDLE_VALUE -#else /* not windows --> */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef LWS_BUILTIN_GETIFADDRS - #include "deps/ifaddrs/ifaddrs.h" -#else - #include -#endif -//#include -#include -#include -#include -#ifndef LWS_NO_FORK -#ifdef HAVE_SYS_PRCTL_H -#include -#endif -#endif -#include -#include -#include -#include -#ifdef LWS_USE_LIBEV -#include -#endif /* LWS_USE_LIBEV */ - -#include -#include - -#define LWS_ERRNO errno -#define LWS_EAGAIN EAGAIN -#define LWS_EALREADY EALREADY -#define LWS_EINPROGRESS EINPROGRESS -#define LWS_EINTR EINTR -#define LWS_EISCONN EISCONN -#define LWS_EWOULDBLOCK EWOULDBLOCK -#define LWS_INVALID_FILE -1 -#define LWS_POLLHUP (POLLHUP|POLLERR) -#define LWS_POLLIN (POLLIN) -#define LWS_POLLOUT (POLLOUT) -#define compatible_close(fd) close(fd) -#define compatible_file_close(fd) close(fd) -#define compatible_file_seek_cur(fd, offset) lseek(fd, offset, SEEK_CUR) -#define compatible_file_read(amount, fd, buf, len) \ - amount = read(fd, buf, len); -#define lws_set_blocking_send(wsi) -#endif - -#ifndef HAVE_BZERO -#define bzero(b, len) (memset((b), '\0', (len)), (void) 0) -#endif - -#ifndef HAVE_STRERROR -#define strerror(x) "" -#endif - -#ifdef LWS_OPENSSL_SUPPORT -#ifdef USE_CYASSL -#include -#include -unsigned char * -SHA1(const unsigned char *d, size_t n, unsigned char *md); -#else -#include -#include -#include -#include -#include -#endif /* not USE_CYASSL */ -#endif - -#include "libwebsockets.h" - -#if defined(WIN32) || defined(_WIN32) - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */ -#endif -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif -typedef unsigned __int64 u_int64_t; - -#undef __P -#ifndef __P -#if __STDC__ -#define __P(protos) protos -#else -#define __P(protos) () -#endif -#endif - -#else - -#include -#include - -#if defined(__APPLE__) -#include -#elif defined(__FreeBSD__) -#include -#elif defined(__linux__) -#include -#endif - -#if !defined(BYTE_ORDER) -# define BYTE_ORDER __BYTE_ORDER -#endif -#if !defined(LITTLE_ENDIAN) -# define LITTLE_ENDIAN __LITTLE_ENDIAN -#endif -#if !defined(BIG_ENDIAN) -# define BIG_ENDIAN __BIG_ENDIAN -#endif - -#endif - -/* - * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag, - * but happily have something equivalent in the SO_NOSIGPIPE flag. - */ -#ifdef __APPLE__ -#define MSG_NOSIGNAL SO_NOSIGPIPE -#endif - -#ifndef LWS_MAX_HEADER_LEN -#define LWS_MAX_HEADER_LEN 1024 -#endif -#ifndef LWS_MAX_PROTOCOLS -#define LWS_MAX_PROTOCOLS 5 -#endif -#ifndef LWS_MAX_EXTENSIONS_ACTIVE -#define LWS_MAX_EXTENSIONS_ACTIVE 3 -#endif -#ifndef SPEC_LATEST_SUPPORTED -#define SPEC_LATEST_SUPPORTED 13 -#endif -#ifndef AWAITING_TIMEOUT -#define AWAITING_TIMEOUT 5 -#endif -#ifndef CIPHERS_LIST_STRING -#define CIPHERS_LIST_STRING "DEFAULT" -#endif -#ifndef LWS_SOMAXCONN -#define LWS_SOMAXCONN SOMAXCONN -#endif - -#define MAX_WEBSOCKET_04_KEY_LEN 128 -#define LWS_MAX_SOCKET_IO_BUF 4096 - -#ifndef SYSTEM_RANDOM_FILEPATH -#define SYSTEM_RANDOM_FILEPATH "/dev/urandom" -#endif -#ifndef LWS_MAX_ZLIB_CONN_BUFFER -#define LWS_MAX_ZLIB_CONN_BUFFER (64 * 1024) -#endif - -/* - * if not in a connection storm, check for incoming - * connections this many normal connection services - */ -#define LWS_LISTEN_SERVICE_MODULO 10 - -enum lws_websocket_opcodes_07 { - LWS_WS_OPCODE_07__CONTINUATION = 0, - LWS_WS_OPCODE_07__TEXT_FRAME = 1, - LWS_WS_OPCODE_07__BINARY_FRAME = 2, - - LWS_WS_OPCODE_07__NOSPEC__MUX = 7, - - /* control extensions 8+ */ - - LWS_WS_OPCODE_07__CLOSE = 8, - LWS_WS_OPCODE_07__PING = 9, - LWS_WS_OPCODE_07__PONG = 0xa, -}; - - -enum lws_connection_states { - WSI_STATE_HTTP, - WSI_STATE_HTTP_ISSUING_FILE, - WSI_STATE_HTTP_HEADERS, - WSI_STATE_HTTP_BODY, - WSI_STATE_DEAD_SOCKET, - WSI_STATE_ESTABLISHED, - WSI_STATE_CLIENT_UNCONNECTED, - WSI_STATE_RETURNED_CLOSE_ALREADY, - WSI_STATE_AWAITING_CLOSE_ACK, - WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE, -}; - -enum lws_rx_parse_state { - LWS_RXPS_NEW, - - LWS_RXPS_04_MASK_NONCE_1, - LWS_RXPS_04_MASK_NONCE_2, - LWS_RXPS_04_MASK_NONCE_3, - - LWS_RXPS_04_FRAME_HDR_1, - LWS_RXPS_04_FRAME_HDR_LEN, - LWS_RXPS_04_FRAME_HDR_LEN16_2, - LWS_RXPS_04_FRAME_HDR_LEN16_1, - LWS_RXPS_04_FRAME_HDR_LEN64_8, - LWS_RXPS_04_FRAME_HDR_LEN64_7, - LWS_RXPS_04_FRAME_HDR_LEN64_6, - LWS_RXPS_04_FRAME_HDR_LEN64_5, - LWS_RXPS_04_FRAME_HDR_LEN64_4, - LWS_RXPS_04_FRAME_HDR_LEN64_3, - LWS_RXPS_04_FRAME_HDR_LEN64_2, - LWS_RXPS_04_FRAME_HDR_LEN64_1, - - LWS_RXPS_07_COLLECT_FRAME_KEY_1, - LWS_RXPS_07_COLLECT_FRAME_KEY_2, - LWS_RXPS_07_COLLECT_FRAME_KEY_3, - LWS_RXPS_07_COLLECT_FRAME_KEY_4, - - LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED -}; - - -enum connection_mode { - LWS_CONNMODE_HTTP_SERVING, - LWS_CONNMODE_HTTP_SERVING_ACCEPTED, /* actual HTTP service going on */ - LWS_CONNMODE_PRE_WS_SERVING_ACCEPT, - - LWS_CONNMODE_WS_SERVING, - LWS_CONNMODE_WS_CLIENT, - - /* transient, ssl delay hiding */ - LWS_CONNMODE_SSL_ACK_PENDING, - - /* transient modes */ - LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT, - LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY, - LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE, - LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2, - LWS_CONNMODE_WS_CLIENT_WAITING_SSL, - LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY, - LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT, - LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD, - - /* special internal types */ - LWS_CONNMODE_SERVER_LISTENER, -}; - -enum { - LWS_RXFLOW_ALLOW = (1 << 0), - LWS_RXFLOW_PENDING_CHANGE = (1 << 1), -}; - -struct libwebsocket_protocols; -struct libwebsocket; - -#ifdef LWS_USE_LIBEV -struct lws_io_watcher { - struct ev_io watcher; - struct libwebsocket_context* context; -}; - -struct lws_signal_watcher { - struct ev_signal watcher; - struct libwebsocket_context* context; -}; -#endif /* LWS_USE_LIBEV */ - -struct libwebsocket_context { -#ifdef _WIN32 - WSAEVENT *events; -#endif - struct libwebsocket_pollfd *fds; - struct libwebsocket **lws_lookup; /* fd to wsi */ - int fds_count; -#ifdef LWS_USE_LIBEV - struct ev_loop* io_loop; - struct lws_io_watcher w_accept; - struct lws_signal_watcher w_sigint; -#endif /* LWS_USE_LIBEV */ - int max_fds; - int listen_port; - const char *iface; - char http_proxy_address[128]; - char canonical_hostname[128]; - unsigned int http_proxy_port; - unsigned int options; - time_t last_timeout_check_s; - - /* - * usable by anything in the service code, but only if the scope - * does not last longer than the service action (since next service - * of any socket can likewise use it and overwrite) - */ - unsigned char service_buffer[LWS_MAX_SOCKET_IO_BUF]; - - int started_with_parent; - - int fd_random; - int listen_service_modulo; - int listen_service_count; - int listen_service_fd; - int listen_service_extraseen; - - /* - * set to the Thread ID that's doing the service loop just before entry - * to poll indicates service thread likely idling in poll() - * volatile because other threads may check it as part of processing - * for pollfd event change. - */ - volatile int service_tid; -#ifndef _WIN32 - int dummy_pipe_fds[2]; -#endif - - int ka_time; - int ka_probes; - int ka_interval; - -#ifdef LWS_LATENCY - unsigned long worst_latency; - char worst_latency_info[256]; -#endif - -#ifdef LWS_OPENSSL_SUPPORT - int use_ssl; - int allow_non_ssl_on_ssl_port; - SSL_CTX *ssl_ctx; - SSL_CTX *ssl_client_ctx; -#endif - struct libwebsocket_protocols *protocols; - int count_protocols; -#ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension *extensions; -#endif - void *user_space; -}; - -enum { - LWS_EV_READ = (1 << 0), - LWS_EV_WRITE = (1 << 1), - LWS_EV_START = (1 << 2), - LWS_EV_STOP = (1 << 3), -}; - -#ifdef LWS_USE_LIBEV -#define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV) -LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info); -LWS_EXTERN void -lws_libev_accept(struct libwebsocket_context *context, - struct libwebsocket *new_wsi, int accept_fd); -LWS_EXTERN void -lws_libev_io(struct libwebsocket_context *context, - struct libwebsocket *wsi, int flags); -LWS_EXTERN int -lws_libev_init_fd_table(struct libwebsocket_context *context); -LWS_EXTERN void -lws_libev_run(struct libwebsocket_context *context); -#else -#define LWS_LIBEV_ENABLED(context) (0) -#define lws_feature_status_libev(_a) \ - lwsl_notice("libev support not compiled in\n") -#define lws_libev_accept(_a, _b, _c) (0) -#define lws_libev_io(_a, _b, _c) (0) -#define lws_libev_init_fd_table(_a) (0) -#define lws_libev_run(_a) (0) -#endif - -#ifdef LWS_USE_IPV6 -#define LWS_IPV6_ENABLED(context) (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6)) -#else -#define LWS_IPV6_ENABLED(context) (0) -#endif - -enum uri_path_states { - URIPS_IDLE, - URIPS_SEEN_SLASH, - URIPS_SEEN_SLASH_DOT, - URIPS_SEEN_SLASH_DOT_DOT, - URIPS_ARGUMENTS, -}; - -enum uri_esc_states { - URIES_IDLE, - URIES_SEEN_PERCENT, - URIES_SEEN_PERCENT_H1, -}; - -/* - * This is totally opaque to code using the library. It's exported as a - * forward-reference pointer-only declaration; the user can use the pointer with - * other APIs to get information out of it. - */ - -struct lws_fragments { - unsigned short offset; - unsigned short len; - unsigned char next_frag_index; -}; - -struct allocated_headers { - unsigned short next_frag_index; - unsigned short pos; - unsigned char frag_index[WSI_TOKEN_COUNT]; - struct lws_fragments frags[WSI_TOKEN_COUNT * 2]; - char data[LWS_MAX_HEADER_LEN]; -#ifndef LWS_NO_CLIENT - char initial_handshake_hash_base64[30]; - unsigned short c_port; -#endif -}; - -struct _lws_http_mode_related { - struct allocated_headers *ah; /* mirroring _lws_header_related */ -#if defined(WIN32) || defined(_WIN32) - HANDLE fd; -#else - int fd; -#endif - unsigned long filepos; - unsigned long filelen; - - int content_length; - int content_length_seen; - int body_index; - unsigned char *post_buffer; -}; - -struct _lws_header_related { - struct allocated_headers *ah; - short lextable_pos; - unsigned char parser_state; /* enum lws_token_indexes */ - enum uri_path_states ups; - enum uri_esc_states ues; - char esc_stash; -}; - -struct _lws_websocket_related { - char *rx_user_buffer; - int rx_user_buffer_head; - unsigned char frame_masking_nonce_04[4]; - unsigned char frame_mask_index; - size_t rx_packet_length; - unsigned char opcode; - unsigned int final:1; - unsigned char rsv; - unsigned int frame_is_binary:1; - unsigned int all_zero_nonce:1; - short close_reason; /* enum lws_close_status */ - unsigned char *rxflow_buffer; - int rxflow_len; - int rxflow_pos; - unsigned int rxflow_change_to:2; - unsigned int this_frame_masked:1; - unsigned int inside_frame:1; /* next write will be more of frame */ - unsigned int clean_buffer:1; /* buffer not rewritten by extension */ -}; - -struct libwebsocket { - - /* lifetime members */ - -#ifdef LWS_USE_LIBEV - struct lws_io_watcher w_read; - struct lws_io_watcher w_write; -#endif /* LWS_USE_LIBEV */ - const struct libwebsocket_protocols *protocol; -#ifndef LWS_NO_EXTENSIONS - struct libwebsocket_extension * - active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; - void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE]; - unsigned char count_active_extensions; - unsigned int extension_data_pending:1; -#endif - unsigned char ietf_spec_revision; - - char mode; /* enum connection_mode */ - char state; /* enum lws_connection_states */ - char lws_rx_parse_state; /* enum lws_rx_parse_state */ - char rx_frame_type; /* enum libwebsocket_write_protocol */ - - unsigned int hdr_parsing_completed:1; - - char pending_timeout; /* enum pending_timeout */ - time_t pending_timeout_limit; - - int sock; - int position_in_fds_table; -#ifdef LWS_LATENCY - unsigned long action_start; - unsigned long latency_start; -#endif - - /* truncated send handling */ - unsigned char *truncated_send_malloc; /* non-NULL means buffering in progress */ - unsigned int truncated_send_allocation; /* size of malloc */ - unsigned int truncated_send_offset; /* where we are in terms of spilling */ - unsigned int truncated_send_len; /* how much is buffered */ - - void *user_space; - - /* members with mutually exclusive lifetimes are unionized */ - - union u { - struct _lws_http_mode_related http; - struct _lws_header_related hdr; - struct _lws_websocket_related ws; - } u; - -#ifdef LWS_OPENSSL_SUPPORT - SSL *ssl; - BIO *client_bio; - unsigned int use_ssl:2; -#endif - -#ifdef _WIN32 - BOOL sock_send_blocking; -#endif -}; - -LWS_EXTERN int log_level; - -LWS_EXTERN void -libwebsocket_close_and_free_session(struct libwebsocket_context *context, - struct libwebsocket *wsi, enum lws_close_status); - -LWS_EXTERN int -remove_wsi_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -#ifndef LWS_LATENCY -static inline void lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion) { while (0); } -static inline void lws_latency_pre(struct libwebsocket_context *context, - struct libwebsocket *wsi) { while (0); } -#else -#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0) -extern void -lws_latency(struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *action, - int ret, int completion); -#endif - -LWS_EXTERN int -libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -libwebsocket_parse(struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -lws_b64_selftest(void); - -LWS_EXTERN struct libwebsocket * -wsi_from_fd(struct libwebsocket_context *context, int fd); - -LWS_EXTERN int -insert_wsi_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN int -lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len); - - -LWS_EXTERN int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec); - -LWS_EXTERN struct libwebsocket * -libwebsocket_client_connect_2(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context); - -LWS_EXTERN char * -libwebsockets_generate_client_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char *pkt); - -LWS_EXTERN int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); -/* - * EXTENSIONS - */ - -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE void -lws_context_init_extensions(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -LWS_EXTERN int -lws_any_extension_handled(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_extension_callback_reasons r, - void *v, size_t len); - -LWS_EXTERN int -lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason, - void *buf, int len); -LWS_EXTERN int -lws_ext_callback_for_each_extension_type( - struct libwebsocket_context *context, struct libwebsocket *wsi, - int reason, void *arg, int len); -#else -#define lws_any_extension_handled(_a, _b, _c, _d, _e) (0) -#define lws_ext_callback_for_each_active(_a, _b, _c, _d) (0) -#define lws_ext_callback_for_each_extension_type(_a, _b, _c, _d, _e) (0) -#define lws_issue_raw_ext_access lws_issue_raw -#define lws_context_init_extensions(_a, _b) -#endif - -LWS_EXTERN int -lws_client_interpret_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi); - -LWS_EXTERN int -libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c); - -LWS_EXTERN int -lws_issue_raw_ext_access(struct libwebsocket *wsi, - unsigned char *buf, size_t len); - -LWS_EXTERN int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi); - -LWS_EXTERN int -user_callback_handle_rxflow(callback_function, - struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len); - -LWS_EXTERN int -lws_plat_set_socket_options(struct libwebsocket_context *context, int fd); - -LWS_EXTERN int -lws_allocate_header_table(struct libwebsocket *wsi); - -LWS_EXTERN char * -lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h); - -LWS_EXTERN int -lws_hdr_simple_create(struct libwebsocket *wsi, - enum lws_token_indexes h, const char *s); - -LWS_EXTERN int -libwebsocket_ensure_user_space(struct libwebsocket *wsi); - -LWS_EXTERN int -lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or); - -#ifndef LWS_NO_SERVER -int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -LWS_EXTERN int handshake_0405(struct libwebsocket_context *context, - struct libwebsocket *wsi); -LWS_EXTERN int -libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len); -LWS_EXTERN void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info); -#else -#define lws_context_init_server(_a, _b) (0) -#define libwebsocket_interpret_incoming_packet(_a, _b, _c) (0) -#define lws_server_get_canonical_hostname(_a, _b) -#endif - -#ifndef LWS_NO_DAEMONIZE -LWS_EXTERN int get_daemonize_pid(); -#else -#define get_daemonize_pid() (0) -#endif - -LWS_EXTERN int interface_to_sa(struct libwebsocket_context *context, - const char *ifname, struct sockaddr_in *addr, size_t addrlen); - -LWS_EXTERN void lwsl_emit_stderr(int level, const char *line); - -#ifdef _WIN32 -LWS_EXTERN HANDLE lws_plat_open_file(const char* filename, unsigned long* filelen); -#else -LWS_EXTERN int lws_plat_open_file(const char* filename, unsigned long* filelen); -#endif - -enum lws_ssl_capable_status { - LWS_SSL_CAPABLE_ERROR = -1, - LWS_SSL_CAPABLE_MORE_SERVICE = -2, -}; - -#ifndef LWS_OPENSSL_SUPPORT -#define LWS_SSL_ENABLED(context) (0) -unsigned char * -SHA1(const unsigned char *d, size_t n, unsigned char *md); -#define lws_context_init_server_ssl(_a, _b) (0) -#define lws_ssl_destroy(_a) -#define lws_context_init_http2_ssl(_a) -#define lws_ssl_pending(_a) (0) -#define lws_ssl_capable_read lws_ssl_capable_read_no_ssl -#define lws_ssl_capable_write lws_ssl_capable_write_no_ssl -#define lws_server_socket_service_ssl(_a, _b, _c, _d, _e) (0) -#define lws_ssl_close(_a) (0) -#define lws_ssl_context_destroy(_a) -#else -#define LWS_SSL_ENABLED(context) (context->use_ssl) -LWS_EXTERN int lws_ssl_pending(struct libwebsocket *wsi); -LWS_EXTERN int openssl_websocket_private_data_index; -LWS_EXTERN int -lws_ssl_capable_read(struct libwebsocket *wsi, unsigned char *buf, int len); - -LWS_EXTERN int -lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len); -LWS_EXTERN int -lws_server_socket_service_ssl(struct libwebsocket_context *context, - struct libwebsocket **wsi, struct libwebsocket *new_wsi, - int accept_fd, struct libwebsocket_pollfd *pollfd); -LWS_EXTERN int -lws_ssl_close(struct libwebsocket *wsi); -LWS_EXTERN void -lws_ssl_context_destroy(struct libwebsocket_context *context); -#ifndef LWS_NO_SERVER -LWS_EXTERN int -lws_context_init_server_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -#else -#define lws_context_init_server_ssl(_a, _b) (0) -#endif -LWS_EXTERN void -lws_ssl_destroy(struct libwebsocket_context *context); - -/* HTTP2-related */ - -#ifdef LWS_USE_HTTP2 -LWS_EXTERN void -lws_context_init_http2_ssl(struct libwebsocket_context *context); -#else -#define lws_context_init_http2_ssl(_a) -#endif -#endif - -LWS_EXTERN int -lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len); - -LWS_EXTERN int -lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len); - -#ifndef LWS_NO_CLIENT - LWS_EXTERN int lws_client_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); -#ifdef LWS_OPENSSL_SUPPORT - LWS_EXTERN int lws_context_init_client_ssl(struct lws_context_creation_info *info, - struct libwebsocket_context *context); -#else - #define lws_context_init_client_ssl(_a, _b) (0) -#endif - LWS_EXTERN int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len); - LWS_EXTERN void - libwebsockets_decode_ssl_error(void); -#else -#define lws_context_init_client_ssl(_a, _b) (0) -#define lws_handshake_client(_a, _b, _c) (0) -#endif -#ifndef LWS_NO_SERVER - LWS_EXTERN int lws_server_socket_service( - struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd); - LWS_EXTERN int _libwebsocket_rx_flow_control(struct libwebsocket *wsi); - LWS_EXTERN int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len); -#else -#define lws_server_socket_service(_a, _b, _c) (0) -#define _libwebsocket_rx_flow_control(_a) (0) -#define lws_handshake_server(_a, _b, _c, _d) (0) -#endif - -/* - * lws_plat_ - */ -LWS_EXTERN void -lws_plat_delete_socket_from_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi, int m); -LWS_EXTERN void -lws_plat_insert_socket_into_fds(struct libwebsocket_context *context, - struct libwebsocket *wsi); -LWS_EXTERN void -lws_plat_service_periodic(struct libwebsocket_context *context); - -LWS_EXTERN int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd); -LWS_EXTERN int -lws_plat_context_early_init(void); -LWS_EXTERN void -lws_plat_context_early_destroy(struct libwebsocket_context *context); -LWS_EXTERN void -lws_plat_context_late_destroy(struct libwebsocket_context *context); -LWS_EXTERN int -lws_poll_listen_fd(struct libwebsocket_pollfd *fd); -LWS_EXTERN int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms); -LWS_EXTERN int -lws_plat_init_fd_tables(struct libwebsocket_context *context); -LWS_EXTERN void -lws_plat_drop_app_privileges(struct lws_context_creation_info *info); -LWS_EXTERN unsigned long long -time_in_microseconds(void); -LWS_EXTERN const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt); diff --git a/core/deps/libwebsocket/server-handshake.c b/core/deps/libwebsocket/server-handshake.c deleted file mode 100644 index 56cf9a13e..000000000 --- a/core/deps/libwebsocket/server-handshake.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); } -#ifndef LWS_NO_EXTENSIONS -LWS_VISIBLE int -lws_extension_server_handshake(struct libwebsocket_context *context, - struct libwebsocket *wsi, char **p) -{ - int n; - char *c; - char ext_name[128]; - struct libwebsocket_extension *ext; - int ext_count = 0; - int more = 1; - - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list - */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) - return 0; - - /* - * break down the list of client extensions - * and go through them - */ - - if (lws_hdr_copy(wsi, (char *)context->service_buffer, - sizeof(context->service_buffer), - WSI_TOKEN_EXTENSIONS) < 0) - return 1; - - c = (char *)context->service_buffer; - lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c); - wsi->count_active_extensions = 0; - n = 0; - while (more) { - - if (*c && (*c != ',' && *c != ' ' && *c != '\t')) { - ext_name[n] = *c++; - if (n < sizeof(ext_name) - 1) - n++; - continue; - } - ext_name[n] = '\0'; - if (!*c) - more = 0; - else { - c++; - if (!n) - continue; - } - - /* check a client's extension against our support */ - - ext = wsi->protocol->owning_server->extensions; - - while (ext && ext->callback) { - - if (strcmp(ext_name, ext->name)) { - ext++; - continue; - } - - /* - * oh, we do support this one he - * asked for... but let's ask user - * code if it's OK to apply it on this - * particular connection + protocol - */ - - n = wsi->protocol->owning_server-> - protocols[0].callback( - wsi->protocol->owning_server, - wsi, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - wsi->user_space, ext_name, 0); - - /* - * zero return from callback means - * go ahead and allow the extension, - * it's what we get if the callback is - * unhandled - */ - - if (n) { - ext++; - continue; - } - - /* apply it */ - - if (ext_count) - *(*p)++ = ','; - else - LWS_CPYAPP(*p, - "\x0d\x0aSec-WebSocket-Extensions: "); - *p += sprintf(*p, "%s", ext_name); - ext_count++; - - /* instantiate the extension on this conn */ - - wsi->active_extensions_user[ - wsi->count_active_extensions] = - malloc(ext->per_session_data_size); - if (wsi->active_extensions_user[ - wsi->count_active_extensions] == NULL) { - lwsl_err("Out of mem\n"); - return 1; - } - memset(wsi->active_extensions_user[ - wsi->count_active_extensions], 0, - ext->per_session_data_size); - - wsi->active_extensions[ - wsi->count_active_extensions] = ext; - - /* allow him to construct his context */ - - ext->callback(wsi->protocol->owning_server, - ext, wsi, - LWS_EXT_CALLBACK_CONSTRUCT, - wsi->active_extensions_user[ - wsi->count_active_extensions], NULL, 0); - - wsi->count_active_extensions++; - lwsl_parser("count_active_extensions <- %d\n", - wsi->count_active_extensions); - - ext++; - } - - n = 0; - } - - return 0; -} -#endif -int -handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi) -{ - unsigned char hash[20]; - int n; - char *response; - char *p; - int accept_len; - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) || - !lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) { - lwsl_parser("handshake_04 missing pieces\n"); - /* completed header processing, but missing some bits */ - goto bail; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >= - MAX_WEBSOCKET_04_KEY_LEN) { - lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN); - goto bail; - } - - /* - * since key length is restricted above (currently 128), cannot - * overflow - */ - n = sprintf((char *)context->service_buffer, - "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY)); - - SHA1(context->service_buffer, n, hash); - - accept_len = lws_b64_encode_string((char *)hash, 20, - (char *)context->service_buffer, - sizeof(context->service_buffer)); - if (accept_len < 0) { - lwsl_warn("Base64 encoded hash too long\n"); - goto bail; - } - - /* allocate the per-connection user memory (if any) */ - if (libwebsocket_ensure_user_space(wsi)) - goto bail; - - /* create the response packet */ - - /* make a buffer big enough for everything */ - - response = (char *)context->service_buffer + MAX_WEBSOCKET_04_KEY_LEN; - p = response; - LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a" - "Upgrade: WebSocket\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Sec-WebSocket-Accept: "); - strcpy(p, (char *)context->service_buffer); - p += accept_len; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) { - LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: "); - n = lws_hdr_copy(wsi, p, 128, WSI_TOKEN_PROTOCOL); - if (n < 0) - goto bail; - p += n; - } - -#ifndef LWS_NO_EXTENSIONS - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list - */ - if (lws_extension_server_handshake(context, wsi, &p)) - goto bail; -#endif - /* end of response packet */ - - LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a"); - - if (!lws_any_extension_handled(context, wsi, - LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX, - response, p - response)) { - - /* okay send the handshake response accepting the connection */ - - lwsl_parser("issuing resp pkt %d len\n", (int)(p - response)); -#ifdef DEBUG - fwrite(response, 1, p - response, stderr); -#endif - n = libwebsocket_write(wsi, (unsigned char *)response, - p - response, LWS_WRITE_HTTP); - if (n != (p - response)) { - lwsl_debug("handshake_0405: ERROR writing to socket\n"); - goto bail; - } - - } - - /* alright clean up and set ourselves into established state */ - - wsi->state = WSI_STATE_ESTABLISHED; - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - - /* notify user code that we're ready to roll */ - - if (wsi->protocol->callback) - wsi->protocol->callback(wsi->protocol->owning_server, - wsi, LWS_CALLBACK_ESTABLISHED, - wsi->user_space, NULL, 0); - - return 0; - - -bail: - /* free up his parsing allocations */ - - if (wsi->u.hdr.ah) - free(wsi->u.hdr.ah); - - return -1; -} - diff --git a/core/deps/libwebsocket/server.c b/core/deps/libwebsocket/server.c deleted file mode 100644 index bb9a1ae1f..000000000 --- a/core/deps/libwebsocket/server.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2013 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - - -#include "private-libwebsockets.h" - -int lws_context_init_server(struct lws_context_creation_info *info, - struct libwebsocket_context *context) -{ - int n; - int sockfd; - struct sockaddr_in sin; - socklen_t len = sizeof(sin); - int opt = 1; - struct libwebsocket *wsi; -#ifdef LWS_USE_IPV6 - struct sockaddr_in6 serv_addr6; -#endif - struct sockaddr_in serv_addr4; - struct sockaddr *v; - - /* set up our external listening socket we serve on */ - - if (info->port == CONTEXT_PORT_NO_LISTEN) - return 0; - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) - sockfd = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - sockfd = socket(AF_INET, SOCK_STREAM, 0); - - if (sockfd < 0) { - lwsl_err("ERROR opening socket\n"); - return 1; - } - - /* - * allow us to restart even if old sockets in TIME_WAIT - */ - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&opt, sizeof(opt)); - - lws_plat_set_socket_options(context, sockfd); - -#ifdef LWS_USE_IPV6 - if (LWS_IPV6_ENABLED(context)) { - v = (struct sockaddr *)&serv_addr6; - n = sizeof(struct sockaddr_in6); - bzero((char *) &serv_addr6, sizeof(serv_addr6)); - serv_addr6.sin6_addr = in6addr_any; - serv_addr6.sin6_family = AF_INET6; - serv_addr6.sin6_port = htons(info->port); - } else -#endif - { - v = (struct sockaddr *)&serv_addr4; - n = sizeof(serv_addr4); - bzero((char *) &serv_addr4, sizeof(serv_addr4)); - serv_addr4.sin_addr.s_addr = INADDR_ANY; - serv_addr4.sin_family = AF_INET; - serv_addr4.sin_port = htons(info->port); - - if (info->iface) { - if (interface_to_sa(context, info->iface, - (struct sockaddr_in *)v, n) < 0) { - lwsl_err("Unable to find interface %s\n", - info->iface); - compatible_close(sockfd); - return 1; - } - } - } /* ipv4 */ - - n = bind(sockfd, v, n); - if (n < 0) { - lwsl_err("ERROR on binding to port %d (%d %d)\n", - info->port, n, LWS_ERRNO); - compatible_close(sockfd); - return 1; - } - - if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1) - lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); - else - info->port = ntohs(sin.sin_port); - - context->listen_port = info->port; - - wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket)); - if (wsi == NULL) { - lwsl_err("Out of mem\n"); - compatible_close(sockfd); - return 1; - } - memset(wsi, 0, sizeof(struct libwebsocket)); - wsi->sock = sockfd; - wsi->mode = LWS_CONNMODE_SERVER_LISTENER; - - insert_wsi_socket_into_fds(context, wsi); - - context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO; - context->listen_service_count = 0; - context->listen_service_fd = sockfd; - - listen(sockfd, LWS_SOMAXCONN); - lwsl_notice(" Listening on port %d\n", info->port); - - return 0; -} - -int -_libwebsocket_rx_flow_control(struct libwebsocket *wsi) -{ - struct libwebsocket_context *context = wsi->protocol->owning_server; - - /* there is no pending change */ - if (!(wsi->u.ws.rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE)) - return 0; - - /* stuff is still buffered, not ready to really accept new input */ - if (wsi->u.ws.rxflow_buffer) { - /* get ourselves called back to deal with stashed buffer */ - libwebsocket_callback_on_writable(context, wsi); - return 0; - } - - /* pending is cleared, we can change rxflow state */ - - wsi->u.ws.rxflow_change_to &= ~LWS_RXFLOW_PENDING_CHANGE; - - lwsl_info("rxflow: wsi %p change_to %d\n", wsi, - wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW); - - /* adjust the pollfd for this wsi */ - - if (wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW) { - if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { - lwsl_info("%s: fail\n", __func__); - return -1; - } - } else - if (lws_change_pollfd(wsi, LWS_POLLIN, 0)) - return -1; - - return 0; -} - - -int lws_handshake_server(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned char **buf, size_t len) -{ - struct allocated_headers *ah; - char *uri_ptr = NULL; - int uri_len = 0; - char content_length_str[32]; - int n; - - /* LWS_CONNMODE_WS_SERVING */ - - while (len--) { - if (libwebsocket_parse(wsi, *(*buf)++)) { - lwsl_info("libwebsocket_parse failed\n"); - goto bail_nuke_ah; - } - - if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE) - continue; - - lwsl_parser("libwebsocket_parse sees parsing complete\n"); - - wsi->mode = LWS_CONNMODE_PRE_WS_SERVING_ACCEPT; - libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* is this websocket protocol or normal http 1.0? */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) || - !lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) { - - /* it's not websocket.... shall we accept it as http? */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) && - !lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - lwsl_warn("Missing URI in HTTP request\n"); - goto bail_nuke_ah; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) && - lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - lwsl_warn("GET and POST methods?\n"); - goto bail_nuke_ah; - } - - if (libwebsocket_ensure_user_space(wsi)) - goto bail_nuke_ah; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) { - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI); - lwsl_info("HTTP GET request for '%s'\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI)); - - } - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - lwsl_info("HTTP POST request for '%s'\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI)); - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI); - } - - /* - * Hm we still need the headers so the - * callback can look at leaders like the URI, but we - * need to transition to http union state.... hold a - * copy of u.hdr.ah and deallocate afterwards - */ - ah = wsi->u.hdr.ah; - - /* union transition */ - memset(&wsi->u, 0, sizeof(wsi->u)); - wsi->mode = LWS_CONNMODE_HTTP_SERVING_ACCEPTED; - wsi->state = WSI_STATE_HTTP; - wsi->u.http.fd = LWS_INVALID_FILE; - - /* expose it at the same offset as u.hdr */ - wsi->u.http.ah = ah; - - /* HTTP header had a content length? */ - - wsi->u.http.content_length = 0; - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) - wsi->u.http.content_length = 100 * 1024 * 1024; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - lws_hdr_copy(wsi, content_length_str, - sizeof(content_length_str) - 1, - WSI_TOKEN_HTTP_CONTENT_LENGTH); - wsi->u.http.content_length = atoi(content_length_str); - } - - if (wsi->u.http.content_length > 0) { - wsi->u.http.body_index = 0; - n = wsi->protocol->rx_buffer_size; - if (!n) - n = LWS_MAX_SOCKET_IO_BUF; - wsi->u.http.post_buffer = malloc(n); - if (!wsi->u.http.post_buffer) { - lwsl_err("Unable to allocate post buffer\n"); - n = -1; - goto cleanup; - } - } - - n = 0; - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_FILTER_HTTP_CONNECTION, - wsi->user_space, uri_ptr, uri_len); - - if (!n) { - /* - * if there is content supposed to be coming, - * put a timeout on it having arrived - */ - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_HTTP_CONTENT, - AWAITING_TIMEOUT); - - if (wsi->protocol->callback) - n = wsi->protocol->callback(context, wsi, - LWS_CALLBACK_HTTP, - wsi->user_space, uri_ptr, uri_len); - } - -cleanup: - /* now drop the header info we kept a pointer to */ - if (ah) - free(ah); - /* not possible to continue to use past here */ - wsi->u.http.ah = NULL; - - if (n) { - lwsl_info("LWS_CALLBACK_HTTP closing\n"); - return 1; /* struct ah ptr already nuked */ - } - - /* - * (if callback didn't start sending a file) - * deal with anything else as body, whether - * there was a content-length or not - */ - - if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) - wsi->state = WSI_STATE_HTTP_BODY; - return 2; /* goto http_postbody; */ - } - - if (!wsi->protocol) - lwsl_err("NULL protocol at libwebsocket_read\n"); - - /* - * It's websocket - * - * Make sure user side is happy about protocol - */ - - while (wsi->protocol->callback) { - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) { - if (wsi->protocol->name == NULL) - break; - } else - if (wsi->protocol->name && strcmp( - lws_hdr_simple_ptr(wsi, - WSI_TOKEN_PROTOCOL), - wsi->protocol->name) == 0) - break; - - wsi->protocol++; - } - - /* we didn't find a protocol he wanted? */ - - if (wsi->protocol->callback == NULL) { - if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL) == - NULL) { - lwsl_info("no protocol -> prot 0 handler\n"); - wsi->protocol = &context->protocols[0]; - } else { - lwsl_err("Req protocol %s not supported\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL)); - goto bail_nuke_ah; - } - } - - /* allocate wsi->user storage */ - if (libwebsocket_ensure_user_space(wsi)) - goto bail_nuke_ah; - - /* - * Give the user code a chance to study the request and - * have the opportunity to deny it - */ - - if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - wsi->user_space, - lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) { - lwsl_warn("User code denied connection\n"); - goto bail_nuke_ah; - } - - - /* - * Perform the handshake according to the protocol version the - * client announced - */ - - switch (wsi->ietf_spec_revision) { - case 13: - lwsl_parser("lws_parse calling handshake_04\n"); - if (handshake_0405(context, wsi)) { - lwsl_info("hs0405 has failed the connection\n"); - goto bail_nuke_ah; - } - break; - - default: - lwsl_warn("Unknown client spec version %d\n", - wsi->ietf_spec_revision); - goto bail_nuke_ah; - } - - /* drop the header info -- no bail_nuke_ah after this */ - - if (wsi->u.hdr.ah) - free(wsi->u.hdr.ah); - - wsi->mode = LWS_CONNMODE_WS_SERVING; - - /* union transition */ - memset(&wsi->u, 0, sizeof(wsi->u)); - wsi->u.ws.rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* - * create the frame buffer for this connection according to the - * size mentioned in the protocol definition. If 0 there, use - * a big default for compatibility - */ - - n = wsi->protocol->rx_buffer_size; - if (!n) - n = LWS_MAX_SOCKET_IO_BUF; - n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING; - wsi->u.ws.rx_user_buffer = malloc(n); - if (!wsi->u.ws.rx_user_buffer) { - lwsl_err("Out of Mem allocating rx buffer %d\n", n); - return 1; - } - lwsl_info("Allocating RX buffer %d\n", n); - - if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) { - lwsl_warn("Failed to set SNDBUF to %d", n); - return 1; - } - - lwsl_parser("accepted v%02d connection\n", - wsi->ietf_spec_revision); - } /* while all chars are handled */ - - return 0; - -bail_nuke_ah: - /* drop the header info */ - if (wsi->u.hdr.ah) - free(wsi->u.hdr.ah); - return 1; -} - -struct libwebsocket * -libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) -{ - struct libwebsocket *new_wsi; - - new_wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket)); - if (new_wsi == NULL) { - lwsl_err("Out of memory for new connection\n"); - return NULL; - } - - memset(new_wsi, 0, sizeof(struct libwebsocket)); - new_wsi->pending_timeout = NO_PENDING_TIMEOUT; - - /* intialize the instance struct */ - - new_wsi->state = WSI_STATE_HTTP; - new_wsi->mode = LWS_CONNMODE_HTTP_SERVING; - new_wsi->hdr_parsing_completed = 0; - - if (lws_allocate_header_table(new_wsi)) { - free(new_wsi); - return NULL; - } - - /* - * these can only be set once the protocol is known - * we set an unestablished connection's protocol pointer - * to the start of the supported list, so it can look - * for matching ones during the handshake - */ - new_wsi->protocol = context->protocols; - new_wsi->user_space = NULL; - new_wsi->ietf_spec_revision = 0; - - /* - * outermost create notification for wsi - * no user_space because no protocol selection - */ - context->protocols[0].callback(context, new_wsi, - LWS_CALLBACK_WSI_CREATE, NULL, NULL, 0); - - return new_wsi; -} - -int lws_server_socket_service(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) -{ - struct libwebsocket *new_wsi = NULL; - int accept_fd = 0; - socklen_t clilen; - struct sockaddr_in cli_addr; - int n; - int len; - - switch (wsi->mode) { - - case LWS_CONNMODE_HTTP_SERVING: - case LWS_CONNMODE_HTTP_SERVING_ACCEPTED: - - /* handle http headers coming in */ - - /* pending truncated sends have uber priority */ - - if (wsi->truncated_send_malloc) { - if (pollfd->revents & LWS_POLLOUT) - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("closing from socket service\n"); - return -1; - } - /* - * we can't afford to allow input processing send - * something new, so spin around he event loop until - * he doesn't have any partials - */ - break; - } - - /* any incoming data ready? */ - - if (pollfd->revents & LWS_POLLIN) { - len = lws_ssl_capable_read(wsi, - context->service_buffer, - sizeof(context->service_buffer)); - switch (len) { - case 0: - lwsl_info("lws_server_skt_srv: read 0 len\n"); - /* lwsl_info(" state=%d\n", wsi->state); */ - if (!wsi->hdr_parsing_completed) - free(wsi->u.hdr.ah); - /* fallthru */ - case LWS_SSL_CAPABLE_ERROR: - libwebsocket_close_and_free_session( - context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 0; - case LWS_SSL_CAPABLE_MORE_SERVICE: - break; - } - - /* just ignore incoming if waiting for close */ - if (wsi->state != WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - - /* hm this may want to send (via HTTP callback for example) */ - - n = libwebsocket_read(context, wsi, - context->service_buffer, len); - if (n < 0) - /* we closed wsi */ - return 0; - - /* hum he may have used up the writability above */ - break; - } - } - - /* this handles POLLOUT for http serving fragments */ - - if (!(pollfd->revents & LWS_POLLOUT)) - break; - - /* one shot */ - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) - goto fail; - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE); - - if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) { - n = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi->protocol->owning_server, - wsi, LWS_CALLBACK_HTTP_WRITEABLE, - wsi->user_space, - NULL, - 0); - if (n < 0) - libwebsocket_close_and_free_session( - context, wsi, LWS_CLOSE_STATUS_NOSTATUS); - break; - } - - /* nonzero for completion or error */ - if (libwebsockets_serve_http_file_fragment(context, wsi)) - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - break; - - case LWS_CONNMODE_SERVER_LISTENER: - - /* pollin means a client has connected to us then */ - - if (!(pollfd->revents & LWS_POLLIN)) - break; - - /* listen socket got an unencrypted connection... */ - - clilen = sizeof(cli_addr); - lws_latency_pre(context, wsi); - accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr, - &clilen); - lws_latency(context, wsi, - "unencrypted accept LWS_CONNMODE_SERVER_LISTENER", - accept_fd, accept_fd >= 0); - if (accept_fd < 0) { - if (LWS_ERRNO == LWS_EAGAIN || LWS_ERRNO == LWS_EWOULDBLOCK) { - lwsl_debug("accept asks to try again\n"); - break; - } - lwsl_warn("ERROR on accept: %s\n", strerror(LWS_ERRNO)); - break; - } - - lws_plat_set_socket_options(context, accept_fd); - - /* - * look at who we connected to and give user code a chance - * to reject based on client IP. There's no protocol selected - * yet so we issue this to protocols[0] - */ - - if ((context->protocols[0].callback)(context, wsi, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - NULL, (void *)(long)accept_fd, 0)) { - lwsl_debug("Callback denied network connection\n"); - compatible_close(accept_fd); - break; - } - - new_wsi = libwebsocket_create_new_server_wsi(context); - if (new_wsi == NULL) { - compatible_close(accept_fd); - break; - } - - new_wsi->sock = accept_fd; - - /* the transport is accepted... give him time to negotiate */ - libwebsocket_set_timeout(new_wsi, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - AWAITING_TIMEOUT); - - /* - * A new connection was accepted. Give the user a chance to - * set properties of the newly created wsi. There's no protocol - * selected yet so we issue this to protocols[0] - */ - - (context->protocols[0].callback)(context, new_wsi, - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0); - - lws_libev_accept(context, new_wsi, accept_fd); - - if (!LWS_SSL_ENABLED(context)) { - lwsl_debug("accepted new conn port %u on fd=%d\n", - ntohs(cli_addr.sin_port), accept_fd); - - insert_wsi_socket_into_fds(context, new_wsi); - } - break; - - default: - break; - } - - if (lws_server_socket_service_ssl(context, &wsi, new_wsi, accept_fd, pollfd)) - goto fail; - - return 0; - -fail: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - return 1; -} - - -static const char *err400[] = { - "Bad Request", - "Unauthorized", - "Payment Required", - "Forbidden", - "Not Found", - "Method Not Allowed", - "Not Acceptable", - "Proxy Auth Required", - "Request Timeout", - "Conflict", - "Gone", - "Length Required", - "Precondition Failed", - "Request Entity Too Large", - "Request URI too Long", - "Unsupported Media Type", - "Requested Range Not Satisfiable", - "Expectation Failed" -}; - -static const char *err500[] = { - "Internal Server Error", - "Not Implemented", - "Bad Gateway", - "Service Unavailable", - "Gateway Timeout", - "HTTP Version Not Supported" -}; - -/** - * libwebsockets_return_http_status() - Return simple http status - * @context: libwebsockets context - * @wsi: Websocket instance (available from user callback) - * @code: Status index, eg, 404 - * @html_body: User-readable HTML description, or NULL - * - * Helper to report HTTP errors back to the client cleanly and - * consistently - */ -LWS_VISIBLE int libwebsockets_return_http_status( - struct libwebsocket_context *context, struct libwebsocket *wsi, - unsigned int code, const char *html_body) -{ - int n, m; - const char *description = ""; - - if (!html_body) - html_body = ""; - - if (code >= 400 && code < (400 + ARRAY_SIZE(err400))) - description = err400[code - 400]; - if (code >= 500 && code < (500 + ARRAY_SIZE(err500))) - description = err500[code - 500]; - - n = sprintf((char *)context->service_buffer, - "HTTP/1.0 %u %s\x0d\x0a" - "Server: libwebsockets\x0d\x0a" - "Content-Type: text/html\x0d\x0a\x0d\x0a" - "

%u %s

%s", - code, description, code, description, html_body); - - lwsl_info((const char *)context->service_buffer); - - m = libwebsocket_write(wsi, context->service_buffer, n, LWS_WRITE_HTTP); - - return m; -} - -/** - * libwebsockets_serve_http_file() - Send a file back to the client using http - * @context: libwebsockets context - * @wsi: Websocket instance (available from user callback) - * @file: The file to issue over http - * @content_type: The http content type, eg, text/html - * @other_headers: NULL or pointer to \0-terminated other header string - * - * This function is intended to be called from the callback in response - * to http requests from the client. It allows the callback to issue - * local files down the http link in a single step. - * - * Returning <0 indicates error and the wsi should be closed. Returning - * >0 indicates the file was completely sent and the wsi should be closed. - * ==0 indicates the file transfer is started and needs more service later, - * the wsi should be left alone. - */ - -LWS_VISIBLE int libwebsockets_serve_http_file( - struct libwebsocket_context *context, - struct libwebsocket *wsi, const char *file, - const char *content_type, const char *other_headers) -{ - unsigned char *p = context->service_buffer; - int ret = 0; - int n; - - wsi->u.http.fd = lws_plat_open_file(file, &wsi->u.http.filelen); - - if (wsi->u.http.fd == LWS_INVALID_FILE) { - lwsl_err("Unable to open '%s'\n", file); - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_NOT_FOUND, NULL); - return -1; - } - - p += sprintf((char *)p, -"HTTP/1.0 200 OK\x0d\x0aServer: libwebsockets\x0d\x0a""Content-Type: %s\x0d\x0a", - content_type); - if (other_headers) { - n = strlen(other_headers); - memcpy(p, other_headers, n); - p += n; - } - p += sprintf((char *)p, - "Content-Length: %lu\x0d\x0a\x0d\x0a", wsi->u.http.filelen); - - ret = libwebsocket_write(wsi, context->service_buffer, - p - context->service_buffer, LWS_WRITE_HTTP); - if (ret != (p - context->service_buffer)) { - lwsl_err("_write returned %d from %d\n", ret, (p - context->service_buffer)); - return -1; - } - - wsi->u.http.filepos = 0; - wsi->state = WSI_STATE_HTTP_ISSUING_FILE; - - return libwebsockets_serve_http_file_fragment(context, wsi); -} - - -int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, - unsigned char *buf, size_t len) -{ - size_t n = 0; - int m; - -#if 0 - lwsl_parser("received %d byte packet\n", (int)len); - lwsl_hexdump(buf, len); -#endif - - /* let the rx protocol state machine have as much as it needs */ - - while (n < len) { - /* - * we were accepting input but now we stopped doing so - */ - if (!(wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW)) { - /* his RX is flowcontrolled, don't send remaining now */ - if (!wsi->u.ws.rxflow_buffer) { - /* a new rxflow, buffer it and warn caller */ - lwsl_info("new rxflow input buffer len %d\n", - len - n); - wsi->u.ws.rxflow_buffer = - (unsigned char *)malloc(len - n); - wsi->u.ws.rxflow_len = len - n; - wsi->u.ws.rxflow_pos = 0; - memcpy(wsi->u.ws.rxflow_buffer, - buf + n, len - n); - } else - /* rxflow while we were spilling prev rxflow */ - lwsl_info("stalling in existing rxflow buf\n"); - - return 1; - } - - /* account for what we're using in rxflow buffer */ - if (wsi->u.ws.rxflow_buffer) - wsi->u.ws.rxflow_pos++; - - /* process the byte */ - m = libwebsocket_rx_sm(wsi, buf[n++]); - if (m < 0) - return -1; - } - - return 0; -} - -LWS_VISIBLE void -lws_server_get_canonical_hostname(struct libwebsocket_context *context, - struct lws_context_creation_info *info) -{ - if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) - return; - - /* find canonical hostname */ - gethostname((char *)context->canonical_hostname, - sizeof(context->canonical_hostname) - 1); - - lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname); -} \ No newline at end of file diff --git a/core/deps/libwebsocket/service.c b/core/deps/libwebsocket/service.c deleted file mode 100644 index 409c2d231..000000000 --- a/core/deps/libwebsocket/service.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2014 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "private-libwebsockets.h" - -int -lws_handle_POLLOUT_event(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd) -{ - int n; - struct lws_tokens eff_buf; - int ret; - int m; - int handled = 0; - - /* pending truncated sends have uber priority */ - - if (wsi->truncated_send_len) { - if (lws_issue_raw(wsi, wsi->truncated_send_malloc + - wsi->truncated_send_offset, - wsi->truncated_send_len) < 0) { - lwsl_info("lws_handle_POLLOUT_event signalling to close\n"); - return -1; - } - /* leave POLLOUT active either way */ - return 0; - } else - if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) { - lwsl_info("***** %x signalling to close in POLLOUT handler\n", wsi); - return -1; /* retry closing now */ - } - - - m = lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_IS_WRITEABLE, - NULL, 0); - if (handled == 1) - goto notify_action; -#ifndef LWS_NO_EXTENSIONS - if (!wsi->extension_data_pending || handled == 2) - goto user_service; -#endif - /* - * check in on the active extensions, see if they - * had pending stuff to spill... they need to get the - * first look-in otherwise sequence will be disordered - * - * NULL, zero-length eff_buf means just spill pending - */ - - ret = 1; - while (ret == 1) { - - /* default to nobody has more to spill */ - - ret = 0; - eff_buf.token = NULL; - eff_buf.token_len = 0; - - /* give every extension a chance to spill */ - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_TX_PRESEND, - &eff_buf, 0); - if (m < 0) { - lwsl_err("ext reports fatal error\n"); - return -1; - } - if (m) - /* - * at least one extension told us he has more - * to spill, so we will go around again after - */ - ret = 1; - - /* assuming they gave us something to send, send it */ - - if (eff_buf.token_len) { - n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - lwsl_info("closing from POLLOUT spill\n"); - return -1; - } - /* - * Keep amount spilled small to minimize chance of this - */ - if (n != eff_buf.token_len) { - lwsl_err("Unable to spill ext %d vs %s\n", - eff_buf.token_len, n); - return -1; - } - } else - continue; - - /* no extension has more to spill */ - - if (!ret) - continue; - - /* - * There's more to spill from an extension, but we just sent - * something... did that leave the pipe choked? - */ - - if (!lws_send_pipe_choked(wsi)) - /* no we could add more */ - continue; - - lwsl_info("choked in POLLOUT service\n"); - - /* - * Yes, he's choked. Leave the POLLOUT masked on so we will - * come back here when he is unchoked. Don't call the user - * callback to enforce ordering of spilling, he'll get called - * when we come back here and there's nothing more to spill. - */ - - return 0; - } -#ifndef LWS_NO_EXTENSIONS - wsi->extension_data_pending = 0; - -user_service: -#endif - /* one shot */ - - if (pollfd) { - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) - return 1; - - lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE); - } - -notify_action: - if (wsi->mode == LWS_CONNMODE_WS_CLIENT) - n = LWS_CALLBACK_CLIENT_WRITEABLE; - else - n = LWS_CALLBACK_SERVER_WRITEABLE; - - return user_callback_handle_rxflow(wsi->protocol->callback, context, - wsi, (enum libwebsocket_callback_reasons) n, - wsi->user_space, NULL, 0); -} - - - -int -libwebsocket_service_timeout_check(struct libwebsocket_context *context, - struct libwebsocket *wsi, unsigned int sec) -{ - /* - * if extensions want in on it (eg, we are a mux parent) - * give them a chance to service child timeouts - */ - if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_1HZ, NULL, sec) < 0) - return 0; - - if (!wsi->pending_timeout) - return 0; - - /* - * if we went beyond the allowed time, kill the - * connection - */ - if (sec > wsi->pending_timeout_limit) { - lwsl_info("TIMEDOUT WAITING on %d\n", wsi->pending_timeout); - libwebsocket_close_and_free_session(context, - wsi, LWS_CLOSE_STATUS_NOSTATUS); - return 1; - } - - return 0; -} - -/** - * libwebsocket_service_fd() - Service polled socket with something waiting - * @context: Websocket context - * @pollfd: The pollfd entry describing the socket fd and which events - * happened. - * - * This function takes a pollfd that has POLLIN or POLLOUT activity and - * services it according to the state of the associated - * struct libwebsocket. - * - * The one call deals with all "service" that might happen on a socket - * including listen accepts, http files as well as websocket protocol. - * - * If a pollfd says it has something, you can just pass it to - * libwebsocket_serice_fd() whether it is a socket handled by lws or not. - * If it sees it is a lws socket, the traffic will be handled and - * pollfd->revents will be zeroed now. - * - * If the socket is foreign to lws, it leaves revents alone. So you can - * see if you should service yourself by checking the pollfd revents - * after letting lws try to service it. - */ - -LWS_VISIBLE int -libwebsocket_service_fd(struct libwebsocket_context *context, - struct libwebsocket_pollfd *pollfd) -{ - struct libwebsocket *wsi; - int n; - int m; - int listen_socket_fds_index = 0; - time_t now; - int timed_out = 0; - int our_fd = 0; - char draining_flow = 0; - int more; - struct lws_tokens eff_buf; - - if (context->listen_service_fd) - listen_socket_fds_index = context->lws_lookup[ - context->listen_service_fd]->position_in_fds_table; - - /* - * you can call us with pollfd = NULL to just allow the once-per-second - * global timeout checks; if less than a second since the last check - * it returns immediately then. - */ - - time(&now); - - /* TODO: if using libev, we should probably use timeout watchers... */ - if (context->last_timeout_check_s != now) { - context->last_timeout_check_s = now; - - lws_plat_service_periodic(context); - - /* global timeout check once per second */ - - if (pollfd) - our_fd = pollfd->fd; - - for (n = 0; n < context->fds_count; n++) { - m = context->fds[n].fd; - wsi = context->lws_lookup[m]; - if (!wsi) - continue; - - if (libwebsocket_service_timeout_check(context, wsi, now)) - /* he did time out... */ - if (m == our_fd) { - /* it was the guy we came to service! */ - timed_out = 1; - /* mark as handled */ - pollfd->revents = 0; - } - } - } - - /* the socket we came to service timed out, nothing to do */ - if (timed_out) - return 0; - - /* just here for timeout management? */ - if (pollfd == NULL) - return 0; - - /* no, here to service a socket descriptor */ - wsi = context->lws_lookup[pollfd->fd]; - if (wsi == NULL) - /* not lws connection ... leave revents alone and return */ - return 0; - - /* - * so that caller can tell we handled, past here we need to - * zero down pollfd->revents after handling - */ - - /* - * deal with listen service piggybacking - * every listen_service_modulo services of other fds, we - * sneak one in to service the listen socket if there's anything waiting - * - * To handle connection storms, as found in ab, if we previously saw a - * pending connection here, it causes us to check again next time. - */ - - if (context->listen_service_fd && pollfd != - &context->fds[listen_socket_fds_index]) { - context->listen_service_count++; - if (context->listen_service_extraseen || - context->listen_service_count == - context->listen_service_modulo) { - context->listen_service_count = 0; - m = 1; - if (context->listen_service_extraseen > 5) - m = 2; - while (m--) { - /* - * even with extpoll, we prepared this - * internal fds for listen - */ - n = lws_poll_listen_fd(&context->fds[listen_socket_fds_index]); - if (n > 0) { /* there's a conn waiting for us */ - libwebsocket_service_fd(context, - &context-> - fds[listen_socket_fds_index]); - context->listen_service_extraseen++; - } else { - if (context->listen_service_extraseen) - context-> - listen_service_extraseen--; - break; - } - } - } - - } - - /* handle session socket closed */ - - if ((!(pollfd->revents & LWS_POLLIN)) && - (pollfd->revents & LWS_POLLHUP)) { - - lwsl_debug("Session Socket %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - goto close_and_handled; - } - - /* okay, what we came here to do... */ - - switch (wsi->mode) { - case LWS_CONNMODE_HTTP_SERVING: - case LWS_CONNMODE_HTTP_SERVING_ACCEPTED: - case LWS_CONNMODE_SERVER_LISTENER: - case LWS_CONNMODE_SSL_ACK_PENDING: - n = lws_server_socket_service(context, wsi, pollfd); - if (n < 0) - goto close_and_handled; - goto handled; - - case LWS_CONNMODE_WS_SERVING: - case LWS_CONNMODE_WS_CLIENT: - - /* the guy requested a callback when it was OK to write */ - - if ((pollfd->revents & LWS_POLLOUT) && - (wsi->state == WSI_STATE_ESTABLISHED || - wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) && - lws_handle_POLLOUT_event(context, wsi, pollfd)) { - lwsl_info("libwebsocket_service_fd: closing\n"); - goto close_and_handled; - } - - if (wsi->u.ws.rxflow_buffer && - (wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW)) { - lwsl_info("draining rxflow\n"); - /* well, drain it */ - eff_buf.token = (char *)wsi->u.ws.rxflow_buffer + - wsi->u.ws.rxflow_pos; - eff_buf.token_len = wsi->u.ws.rxflow_len - - wsi->u.ws.rxflow_pos; - draining_flow = 1; - goto drain; - } - - /* any incoming data ready? */ - - if (!(pollfd->revents & LWS_POLLIN)) - break; - -read_pending: - eff_buf.token_len = lws_ssl_capable_read(wsi, - context->service_buffer, - sizeof(context->service_buffer)); - switch (eff_buf.token_len) { - case 0: - lwsl_info("service_fd: closing due to 0 length read\n"); - goto close_and_handled; - case LWS_SSL_CAPABLE_ERROR: - n = 0; - goto handled; - case LWS_SSL_CAPABLE_MORE_SERVICE: - goto close_and_handled; - } - - /* - * give any active extensions a chance to munge the buffer - * before parse. We pass in a pointer to an lws_tokens struct - * prepared with the default buffer and content length that's in - * there. Rather than rewrite the default buffer, extensions - * that expect to grow the buffer can adapt .token to - * point to their own per-connection buffer in the extension - * user allocation. By default with no extensions or no - * extension callback handling, just the normal input buffer is - * used then so it is efficient. - */ - - eff_buf.token = (char *)context->service_buffer; -drain: - - do { - - more = 0; - - m = lws_ext_callback_for_each_active(wsi, - LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, &eff_buf, 0); - if (m < 0) - goto close_and_handled; - if (m) - more = 1; - - /* service incoming data */ - - if (eff_buf.token_len) { - n = libwebsocket_read(context, wsi, - (unsigned char *)eff_buf.token, - eff_buf.token_len); - if (n < 0) { - /* we closed wsi */ - n = 0; - goto handled; - } - } - - eff_buf.token = NULL; - eff_buf.token_len = 0; - } while (more); - - if (draining_flow && wsi->u.ws.rxflow_buffer && - wsi->u.ws.rxflow_pos == wsi->u.ws.rxflow_len) { - lwsl_info("flow buffer: drained\n"); - free(wsi->u.ws.rxflow_buffer); - wsi->u.ws.rxflow_buffer = NULL; - /* having drained the rxflow buffer, can rearm POLLIN */ - n = _libwebsocket_rx_flow_control(wsi); /* n ignored, needed for NO_SERVER case */ - } - - if (lws_ssl_pending(wsi)) - goto read_pending; - break; - - default: -#ifdef LWS_NO_CLIENT - break; -#else - n = lws_client_socket_service(context, wsi, pollfd); - goto handled; -#endif - } - - n = 0; - goto handled; - -close_and_handled: - libwebsocket_close_and_free_session(context, wsi, - LWS_CLOSE_STATUS_NOSTATUS); - n = 1; - -handled: - pollfd->revents = 0; - return n; -} - -/** - * libwebsocket_service() - Service any pending websocket activity - * @context: Websocket context - * @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed - * service otherwise block and service immediately, returning - * after the timeout if nothing needed service. - * - * This function deals with any pending websocket traffic, for three - * kinds of event. It handles these events on both server and client - * types of connection the same. - * - * 1) Accept new connections to our context's server - * - * 2) Call the receive callback for incoming frame data received by - * server or client connections. - * - * You need to call this service function periodically to all the above - * functions to happen; if your application is single-threaded you can - * just call it in your main event loop. - * - * Alternatively you can fork a new process that asynchronously handles - * calling this service in a loop. In that case you are happy if this - * call blocks your thread until it needs to take care of something and - * would call it with a large nonzero timeout. Your loop then takes no - * CPU while there is nothing happening. - * - * If you are calling it in a single-threaded app, you don't want it to - * wait around blocking other things in your loop from happening, so you - * would call it with a timeout_ms of 0, so it returns immediately if - * nothing is pending, or as soon as it services whatever was pending. - */ - -LWS_VISIBLE int -libwebsocket_service(struct libwebsocket_context *context, int timeout_ms) -{ - return lws_plat_service(context, timeout_ms); -} - diff --git a/core/deps/libwebsocket/sha-1.c b/core/deps/libwebsocket/sha-1.c deleted file mode 100644 index f29b2c3a6..000000000 --- a/core/deps/libwebsocket/sha-1.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://csrc.nist.gov/fips/fip180-1.txt - * implemented by Jun-ichiro itojun Itoh - */ - -#include "private-libwebsockets.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -struct sha1_ctxt { - union { - unsigned char b8[20]; - unsigned int b32[5]; - } h; - union { - unsigned char b8[8]; - u_int64_t b64[1]; - } c; - union { - unsigned char b8[64]; - unsigned int b32[16]; - } m; - unsigned char count; -}; - -/* sanity check */ -#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) -# define unsupported 1 -#elif BYTE_ORDER != BIG_ENDIAN -# if BYTE_ORDER != LITTLE_ENDIAN -# define unsupported 1 -# endif -#endif - -#ifndef unsupported - -/* constant table */ -static const unsigned int _K[] = - { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTBYTE(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - -#define PUTPAD(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - -static void -sha1_step(struct sha1_ctxt *ctxt) -{ - unsigned int a, b, c, d, e, tmp; - size_t t, s; - -#if BYTE_ORDER == LITTLE_ENDIAN - struct sha1_ctxt tctxt; - - memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); - - for (t = 0; t < 20; t++) { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 20; t < 40; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 40; t < 60; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 60; t < 80; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - bzero(&ctxt->m.b8[0], 64); -} - -/*------------------------------------------------------------*/ - -static void -sha1_init(struct sha1_ctxt *ctxt) -{ - bzero(ctxt, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt *ctxt) -{ - size_t padlen; /*pad length in bytes*/ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) { - bzero(&ctxt->m.b8[padstart], padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - bzero(&ctxt->m.b8[padstart], padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; -#if BYTE_ORDER == BIG_ENDIAN - PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) -{ - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - off = 0; - - while (off < len) { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt *ctxt, void *digest0) -{ - unsigned char *digest; - - digest = (unsigned char *)digest0; - sha1_pad(ctxt); -#if BYTE_ORDER == BIG_ENDIAN - memcpy(digest, &ctxt->h.b8[0], 20); -#else - digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; -#endif -} - -/* - * This should look and work like the libcrypto implementation - */ - -unsigned char * -SHA1(const unsigned char *d, size_t n, unsigned char *md) -{ - struct sha1_ctxt ctx; - - sha1_init(&ctx); - sha1_loop(&ctx, d, n); - sha1_result(&ctx, (void *)md); - - return md; -} - -#endif /*unsupported*/ diff --git a/core/webui/server.cpp b/core/webui/server.cpp deleted file mode 100644 index e275ad867..000000000 --- a/core/webui/server.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/* - * libwebsockets-test-server - libwebsockets test implementation - * - * Copyright (C) 2010-2011 Andy Green - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -#ifdef CMAKE_BUILD -#include "lws_config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#ifdef EXTERNAL_POLL -#define poll WSAPoll -#endif -#else -#include -#include -#include -#endif - -#include "deps/libwebsocket/libwebsockets.h" -#include "oslib/oslib.h" - -static int close_testing; -int max_poll_elements; - -struct pollfd *pollfds; -int *fd_lookup; -int count_pollfds; -static volatile int force_exit = 0; -static struct libwebsocket_context *context; - -/* - * This demo server shows how to use libwebsockets for one or more - * websocket protocols in the same server - * - * It defines the following websocket protocols: - * - * dumb-increment-protocol: once the socket is opened, an incrementing - * ascii string is sent down it every 50ms. - * If you send "reset\n" on the websocket, then - * the incrementing number is reset to 0. - * - * lws-mirror-protocol: copies any received packet to every connection also - * using this protocol, including the sender - */ - -enum demo_protocols { - /* always first */ - PROTOCOL_HTTP = 0, - - PROTOCOL_DUMB_INCREMENT, - PROTOCOL_LWS_MIRROR, - - /* always last */ - DEMO_PROTOCOL_COUNT -}; - -#define WEBUI_PATH get_writable_data_path("/webui") - -/* - * We take a strict whitelist approach to stop ../ attacks - */ - -struct serveable { - const char *urlpath; - const char *mimetype; -}; - -struct per_session_data__http { - int fd; -}; - -/* - * this is just an example of parsing handshake headers, you don't need this - * in your code unless you will filter allowing connections by the header - * content - */ - -static void -dump_handshake_info(struct libwebsocket *wsi) -{ - int n; - static const char *token_names[] = { - /*[WSI_TOKEN_GET_URI] =*/ "GET URI", - /*[WSI_TOKEN_POST_URI] =*/ "POST URI", - /*[WSI_TOKEN_HOST] =*/ "Host", - /*[WSI_TOKEN_CONNECTION] =*/ "Connection", - /*[WSI_TOKEN_KEY1] =*/ "key 1", - /*[WSI_TOKEN_KEY2] =*/ "key 2", - /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol", - /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade", - /*[WSI_TOKEN_ORIGIN] =*/ "Origin", - /*[WSI_TOKEN_DRAFT] =*/ "Draft", - /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge", - - /* new for 04 */ - /*[WSI_TOKEN_KEY] =*/ "Key", - /*[WSI_TOKEN_VERSION] =*/ "Version", - /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin", - - /* new for 05 */ - /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions", - - /* client receives these */ - /*[WSI_TOKEN_ACCEPT] =*/ "Accept", - /*[WSI_TOKEN_NONCE] =*/ "Nonce", - /*[WSI_TOKEN_HTTP] =*/ "Http", - - "Accept:", - "If-Modified-Since:", - "Accept-Encoding:", - "Accept-Language:", - "Pragma:", - "Cache-Control:", - "Authorization:", - "Cookie:", - "Content-Length:", - "Content-Type:", - "Date:", - "Range:", - "Referer:", - "Uri-Args:", - - /*[WSI_TOKEN_MUXURL] =*/ "MuxURL", - }; - char buf[256]; - - for (n = 0; n < sizeof(token_names) / sizeof(token_names[0]); n++) { - if (!lws_hdr_total_length(wsi, (lws_token_indexes)n)) - continue; - - lws_hdr_copy(wsi, buf, sizeof buf, (lws_token_indexes)n); - - fprintf(stderr, " %s = %s\n", token_names[n], buf); - } -} - -const char * get_mimetype(const char *file) -{ - int n = strlen(file); - - if (n < 5) - return NULL; - - if (!strcmp(&file[n - 4], ".ico")) - return "image/x-icon"; - - if (!strcmp(&file[n - 4], ".png")) - return "image/png"; - - if (!strcmp(&file[n - 5], ".html")) - return "text/html"; - - return NULL; -} - -/* this protocol server (always the first one) just knows how to do HTTP */ - -static int callback_http(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, void *user, - void *in, size_t len) -{ -#if 0 - char client_name[128]; - char client_ip[128]; -#endif - char buf[256]; - char leaf_path[1024]; - char b64[64]; - struct timeval tv; - int n, m; - unsigned char *p; - char *other_headers = 0; - static unsigned char buffer[4096]; - struct stat stat_buf; - struct per_session_data__http *pss = - (struct per_session_data__http *)user; - const char *mimetype; -#ifdef EXTERNAL_POLL - struct libwebsocket_pollargs *pa = (struct libwebsocket_pollargs *)in; -#endif - - const string path = WEBUI_PATH; - - const char* resource_path = path.c_str(); - - switch (reason) { - case LWS_CALLBACK_HTTP: - - dump_handshake_info(wsi); - - if (len < 1) { - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_BAD_REQUEST, NULL); - return -1; - } - - /* this server has no concept of directories */ - if (strchr((const char *)in + 1, '/')) { - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_FORBIDDEN, NULL); - return -1; - } - - /* if a legal POST URL, let it continue and accept data */ - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) - return 0; - - /* check for the "send a big file by hand" example case */ - - if (!strcmp((const char *)in, "/leaf.jpg")) { - if (strlen(resource_path) > sizeof(leaf_path) - 10) - return -1; - sprintf(leaf_path, "%s/leaf.jpg", resource_path); - - /* well, let's demonstrate how to send the hard way */ - - p = buffer; - -#ifdef WIN32 - pss->fd = open(leaf_path, O_RDONLY | _O_BINARY); -#else - pss->fd = open(leaf_path, O_RDONLY); -#endif - - if (pss->fd < 0) - return -1; - - fstat(pss->fd, &stat_buf); - - /* - * we will send a big jpeg file, but it could be - * anything. Set the Content-Type: appropriately - * so the browser knows what to do with it. - */ - - p += sprintf((char *)p, - "HTTP/1.0 200 OK\x0d\x0a" - "Server: libwebsockets\x0d\x0a" - "Content-Type: image/jpeg\x0d\x0a" - "Content-Length: %u\x0d\x0a\x0d\x0a", - (unsigned int)stat_buf.st_size); - - /* - * send the http headers... - * this won't block since it's the first payload sent - * on the connection since it was established - * (too small for partial) - */ - - n = libwebsocket_write(wsi, buffer, - p - buffer, LWS_WRITE_HTTP); - - if (n < 0) { - close(pss->fd); - return -1; - } - /* - * book us a LWS_CALLBACK_HTTP_WRITEABLE callback - */ - libwebsocket_callback_on_writable(context, wsi); - break; - } - - /* if not, send a file the easy way */ - - // FIXME: Data loss if buffer is too small - strncpy(buf, resource_path, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - - if (strcmp((const char*)in, "/")) { - if (*((const char *)in) != '/') - strcat(buf, "/"); - strncat(buf, (const char*)in, sizeof(buf) - strlen(resource_path)); - } else /* default file to serve */ - strcat(buf, "/debugger.html"); - buf[sizeof(buf) - 1] = '\0'; - - /* refuse to serve files we don't understand */ - mimetype = get_mimetype(buf); - if (!mimetype) { - lwsl_err("Unknown mimetype for %s\n", buf); - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, NULL); - return -1; - } - - if (libwebsockets_serve_http_file(context, wsi, buf, - mimetype, other_headers)) - return -1; /* through completion or error, close the socket */ - - /* - * notice that the sending of the file completes asynchronously, - * we'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION callback when - * it's done - */ - - break; - - case LWS_CALLBACK_HTTP_BODY: - strncpy(buf, (const char*)in, 20); - buf[20] = '\0'; - if (len < 20) - buf[len] = '\0'; - - lwsl_notice("LWS_CALLBACK_HTTP_BODY: %s... len %d\n", - (const char *)buf, (int)len); - - break; - - case LWS_CALLBACK_HTTP_BODY_COMPLETION: - lwsl_notice("LWS_CALLBACK_HTTP_BODY_COMPLETION\n"); - /* the whole of the sent body arried, close the connection */ - libwebsockets_return_http_status(context, wsi, - HTTP_STATUS_OK, NULL); - - return -1; - - case LWS_CALLBACK_HTTP_FILE_COMPLETION: -// lwsl_info("LWS_CALLBACK_HTTP_FILE_COMPLETION seen\n"); - /* kill the connection after we sent one file */ - return -1; - - case LWS_CALLBACK_HTTP_WRITEABLE: - /* - * we can send more of whatever it is we were sending - */ - - do { - n = read(pss->fd, buffer, sizeof buffer); - /* problem reading, close conn */ - if (n < 0) - goto bail; - /* sent it all, close conn */ - if (n == 0) - goto flush_bail; - /* - * because it's HTTP and not websocket, don't need to take - * care about pre and postamble - */ - m = libwebsocket_write(wsi, buffer, n, LWS_WRITE_HTTP); - if (m < 0) - /* write failed, close conn */ - goto bail; - if (m != n) - /* partial write, adjust */ - lseek(pss->fd, m - n, SEEK_CUR); - - if (m) /* while still active, extend timeout */ - libwebsocket_set_timeout(wsi, - PENDING_TIMEOUT_HTTP_CONTENT, 5); - - } while (!lws_send_pipe_choked(wsi)); - libwebsocket_callback_on_writable(context, wsi); - break; -flush_bail: - /* true if still partial pending */ - if (lws_send_pipe_choked(wsi)) { - libwebsocket_callback_on_writable(context, wsi); - break; - } - -bail: - close(pss->fd); - return -1; - - /* - * callback for confirming to continue with client IP appear in - * protocol 0 callback since no websocket protocol has been agreed - * yet. You can just ignore this if you won't filter on client IP - * since the default uhandled callback return is 0 meaning let the - * connection continue. - */ - - case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: -#if 0 - libwebsockets_get_peer_addresses(context, wsi, (int)(long)in, client_name, - sizeof(client_name), client_ip, sizeof(client_ip)); - - fprintf(stderr, "Received network connect from %s (%s)\n", - client_name, client_ip); -#endif - /* if we returned non-zero from here, we kill the connection */ - break; - -#ifdef EXTERNAL_POLL - /* - * callbacks for managing the external poll() array appear in - * protocol 0 callback - */ - - case LWS_CALLBACK_LOCK_POLL: - /* - * lock mutex to protect pollfd state - * called before any other POLL related callback - */ - break; - - case LWS_CALLBACK_UNLOCK_POLL: - /* - * unlock mutex to protect pollfd state when - * called after any other POLL related callback - */ - break; - - case LWS_CALLBACK_ADD_POLL_FD: - - if (count_pollfds >= max_poll_elements) { - lwsl_err("LWS_CALLBACK_ADD_POLL_FD: too many sockets to track\n"); - return 1; - } - - fd_lookup[pa->fd] = count_pollfds; - pollfds[count_pollfds].fd = pa->fd; - pollfds[count_pollfds].events = pa->events; - pollfds[count_pollfds++].revents = 0; - break; - - case LWS_CALLBACK_DEL_POLL_FD: - if (!--count_pollfds) - break; - m = fd_lookup[pa->fd]; - /* have the last guy take up the vacant slot */ - pollfds[m] = pollfds[count_pollfds]; - fd_lookup[pollfds[count_pollfds].fd] = m; - break; - - case LWS_CALLBACK_CHANGE_MODE_POLL_FD: - pollfds[fd_lookup[pa->fd]].events = pa->events; - break; - -#endif - - case LWS_CALLBACK_GET_THREAD_ID: - /* - * if you will call "libwebsocket_callback_on_writable" - * from a different thread, return the caller thread ID - * here so lws can use this information to work out if it - * should signal the poll() loop to exit and restart early - */ - - /* return pthread_getthreadid_np(); */ - - break; - - default: - break; - } - - return 0; -} - - -/* dumb_increment protocol */ - -/* - * one of these is auto-created for each connection and a pointer to the - * appropriate instance is passed to the callback in the user parameter - * - * for this example protocol we use it to individualize the count for each - * connection. - */ - -struct per_session_data__dumb_increment { - int number; -}; - -static int -callback_dumb_increment(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, - void *user, void *in, size_t len) -{ - int n, m; - unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + - LWS_SEND_BUFFER_POST_PADDING]; - unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING]; - struct per_session_data__dumb_increment *pss = (struct per_session_data__dumb_increment *)user; - - switch (reason) { - - case LWS_CALLBACK_ESTABLISHED: - lwsl_info("callback_dumb_increment: " - "LWS_CALLBACK_ESTABLISHED\n"); - pss->number = 0; - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - n = sprintf((char *)p, "%d", pss->number++); - m = libwebsocket_write(wsi, (u8*)&p_sh4rcb->cntx, sizeof(p_sh4rcb->cntx), LWS_WRITE_BINARY); - if (m < n) { - lwsl_err("ERROR %d writing to di socket\n", n); - return -1; - } - if (close_testing && pss->number == 50) { - lwsl_info("close tesing limit, closing\n"); - return -1; - } - break; - - case LWS_CALLBACK_RECEIVE: -// fprintf(stderr, "rx %d\n", (int)len); - if (len < 6) - break; - if (strcmp((const char *)in, "reset\n") == 0) - pss->number = 0; - break; - /* - * this just demonstrates how to use the protocol filter. If you won't - * study and reject connections based on header content, you don't need - * to handle this callback - */ - - case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: - dump_handshake_info(wsi); - /* you could return non-zero here and kill the connection */ - break; - - default: - break; - } - - return 0; -} - - -/* lws-mirror_protocol */ - -#define MAX_MESSAGE_QUEUE 32 - -struct per_session_data__lws_mirror { - struct libwebsocket *wsi; - int ringbuffer_tail; -}; - -struct a_message { - void *payload; - size_t len; -}; - -static struct a_message ringbuffer[MAX_MESSAGE_QUEUE]; -static int ringbuffer_head; - -static int -callback_lws_mirror(struct libwebsocket_context *context, - struct libwebsocket *wsi, - enum libwebsocket_callback_reasons reason, - void *user, void *in, size_t len) -{ - int n; - struct per_session_data__lws_mirror *pss = (struct per_session_data__lws_mirror *)user; - - switch (reason) { - - case LWS_CALLBACK_ESTABLISHED: - lwsl_info("callback_lws_mirror: LWS_CALLBACK_ESTABLISHED\n"); - pss->ringbuffer_tail = ringbuffer_head; - pss->wsi = wsi; - break; - - case LWS_CALLBACK_PROTOCOL_DESTROY: - lwsl_notice("mirror protocol cleaning up\n"); - for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++) - if (ringbuffer[n].payload) - free(ringbuffer[n].payload); - break; - - case LWS_CALLBACK_SERVER_WRITEABLE: - if (close_testing) - break; - while (pss->ringbuffer_tail != ringbuffer_head) { - - n = libwebsocket_write(wsi, (unsigned char *) - ringbuffer[pss->ringbuffer_tail].payload + - LWS_SEND_BUFFER_PRE_PADDING, - ringbuffer[pss->ringbuffer_tail].len, - LWS_WRITE_TEXT); - if (n < 0) { - lwsl_err("ERROR %d writing to mirror socket\n", n); - return -1; - } - if (n < ringbuffer[pss->ringbuffer_tail].len) - lwsl_err("mirror partial write %d vs %d\n", - n, ringbuffer[pss->ringbuffer_tail].len); - - if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1)) - pss->ringbuffer_tail = 0; - else - pss->ringbuffer_tail++; - - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 15)) - libwebsocket_rx_flow_allow_all_protocol( - libwebsockets_get_protocol(wsi)); - - // lwsl_debug("tx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); - - if (lws_send_pipe_choked(wsi)) { - libwebsocket_callback_on_writable(context, wsi); - break; - } - /* - * for tests with chrome on same machine as client and - * server, this is needed to stop chrome choking - */ -#ifdef _WIN32 - Sleep(1); -#else - usleep(1); -#endif - } - break; - - case LWS_CALLBACK_RECEIVE: - - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) == (MAX_MESSAGE_QUEUE - 1)) { - lwsl_err("dropping!\n"); - goto choke; - } - - if (ringbuffer[ringbuffer_head].payload) - free(ringbuffer[ringbuffer_head].payload); - - ringbuffer[ringbuffer_head].payload = - malloc(LWS_SEND_BUFFER_PRE_PADDING + len + - LWS_SEND_BUFFER_POST_PADDING); - ringbuffer[ringbuffer_head].len = len; - memcpy((char *)ringbuffer[ringbuffer_head].payload + - LWS_SEND_BUFFER_PRE_PADDING, in, len); - if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) - ringbuffer_head = 0; - else - ringbuffer_head++; - - if (((ringbuffer_head - pss->ringbuffer_tail) & - (MAX_MESSAGE_QUEUE - 1)) != (MAX_MESSAGE_QUEUE - 2)) - goto done; - -choke: - lwsl_debug("LWS_CALLBACK_RECEIVE: throttling %p\n", wsi); - libwebsocket_rx_flow_control(wsi, 0); - -// lwsl_debug("rx fifo %d\n", (ringbuffer_head - pss->ringbuffer_tail) & (MAX_MESSAGE_QUEUE - 1)); -done: - libwebsocket_callback_on_writable_all_protocol( - libwebsockets_get_protocol(wsi)); - break; - - /* - * this just demonstrates how to use the protocol filter. If you won't - * study and reject connections based on header content, you don't need - * to handle this callback - */ - - case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: - dump_handshake_info(wsi); - /* you could return non-zero here and kill the connection */ - break; - - default: - break; - } - - return 0; -} - - -/* list of supported protocols and callbacks */ - -static struct libwebsocket_protocols protocols[] = { - /* first protocol must always be HTTP handler */ - - { - "http-only", /* name */ - callback_http, /* callback */ - sizeof (struct per_session_data__http), /* per_session_data_size */ - 0, /* max frame size / rx buffer */ - }, - { - "dumb-increment-protocol", - callback_dumb_increment, - sizeof(struct per_session_data__dumb_increment), - 10, - }, - { - "lws-mirror-protocol", - callback_lws_mirror, - sizeof(struct per_session_data__lws_mirror), - 128, - }, - { NULL, NULL, 0, 0 } /* terminator */ -}; - -void sighandler(int sig) -{ - force_exit = 1; - libwebsocket_cancel_service(context); -} - -void webui_start() -{ - char cert_path[1024]; - char key_path[1024]; - int n = 0; - int use_ssl = 0; - int opts = 0; - char interface_name[128] = ""; - const char *iface = NULL; -#ifndef WIN32 - int syslog_options = LOG_PID | LOG_PERROR; -#endif - struct lws_context_creation_info info; - - int debug_level = 7; -#ifndef LWS_NO_DAEMONIZE - int daemonize = 0; -#endif - - memset(&info, 0, sizeof info); - info.port = 5678; - - const string path = WEBUI_PATH; - - const char* resource_path = path.c_str(); - -#ifndef WIN32 - /* we will only try to log things according to our debug_level */ - setlogmask(LOG_UPTO (LOG_DEBUG)); - openlog("lwsts", syslog_options, LOG_DAEMON); -#endif - - /* tell the library what debug level to emit and to send it to syslog */ - lws_set_log_level(debug_level, lwsl_emit_syslog); - - lwsl_notice("libwebsockets test server - " - "(C) Copyright 2010-2013 Andy Green - " - "licensed under LGPL2.1\n"); -#ifdef EXTERNAL_POLL - max_poll_elements = getdtablesize(); - pollfds = malloc(max_poll_elements * sizeof (struct pollfd)); - fd_lookup = malloc(max_poll_elements * sizeof (int)); - if (pollfds == NULL || fd_lookup == NULL) { - lwsl_err("Out of memory pollfds=%d\n", max_poll_elements); - return -1; - } -#endif - - info.iface = iface; - info.protocols = protocols; -#ifndef LWS_NO_EXTENSIONS - info.extensions = libwebsocket_get_internal_extensions(); -#endif - if (!use_ssl) { - info.ssl_cert_filepath = NULL; - info.ssl_private_key_filepath = NULL; - } else { - if (strlen(resource_path) > sizeof(cert_path) - 32) { - lwsl_err("resource path too long\n"); - return ; - } - sprintf(cert_path, "%s/libwebsockets-test-server.pem", - resource_path); - if (strlen(resource_path) > sizeof(key_path) - 32) { - lwsl_err("resource path too long\n"); - return; - } - sprintf(key_path, "%s/libwebsockets-test-server.key.pem", - resource_path); - - info.ssl_cert_filepath = cert_path; - info.ssl_private_key_filepath = key_path; - } - info.gid = -1; - info.uid = -1; - info.options = opts; - - context = libwebsocket_create_context(&info); - if (context == NULL) { - lwsl_err("libwebsocket init failed\n"); - return ; - } - - n = 0; - double old_time = 0; - - while (n >= 0 && !force_exit) { - - double time = os_GetSeconds(); - - /* - * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every - * live websocket connection using the DUMB_INCREMENT protocol, - * as soon as it can take more packets (usually immediately) - */ - - if ((time - old_time ) > 0.050) { - libwebsocket_callback_on_writable_all_protocol(&protocols[PROTOCOL_DUMB_INCREMENT]); - old_time = time; - } - -#ifdef EXTERNAL_POLL - - /* - * this represents an existing server's single poll action - * which also includes libwebsocket sockets - */ - - n = poll(pollfds, count_pollfds, 50); - if (n < 0) - continue; - - - if (n) - for (n = 0; n < count_pollfds; n++) - if (pollfds[n].revents) - /* - * returns immediately if the fd does not - * match anything under libwebsockets - * control - */ - if (libwebsocket_service_fd(context, - &pollfds[n]) < 0) - goto done; -#else - /* - * If libwebsockets sockets are all we care about, - * you can use this api which takes care of the poll() - * and looping through finding who needed service. - * - * If no socket needs service, it'll return anyway after - * the number of ms in the second argument. - */ - - n = libwebsocket_service(context, 50); -#endif - } - -#ifdef EXTERNAL_POLL -done: -#endif - - libwebsocket_context_destroy(context); - - lwsl_notice("libwebsockets-test-server exited cleanly\n"); - -#ifndef WIN32 - closelog(); -#endif - - return; -} diff --git a/core/webui/server.h b/core/webui/server.h deleted file mode 100644 index 2dd42c05b..000000000 --- a/core/webui/server.h +++ /dev/null @@ -1 +0,0 @@ -void webui_start(); \ No newline at end of file diff --git a/shell/android-studio/reicast/src/main/jni/Android.mk b/shell/android-studio/reicast/src/main/jni/Android.mk index cd3c4ba5a..7841229dc 100644 --- a/shell/android-studio/reicast/src/main/jni/Android.mk +++ b/shell/android-studio/reicast/src/main/jni/Android.mk @@ -18,7 +18,6 @@ LOCAL_PATH:= $(call my-dir)/.. include $(CLEAR_VARS) FOR_ANDROID := 1 -WEBUI := 1 USE_GLES := 1 CHD5_LZMA := 1 CHD5_FLAC := 1 diff --git a/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj b/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj index 1db463737..158cdeef7 100644 --- a/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-ios/reicast-ios.xcodeproj/project.pbxproj @@ -1826,7 +1826,6 @@ "DEBUG=1", "TARGET_IPHONE=1", "$(inherited)", - "TARGET_NO_WEBUI=1", ); HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -1861,7 +1860,6 @@ GCC_PREPROCESSOR_DEFINITIONS = ( "GLES=1", "TARGET_IPHONE=1", - "TARGET_NO_WEBUI=1", ); HEADER_SEARCH_PATHS = ( "$(inherited)", diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index 3130bb2ee..700df50f0 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -2592,7 +2592,6 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_NO_WEBUI, TARGET_NO_NIXPROF, TARGET_NO_COREIO_HTTP, TARGET_NO_AREC, @@ -2650,7 +2649,6 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_NO_WEBUI, TARGET_NO_NIXPROF, TARGET_NO_COREIO_HTTP, TARGET_NO_AREC, @@ -2816,7 +2814,6 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_NO_WEBUI, TARGET_NO_NIXPROF, TARGET_NO_COREIO_HTTP, TARGET_NO_AREC, @@ -2934,7 +2931,6 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = ( - TARGET_NO_WEBUI, TARGET_NO_NIXPROF, TARGET_NO_COREIO_HTTP, TARGET_NO_AREC, diff --git a/shell/cmake/CMakeLists.txt b/shell/cmake/CMakeLists.txt index aef683440..6ef80613d 100644 --- a/shell/cmake/CMakeLists.txt +++ b/shell/cmake/CMakeLists.txt @@ -21,7 +21,6 @@ option(USE_ALSA "Use ALSA" ON) option(USE_LIBAO "Use LibAO" OFF) option(USE_GLES "Use GL ES" OFF) option(USE_PULSEAUDIO "Use PulseAudio" OFF) -option(USE_WEBUI "Use WebUI" ON) option(USE_REND "Use some rendering" ON) option(USE_EVDEV "Use EVDEV" ON) option(USE_JOYSTICK "Use Joystick" ON) @@ -189,13 +188,6 @@ endif() # Optional features -if(USE_WEBUI) - add_definitions(-DWEBUI) - add_directory(core/webui) - add_directory(core/deps/libwebsocket) - # TODO, deps/ifaddrs/ for Android -endif() - if(USE_EVDEV) add_definitions(-DUSE_EVDEV) endif() diff --git a/shell/cmake/config.cmake b/shell/cmake/config.cmake index da6b9fa44..2c0967191 100644 --- a/shell/cmake/config.cmake +++ b/shell/cmake/config.cmake @@ -340,7 +340,7 @@ if (TARGET_NSW) # -DCMAKE_TOOLCHAIN_FILE=./cmake/devkitA64.cmake -DTARGET_NSW=ON add_definitions(-D__SWITCH__ -DGLES -DMESA_EGL_NO_X11_HEADERS) add_definitions(-DTARGET_NO_THREADS -DTARGET_NO_EXCEPTIONS -DTARGET_NO_NIXPROF) - add_definitions(-DTARGET_NO_COREIO_HTTP -DTARGET_NO_WEBUI -UTARGET_SOFTREND) + add_definitions(-DTARGET_NO_COREIO_HTTP -UTARGET_SOFTREND) add_definitions(-D_GLIBCXX_USE_C99_MATH_TR1 -D_LDBL_EQ_DBL) endif() @@ -352,14 +352,12 @@ if (TARGET_PS4) # -DCMAKE_TOOLCHAIN_FILE=./cmake/{ps4sdk,clang_scei}.cmake -DTAR add_definitions(-DPS4 -DTARGET_PS4 -DTARGET_BSD -D__ORBIS__ -DGLES -DMESA_EGL_NO_X11_HEADERS) ## last needed for __unix__ on eglplatform.h add_definitions(-DTARGET_NO_THREADS -DTARGET_NO_EXCEPTIONS -DTARGET_NO_NIXPROF) - add_definitions(-DTARGET_NO_COREIO_HTTP -DTARGET_NO_WEBUI -UTARGET_SOFTREND) + add_definitions(-DTARGET_NO_COREIO_HTTP -UTARGET_SOFTREND) message("*******FIXME******** LARGE PAGES !!") endif() - - if(ZBUILD) set(DEBUG_CMAKE ON) add_definitions(-D_Z_) # Get rid of some warnings and internal dev testing @@ -370,8 +368,6 @@ if(ZBUILD) endif() endif() - - # configure options for osd/ui # osd_default, osd_qt # ui_default, ui_sdl, ui_qt @@ -379,23 +375,10 @@ endif() option(USE_QT False "Use Qt5 for UI and support OS Deps.") - - - -#option TARGET_NO_WEBUI - - - - - #option(BUILD_TESTS "Build tests" OFF) # todo: luserx0 this is your arena, you want tests add em - add_definitions(-DCMAKE_BUILD) - - - add_definitions(-DHOST_OS=${HOST_OS}) add_definitions(-DHOST_CPU=${HOST_CPU}) @@ -405,14 +388,8 @@ add_definitions(-DFEAT_DSPREC=${FEAT_DSPREC}) add_definitions(-DBUILD_COMPILER=${BUILD_COMPILER}) -add_definitions(-DTARGET_NO_WEBUI) add_definitions(-DDEF_CONSOLE) set(RE_CMAKE_CONFIGURED 1) #add_definitions(-D=${}) - - - - - diff --git a/shell/emscripten/Makefile b/shell/emscripten/Makefile index 1b8ef4c22..237e10d01 100644 --- a/shell/emscripten/Makefile +++ b/shell/emscripten/Makefile @@ -26,7 +26,7 @@ LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common CXXONLYFLAGS := -std=c++11 -CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_EXCEPTIONS -D TARGET_NO_WEBUI -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_COREIO_HTTP +CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_EXCEPTIONS -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_COREIO_HTTP CXXFLAGS += -fno-strict-aliasing CXXFLAGS += -ffast-math diff --git a/shell/linux/Makefile b/shell/linux/Makefile index 0b4f36d83..9c8caa2f8 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -3,7 +3,6 @@ LOCAL_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) FOR_LINUX :=1 #NO_REC := 1 #NO_REND := 1 -WEBUI :=1 USE_OSS := 1 #USE_PULSEAUDIO := 1 #USE_SDLAUDIO := 1 @@ -13,11 +12,11 @@ USE_UDEV := 1 USE_MODEM := 1 PLATFORM_EXT := elf -CXX=${CC_PREFIX}g++ -CC=${CC_PREFIX}gcc -AS=${CC_PREFIX}as -STRIP=${CC_PREFIX}strip -LD=${CC} +CXX ?= ${CC_PREFIX}g++ +CC ?= ${CC_PREFIX}gcc +AS ?= ${CC_PREFIX}as +STRIP ?= ${CC_PREFIX}strip +LD ?= ${CC} WINDRES=${CC_PREFIX}windres CHD5_LZMA := 1 CHD5_FLAC := 1 @@ -252,7 +251,7 @@ else ifneq (,$(findstring vero4k,$(platform))) # Windows else ifneq (,$(findstring win32,$(platform))) NOT_ARM := 1 - CFLAGS += -DTARGET_NO_WEBUI -fno-builtin-sqrtf -funroll-loops -DHAVE_FSEEKO -D TARGET_NO_AREC + CFLAGS += -fno-builtin-sqrtf -funroll-loops -DHAVE_FSEEKO -D TARGET_NO_AREC LDFLAGS += -static-libgcc -static-libstdc++ -Wl,-subsystem,windows LIBS := -lopengl32 -lwinmm -lgdi32 -lwsock32 -ldsound -lcomctl32 -lcomdlg32 -lxinput -liphlpapi PLATFORM_EXT := exe @@ -271,7 +270,6 @@ endif undefine USE_EVDEV undefine USE_UDEV undefine FOR_LINUX - undefine WEBUI NO_NIXPROF := 1 FOR_WINDOWS := 1 else @@ -397,6 +395,10 @@ ifdef TEST_AUTOMATION CFLAGS += -DTEST_AUTOMATION endif +ifdef DEBUGFAST + CFLAGS += -DDEBUGFAST +endif + EXECUTABLE_STRIPPED=nosym-reicast.$(PLATFORM_EXT) ifdef NAOMI CFLAGS += -D TARGET_NAOMI From 10e6b296c5696e89475899d8ae4d6fa651ef9126 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 8 Jul 2019 00:03:44 +0200 Subject: [PATCH 128/158] fix cue issue. better logging --- core/hw/sh4/dyna/blockmanager.cpp | 16 ++-- core/hw/sh4/sh4_mmr.cpp | 122 +++++++++++++++--------------- core/imgread/common.h | 2 +- 3 files changed, 68 insertions(+), 72 deletions(-) diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 1a72a7219..26f994527 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -11,6 +11,7 @@ #include "../sh4_core.h" #include "hw/sh4/sh4_mem.h" +#include "hw/sh4/sh4_opcode_list.h" #include "hw/sh4/sh4_sched.h" @@ -785,8 +786,8 @@ bool bm_RamWriteAccess(void *p) return true; } -bool print_stats; -#if 0 +bool print_stats = true; + void fprint_hex(FILE* d,const char* init,u8* ptr, u32& ofs, u32 limit) { int base=ofs; @@ -822,12 +823,12 @@ void print_blocks() INFO_LOG(DYNAREC, "Writing blocks to %p", f); } - for (RuntimeBlockInfo *blk : blkmap) + for (auto it : blkmap) { - + RuntimeBlockInfoPtr blk = it.second; if (f) { - fprintf(f,"block: %p\n",blk); + fprintf(f,"block: %p\n",blk.get()); fprintf(f,"vaddr: %08X\n",blk->vaddr); fprintf(f,"paddr: %08X\n",blk->addr); fprintf(f,"hash: %s\n",blk->hash()); @@ -854,7 +855,7 @@ void print_blocks() for (;joplist.size();j++) { shil_opcode* op = &blk->oplist[j]; - fprint_hex(f,"//h:",pucode,hcode,op->host_offs); + //fprint_hex(f,"//h:",pucode,hcode,op->host_offs); if (gcode!=op->guest_offs) { @@ -880,7 +881,7 @@ void print_blocks() fprintf(f,"//il:%d:%d: %s\n",op->guest_offs,op->host_offs,s.c_str()); } - fprint_hex(f,"//h:",pucode,hcode,blk->host_code_size); + //fprint_hex(f,"//h:",pucode,hcode,blk->host_code_size); fprintf(f,"}\n"); } @@ -891,5 +892,4 @@ void print_blocks() if (f) fclose(f); } #endif -#endif diff --git a/core/hw/sh4/sh4_mmr.cpp b/core/hw/sh4/sh4_mmr.cpp index ca6ca8830..854a2438c 100644 --- a/core/hw/sh4/sh4_mmr.cpp +++ b/core/hw/sh4/sh4_mmr.cpp @@ -443,6 +443,9 @@ void DYNACALL WriteMem_sq(u32 addr,T data) //*********** //**Area 7** //*********** + +#define OUT_OF_RANGE(reg) INFO_LOG(SH4, "Out of range on register %s index %x", reg, addr) + //Read Area7 template T DYNACALL ReadMem_area7(u32 addr) @@ -478,7 +481,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("CCN"); + return 0; } break; @@ -489,7 +493,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("UBC"); + return 0; } break; @@ -498,21 +503,20 @@ T DYNACALL ReadMem_area7(u32 addr) { return (T)sh4_rio_read(BSC,addr & 0xFF); } - else if ((addr>=BSC_SDMR2_addr) && (addr<= 0x1F90FFFF)) - { - //dram settings 2 / write only - INFO_LOG(SH4, "Read from write-only registers [dram settings 2]"); - } - else if ((addr>=BSC_SDMR3_addr) && (addr<= 0x1F94FFFF)) - { - //dram settings 3 / write only - INFO_LOG(SH4, "Read from write-only registers [dram settings 3]"); - } else { - INFO_LOG(SH4, "Out of range on register index . %x", addr); + OUT_OF_RANGE("BSC"); + return 0; } break; + case A7_REG_HASH(BSC_SDMR2_addr): + //dram settings 2 / write only + INFO_LOG(SH4, "Read from write-only registers [dram settings 2]"); + return 0; + case A7_REG_HASH(BSC_SDMR3_addr): + //dram settings 3 / write only + INFO_LOG(SH4, "Read from write-only registers [dram settings 3]"); + return 0; @@ -523,7 +527,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("DMAC"); + return 0; } break; @@ -534,7 +539,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("CPG"); + return 0; } break; @@ -545,7 +551,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("RTC"); + return 0; } break; @@ -556,7 +563,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("INTC"); + return 0; } break; @@ -567,7 +575,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("TMU"); + return 0; } break; @@ -578,7 +587,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("SCI"); + return 0; } break; @@ -589,7 +599,8 @@ T DYNACALL ReadMem_area7(u32 addr) } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("SCIF"); + return 0; } break; @@ -610,7 +621,7 @@ T DYNACALL ReadMem_area7(u32 addr) } - //INFO_LOG(SH4, "Unknown Read from Area7 - addr=%x", addr); + INFO_LOG(SH4, "Unknown Read from Area7 - addr=%x", addr); return 0; } @@ -640,133 +651,118 @@ void DYNACALL WriteMem_area7(u32 addr,T data) if (addr<=0x1F00003C) { sh4_rio_write(CCN,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("CCN"); } - break; + return; case A7_REG_HASH(UBC_BASE_addr): if (addr<=0x1F200020) { sh4_rio_write(UBC,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("UBC"); } - break; + return; case A7_REG_HASH(BSC_BASE_addr): if (addr<=0x1F800048) { sh4_rio_write(BSC,addr & 0xFF,data); - return; - } - else if ((addr>=BSC_SDMR2_addr) && (addr<= 0x1F90FFFF)) - { - //dram settings 2 / write only - return;//no need ? - } - else if ((addr>=BSC_SDMR3_addr) && (addr<= 0x1F94FFFF)) - { - //dram settings 3 / write only - return;//no need ? } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("BSC"); } - break; - + return; + case A7_REG_HASH(BSC_SDMR2_addr): + //dram settings 2 / write only + return; + case A7_REG_HASH(BSC_SDMR3_addr): + //dram settings 3 / write only + return; case A7_REG_HASH(DMAC_BASE_addr): if (addr<=0x1FA00040) { sh4_rio_write(DMAC,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("DMAC"); } - break; + return; case A7_REG_HASH(CPG_BASE_addr): if (addr<=0x1FC00010) { sh4_rio_write(CPG,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("CPG"); } - break; + return; case A7_REG_HASH(RTC_BASE_addr): if (addr<=0x1FC8003C) { sh4_rio_write(RTC,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("RTC"); } - break; + return; case A7_REG_HASH(INTC_BASE_addr): if (addr<=0x1FD0000C) { sh4_rio_write(INTC,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("INTC"); } - break; + return; case A7_REG_HASH(TMU_BASE_addr): if (addr<=0x1FD8002C) { sh4_rio_write(TMU,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("TMU"); } - break; + return; case A7_REG_HASH(SCI_BASE_addr): if (addr<=0x1FE0001C) { sh4_rio_write(SCI,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("SCI"); } - break; + return; case A7_REG_HASH(SCIF_BASE_addr): if (addr<=0x1FE80024) { sh4_rio_write(SCIF,addr & 0xFF,data); - return; } else { - INFO_LOG(SH4, "Out of range on register index %x", addr); + OUT_OF_RANGE("SCIF"); } - break; + return; //who really cares about ht-udi ? it's not existent on dc iirc .. case A7_REG_HASH(UDI_BASE_addr): @@ -784,7 +780,7 @@ void DYNACALL WriteMem_area7(u32 addr,T data) break; } - //EMUERROR3("Write to Area7 not implemented , addr=%x,data=%x",addr,data); + INFO_LOG(SH4, "Write to Area7 not implemented, addr=%x, data=%x", addr, data); } diff --git a/core/imgread/common.h b/core/imgread/common.h index 194bbf11c..275c66f15 100644 --- a/core/imgread/common.h +++ b/core/imgread/common.h @@ -230,7 +230,7 @@ struct Disc //session 2 : start @ track 3, and its fad ses.FirstTrack=3; - ses.StartFAD=tracks[0].StartFAD; + ses.StartFAD=tracks[2].StartFAD; sessions.push_back(ses); //this isn't always true for gdroms, depends on area look @ the get-toc code From 478b1c719c4f2e86d6a30cceccb009e7c4abd00b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 8 Jul 2019 16:30:07 +0200 Subject: [PATCH 129/158] gl4: do a depth-only TR pass in non-autosort mode fixes HeadHunter map/radar issue --- core/rend/gl4/gldraw.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index cfe1302be..d6e5a5f78 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -279,6 +279,11 @@ static void DrawList(const List& gply, int first, int count, int pass continue; } } + if (pass == 0 && Type == ListType_Translucent && (params->isp.DepthMode != 7 || params->isp.ZWriteDis)) + { + params++; + continue; + } gl4ShaderUniforms.poly_number = params - gply.head(); SetGPState(params, pass); glDrawElements(GL_TRIANGLE_STRIP, params->count, GL_UNSIGNED_INT, (GLvoid*)(sizeof(u32) * params->first)); glCheck(); @@ -578,6 +583,22 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) if (!skip_tr) { + + if (!current_pass.autosort) + { + // This pass is for HeadHunter but possibly others as well. + // The map/radar HUD is drawn is a second pass without autosort. + // The first poly drawn uses Always depth func to punch a hole in the depth buffer + // and the subsequent polys draw on top of it with Greater depth func. + // That doesn't work with this renderer because the depth test for transparent polys + // only use the opaque/pt depth, so the first poly is correctly drawn but subsequent polys are discarded. + // To work around this problem, we do a depth only pass with the transparent polys + // that use the Always depth func. + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glcache.Enable(GL_DEPTH_TEST); + glcache.DepthMask(GL_TRUE); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + } // // PASS 3: Render TR to a-buffers // From 329230bf8dc629e9dc0f6eca740bb35d09d6bcde Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 8 Jul 2019 16:31:50 +0200 Subject: [PATCH 130/158] Fix Naomi reset. Add some per-game settings Re-Volt needs 100 extra deptch scale for perfect menus Tom Clancy's Rainbow Six needs RTT to vram for correct loading screens --- core/nullDC.cpp | 27 +++++++++++++++++++-------- core/rend/gui.cpp | 4 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index a2bedf745..bc7954970 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -170,7 +170,11 @@ void LoadSpecialSettings() // L.O.L || !strncmp("T2106M", reios_product_number, 6) // Miss Moonlight - || !strncmp("T18702M", reios_product_number, 7)) + || !strncmp("T18702M", reios_product_number, 7) + // Tom Clancy's Rainbow Six (US) + || !strncmp("T40401N", reios_product_number, 7) + // Tom Clancy's Rainbow Six incl. Eagle Watch Missions (EU) + || !strncmp("T-45001D05", reios_product_number, 10)) { settings.rend.RenderToTextureBuffer = 1; rtt_to_buffer_game = true; @@ -199,6 +203,13 @@ void LoadSpecialSettings() settings.rend.ExtraDepthScale = 10000; extra_depth_game = true; } + // Re-Volt (US, EU) + else if (!strncmp("T-8109N", reios_product_number, 7) || !strncmp("T8107D 50", reios_product_number, 10)) + { + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); + settings.rend.ExtraDepthScale = 100; + extra_depth_game = true; + } // Super Producers if (!strncmp("T14303M", reios_product_number, 7) // Giant Killers @@ -292,12 +303,12 @@ void LoadSpecialSettings() #endif } -void dc_reset() +void dc_reset(bool manual) { - plugins_Reset(false); - mem_Reset(false); + plugins_Reset(manual); + mem_Reset(manual); - sh4_cpu.Reset(false); + sh4_cpu.Reset(manual); } static bool init_done; @@ -358,7 +369,7 @@ int dc_start_game(const char *path) if (init_done) { InitSettings(); - dc_reset(); + dc_reset(true); LoadSettings(false); #if DC_PLATFORM == DC_PLATFORM_DREAMCAST if (!settings.bios.UseReios) @@ -449,7 +460,7 @@ int dc_start_game(const char *path) #endif init_done = true; - dc_reset(); + dc_reset(true); game_started = true; dc_resume(); @@ -489,7 +500,7 @@ void* dc_run(void*) SaveRomFiles(get_writable_data_path("/data/")); if (reset_requested) { - dc_reset(); + dc_reset(false); } } while (reset_requested); diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 6d8217149..cf02f651c 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -47,7 +47,7 @@ extern void dc_loadstate(); extern void dc_savestate(); extern void dc_stop(); -extern void dc_reset(); +extern void dc_reset(bool manual); extern void dc_resume(); extern int dc_start_game(const char *path); extern void UpdateInputState(u32 port); @@ -337,7 +337,7 @@ static void gui_display_commands() ImGui::NextColumn(); if (ImGui::Button("Restart", ImVec2(150 * scaling, 50 * scaling))) { - dc_reset(); + dc_reset(true); gui_state = Closed; } ImGui::NextColumn(); From d5e24d8aedbed5166e03e8ffb0bd96a2ee25a957 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Mon, 8 Jul 2019 18:10:43 +0200 Subject: [PATCH 131/158] Cleaner init. Get rid of LastImage --- core/hw/aica/aica.cpp | 1 + core/hw/arm7/arm_mem.h | 3 - core/hw/arm7/vbaARM.cpp | 2 - core/hw/maple/maple_devs.cpp | 8 ++ core/imgread/common.cpp | 37 +++------- core/nullDC.cpp | 137 ++++++++++++++++------------------- core/types.h | 1 - 7 files changed, 83 insertions(+), 106 deletions(-) diff --git a/core/hw/aica/aica.cpp b/core/hw/aica/aica.cpp index 4ef983a31..381616838 100644 --- a/core/hw/aica/aica.cpp +++ b/core/hw/aica/aica.cpp @@ -216,4 +216,5 @@ void libAICA_Reset(bool manual) void libAICA_Term() { sgc_Term(); + term_mem(); } diff --git a/core/hw/arm7/arm_mem.h b/core/hw/arm7/arm_mem.h index ee4055e41..10db8a668 100644 --- a/core/hw/arm7/arm_mem.h +++ b/core/hw/arm7/arm_mem.h @@ -54,9 +54,6 @@ static inline void DYNACALL WriteMemArm(u32 addr,T data) u32 sh4_ReadMem_reg(u32 addr,u32 size); void sh4_WriteMem_reg(u32 addr,u32 data,u32 size); -void init_mem(); -void term_mem(); - #define aica_reg_16 ((u16*)aica_reg) #define AICA_RAM_SIZE (ARAM_SIZE) diff --git a/core/hw/arm7/vbaARM.cpp b/core/hw/arm7/vbaARM.cpp index 182e95868..037c7b28c 100644 --- a/core/hw/arm7/vbaARM.cpp +++ b/core/hw/arm7/vbaARM.cpp @@ -9,7 +9,6 @@ //called when plugin is used by emu (you should do first time init here) s32 libARM_Init() { - init_mem(); arm_Init(); return rv_ok; @@ -18,7 +17,6 @@ s32 libARM_Init() //called when plugin is unloaded by emu, only if dcInit is called (eg, not called to enumerate plugins) void libARM_Term() { - term_mem(); //arm7_Term ? } diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index f7acc5e38..dde4e456f 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -2189,6 +2189,14 @@ struct maple_naomi_jamma : maple_sega_controller break; + case MDCF_GetCondition: + w8(MDRE_UnknownCmd); + w8(0x00); + w8(0x00); + w8(0x00); + + break; + default: INFO_LOG(MAPLE, "Unknown Maple command %x", cmd); w8(MDRE_UnknownCmd); diff --git a/core/imgread/common.cpp b/core/imgread/common.cpp index 9f802e6d1..f7e2643e2 100644 --- a/core/imgread/common.cpp +++ b/core/imgread/common.cpp @@ -192,8 +192,7 @@ bool InitDrive(u32 fileflags) // FIXME: Data loss if buffer is too small wchar fn[512]; - strncpy(fn,settings.imgread.LastImage, sizeof(fn)); - fn[sizeof(fn) - 1] = '\0'; + fn[0] = '\0'; #ifdef BUILD_DREAMCAST int gfrv=GetFile(fn,0,fileflags); @@ -214,20 +213,14 @@ bool InitDrive(u32 fileflags) return false; } - // FIXME: Data loss if buffer is too small - strncpy(settings.imgread.LastImage, fn, sizeof(settings.imgread.LastImage)); - settings.imgread.LastImage[sizeof(settings.imgread.LastImage) - 1] = '\0'; - - SaveSettings(); - if (!InitDrive_(fn)) { //msgboxf("Selected image failed to load",MBX_ICONERROR); - NullDriveDiscType=NoDisk; - gd_setdisc(); - sns_asc=0x29; - sns_ascq=0x00; - sns_key=0x6; + NullDriveDiscType = NoDisk; + gd_setdisc(); + sns_asc = 0x29; + sns_ascq = 0x00; + sns_key = 0x6; return true; } else @@ -256,8 +249,7 @@ bool DiscSwap(u32 fileflags) // FIXME: Data loss if buffer is too small wchar fn[512]; - strncpy(fn, settings.imgread.LastImage, sizeof(fn)); - fn[sizeof(fn) - 1] = '\0'; + fn[0] = '\0'; #ifdef BUILD_DREAMCAST @@ -267,7 +259,7 @@ bool DiscSwap(u32 fileflags) #endif if (gfrv == 0) { - NullDriveDiscType=Open; + NullDriveDiscType = Open; gd_setdisc(); return true; } @@ -276,17 +268,10 @@ bool DiscSwap(u32 fileflags) return false; } - // FIXME: Data loss if buffer is too small - strncpy(settings.imgread.LastImage, fn, sizeof(settings.imgread.LastImage)); - settings.imgread.LastImage[sizeof(settings.imgread.LastImage) - 1] = '\0'; - - - SaveSettings(); - if (!InitDrive_(fn)) { //msgboxf("Selected image failed to load",MBX_ICONERROR); - NullDriveDiscType=Open; + NullDriveDiscType = Open; gd_setdisc(); } @@ -296,10 +281,10 @@ bool DiscSwap(u32 fileflags) void TermDrive() { - if (disc!=0) + if (disc != NULL) delete disc; - disc=0; + disc = NULL; } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index bc7954970..e193a948d 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -311,7 +311,6 @@ void dc_reset(bool manual) sh4_cpu.Reset(manual); } -static bool init_done; static bool reset_requested; int reicast_init(int argc, char* argv[]) @@ -359,81 +358,14 @@ int reicast_init(int argc, char* argv[]) #define DATA_PATH "/" #endif -bool game_started; - -int dc_start_game(const char *path) +static int dc_init() { - if (path != NULL) - cfgSetVirtual("config", "image", path); + static bool init_done; if (init_done) - { - InitSettings(); - dc_reset(true); - LoadSettings(false); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - if (!settings.bios.UseReios) -#endif - if (!LoadRomFiles(get_readonly_data_path(DATA_PATH))) - return -5; - -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - if (path == NULL) - { - // Boot BIOS - settings.imgread.LastImage[0] = 0; - TermDrive(); - InitDrive(); - } - else - { - if (DiscSwap()) - LoadCustom(); - } -#elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - if (!naomi_cart_SelectFile()) - return -6; - LoadCustom(); -#if DC_PLATFORM == DC_PLATFORM_NAOMI - mcfg_CreateNAOMIJamma(); -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - mcfg_CreateAtomisWaveControllers(); -#endif -#endif - - game_started = true; - dc_resume(); - return 0; - } - - if (settings.bios.UseReios || !LoadRomFiles(get_readonly_data_path(DATA_PATH))) - { -#ifdef USE_REIOS - if (!LoadHle(get_readonly_data_path(DATA_PATH))) - { - return -5; - } - else - { - NOTICE_LOG(BOOT, "Did not load bios, using reios\n"); - } -#else - ERROR_LOG(BOOT, "Cannot find BIOS files\n"); - return -5; -#endif - } - if (plugins_Init()) return -3; - -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - if (!naomi_cart_SelectFile()) - return -6; -#endif - - LoadCustom(); - #if FEAT_SHREC != DYNAREC_NONE Get_Sh4Recompiler(&sh4_cpu); sh4_cpu.Init(); // Also initialize the interpreter @@ -450,17 +382,74 @@ int dc_start_game(const char *path) } mem_Init(); + mem_map_default(); // TODO needs to be called again if changing platform - mem_map_default(); + init_done = true; + return 0; +} + +bool game_started; + +int dc_start_game(const char *path) +{ + if (path != NULL) + cfgSetVirtual("config", "image", path); + + int rc = dc_init(); + if (rc != 0) + return rc; + + InitSettings(); + dc_reset(true); + LoadSettings(false); + if (!LoadRomFiles(get_readonly_data_path(DATA_PATH))) + { +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST +#ifdef USE_REIOS + if (settings.bios.UseReios) + { + if (!LoadHle(get_readonly_data_path(DATA_PATH))) + { + ERROR_LOG(BOOT, "Cannot init HLE BIOS"); + return -5; + } + else + { + NOTICE_LOG(BOOT, "Did not load bios, using reios"); + } + } + else +#endif + { + ERROR_LOG(BOOT, "Cannot find BIOS files"); + return -5; + } +#endif + } + +#if DC_PLATFORM == DC_PLATFORM_DREAMCAST + if (path == NULL) + { + // Boot BIOS + TermDrive(); + InitDrive(); + } + else + { + if (DiscSwap()) + LoadCustom(); + } +#elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + if (!naomi_cart_SelectFile()) + return -6; + LoadCustom(); #if DC_PLATFORM == DC_PLATFORM_NAOMI mcfg_CreateNAOMIJamma(); #elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE mcfg_CreateAtomisWaveControllers(); #endif - init_done = true; - - dc_reset(true); +#endif game_started = true; dc_resume(); diff --git a/core/types.h b/core/types.h index e4a0e3c0b..cf5522668 100644 --- a/core/types.h +++ b/core/types.h @@ -707,7 +707,6 @@ struct settings_t bool PatchRegion; bool LoadDefaultImage; char DefaultImage[512]; - char LastImage[512]; } imgread; struct From 632aa95c2dbe2b0845893e449ebf308b041f8a70 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 9 Jul 2019 15:25:15 +0200 Subject: [PATCH 132/158] gl4: depth test issue in non-autosort mode Depth testing is done in the fragment shader so it shouldn't be done in the a-buffer shader for the first pixel, or until the depth is updated. Fixes flashlight and lightstorm effects in Alone in the Dark --- core/rend/gl4/abuffer.cpp | 65 ++++++++++++++++++++++----------------- core/rend/gl4/gldraw.cpp | 33 ++++++++++---------- core/rend/gles/gldraw.cpp | 3 +- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index f0e9bb0f4..470309fba 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -72,46 +72,53 @@ vec4 resolveAlphaBlend(ivec2 coords) { \n\ vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer \n\ float depth = 1.0; \n\ \n\ + bool do_depth_test = false; \n\ for (int i = 0; i < num_frag; i++) \n\ { \n\ const Pixel pixel = pixels[pixel_list[i]]; \n\ const PolyParam pp = tr_poly_params[getPolyNumber(pixel)]; \n\ #if DEPTH_SORTED != 1 \n\ const float frag_depth = pixel.depth; \n\ - switch (getDepthFunc(pp)) \n\ + if (do_depth_test) \n\ { \n\ - case 0: // Never \n\ - continue; \n\ - case 1: // Greater \n\ - if (frag_depth <= depth) \n\ + switch (getDepthFunc(pp)) \n\ + { \n\ + case 0: // Never \n\ continue; \n\ - break; \n\ - case 2: // Equal \n\ - if (frag_depth != depth) \n\ - continue; \n\ - break; \n\ - case 3: // Greater or equal \n\ - if (frag_depth < depth) \n\ - continue; \n\ - break; \n\ - case 4: // Less \n\ - if (frag_depth >= depth) \n\ - continue; \n\ - break; \n\ - case 5: // Not equal \n\ - if (frag_depth == depth) \n\ - continue; \n\ - break; \n\ - case 6: // Less or equal \n\ - if (frag_depth > depth) \n\ - continue; \n\ - break; \n\ - case 7: // Always \n\ - break; \n\ + case 1: // Greater \n\ + if (frag_depth <= depth) \n\ + continue; \n\ + break; \n\ + case 2: // Equal \n\ + if (frag_depth != depth) \n\ + continue; \n\ + break; \n\ + case 3: // Greater or equal \n\ + if (frag_depth < depth) \n\ + continue; \n\ + break; \n\ + case 4: // Less \n\ + if (frag_depth >= depth) \n\ + continue; \n\ + break; \n\ + case 5: // Not equal \n\ + if (frag_depth == depth) \n\ + continue; \n\ + break; \n\ + case 6: // Less or equal \n\ + if (frag_depth > depth) \n\ + continue; \n\ + break; \n\ + case 7: // Always \n\ + break; \n\ + } \n\ } \n\ \n\ if (getDepthMask(pp)) \n\ + { \n\ depth = frag_depth; \n\ + do_depth_test = true; \n\ + } \n\ #endif \n\ bool area1 = false; \n\ bool shadowed = false; \n\ @@ -207,7 +214,7 @@ void main(void) \n\ ivec2 coords = ivec2(gl_FragCoord.xy); \n\ // Compute and output final color for the frame buffer \n\ // Visualize the number of layers in use \n\ - //FragColor = vec4(float(fillFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT, 0, 0, 1); \n\ + //FragColor = vec4(float(fillAndSortFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT * 4, 0, 0, 1); \n\ FragColor = resolveAlphaBlend(coords); \n\ } \n\ "; diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index d6e5a5f78..ac207c6ad 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -103,7 +103,7 @@ static void SetTextureRepeatMode(int index, GLuint dir, u32 clamp, u32 mirror) } template - static void SetGPState(const PolyParam* gp, int pass, u32 cflip=0) + static void SetGPState(PolyParam* gp, int pass) { if (gp->pcw.Texture && gp->tsp.FilterMode > 1) { @@ -231,14 +231,14 @@ template //set cull mode ! //cflip is required when exploding triangles for triangle sorting //gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction - SetCull(gp->isp.CullMode^cflip^gcflip); + SetCull(gp->isp.CullMode ^ gcflip); //set Z mode, only if required - if (Type == ListType_Punch_Through || (Type == ListType_Translucent && SortingEnabled)) + if (Type == ListType_Punch_Through) { glcache.DepthFunc(Zfunction[6]); // Greater or equal } - else + else if (Type == ListType_Opaque) { glcache.DepthFunc(Zfunction[gp->isp.DepthMode]); } @@ -246,7 +246,8 @@ template // Depth buffer is updated in pass 0 (and also in pass 1 for OP PT) if (pass < 2) { - // Ignore ZWriteDis for punch-through? fixes Worms World Party + // Z Write Disable seems to be ignored for punch-through polys + // Fixes Worms World Party, Bust-a-Move 4 and Re-Volt if (Type == ListType_Punch_Through) glcache.DepthMask(GL_TRUE); else @@ -256,7 +257,7 @@ template glcache.DepthMask(GL_FALSE); } -template +template static void DrawList(const List& gply, int first, int count, int pass) { PolyParam* params = &gply.head()[first]; @@ -279,7 +280,7 @@ static void DrawList(const List& gply, int first, int count, int pass continue; } } - if (pass == 0 && Type == ListType_Translucent && (params->isp.DepthMode != 7 || params->isp.ZWriteDis)) + if (OnlyAlwaysDepth && (params->isp.DepthMode != 7 || params->isp.ZWriteDis)) { params++; continue; @@ -534,8 +535,8 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glcache.Enable(GL_STENCIL_TEST); glcache.StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0); - DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0); + DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 0); + DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 0); // Modifier volumes if (settings.rend.ModifierVolumes) @@ -570,10 +571,10 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glCheck(); //Opaque - DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1); + DrawList(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count, 1); //Alpha tested - DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1); + DrawList(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count, 1); // Unbind stencil glActiveTexture(GL_TEXTURE3); @@ -597,7 +598,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glcache.Enable(GL_DEPTH_TEST); glcache.DepthMask(GL_TRUE); - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); } // // PASS 3: Render TR to a-buffers @@ -611,9 +612,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) //Alpha blended if (current_pass.autosort) - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more else - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 3); // 3 because pass 2 is no more glCheck(); // Translucent modifier volumes @@ -632,9 +633,9 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) glcache.Enable(GL_DEPTH_TEST); if (current_pass.autosort) - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); else - DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); + DrawList(pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count, 0); // // PASS 3c: Render a-buffer to temporary texture diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 4f0c746ce..51c1a2ca8 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -264,7 +264,8 @@ __forceinline glcache.DepthMask(GL_FALSE); else { - // Ignore ZWriteDis for punch-through? fixes Worms World Party + // Z Write Disable seems to be ignored for punch-through. + // Fixes Worms World Party, Bust-a-Move 4 and Re-Volt if (Type == ListType_Punch_Through) glcache.DepthMask(GL_TRUE); else From f3a91de1affab4e41f846b92351be212f3f34fe5 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 9 Jul 2019 23:52:19 +0200 Subject: [PATCH 133/158] Unify dreamcast, naomi and atomiswave builds WIP --- .cproject | 42 + .project | 27 + .settings/language.settings.xml | 15 + core/build.h | 89 +- core/cfg/cl.cpp | 7 +- core/deps/vixl/platform-vixl.h | 2 +- core/hw/flashrom/flashrom.h | 106 +- core/hw/gdrom/gdromv3.cpp | 15 +- core/hw/holly/sb.cpp | 15 +- core/hw/holly/sb_mem.cpp | 277 ++- core/hw/maple/maple_cfg.cpp | 55 +- core/hw/maple/maple_cfg.h | 3 - core/hw/maple/maple_devs.cpp | 18 +- core/hw/maple/maple_if.cpp | 7 +- core/hw/mem/_vmem.cpp | 44 +- core/hw/mem/_vmem.h | 1 + core/hw/mem/vmem32.cpp | 2 +- core/hw/naomi/naomi.cpp | 7 +- core/hw/naomi/naomi_cart.cpp | 54 +- core/hw/naomi/naomi_cart.h | 1 + core/hw/sh4/dyna/blockmanager.cpp | 21 +- core/hw/sh4/modules/bsc.cpp | 29 +- core/imgread/ImgReader.cpp | 4 +- core/linux-dist/main.cpp | 5 - core/nullDC.cpp | 499 +++-- core/reios/reios.cpp | 4 +- core/rend/TexCache.cpp | 2 +- core/rend/gui.cpp | 45 +- core/serialize.cpp | 59 +- core/types.h | 27 +- core/windows/winmain.cpp | 4 - p.patch | 1994 +++++++++++++++++ shell/android-studio/reicast/build.gradle | 14 +- .../reicast/src/main/jni/src/Android.cpp | 3 - shell/apple/emulator-ios/emulator/ios_main.mm | 3 - .../emulator-osx/emulator-osx/osx-main.mm | 4 - shell/linux/.gdb_history | 42 + shell/linux/flycast.log | 0 38 files changed, 2857 insertions(+), 689 deletions(-) create mode 100644 .cproject create mode 100644 .project create mode 100644 .settings/language.settings.xml create mode 100644 p.patch create mode 100644 shell/linux/.gdb_history create mode 100644 shell/linux/flycast.log diff --git a/.cproject b/.cproject new file mode 100644 index 000000000..ba11c3feb --- /dev/null +++ b/.cproject @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 000000000..dd1c00db8 --- /dev/null +++ b/.project @@ -0,0 +1,27 @@ + + + flycast-unified + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 000000000..4762844a1 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/core/build.h b/core/build.h index 3ba546c1d..c74634071 100755 --- a/core/build.h +++ b/core/build.h @@ -345,94 +345,7 @@ #define RAM_SIZE_MAX (32*1024*1024) #define VRAM_SIZE_MAX (16*1024*1024) #define ARAM_SIZE_MAX (8*1024*1024) - -#if (DC_PLATFORM==DC_PLATFORM_DREAMCAST) - - #define BUILD_DREAMCAST 1 - - //DC : 16 mb ram, 8 mb vram, 2 mb aram, 2 mb bios, 128k flash - #define RAM_SIZE (16*1024*1024) - #define VRAM_SIZE (8*1024*1024) - #define ARAM_SIZE (2*1024*1024) - #define BIOS_SIZE (2*1024*1024) - #define FLASH_SIZE (128*1024) - - #define ROM_PREFIX "dc_" - #define ROM_NAMES - #define NVR_OPTIONAL 0 - -#elif (DC_PLATFORM==DC_PLATFORM_DEV_UNIT) - - #define BUILD_DEV_UNIT 1 - - //Devkit : 32 mb ram, 8? mb vram, 2? mb aram, 2? mb bios, ? flash - #define RAM_SIZE (32*1024*1024) - #define VRAM_SIZE (8*1024*1024) - #define ARAM_SIZE (2*1024*1024) - #define BIOS_SIZE (2*1024*1024) - #define FLASH_SIZE (128*1024) - - #define ROM_PREFIX "hkt_" - #define ROM_NAMES - #define NVR_OPTIONAL 0 - -#elif (DC_PLATFORM==DC_PLATFORM_NAOMI) - - //Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash - #define RAM_SIZE (32*1024*1024) - #define VRAM_SIZE (16*1024*1024) - #define ARAM_SIZE (8*1024*1024) - #define BIOS_SIZE (2*1024*1024) - #define BBSRAM_SIZE (32*1024) - - #define ROM_PREFIX "naomi_" - #define ROM_NAMES ";epr-21576d.bin" - #define NVR_OPTIONAL 1 - -#elif (DC_PLATFORM==DC_PLATFORM_NAOMI2) - - //Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash - #define RAM_SIZE (32*1024*1024) - #define VRAM_SIZE (16*1024*1024) - #define ARAM_SIZE (8*1024*1024) - #define BIOS_SIZE (2*1024*1024) - #define BBSRAM_SIZE (32*1024) - - #define ROM_PREFIX "n2_" - #define ROM_NAMES - #define NVR_OPTIONAL 1 - -#elif (DC_PLATFORM==DC_PLATFORM_ATOMISWAVE) - - #define BUILD_ATOMISWAVE 1 - - //Atomiswave : 16 mb ram, 8 mb vram, 8 mb aram, 128kb bios on flash, 128kb battery-backed ram - #define RAM_SIZE (16*1024*1024) - #define VRAM_SIZE (8*1024*1024) - #define ARAM_SIZE (8*1024*1024) - #define BIOS_SIZE (128*1024) - #define BBSRAM_SIZE (128*1024) - - #define ROM_PREFIX "aw_" - #define ROM_NAMES ";bios.ic23_l" - #define NVR_OPTIONAL 1 - -#else - #error invalid build config -#endif - -#define RAM_MASK (RAM_SIZE-1) -#define VRAM_MASK (VRAM_SIZE-1) -#define ARAM_MASK (ARAM_SIZE-1) -#define BIOS_MASK (BIOS_SIZE-1) - -#ifdef FLASH_SIZE -#define FLASH_MASK (FLASH_SIZE-1) -#endif - -#ifdef BBSRAM_SIZE -#define BBSRAM_MASK (BBSRAM_SIZE-1) -#endif +#define BUILD_DREAMCAST 1 #define GD_CLOCK 33868800 //GDROM XTAL -- 768fs diff --git a/core/cfg/cl.cpp b/core/cfg/cl.cpp index 8f8a2140d..8d39747f5 100644 --- a/core/cfg/cl.cpp +++ b/core/cfg/cl.cpp @@ -133,8 +133,7 @@ bool ParseCommandLine(int argc,wchar* argv[]) if (extension && (stricmp(extension, ".cdi") == 0 || stricmp(extension, ".chd") == 0 - || stricmp(extension, ".gdi") == 0 || stricmp(extension, ".lst") == 0 - || stricmp(extension, ".cue") == 0)) + || stricmp(extension, ".gdi") == 0 || stricmp(extension, ".cue") == 0)) { INFO_LOG(COMMON, "Using '%s' as cd image", *arg); cfgSetVirtual("config", "image", *arg); @@ -147,12 +146,8 @@ bool ParseCommandLine(int argc,wchar* argv[]) } else { -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE INFO_LOG(COMMON, "Using '%s' as rom", *arg); cfgSetVirtual("config", "image", *arg); -#else - WARN_LOG(COMMON, "wtf %s is supposed to do ?",*arg); -#endif } } arg++; diff --git a/core/deps/vixl/platform-vixl.h b/core/deps/vixl/platform-vixl.h index ad8d057d9..8da090c85 100644 --- a/core/deps/vixl/platform-vixl.h +++ b/core/deps/vixl/platform-vixl.h @@ -33,7 +33,7 @@ extern "C" { } #define VIXL_CODE_BUFFER_MALLOC - +#define VIXL_DEBUG #if defined(_ANDROID) && defined(VIXL_DEBUG) #include diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index 807f128e6..b2674b357 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -40,6 +40,11 @@ struct MemChip return rv; } + virtual void Write(u32 addr, u32 data, u32 size) + { + die("Method not supported"); + } + bool Load(const string& file) { FILE* f=fopen(file.c_str(),"rb"); @@ -119,20 +124,20 @@ struct MemChip INFO_LOG(FLASHROM, "Saved %s as %s", path, title.c_str()); } virtual void Reset() {} + virtual bool Serialize(void **data, unsigned int *total_size) { return true; } + virtual bool Unserialize(void **data, unsigned int *total_size) { return true; } }; + struct RomChip : MemChip { RomChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} - void Write(u32 addr,u32 data,u32 sz) - { - die("Write to RomChip is not possible, address=%x, data=%x, size=%d"); - } }; + struct SRamChip : MemChip { SRamChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} - void Write(u32 addr,u32 val,u32 sz) + void Write(u32 addr,u32 val,u32 sz) override { addr&=mask; if (addr < write_protect_size) @@ -152,6 +157,18 @@ struct SRamChip : MemChip die("invalid access size"); } } + + virtual bool Serialize(void **data, unsigned int *total_size) + { + REICAST_SA(&this->data[write_protect_size], size - write_protect_size); + return true; + } + + virtual bool Unserialize(void **data, unsigned int *total_size) + { + REICAST_USA(&this->data[write_protect_size], size - write_protect_size); + return true; + } }; // @@ -235,26 +252,27 @@ struct DCFlashChip : MemChip virtual u8 Read8(u32 addr) override { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - switch (addr) + if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - case 0x1A002: - case 0x1A0A2: - if (settings.dreamcast.region <= 2) - return '0' + settings.dreamcast.region; - break; - case 0x1A003: - case 0x1A0A3: - if (settings.dreamcast.language <= 5) - return '0' + settings.dreamcast.language; - break; - case 0x1A004: - case 0x1A0A4: - if (settings.dreamcast.broadcast <= 3) - return '0' + settings.dreamcast.broadcast; - break; + switch (addr) + { + case 0x1A002: + case 0x1A0A2: + if (settings.dreamcast.region <= 2) + return '0' + settings.dreamcast.region; + break; + case 0x1A003: + case 0x1A0A3: + if (settings.dreamcast.language <= 5) + return '0' + settings.dreamcast.language; + break; + case 0x1A004: + case 0x1A0A4: + if (settings.dreamcast.broadcast <= 3) + return '0' + settings.dreamcast.broadcast; + break; + } } -#endif u32 rv=MemChip::Read8(addr); @@ -262,7 +280,7 @@ struct DCFlashChip : MemChip } - void Write(u32 addr,u32 val,u32 sz) + void Write(u32 addr,u32 val,u32 sz) override { if (sz != 1) die("invalid access size"); @@ -283,7 +301,7 @@ struct DCFlashChip : MemChip state = FS_ReadAMDID1; break; default: - EMUERROR("Unknown FlashWrite mode: %x\n", val); + INFO_LOG(FLASHROM, "Unknown FlashWrite mode: %x\n", val); break; } break; @@ -357,15 +375,13 @@ struct DCFlashChip : MemChip { // chip erase INFO_LOG(FLASHROM, "Erasing Chip!"); -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE u8 save[0x2000]; - // this area is write-protected on AW - memcpy(save, data + 0x1a000, 0x2000); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + // this area is write-protected on AW + memcpy(save, data + 0x1a000, 0x2000); memset(data + write_protect_size, 0xff, size - write_protect_size); -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - memcpy(data + 0x1a000, save, 0x2000); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + memcpy(data + 0x1a000, save, 0x2000); state = FS_Normal; } else if ((val & 0xff) == 0x30) @@ -373,16 +389,14 @@ struct DCFlashChip : MemChip // sector erase if (addr >= write_protect_size) { -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE u8 save[0x2000]; - // this area is write-protected on AW - memcpy(save, data + 0x1a000, 0x2000); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + // this area is write-protected on AW + memcpy(save, data + 0x1a000, 0x2000); INFO_LOG(FLASHROM, "Erase Sector %08X! (%08X)", addr, addr & ~0x3FFF); memset(&data[addr&(~0x3FFF)],0xFF,0x4000); -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - memcpy(data + 0x1a000, save, 0x2000); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + memcpy(data + 0x1a000, save, 0x2000); } state = FS_Normal; } @@ -627,4 +641,18 @@ private: return result; } + + virtual bool Serialize(void **data, unsigned int *total_size) + { + REICAST_SA(&this->data[write_protect_size], size - write_protect_size); + REICAST_S(state); + return true; + } + + virtual bool Unserialize(void **data, unsigned int *total_size) + { + REICAST_USA(&this->data[write_protect_size], size - write_protect_size); + REICAST_US(state); + return true; + } }; diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index cf675d953..8e3bb6a37 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -1121,20 +1121,9 @@ void GDROM_DmaEnable(u32 addr, u32 data) //Init/Term/Res void gdrom_reg_Init() { - sb_rio_register(SB_GDST_addr, RIO_WF, 0, &GDROM_DmaStart); - /* - sb_regs[(SB_GDST_addr-SB_BASE)>>2].flags=REG_32BIT_READWRITE | REG_READ_DATA; - sb_regs[(SB_GDST_addr-SB_BASE)>>2].writeFunction=GDROM_DmaStart; - */ - - sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &GDROM_DmaEnable); - /* - sb_regs[(SB_GDEN_addr-SB_BASE)>>2].flags=REG_32BIT_READWRITE | REG_READ_DATA; - sb_regs[(SB_GDEN_addr-SB_BASE)>>2].writeFunction=GDROM_DmaEnable; - */ - gdrom_schid = sh4_sched_register(0, &GDRomschd); } + void gdrom_reg_Term() { @@ -1142,6 +1131,8 @@ void gdrom_reg_Term() void gdrom_reg_Reset(bool Manual) { + sb_rio_register(SB_GDST_addr, RIO_WF, 0, &GDROM_DmaStart); + sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &GDROM_DmaEnable); SB_GDST = 0; SB_GDEN = 0; } diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index a3f50bcf6..dd237c4e6 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -773,32 +773,26 @@ void sb_Init() asic_reg_Init(); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST gdrom_reg_Init(); -#else naomi_reg_Init(); -#endif pvr_sb_Init(); maple_Init(); aica_sb_Init(); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) +#ifdef ENABLE_MODEM ModemInit(); #endif } void sb_Reset(bool Manual) { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) +#ifdef ENABLE_MODEM ModemTerm(); #endif asic_reg_Reset(Manual); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST gdrom_reg_Reset(Manual); -#else naomi_reg_Reset(Manual); -#endif pvr_sb_Reset(Manual); maple_Reset(Manual); aica_sb_Reset(Manual); @@ -806,16 +800,13 @@ void sb_Reset(bool Manual) void sb_Term() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST && defined(ENABLE_MODEM) +#ifdef ENABLE_MODEM ModemTerm(); #endif aica_sb_Term(); maple_Term(); pvr_sb_Term(); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST gdrom_reg_Term(); -#else naomi_reg_Term(); -#endif asic_reg_Term(); } diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index 77728c116..cee5a6fce 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -18,132 +18,139 @@ #include "hw/flashrom/flashrom.h" #include "reios/reios.h" -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE -DCFlashChip sys_rom(BIOS_SIZE, BIOS_SIZE / 2); -#else -RomChip sys_rom(BIOS_SIZE); -#endif - -#ifdef FLASH_SIZE -DCFlashChip sys_nvmem(FLASH_SIZE); -#endif - -#ifdef BBSRAM_SIZE -SRamChip sys_nvmem(BBSRAM_SIZE); -#endif +MemChip *sys_rom; +MemChip *sys_nvmem; extern bool bios_loaded; +static std::string getRomPrefix() +{ + switch (settings.platform.system) + { + case DC_PLATFORM_DREAMCAST: + return "dc_"; + case DC_PLATFORM_NAOMI: + return "naomi_"; + case DC_PLATFORM_ATOMISWAVE: + return "aw_"; + default: + die("Unsupported platform"); + return ""; + } +} + +static bool nvmemOptional() +{ + return settings.platform.system != DC_PLATFORM_DREAMCAST; +} + bool LoadRomFiles(const string& root) { -#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE - if (!sys_rom.Load(root, ROM_PREFIX, "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin" ROM_NAMES, "bootrom")) + if (settings.platform.system != DC_PLATFORM_ATOMISWAVE) { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - // Dreamcast absolutely needs a BIOS - msgboxf("Unable to find bios in %s. Exiting...", MBX_ICONERROR, root.c_str()); - return false; -#endif + if (!sys_rom->Load(root, getRomPrefix(), "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin", "bootrom")) + { + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + { + // Dreamcast absolutely needs a BIOS + msgboxf("Unable to find bios in %s. Exiting...", MBX_ICONERROR, root.c_str()); + return false; + } + } + else + bios_loaded = true; } + bool rc; + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + rc = sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram"); else - bios_loaded = true; -#endif -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) -#else - if (!sys_nvmem.Load(get_game_save_prefix() + ".nvmem")) -#endif + rc = sys_nvmem->Load(get_game_save_prefix() + ".nvmem"); + if (!rc) { - if (NVR_OPTIONAL) + if (nvmemOptional()) { INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); } else { - msgboxf("Unable to find flash/nvmem in \n%s\nExiting...", MBX_ICONERROR, root.c_str()); + msgboxf("Unable to find flash/nvmem in %s. Exiting...", MBX_ICONERROR, root.c_str()); return false; } } -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - struct flash_syscfg_block syscfg; - int res = sys_nvmem.ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); - - if (!res) + if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - // write out default settings - memset(&syscfg, 0xff, sizeof(syscfg)); - syscfg.time_lo = 0; - syscfg.time_hi = 0; - syscfg.lang = 0; - syscfg.mono = 0; - syscfg.autostart = 1; + struct flash_syscfg_block syscfg; + int res = static_cast(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); + + if (!res) + { + // write out default settings + memset(&syscfg, 0xff, sizeof(syscfg)); + syscfg.time_lo = 0; + syscfg.time_hi = 0; + syscfg.lang = 0; + syscfg.mono = 0; + syscfg.autostart = 1; + } + u32 time = GetRTC_now(); + syscfg.time_lo = time & 0xffff; + syscfg.time_hi = time >> 16; + if (settings.dreamcast.language <= 5) + syscfg.lang = settings.dreamcast.language; + + if (static_cast(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) + WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); } - u32 time = GetRTC_now(); - syscfg.time_lo = time & 0xffff; - syscfg.time_hi = time >> 16; - if (settings.dreamcast.language <= 5) - syscfg.lang = settings.dreamcast.language; - if (sys_nvmem.WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) - WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); - -#endif - -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - sys_rom.Load(get_game_save_prefix() + ".nvmem2"); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + sys_rom->Load(get_game_save_prefix() + ".nvmem2"); return true; } void SaveRomFiles(const string& root) { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - sys_nvmem.Save(root, ROM_PREFIX, "nvmem.bin", "nvmem"); -#else - sys_nvmem.Save(get_game_save_prefix() + ".nvmem"); -#endif -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - sys_rom.Save(get_game_save_prefix() + ".nvmem2"); -#endif + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + sys_nvmem->Save(root, getRomPrefix(), "nvmem.bin", "nvmem"); + else + sys_nvmem->Save(get_game_save_prefix() + ".nvmem"); + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + sys_rom->Save(get_game_save_prefix() + ".nvmem2"); } bool LoadHle(const string& root) { - if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { + if (!sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { INFO_LOG(FLASHROM, "No nvmem loaded"); } - return reios_init(sys_rom.data, sys_nvmem.data); + return reios_init(sys_rom->data, sys_nvmem->data); } -u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem.Read(addr,sz); } -void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem.Write(addr,data,sz); } +u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); } +void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); } -#if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2) +u32 ReadBios(u32 addr,u32 sz) +{ + return sys_rom->Read(addr, sz); +} -u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); } -void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz); } - -#elif (DC_PLATFORM == DC_PLATFORM_ATOMISWAVE) - u32 ReadBios(u32 addr,u32 sz) - { - return sys_rom.Read(addr, sz); - } - - void WriteBios(u32 addr,u32 data,u32 sz) +void WriteBios(u32 addr,u32 data,u32 sz) +{ + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) { if (sz != 1) { INFO_LOG(MEMORY, "Invalid access size @%08x data %x sz %d", addr, data, sz); return; } - sys_rom.Write(addr, data, sz); + sys_rom->Write(addr, data, sz); } - -#else -#error unknown flash -#endif + else + { + INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz); + } +} //Area 0 mem map //0x00000000- 0x001FFFFF :MPX System/Boot ROM @@ -174,11 +181,9 @@ T DYNACALL ReadMem_area0(u32 addr) //map 0x0000 to 0x01FF to Default handler //mirror 0x0200 to 0x03FF , from 0x0000 to 0x03FFF //map 0x0000 to 0x001F -#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE - if (base<=0x001F)// :MPX System/Boot ROM -#else - if (base<=0x0001) // Only 128k BIOS on AtomisWave -#endif + + // :MPX System/Boot ROM + if (base <= (settings.platform.system == DC_PLATFORM_ATOMISWAVE ? 0x0001 : 0x001F)) // Only 128k BIOS on AtomisWave { return ReadBios(addr,sz); } @@ -196,11 +201,10 @@ T DYNACALL ReadMem_area0(u32 addr) } else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM { -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - return (T)ReadMem_naomi(addr,sz); -#else - return (T)ReadMem_gdrom(addr,sz); -#endif + if (settings.platform.system != DC_PLATFORM_DREAMCAST) + return (T)ReadMem_naomi(addr, sz); + else + return (T)ReadMem_gdrom(addr, sz); } else if (likely((addr>= 0x005F6800) && (addr<=0x005F7CFF))) // /*:PVR i/f Control Reg.*/ -> ALL SB registers now { @@ -217,12 +221,13 @@ T DYNACALL ReadMem_area0(u32 addr) //map 0x0060 to 0x0060 else if ((base ==0x0060) /*&& (addr>= 0x00600000)*/ && (addr<= 0x006007FF)) // :MODEM { -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - return (T)libExtDevice_ReadMem_A0_006(addr, sz); -#elif defined(ENABLE_MODEM) - return (T)ModemReadMem_A0_006(addr, sz); + if (settings.platform.system != DC_PLATFORM_DREAMCAST) + return (T)libExtDevice_ReadMem_A0_006(addr, sz); + else +#if defined(ENABLE_MODEM) + return (T)ModemReadMem_A0_006(addr, sz); #else - return (T)0; + return (T)0; #endif } //map 0x0060 to 0x006F @@ -261,12 +266,8 @@ void DYNACALL WriteMem_area0(u32 addr,T data) const u32 base=(addr>>16); //map 0x0000 to 0x001F -#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE - if ((base <=0x001F) /*&& (addr<=0x001FFFFF)*/)// :MPX System/Boot ROM -#else - - if (base <= 0x0001) // Only 128k BIOS on AtomisWave -#endif + // :MPX System/Boot ROM + if (base <= (settings.platform.system == DC_PLATFORM_ATOMISWAVE ? 0x0001 : 0x001F)) // Only 128k BIOS on AtomisWave { WriteBios(addr,data,sz); } @@ -285,11 +286,10 @@ void DYNACALL WriteMem_area0(u32 addr,T data) } else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM { -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - WriteMem_naomi(addr,data,sz); -#else - WriteMem_gdrom(addr,data,sz); -#endif + if (settings.platform.system != DC_PLATFORM_DREAMCAST) + WriteMem_naomi(addr,data,sz); + else + WriteMem_gdrom(addr,data,sz); } else if ( likely((addr>= 0x005F6800) && (addr<=0x005F7CFF)) ) // /*:PVR i/f Control Reg.*/ -> ALL SB registers { @@ -304,10 +304,11 @@ void DYNACALL WriteMem_area0(u32 addr,T data) //map 0x0060 to 0x0060 else if ((base ==0x0060) /*&& (addr>= 0x00600000)*/ && (addr<= 0x006007FF)) // MODEM { -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - libExtDevice_WriteMem_A0_006(addr, data, sz); -#elif defined(ENABLE_MODEM) - ModemWriteMem_A0_006(addr, data, sz); + if (settings.platform.system != DC_PLATFORM_DREAMCAST) + libExtDevice_WriteMem_A0_006(addr, data, sz); +#if defined(ENABLE_MODEM) + else + ModemWriteMem_A0_006(addr, data, sz); #endif } //map 0x0060 to 0x006F @@ -347,17 +348,57 @@ void sh4_area0_Init() sb_Init(); } -void sh4_area0_Reset(bool Manual) +void sh4_area0_Reset(bool manual) { - sb_Reset(Manual); - sys_rom.Reset(); -#if defined(FLASH_SIZE) || defined(BBSRAM_SIZE) - sys_nvmem.Reset(); -#endif + if (manual) + { + if (sys_rom != NULL) + { + delete sys_rom; + sys_rom = NULL; + } + if (sys_nvmem != NULL) + { + delete sys_nvmem; + sys_nvmem = NULL; + } + + switch (settings.platform.system) + { + case DC_PLATFORM_DREAMCAST: + sys_rom = new RomChip(settings.platform.bios_size); + sys_nvmem = new DCFlashChip(settings.platform.flash_size); + break; + case DC_PLATFORM_NAOMI: + sys_rom = new RomChip(settings.platform.bios_size); + sys_nvmem = new SRamChip(settings.platform.bbsram_size); + break; + case DC_PLATFORM_ATOMISWAVE: + sys_rom = new DCFlashChip(settings.platform.bios_size, settings.platform.bios_size / 2); + sys_nvmem = new SRamChip(settings.platform.bbsram_size); + break; + } + } + else + { + sys_rom->Reset(); + sys_nvmem->Reset(); + } + sb_Reset(manual); } void sh4_area0_Term() { + if (sys_rom != NULL) + { + delete sys_rom; + sys_rom = NULL; + } + if (sys_nvmem != NULL) + { + delete sys_nvmem; + sys_nvmem = NULL; + } sb_Term(); } diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 4f8c9d2d6..d3b4a8661 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -77,33 +77,36 @@ struct MapleConfigMap : IMapleConfigMap UpdateInputState(player_num); pjs->kcode=kcode[player_num]; -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - pjs->kcode |= 0xF901; // mask off DPad2, C, D and Z - pjs->joy[PJAI_X1]=GetBtFromSgn(joyx[player_num]); - pjs->joy[PJAI_Y1]=GetBtFromSgn(joyy[player_num]); - pjs->trigger[PJTI_R]=rt[player_num]; - pjs->trigger[PJTI_L]=lt[player_num]; -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - pjs->kcode = 0xFFFF; - for (int i = 0; i < 16; i++) + if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - if ((kcode[player_num] & (1 << i)) == 0) - pjs->kcode &= ~awave_button_mapping[i]; + pjs->kcode |= 0xF901; // mask off DPad2, C, D and Z + pjs->joy[PJAI_X1]=GetBtFromSgn(joyx[player_num]); + pjs->joy[PJAI_Y1]=GetBtFromSgn(joyy[player_num]); + pjs->trigger[PJTI_R]=rt[player_num]; + pjs->trigger[PJTI_L]=lt[player_num]; } - pjs->joy[PJAI_X1] = GetBtFromSgn(joyx[player_num]); - if (NaomiGameInputs != NULL && NaomiGameInputs->axes[1].name != NULL && NaomiGameInputs->axes[1].type == Half) + else if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) { - // Driving games: put axis 2 on RT (accel) and axis 3 on LT (brake) - pjs->joy[PJAI_Y1] = rt[player_num]; - pjs->joy[PJAI_X2] = lt[player_num]; + pjs->kcode = 0xFFFF; + for (int i = 0; i < 16; i++) + { + if ((kcode[player_num] & (1 << i)) == 0) + pjs->kcode &= ~awave_button_mapping[i]; + } + pjs->joy[PJAI_X1] = GetBtFromSgn(joyx[player_num]); + if (NaomiGameInputs != NULL && NaomiGameInputs->axes[1].name != NULL && NaomiGameInputs->axes[1].type == Half) + { + // Driving games: put axis 2 on RT (accel) and axis 3 on LT (brake) + pjs->joy[PJAI_Y1] = rt[player_num]; + pjs->joy[PJAI_X2] = lt[player_num]; + } + else + { + pjs->joy[PJAI_Y1] = GetBtFromSgn(joyy[player_num]); + pjs->joy[PJAI_X2] = rt[player_num]; + pjs->joy[PJAI_Y2] = lt[player_num]; + } } - else - { - pjs->joy[PJAI_Y1] = GetBtFromSgn(joyy[player_num]); - pjs->joy[PJAI_X2] = rt[player_num]; - pjs->joy[PJAI_Y2] = lt[player_num]; - } -#endif } void SetImage(void* img) { @@ -134,12 +137,16 @@ void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num = -1) void mcfg_CreateNAOMIJamma() { + printf("mcfg_CreateNAOMIJamma\n"); + mcfg_DestroyDevices(); mcfg_Create(MDT_NaomiJamma, 0, 5); // mcfg_Create(MDT_Keyboard, 2, 5); } void mcfg_CreateAtomisWaveControllers() { + printf("mcfg_CreateAtomisWaveControllers\n"); + mcfg_DestroyDevices(); // Looks like two controllers needs to be on bus 0 and 1 for digital inputs // Then other devices on port 2 and 3 for analog axes, light guns, ... mcfg_Create(MDT_SegaController, 0, 5); @@ -174,6 +181,7 @@ void mcfg_CreateAtomisWaveControllers() void mcfg_CreateDevices() { + printf("mcfg_CreateDevices\n"); for (int bus = 0; bus < MAPLE_PORTS; ++bus) { switch ((MapleDeviceType)settings.input.maple_devices[bus]) @@ -205,6 +213,7 @@ void mcfg_CreateDevices() void mcfg_DestroyDevices() { + printf("mcfg_DestroyDevices\n"); for (int i = 0; i < MAPLE_PORTS; i++) for (int j=0;j<=5;j++) { diff --git a/core/hw/maple/maple_cfg.h b/core/hw/maple/maple_cfg.h index 75d4d116e..299117bb6 100644 --- a/core/hw/maple/maple_cfg.h +++ b/core/hw/maple/maple_cfg.h @@ -58,12 +58,9 @@ struct IMapleConfigMap virtual ~IMapleConfigMap() {} }; -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST void mcfg_CreateDevices(); -#else void mcfg_CreateNAOMIJamma(); void mcfg_CreateAtomisWaveControllers(); -#endif void mcfg_DestroyDevices(); void mcfg_SerializeDevices(void **data, unsigned int *total_size); diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index dde4e456f..b7ecc68f1 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -2619,11 +2619,10 @@ maple_device* maple_Create(MapleDeviceType type) switch(type) { case MDT_SegaController: -#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE - rv = new maple_sega_controller(); -#else - rv = new maple_atomiswave_controller(); -#endif + if (settings.platform.system != DC_PLATFORM_ATOMISWAVE) + rv = new maple_sega_controller(); + else + rv = new maple_atomiswave_controller(); break; case MDT_Microphone: @@ -2647,11 +2646,10 @@ maple_device* maple_Create(MapleDeviceType type) break; case MDT_LightGun: -#if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE - rv = new maple_lightgun(); -#else - rv = new atomiswave_lightgun(); -#endif + if (settings.platform.system != DC_PLATFORM_ATOMISWAVE) + rv = new maple_lightgun(); + else + rv = new atomiswave_lightgun(); break; case MDT_NaomiJamma: diff --git a/core/hw/maple/maple_if.cpp b/core/hw/maple/maple_if.cpp index c666f7189..e3a002b71 100644 --- a/core/hw/maple/maple_if.cpp +++ b/core/hw/maple/maple_if.cpp @@ -71,9 +71,8 @@ void maple_vblank() maple_ddt_pending_reset=false; } } -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - maple_handle_reconnect(); -#endif + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + maple_handle_reconnect(); } void maple_SB_MSHTCL_Write(u32 addr, u32 data) { @@ -277,7 +276,6 @@ void maple_Term() } -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST static u64 reconnect_time; void maple_ReconnectDevices() @@ -294,4 +292,3 @@ static void maple_handle_reconnect() mcfg_CreateDevices(); } } -#endif diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 1eb8d6bf9..a49bcc8bc 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -441,6 +441,7 @@ void _vmem_term() {} u8* virt_ram_base; bool vmem_4gb_space; +static VMemType vmemstatus; void* malloc_pages(size_t size) { #if HOST_OS == OS_WINDOWS @@ -512,14 +513,49 @@ bool _vmem_reserve() { // TODO: Static assert? verify((sizeof(Sh4RCB)%PAGE_SIZE)==0); - VMemType vmemstatus = MemTypeError; + vmemstatus = MemTypeError; // Use vmem only if settings mandate so, and if we have proper exception handlers. - #ifndef TARGET_NO_EXCEPTIONS +#ifndef TARGET_NO_EXCEPTIONS if (!settings.dynarec.disable_nvmem) vmemstatus = vmem_platform_init((void**)&virt_ram_base, (void**)&p_sh4rcb); - #endif +#endif + return true; +} +void _vmem_term_mappings() +{ + if (vmemstatus == MemTypeError) { + if (p_sh4rcb != NULL) + { + free(p_sh4rcb); + p_sh4rcb = NULL; + } + if (mem_b.data != NULL) + { + free(mem_b.data); + mem_b.data = NULL; + } + if (vram.data != NULL) + { + free(vram.data); + vram.data = NULL; + } + if (aica_ram.data != NULL) + { + free(aica_ram.data); + aica_ram.data = NULL; + } + } + else + { + //vmem_platform_destroy(); // FIXME Needed for Windows + } +} + +void _vmem_init_mappings() +{ + _vmem_term_mappings(); // Fallback to statically allocated buffers, this results in slow-ops being generated. if (vmemstatus == MemTypeError) { WARN_LOG(VMEM, "Warning! nvmem is DISABLED (due to failure or not being built-in"); @@ -627,8 +663,6 @@ bool _vmem_reserve() { aica_ram.Zero(); vram.Zero(); mem_b.Zero(); - - return true; } #define freedefptr(x) \ diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index c75974540..d83705497 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -55,6 +55,7 @@ typedef u32 _vmem_handler; void _vmem_init(); void _vmem_reset(); void _vmem_term(); +void _vmem_init_mappings(); //functions to register and map handlers/memory _vmem_handler _vmem_register_handler(_vmem_ReadMem8FP* read8,_vmem_ReadMem16FP* read16,_vmem_ReadMem32FP* read32, _vmem_WriteMem8FP* write8,_vmem_WriteMem16FP* write16,_vmem_WriteMem32FP* write32); diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index e40c89360..12e26e399 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -66,7 +66,7 @@ struct vram_lock { u32 start; u32 end; }; -static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; +static std::vector vram_blocks[VRAM_SIZE_MAX / VRAM_PROT_SEGMENT]; static u8 sram_mapped_pages[USER_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped bool vmem32_inited; diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index 131559ea7..bf9999864 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -534,10 +534,6 @@ void naomi_reg_Init() } #endif NaomiInit(); - - sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart); - - sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable); } void naomi_reg_Term() @@ -555,6 +551,9 @@ void naomi_reg_Term() } void naomi_reg_Reset(bool Manual) { + sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart); + sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable); + NaomiDataRead = false; aw_ram_test_skipped = false; GSerialBuffer = 0; diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 209df28cb..d39eaa34c 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -55,7 +55,7 @@ char naomi_game_id[33]; InputDescriptors *NaomiGameInputs; u8 *naomi_default_eeprom; -extern RomChip sys_rom; +extern MemChip *sys_rom; static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive *parent_archive, int region) { @@ -94,7 +94,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive { verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); verify(bios->blobs[romid].src_offset + bios->blobs[romid].length <= BIOS_SIZE); - memcpy(sys_rom.data + bios->blobs[romid].offset, sys_rom.data + bios->blobs[romid].src_offset, bios->blobs[romid].length); + memcpy(sys_rom->data + bios->blobs[romid].offset, sys_rom->data + bios->blobs[romid].src_offset, bios->blobs[romid].length); DEBUG_LOG(NAOMI, "Copied: %x bytes from %07x to %07x", bios->blobs[romid].length, bios->blobs[romid].src_offset, bios->blobs[romid].offset); } else @@ -113,7 +113,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive if (bios->blobs[romid].blob_type == Normal) { verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); - u32 read = file->Read(sys_rom.data + bios->blobs[romid].offset, bios->blobs[romid].length); + u32 read = file->Read(sys_rom->data + bios->blobs[romid].offset, bios->blobs[romid].length); DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); } else if (bios->blobs[romid].blob_type == InterleavedWord) @@ -127,7 +127,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive } verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); u32 read = file->Read(buf, bios->blobs[romid].length); - u16 *to = (u16 *)(sys_rom.data + bios->blobs[romid].offset); + u16 *to = (u16 *)(sys_rom->data + bios->blobs[romid].offset); u16 *from = (u16 *)buf; for (int i = bios->blobs[romid].length / 2; --i >= 0; to++) *to++ = *from++; @@ -143,10 +143,9 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive if (bios_archive != NULL) delete bios_archive; -#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - // Reload the writeable portion of the FlashROM - sys_rom.Reload(); -#endif + if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + // Reload the writeable portion of the FlashROM + sys_rom->Reload(); return found_region; @@ -156,9 +155,9 @@ error: return false; } -static bool naomi_cart_LoadZip(char *filename) +static Game *FindGame(const char *filename) { - char *p = strrchr(filename, '/'); + const char *p = strrchr(filename, '/'); #ifdef _WIN32 p = strrchr(p == NULL ? filename : p, '\\'); #endif @@ -178,25 +177,19 @@ static bool naomi_cart_LoadZip(char *filename) if (!stricmp(Games[gameid].name, game_name)) break; if (Games[gameid].name == NULL) + return NULL; + + return &Games[gameid]; +} + +static bool naomi_cart_LoadZip(char *filename) +{ + Game *game = FindGame(filename); + if (game == NULL) { ERROR_LOG(NAOMI, "Unknown game %s", filename); return false; } - - struct Game *game = &Games[gameid]; -#if DC_PLATFORM == DC_PLATFORM_NAOMI - if (game->cart_type == AW) - { - msgboxf("Atomiswave cartridges are not supported by NAOMI", 0); - return false; - } -#else - if (game->cart_type != AW) - { - msgboxf("NAOMI cartridges are not supported by Atomiswave", 0); - return false; - } -#endif Archive *archive = OpenArchive(filename); if (archive != NULL) INFO_LOG(NAOMI, "Opened %s", filename); @@ -650,6 +643,17 @@ bool naomi_cart_SelectFile() return true; } +int naomi_cart_GetPlatform(const char *path) +{ + Game *game = FindGame(path); + if (game == NULL) + return DC_PLATFORM_NAOMI; + else if (game->cart_type == AW) + return DC_PLATFORM_ATOMISWAVE; + else + return DC_PLATFORM_NAOMI; +} + Cartridge::Cartridge(u32 size) { RomPtr = (u8 *)malloc(size); diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h index 55eb75461..c1319a98b 100644 --- a/core/hw/naomi/naomi_cart.h +++ b/core/hw/naomi/naomi_cart.h @@ -95,6 +95,7 @@ public: bool naomi_cart_SelectFile(); void naomi_cart_Close(); +int naomi_cart_GetPlatform(const char *path); extern char naomi_game_id[]; extern u8 *naomi_default_eeprom; diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 26f994527..18844836d 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -412,15 +412,18 @@ void bm_Reset() // Windows cannot lock/unlock a region spanning more than one VirtualAlloc or MapViewOfFile // so we have to unlock each region individually // No need for this mess in 4GB mode since windows doesn't use it -#if RAM_SIZE == 16 * 1024 * 1024 - mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); - mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); - mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); - mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); -#else - mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); - mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); -#endif + if (settings.platform.ram_size == 16 * 1024 * 1024) + { + mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); + } + else + { + mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); + mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); + } if (_nvmem_4gb_space()) { mem_region_unlock(virt_ram_base + 0x8C000000, 0x90000000 - 0x8C000000); diff --git a/core/hw/sh4/modules/bsc.cpp b/core/hw/sh4/modules/bsc.cpp index c939c4e5e..a238785b7 100644 --- a/core/hw/sh4/modules/bsc.cpp +++ b/core/hw/sh4/modules/bsc.cpp @@ -11,11 +11,10 @@ BSC_PDTRA_type BSC_PDTRA; void write_BSC_PCTRA(u32 addr, u32 data) { BSC_PCTRA.full=(u16)data; - #if DC_PLATFORM == DC_PLATFORM_NAOMI + if (settings.platform.system == DC_PLATFORM_NAOMI) NaomiBoardIDWriteControl((u16)data); - #else + //else //printf("C:BSC_PCTRA = %08X\n",data); - #endif } //u32 port_out_data; void write_BSC_PDTRA(u32 addr, u32 data) @@ -23,19 +22,18 @@ void write_BSC_PDTRA(u32 addr, u32 data) BSC_PDTRA.full=(u16)data; //printf("D:BSC_PDTRA = %08X\n",data); - #if DC_PLATFORM == DC_PLATFORM_NAOMI + if (settings.platform.system == DC_PLATFORM_NAOMI) NaomiBoardIDWrite((u16)data); - #endif } u32 read_BSC_PDTRA(u32 addr) { - #if DC_PLATFORM == DC_PLATFORM_NAOMI - + if (settings.platform.system == DC_PLATFORM_NAOMI) + { return NaomiBoardIDRead(); - - #else - + } + else + { /* as seen on chankast */ u32 tpctra = BSC_PCTRA.full; u32 tpdtra = BSC_PDTRA.full; @@ -57,8 +55,7 @@ u32 read_BSC_PDTRA(u32 addr) tfinal |= settings.dreamcast.cable <<8; return tfinal; - - #endif + } } //Init term res @@ -113,14 +110,10 @@ void bsc_init() sh4_rio_reg(BSC,BSC_GPIOIC_addr,RIO_DATA,16); //note: naomi//aw might depend on rfcr -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE sh4_rio_reg(BSC, BSC_RFCR_addr, RIO_RO, 16); BSC_RFCR.full = 17; -#endif } - - void bsc_reset() { /* @@ -160,10 +153,10 @@ void bsc_reset() BSC_PCTRB.full=0x0; //BSC_PDTRB.full; undef BSC_GPIOIC.full=0x0; -#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + BSC_RFCR.full = 17; -#endif } + void bsc_term() { } diff --git a/core/imgread/ImgReader.cpp b/core/imgread/ImgReader.cpp index ea0e98221..ea2ea0bf8 100644 --- a/core/imgread/ImgReader.cpp +++ b/core/imgread/ImgReader.cpp @@ -70,10 +70,8 @@ void libGDR_Reset(bool Manual) //called when entering sh4 thread , from the new thread context (for any thread specific init) s32 libGDR_Init() { - if (!InitDrive()) - return rv_serror; libCore_gdrom_disc_change(); - settings.imgread.PatchRegion=true; + settings.imgread.PatchRegion = true; return rv_ok; } diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 94565b026..f9d2ce56b 100644 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -11,7 +11,6 @@ #include #include #include "hw/sh4/dyna/blockmanager.h" -#include "hw/maple/maple_cfg.h" #include "log/LogManager.h" #include @@ -107,10 +106,6 @@ void os_SetupInput() #if defined(USE_SDL) input_sdl_init(); #endif - -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif } void UpdateInputState(u32 port) diff --git a/core/nullDC.cpp b/core/nullDC.cpp index e193a948d..291274269 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -132,175 +132,178 @@ void plugins_Reset(bool Manual) void LoadSpecialSettings() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - INFO_LOG(BOOT, "Game ID is [%s]", reios_product_number); - rtt_to_buffer_game = false; - safemode_game = false; - tr_poly_depth_mask_game = false; - extra_depth_game = false; - full_mmu_game = false; - disable_vmem32_game = false; + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + { + INFO_LOG(BOOT, "Game ID is [%s]", reios_product_number); + rtt_to_buffer_game = false; + safemode_game = false; + tr_poly_depth_mask_game = false; + extra_depth_game = false; + full_mmu_game = false; + disable_vmem32_game = false; - if (reios_windows_ce || !strncmp("T26702N", reios_product_number, 7)) // PBA Tour Bowling 2001 - { - INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); - settings.rend.ExtraDepthScale = 0.1; - extra_depth_game = true; - settings.dreamcast.FullMMU = true; - full_mmu_game = true; - settings.aica.NoBatch = true; - } + if (reios_windows_ce || !strncmp("T26702N", reios_product_number, 7)) // PBA Tour Bowling 2001 + { + INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); + settings.rend.ExtraDepthScale = 0.1; + extra_depth_game = true; + settings.dreamcast.FullMMU = true; + full_mmu_game = true; + settings.aica.NoBatch = true; + } - // Tony Hawk's Pro Skater 2 - if (!strncmp("T13008D", reios_product_number, 7) || !strncmp("T13006N", reios_product_number, 7) - // Tony Hawk's Pro Skater 1 - || !strncmp("T40205N", reios_product_number, 7) - // Tony Hawk's Skateboarding - || !strncmp("T40204D", reios_product_number, 7) - // Skies of Arcadia - || !strncmp("MK-51052", reios_product_number, 8) - // Eternal Arcadia (JP) - || !strncmp("HDR-0076", reios_product_number, 8) - // Flag to Flag (US) - || !strncmp("MK-51007", reios_product_number, 8) - // Super Speed Racing (JP) - || !strncmp("HDR-0013", reios_product_number, 8) - // Yu Suzuki Game Works Vol. 1 - || !strncmp("6108099", reios_product_number, 7) - // L.O.L - || !strncmp("T2106M", reios_product_number, 6) - // Miss Moonlight - || !strncmp("T18702M", reios_product_number, 7) - // Tom Clancy's Rainbow Six (US) - || !strncmp("T40401N", reios_product_number, 7) - // Tom Clancy's Rainbow Six incl. Eagle Watch Missions (EU) - || !strncmp("T-45001D05", reios_product_number, 10)) - { - settings.rend.RenderToTextureBuffer = 1; - rtt_to_buffer_game = true; + // Tony Hawk's Pro Skater 2 + if (!strncmp("T13008D", reios_product_number, 7) || !strncmp("T13006N", reios_product_number, 7) + // Tony Hawk's Pro Skater 1 + || !strncmp("T40205N", reios_product_number, 7) + // Tony Hawk's Skateboarding + || !strncmp("T40204D", reios_product_number, 7) + // Skies of Arcadia + || !strncmp("MK-51052", reios_product_number, 8) + // Eternal Arcadia (JP) + || !strncmp("HDR-0076", reios_product_number, 8) + // Flag to Flag (US) + || !strncmp("MK-51007", reios_product_number, 8) + // Super Speed Racing (JP) + || !strncmp("HDR-0013", reios_product_number, 8) + // Yu Suzuki Game Works Vol. 1 + || !strncmp("6108099", reios_product_number, 7) + // L.O.L + || !strncmp("T2106M", reios_product_number, 6) + // Miss Moonlight + || !strncmp("T18702M", reios_product_number, 7) + // Tom Clancy's Rainbow Six (US) + || !strncmp("T40401N", reios_product_number, 7) + // Tom Clancy's Rainbow Six incl. Eagle Watch Missions (EU) + || !strncmp("T-45001D05", reios_product_number, 10)) + { + settings.rend.RenderToTextureBuffer = 1; + rtt_to_buffer_game = true; + } + if (!strncmp("HDR-0176", reios_product_number, 8) || !strncmp("RDC-0057", reios_product_number, 8)) + { + // Cosmic Smash + settings.rend.TranslucentPolygonDepthMask = 1; + tr_poly_depth_mask_game = true; + } + // Demolition Racer + if (!strncmp("T15112N", reios_product_number, 7) + // Ducati World - Racing Challenge (NTSC) + || !strncmp("T-8113N", reios_product_number, 7) + // Ducati World (PAL) + || !strncmp("T-8121D-50", reios_product_number, 10)) + { + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", reios_product_number); + settings.dynarec.safemode = 1; + safemode_game = true; + } + // NHL 2K2 + if (!strncmp("MK-51182", reios_product_number, 8)) + { + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); + settings.rend.ExtraDepthScale = 10000; + extra_depth_game = true; + } + // Re-Volt (US, EU) + else if (!strncmp("T-8109N", reios_product_number, 7) || !strncmp("T8107D 50", reios_product_number, 10)) + { + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); + settings.rend.ExtraDepthScale = 100; + extra_depth_game = true; + } + // Super Producers + if (!strncmp("T14303M", reios_product_number, 7) + // Giant Killers + || !strncmp("T45401D 50", reios_product_number, 10) + // Wild Metal (US) + || !strncmp("T42101N 00", reios_product_number, 10) + // Wild Metal (EU) + || !strncmp("T40501D-50", reios_product_number, 10) + // Resident Evil 2 (US) + || !strncmp("T1205N", reios_product_number, 6) + // Resident Evil 2 (EU) + || !strncmp("T7004D 50", reios_product_number, 10) + // Rune Jade + || !strncmp("T14304M", reios_product_number, 7) + // Marionette Company + || !strncmp("T5202M", reios_product_number, 6) + // Marionette Company 2 + || !strncmp("T5203M", reios_product_number, 6) + // Maximum Pool (for online support) + || !strncmp("T11010N", reios_product_number, 7) + // StarLancer (US) (for online support) + || !strncmp("T40209N", reios_product_number, 7) + // StarLancer (EU) (for online support) + || !strncmp("T17723D 05", reios_product_number, 10) + ) + { + INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", reios_product_number); + settings.dynarec.disable_vmem32 = true; + disable_vmem32_game = true; + } } - if (!strncmp("HDR-0176", reios_product_number, 8) || !strncmp("RDC-0057", reios_product_number, 8)) + else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) { - // Cosmic Smash - settings.rend.TranslucentPolygonDepthMask = 1; - tr_poly_depth_mask_game = true; - } - // Demolition Racer - if (!strncmp("T15112N", reios_product_number, 7) - // Ducati World - Racing Challenge (NTSC) - || !strncmp("T-8113N", reios_product_number, 7) - // Ducati World (PAL) - || !strncmp("T-8121D-50", reios_product_number, 10)) - { - INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", reios_product_number); - settings.dynarec.safemode = 1; - safemode_game = true; - } - // NHL 2K2 - if (!strncmp("MK-51182", reios_product_number, 8)) - { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); - settings.rend.ExtraDepthScale = 10000; - extra_depth_game = true; - } - // Re-Volt (US, EU) - else if (!strncmp("T-8109N", reios_product_number, 7) || !strncmp("T8107D 50", reios_product_number, 10)) - { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); - settings.rend.ExtraDepthScale = 100; - extra_depth_game = true; - } - // Super Producers - if (!strncmp("T14303M", reios_product_number, 7) - // Giant Killers - || !strncmp("T45401D 50", reios_product_number, 10) - // Wild Metal (US) - || !strncmp("T42101N 00", reios_product_number, 10) - // Wild Metal (EU) - || !strncmp("T40501D-50", reios_product_number, 10) - // Resident Evil 2 (US) - || !strncmp("T1205N", reios_product_number, 6) - // Resident Evil 2 (EU) - || !strncmp("T7004D 50", reios_product_number, 10) - // Rune Jade - || !strncmp("T14304M", reios_product_number, 7) - // Marionette Company - || !strncmp("T5202M", reios_product_number, 6) - // Marionette Company 2 - || !strncmp("T5203M", reios_product_number, 6) - // Maximum Pool (for online support) - || !strncmp("T11010N", reios_product_number, 7) - // StarLancer (US) (for online support) - || !strncmp("T40209N", reios_product_number, 7) - // StarLancer (EU) (for online support) - || !strncmp("T17723D 05", reios_product_number, 10) - ) - { - INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", reios_product_number); - settings.dynarec.disable_vmem32 = true; - disable_vmem32_game = true; - } -#elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - INFO_LOG(BOOT, "Game ID is [%s]", naomi_game_id); + INFO_LOG(BOOT, "Game ID is [%s]", naomi_game_id); - if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", naomi_game_id); - settings.dynarec.safemode = 1; - safemode_game = true; + if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", naomi_game_id); + settings.dynarec.safemode = 1; + safemode_game = true; + } + if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id); + settings.rend.ExtraDepthScale = 1e26; + extra_depth_game = true; + } + if (!strcmp("DYNAMIC GOLF", naomi_game_id) + || !strcmp("SHOOTOUT POOL", naomi_game_id) + || !strcmp("OUTTRIGGER JAPAN", naomi_game_id) + || !strcmp("CRACKIN'DJ ver JAPAN", naomi_game_id) + || !strcmp("CRACKIN'DJ PART2 ver JAPAN", naomi_game_id) + || !strcmp("KICK '4' CASH", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id); + settings.input.JammaSetup = 2; + } + else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi + || !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW + { + INFO_LOG(BOOT, "Enabling 4-player setup for game %s", naomi_game_id); + settings.input.JammaSetup = 1; + } + else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id) + || !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW + { + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); + settings.input.JammaSetup = 3; + } + else if (!strcmp("RINGOUT 4X4 JAPAN", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); + settings.input.JammaSetup = 4; + } + else if (!strcmp("NINJA ASSAULT", naomi_game_id) + || !strcmp(naomi_game_id, "Sports Shooting USA") // AW + || !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE")) // AW + { + INFO_LOG(BOOT, "Enabling lightgun setup for game %s", naomi_game_id); + settings.input.JammaSetup = 5; + } + else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); + settings.input.JammaSetup = 7; + } + if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id)) + { + INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id); + settings.rend.TranslucentPolygonDepthMask = true; + tr_poly_depth_mask_game = true; + } } - if (!strcmp("SAMURAI SPIRITS 6", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", naomi_game_id); - settings.rend.ExtraDepthScale = 1e26; - extra_depth_game = true; - } - if (!strcmp("DYNAMIC GOLF", naomi_game_id) - || !strcmp("SHOOTOUT POOL", naomi_game_id) - || !strcmp("OUTTRIGGER JAPAN", naomi_game_id) - || !strcmp("CRACKIN'DJ ver JAPAN", naomi_game_id) - || !strcmp("CRACKIN'DJ PART2 ver JAPAN", naomi_game_id) - || !strcmp("KICK '4' CASH", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling JVS rotary encoders for game %s", naomi_game_id); - settings.input.JammaSetup = 2; - } - else if (!strcmp("POWER STONE 2 JAPAN", naomi_game_id) // Naomi - || !strcmp("GUILTY GEAR isuka", naomi_game_id)) // AW - { - INFO_LOG(BOOT, "Enabling 4-player setup for game %s", naomi_game_id); - settings.input.JammaSetup = 1; - } - else if (!strcmp("SEGA MARINE FISHING JAPAN", naomi_game_id) - || !strcmp(naomi_game_id, "BASS FISHING SIMULATOR VER.A")) // AW - { - INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); - settings.input.JammaSetup = 3; - } - else if (!strcmp("RINGOUT 4X4 JAPAN", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); - settings.input.JammaSetup = 4; - } - else if (!strcmp("NINJA ASSAULT", naomi_game_id) - || !strcmp(naomi_game_id, "Sports Shooting USA") // AW - || !strcmp(naomi_game_id, "SEGA CLAY CHALLENGE")) // AW - { - INFO_LOG(BOOT, "Enabling lightgun setup for game %s", naomi_game_id); - settings.input.JammaSetup = 5; - } - else if (!strcmp(" BIOHAZARD GUN SURVIVOR2", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling specific JVS setup for game %s", naomi_game_id); - settings.input.JammaSetup = 7; - } - if (!strcmp("COSMIC SMASH IN JAPAN", naomi_game_id)) - { - INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", naomi_game_id); - settings.rend.TranslucentPolygonDepthMask = true; - tr_poly_depth_mask_game = true; - } -#endif } void dc_reset(bool manual) @@ -358,12 +361,58 @@ int reicast_init(int argc, char* argv[]) #define DATA_PATH "/" #endif +void set_platform(int platform) +{ + switch (platform) + { + case DC_PLATFORM_DREAMCAST: + printf("Starting Dreamcast game\n"); + settings.platform.ram_size = 16 * 1024 * 1024; + settings.platform.vram_size = 8 * 1024 * 1024; + settings.platform.aram_size = 2 * 1024 * 1024; + settings.platform.bios_size = 2 * 1024 * 1024; + settings.platform.flash_size = 128 * 1024; + settings.platform.bbsram_size = 0; + break; + case DC_PLATFORM_NAOMI: + printf("Starting Naomi game\n"); + settings.platform.ram_size = 32 * 1024 * 1024; + settings.platform.vram_size = 16 * 1024 * 1024; + settings.platform.aram_size = 8 * 1024 * 1024; + settings.platform.bios_size = 2 * 1024 * 1024; + settings.platform.flash_size = 0; + settings.platform.bbsram_size = 32 * 1024; + break; + case DC_PLATFORM_ATOMISWAVE: + printf("Starting Atomiswave game\n"); + settings.platform.ram_size = 16 * 1024 * 1024; + settings.platform.vram_size = 8 * 1024 * 1024; + settings.platform.aram_size = 8 * 1024 * 1024; + settings.platform.bios_size = 128 * 1024; + settings.platform.flash_size = 0; + settings.platform.bbsram_size = 128 * 1024; + break; + default: + die("Unsupported platform"); + break; + } + settings.platform.system = platform; + settings.platform.ram_mask = settings.platform.ram_size - 1; + settings.platform.vram_mask = settings.platform.vram_size - 1; + settings.platform.aram_mask = settings.platform.aram_size - 1; + _vmem_init_mappings(); +} + static int dc_init() { static bool init_done; if (init_done) return 0; + + // Default platform + set_platform(DC_PLATFORM_DREAMCAST); + if (plugins_Init()) return -3; #if FEAT_SHREC != DYNAREC_NONE @@ -382,7 +431,6 @@ static int dc_init() } mem_Init(); - mem_map_default(); // TODO needs to be called again if changing platform init_done = true; @@ -391,6 +439,23 @@ static int dc_init() bool game_started; +static int get_game_platform(const char *path) +{ + if (path == NULL) + // Dreamcast BIOS + return DC_PLATFORM_DREAMCAST; + + const char *dot = strrchr(path, '.'); + if (dot == NULL) + return DC_PLATFORM_DREAMCAST; // unknown + if (!stricmp(dot, ".zip") || !stricmp(dot, ".7z")) + return naomi_cart_GetPlatform(path); + if (!stricmp(dot, ".bin") || !stricmp(dot, ".dat")) + return DC_PLATFORM_NAOMI; + + return DC_PLATFORM_DREAMCAST; +} + int dc_start_game(const char *path) { if (path != NULL) @@ -400,57 +465,64 @@ int dc_start_game(const char *path) if (rc != 0) return rc; + set_platform(get_game_platform(path)); + mem_map_default(); + InitSettings(); dc_reset(true); LoadSettings(false); if (!LoadRomFiles(get_readonly_data_path(DATA_PATH))) { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST -#ifdef USE_REIOS - if (settings.bios.UseReios) + if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - if (!LoadHle(get_readonly_data_path(DATA_PATH))) +#ifdef USE_REIOS + if (settings.bios.UseReios) { - ERROR_LOG(BOOT, "Cannot init HLE BIOS"); - return -5; + if (!LoadHle(get_readonly_data_path(DATA_PATH))) + { + ERROR_LOG(BOOT, "Cannot init HLE BIOS"); + return -5; + } + else + { + NOTICE_LOG(BOOT, "Did not load bios, using reios"); + } } else +#endif { - NOTICE_LOG(BOOT, "Did not load bios, using reios"); + ERROR_LOG(BOOT, "Cannot find BIOS files"); + return -5; } } - else -#endif + } + + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + { + mcfg_CreateDevices(); + + if (path == NULL) { - ERROR_LOG(BOOT, "Cannot find BIOS files"); - return -5; + // Boot BIOS + TermDrive(); + InitDrive(); + } + else + { + if (DiscSwap()) + LoadCustom(); } -#endif } - -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - if (path == NULL) + else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) { - // Boot BIOS - TermDrive(); - InitDrive(); + if (!naomi_cart_SelectFile()) + return -6; + LoadCustom(); + if (settings.platform.system == DC_PLATFORM_NAOMI) + mcfg_CreateNAOMIJamma(); + else if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) + mcfg_CreateAtomisWaveControllers(); } - else - { - if (DiscSwap()) - LoadCustom(); - } -#elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - if (!naomi_cart_SelectFile()) - return -6; - LoadCustom(); -#if DC_PLATFORM == DC_PLATFORM_NAOMI - mcfg_CreateNAOMIJamma(); -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - mcfg_CreateAtomisWaveControllers(); -#endif -#endif - game_started = true; dc_resume(); @@ -502,9 +574,8 @@ void* dc_run(void*) void dc_term() { sh4_cpu.Term(); -#if DC_PLATFORM != DC_PLATFORM_DREAMCAST - naomi_cart_Close(); -#endif + if (settings.platform.system != DC_PLATFORM_DREAMCAST) + naomi_cart_Close(); plugins_Term(); mem_Term(); _vmem_release(); @@ -736,18 +807,22 @@ void LoadSettings(bool game_specific) void LoadCustom() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - char *reios_id = reios_disk_id(); + char *reios_id; + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + { + reios_id = reios_disk_id(); - char *p = reios_id + strlen(reios_id) - 1; - while (p >= reios_id && *p == ' ') - *p-- = '\0'; - if (*p == '\0') - return; -#elif DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - char *reios_id = naomi_game_id; - char *reios_software_name = naomi_game_id; -#endif + char *p = reios_id + strlen(reios_id) - 1; + while (p >= reios_id && *p == ' ') + *p-- = '\0'; + if (*p == '\0') + return; + } + else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) + { + reios_id = naomi_game_id; + char *reios_software_name = naomi_game_id; + } // Default per-game settings LoadSpecialSettings(); diff --git a/core/reios/reios.cpp b/core/reios/reios.cpp index 8f901f5c5..822a331ef 100644 --- a/core/reios/reios.cpp +++ b/core/reios/reios.cpp @@ -598,13 +598,13 @@ void reios_boot() { reios_setup_state(0x8C010000); } else { - if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) { + if (settings.platform.system == DC_PLATFORM_DREAMCAST) { if (!bootfile_inited) msgboxf("Failed to locate bootfile", MBX_ICONERROR); reios_setup_state(0xac008300); } else { - verify(DC_PLATFORM == DC_PLATFORM_NAOMI); + verify(settings.platform.system == DC_PLATFORM_NAOMI); if (CurrentCartridge == NULL) { WARN_LOG(REIOS, "No cartridge loaded"); diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index e6aa10ac0..fba0ce9b4 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -125,7 +125,7 @@ void palette_update() using namespace std; -vector VramLocks[VRAM_SIZE/PAGE_SIZE]; +vector VramLocks[VRAM_SIZE_MAX / PAGE_SIZE]; VLockedMemory vram; // vram 32-64b //List functions diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index cf02f651c..e61a8679a 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -653,10 +653,11 @@ static void gui_display_settings() if (maple_devices_changed) { maple_devices_changed = false; -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - maple_ReconnectDevices(); - reset_vmus(); -#endif + if (game_started && settings.platform.system == DC_PLATFORM_DREAMCAST) + { + maple_ReconnectDevices(); + reset_vmus(); + } } SaveSettings(); } @@ -811,14 +812,12 @@ static void gui_display_settings() if (ImGui::BeginTabItem("Controls")) { ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE if (ImGui::CollapsingHeader("Dreamcast Devices", ImGuiTreeNodeFlags_DefaultOpen)) { for (int bus = 0; bus < MAPLE_PORTS; bus++) { ImGui::Text("Device %c", bus + 'A'); ImGui::SameLine(); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST char device_name[32]; sprintf(device_name, "##device%d", bus); float w = ImGui::CalcItemWidth() / 3; @@ -862,14 +861,9 @@ static void gui_display_settings() ImGui::PopID(); } ImGui::PopItemWidth(); -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE - if (MapleDevices[bus][5] != NULL) - ImGui::Text("%s", maple_device_name(MapleDevices[bus][5]->get_device_type())); -#endif } ImGui::Spacing(); } -#endif if (ImGui::CollapsingHeader("Physical Devices", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Columns(4, "renderers", false); @@ -1253,15 +1247,14 @@ static void gui_display_settings() ImGui::Text("Git Hash: %s", GIT_HASH); ImGui::Text("Build Date: %s", BUILD_DATE); ImGui::Text("Target: %s", -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST + settings.platform.system == DC_PLATFORM_DREAMCAST ? "Dreamcast" -#elif DC_PLATFORM == DC_PLATFORM_NAOMI + : settings.platform.system == DC_PLATFORM_NAOMI ? "Naomi" -#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE + : settings.platform.system == DC_PLATFORM_ATOMISWAVE ? "Atomiswave" -#else + : "Unknown" -#endif ); } if (ImGui::CollapsingHeader("Platform", ImGuiTreeNodeFlags_DefaultOpen)) @@ -1379,25 +1372,17 @@ static void add_game_directory(const std::string& path, std::vector& } else { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - if (name.size() >= 4) - { - std::string extension = name.substr(name.size() - 4).c_str(); - //printf(" found game %s ext %s\n", entry->d_name, extension.c_str()); - if (stricmp(extension.c_str(), ".cdi") && stricmp(extension.c_str(), ".gdi") && stricmp(extension.c_str(), ".chd") && stricmp(extension.c_str(), ".cue")) - continue; - game_list.push_back({ name, child_path }); - } -#else std::string::size_type dotpos = name.find_last_of("."); if (dotpos == std::string::npos || dotpos == name.size() - 1) continue; std::string extension = name.substr(dotpos); - if (stricmp(extension.c_str(), ".zip") && stricmp(extension.c_str(), ".7z") && stricmp(extension.c_str(), ".bin") - && stricmp(extension.c_str(), ".lst") && stricmp(extension.c_str(), ".dat")) + if (stricmp(extension.c_str(), ".zip") && stricmp(extension.c_str(), ".7z") + && stricmp(extension.c_str(), ".bin") && stricmp(extension.c_str(), ".lst") + && stricmp(extension.c_str(), ".dat") + && stricmp(extension.c_str(), ".cdi") && stricmp(extension.c_str(), ".gdi") + && stricmp(extension.c_str(), ".chd") && stricmp(extension.c_str(), ".cue")) continue; game_list.push_back({ name, child_path }); -#endif } } closedir(dir); @@ -1484,7 +1469,6 @@ static void gui_display_content() { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8 * scaling, 20 * scaling)); // from 8, 4 -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST ImGui::PushID("bios"); if (ImGui::Selectable("Dreamcast BIOS")) { @@ -1493,7 +1477,6 @@ static void gui_display_content() gui_start_game(""); } ImGui::PopID(); -#endif for (auto& game : game_list) if (filter.PassFilter(game.name.c_str())) diff --git a/core/serialize.cpp b/core/serialize.cpp index 699757a68..2a98a00cf 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -157,19 +157,8 @@ extern u32 SB_FFST; //static HollyInterruptID dmatmp2; //static HollyInterruptID OldDmaId; -//this is one-time init, no updates - don't need to serialize -//extern RomChip sys_rom; -#ifdef FLASH_SIZE -extern DCFlashChip sys_nvmem; -#endif - -#ifdef BBSRAM_SIZE -extern SRamChip sys_nvmem; -#endif -//this is one-time init, no updates - don't need to serialize -//extern _vmem_handler area0_handler; - - +extern MemChip *sys_rom; +extern MemChip *sys_nvmem; //./core/hw/gdrom/gdrom_response.o @@ -831,20 +820,16 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(SB_FFST); - - //this is one-time init, no updates - don't need to serialize - //extern RomChip sys_rom; - REICAST_S(sys_nvmem.size); - REICAST_S(sys_nvmem.mask); + sys_rom->Serialize(data, total_size); + sys_nvmem->Serialize(data, total_size); + /* + REICAST_S(sys_nvmem->size); + REICAST_S(sys_nvmem->mask); #ifdef FLASH_SIZE - REICAST_S(sys_nvmem.state); + REICAST_S(sys_nvmem->state); #endif - REICAST_SA(sys_nvmem.data,sys_nvmem.size); - - //this is one-time init, no updates - don't need to serialize - //extern _vmem_handler area0_handler; - - + REICAST_SA(sys_nvmem->data, sys_nvmem->size); + */ REICAST_SA(reply_11,16) ; @@ -1198,15 +1183,14 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(i); //LIBRETRO_S(sys_nvmem_sram.mask); //LIBRETRO_SA(sys_nvmem_sram.data,sys_nvmem_sram.size); - REICAST_US(sys_nvmem.size); - REICAST_US(sys_nvmem.mask); -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - REICAST_US(sys_nvmem.state); -#else - // FIXME - die("Naomi/Atomiswave libretro savestates are not supported"); -#endif - REICAST_USA(sys_nvmem.data,sys_nvmem.size); + REICAST_US(sys_nvmem->size); + REICAST_US(sys_nvmem->mask); + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + REICAST_US(static_cast(sys_nvmem)->state); + else + // FIXME + die("Naomi/Atomiswave libretro savestates are not supported"); + REICAST_USA(sys_nvmem->data, sys_nvmem->size); //this is one-time init, no updates - don't need to serialize @@ -1580,15 +1564,16 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(SB_FFST_rc); REICAST_US(SB_FFST); - //this is one-time init, no updates - don't need to serialize - //extern RomChip sys_rom; + sys_rom->Unserialize(data, total_size); + sys_nvmem->Unserialize(data, total_size); + /* REICAST_US(sys_nvmem.size); REICAST_US(sys_nvmem.mask); #ifdef FLASH_SIZE REICAST_US(sys_nvmem.state); #endif REICAST_USA(sys_nvmem.data,sys_nvmem.size); - + */ //this is one-time init, no updates - don't need to serialize //extern _vmem_handler area0_handler; diff --git a/core/types.h b/core/types.h index cf5522668..a179a01d8 100644 --- a/core/types.h +++ b/core/types.h @@ -421,8 +421,8 @@ bool dc_unserialize(void **data, unsigned int *total_size); #define REICAST_S(v) rc_serialize(&(v), sizeof(v), data, total_size) #define REICAST_US(v) rc_unserialize(&(v), sizeof(v), data, total_size) -#define REICAST_SA(v_arr,num) rc_serialize(v_arr, sizeof(v_arr[0])*num, data, total_size) -#define REICAST_USA(v_arr,num) rc_unserialize(v_arr, sizeof(v_arr[0])*num, data, total_size) +#define REICAST_SA(v_arr,num) rc_serialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) +#define REICAST_USA(v_arr,num) rc_unserialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) enum { @@ -605,6 +605,19 @@ enum LimitFPSEnum { struct settings_t { + struct { + int system; + u32 ram_size; + u32 ram_mask; + u32 vram_size; + u32 vram_mask; + u32 aram_size; + u32 aram_mask; + u32 bios_size; + u32 flash_size; + u32 bbsram_size; + } platform; + struct { bool UseReios; } bios; @@ -738,6 +751,16 @@ struct settings_t extern settings_t settings; +#define RAM_SIZE settings.platform.ram_size +#define RAM_MASK settings.platform.ram_mask +#define ARAM_SIZE settings.platform.aram_size +#define ARAM_MASK settings.platform.aram_mask +#define VRAM_SIZE settings.platform.vram_size +#define VRAM_MASK settings.platform.vram_mask +#define BIOS_SIZE settings.platform.bios_size +#define FLASH_SIZE settings.platform.flash_size +#define BBSRAM_SIZE settings.platform.bbsram_size + void InitSettings(); void LoadSettings(bool game_specific); void SaveSettings(); diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 50dc123a3..ed9825833 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -14,7 +14,6 @@ #include #include -#include "hw/maple/maple_cfg.h" #pragma comment(lib, "XInput9_1_0.lib") PCHAR* @@ -122,9 +121,6 @@ static std::shared_ptr mouse_gamepad; void os_SetupInput() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif XInputGamepadDevice::CreateDevices(); kb_gamepad = std::make_shared(0); GamepadDevice::Register(kb_gamepad); diff --git a/p.patch b/p.patch new file mode 100644 index 000000000..83b53818e --- /dev/null +++ b/p.patch @@ -0,0 +1,1994 @@ +diff --git a/core/build.h b/core/build.h +index 3ba546c..398c301 100755 +--- a/core/build.h ++++ b/core/build.h +@@ -345,7 +345,7 @@ + #define RAM_SIZE_MAX (32*1024*1024) + #define VRAM_SIZE_MAX (16*1024*1024) + #define ARAM_SIZE_MAX (8*1024*1024) +- ++/* + #if (DC_PLATFORM==DC_PLATFORM_DREAMCAST) + + #define BUILD_DREAMCAST 1 +@@ -433,7 +433,7 @@ + #ifdef BBSRAM_SIZE + #define BBSRAM_MASK (BBSRAM_SIZE-1) + #endif +- ++*/ + #define GD_CLOCK 33868800 //GDROM XTAL -- 768fs + + #define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs +diff --git a/core/deps/vixl/platform-vixl.h b/core/deps/vixl/platform-vixl.h +index ad8d057..8da090c 100644 +--- a/core/deps/vixl/platform-vixl.h ++++ b/core/deps/vixl/platform-vixl.h +@@ -33,7 +33,7 @@ extern "C" { + } + + #define VIXL_CODE_BUFFER_MALLOC +- ++#define VIXL_DEBUG + + #if defined(_ANDROID) && defined(VIXL_DEBUG) + #include +diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h +index 807f128..7dd03a9 100644 +--- a/core/hw/flashrom/flashrom.h ++++ b/core/hw/flashrom/flashrom.h +@@ -40,6 +40,11 @@ struct MemChip + return rv; + } + ++ virtual void Write(u32 addr, u32 data, u32 size) ++ { ++ die("Method not supported"); ++ } ++ + bool Load(const string& file) + { + FILE* f=fopen(file.c_str(),"rb"); +@@ -119,20 +124,20 @@ struct MemChip + INFO_LOG(FLASHROM, "Saved %s as %s", path, title.c_str()); + } + virtual void Reset() {} ++ virtual bool Serialize(void **data, unsigned int *total_size) { return true; } ++ virtual bool Unserialize(void **data, unsigned int *total_size) { return true; } + }; ++ + struct RomChip : MemChip + { + RomChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} +- void Write(u32 addr,u32 data,u32 sz) +- { +- die("Write to RomChip is not possible, address=%x, data=%x, size=%d"); +- } + }; ++ + struct SRamChip : MemChip + { + SRamChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} + +- void Write(u32 addr,u32 val,u32 sz) ++ void Write(u32 addr,u32 val,u32 sz) override + { + addr&=mask; + if (addr < write_protect_size) +@@ -152,6 +157,18 @@ struct SRamChip : MemChip + die("invalid access size"); + } + } ++ ++ virtual bool Serialize(void **data, unsigned int *total_size) ++ { ++ REICAST_SA(&this->data[write_protect_size], size - write_protect_size); ++ return true; ++ } ++ ++ virtual bool Unserialize(void **data, unsigned int *total_size) ++ { ++ REICAST_USA(&this->data[write_protect_size], size - write_protect_size); ++ return true; ++ } + }; + + // +@@ -262,7 +279,7 @@ struct DCFlashChip : MemChip + } + + +- void Write(u32 addr,u32 val,u32 sz) ++ void Write(u32 addr,u32 val,u32 sz) override + { + if (sz != 1) + die("invalid access size"); +@@ -283,7 +300,19 @@ struct DCFlashChip : MemChip + state = FS_ReadAMDID1; + break; + default: +- EMUERROR("Unknown FlashWrite mode: %x\n", val); ++ INFO_LOG(FLASHROM, "Unknown FlashWrite mode: %x\n", val); ++/* ++ void print_blocks(); ++ print_blocks(); ++#define r p_sh4rcb->cntx.r ++#define next_pc p_sh4rcb->cntx.pc ++ DEBUG_LOG(SH4, "r0 %08x r1 %08x r2 %08x r3 %08x r4 %08x r5 %08x r6 %08x r7 %08x pc %08x ", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], next_pc); ++ DEBUG_LOG(SH4, "r8 %08x r9 %08x r10 %08x r11 %08x r12 %08x r13 %08x r14 %08x r15 %08x", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); ++#undef r ++#undef next_pc ++ INFO_LOG(MEMORY, "[flash]Write pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++ die("done"); ++*/ + break; + } + break; +@@ -627,4 +656,18 @@ private: + + return result; + } ++ ++ virtual bool Serialize(void **data, unsigned int *total_size) ++ { ++ REICAST_SA(&this->data[write_protect_size], size - write_protect_size); ++ REICAST_S(state); ++ return true; ++ } ++ ++ virtual bool Unserialize(void **data, unsigned int *total_size) ++ { ++ REICAST_USA(&this->data[write_protect_size], size - write_protect_size); ++ REICAST_US(state); ++ return true; ++ } + }; +diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp +index cf675d9..9cccf3e 100644 +--- a/core/hw/gdrom/gdromv3.cpp ++++ b/core/hw/gdrom/gdromv3.cpp +@@ -115,6 +115,27 @@ void FillReadBuffer() + libGDR_ReadSector(read_buff.cache,read_params.start_sector,count,read_params.sector_type); + read_params.start_sector+=count; + read_params.remaining_sectors-=count; ++/* ++ static const u8 pattern[] = { ++ // debug 0x01, 0xe5, 0x07, 0xe4, //0x01, 0xe5, //0x10, 0xe6, //0x00, 0xe7 ++ //0x08, 0xe4, 0x74, 0x1f, 0x01, 0xe5, 0x75, 0x1f ++ //0x43, 0x6b, 0x53, 0x6d, 0x63, 0x6c, 0xec, 0x7f ++ 0x20, 0x62, 0x2c, 0x62, 0x37, 0x32, 0x01, 0x8b ++ }; ++ for (int i = 0; i < read_buff.cache_size - sizeof(pattern); i++) ++ { ++ if (!memcmp(&read_buff.cache[i], pattern, sizeof(pattern))) ++ { ++// read_buff.cache[i + 0] = 0x00; ++// read_buff.cache[i + 1] = 0xeb; ++// read_buff.cache[i + 2] = 0x00; ++// read_buff.cache[i + 3] = 0xed; ++// read_buff.cache[i + 6] = 0x09; ++// read_buff.cache[i + 7] = 0x00; ++ ERROR_LOG(GDROM, "Pattern found"); ++ } ++ } ++*/ + } + + +@@ -755,7 +776,7 @@ void gd_process_spi_cmd() + subc_info[1]=0x15;//15h No audio status information + } + +- subc_info[1]=0x15; ++// subc_info[1]=0x15; + + if (format==0) + { +@@ -1029,14 +1050,14 @@ int GDRomschd(int i, int c, int j) + { + while(len) + { +- u32 buff_size =read_buff.cache_size; +- if (buff_size==0) ++ u32 buff_size = read_buff.cache_size; ++ if (buff_size == 0) + { + verify(read_params.remaining_sectors>0); + //buffer is empty , fill it :) + FillReadBuffer(); ++ buff_size = read_buff.cache_size; + } +- + //transfer up to len bytes + if (buff_size>len) + { +diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp +index a3f50bc..7fc081c 100644 +--- a/core/hw/holly/sb.cpp ++++ b/core/hw/holly/sb.cpp +@@ -426,14 +426,14 @@ void sb_Init() + sb_rio_register(SB_GDDIR_addr,RIO_DATA); + + +- ++//#if 0 + //0x005F7414 SB_GDEN RW GD-DMA enable + sb_rio_register(SB_GDEN_addr,RIO_DATA); + + + //0x005F7418 SB_GDST RW GD-DMA start + sb_rio_register(SB_GDST_addr,RIO_DATA); +- ++//#endif + + + //0x005F7480 SB_G1RRC W System ROM read access timing +diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp +index 77728c1..bc9b8d0 100644 +--- a/core/hw/holly/sb_mem.cpp ++++ b/core/hw/holly/sb_mem.cpp +@@ -18,26 +18,36 @@ + #include "hw/flashrom/flashrom.h" + #include "reios/reios.h" + +-#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE +-DCFlashChip sys_rom(BIOS_SIZE, BIOS_SIZE / 2); +-#else +-RomChip sys_rom(BIOS_SIZE); +-#endif ++MemChip *sys_rom; ++MemChip *sys_nvmem; + +-#ifdef FLASH_SIZE +-DCFlashChip sys_nvmem(FLASH_SIZE); +-#endif ++extern bool bios_loaded; + +-#ifdef BBSRAM_SIZE +-SRamChip sys_nvmem(BBSRAM_SIZE); +-#endif ++static std::string getRomPrefix() ++{ ++ switch (settings.platform.system) ++ { ++ case DC_PLATFORM_DREAMCAST: ++ return "dc_"; ++ case DC_PLATFORM_NAOMI: ++ return "naomi_"; ++ case DC_PLATFORM_ATOMISWAVE: ++ return "aw_"; ++ default: ++ die("Unsupported platform"); ++ return ""; ++ } ++} + +-extern bool bios_loaded; ++static bool nvmemOptional() ++{ ++ return settings.platform.system != DC_PLATFORM_DREAMCAST; ++} + + bool LoadRomFiles(const string& root) + { + #if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE +- if (!sys_rom.Load(root, ROM_PREFIX, "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin" ROM_NAMES, "bootrom")) ++ if (!sys_rom->Load(root, getRomPrefix(), "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin", "bootrom")) + { + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST + // Dreamcast absolutely needs a BIOS +@@ -49,12 +59,12 @@ bool LoadRomFiles(const string& root) + bios_loaded = true; + #endif + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST +- if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) ++ if (!sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) + #else +- if (!sys_nvmem.Load(get_game_save_prefix() + ".nvmem")) ++ if (!sys_nvmem->Load(get_game_save_prefix() + ".nvmem")) + #endif + { +- if (NVR_OPTIONAL) ++ if (nvmemOptional()) + { + INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); + } +@@ -67,7 +77,7 @@ bool LoadRomFiles(const string& root) + + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST + struct flash_syscfg_block syscfg; +- int res = sys_nvmem.ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); ++ int res = static_cast(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); + + if (!res) + { +@@ -85,13 +95,13 @@ bool LoadRomFiles(const string& root) + if (settings.dreamcast.language <= 5) + syscfg.lang = settings.dreamcast.language; + +- if (sys_nvmem.WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) ++ if (static_cast(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) + WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); + + #endif + + #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE +- sys_rom.Load(get_game_save_prefix() + ".nvmem2"); ++ sys_rom->Load(get_game_save_prefix() + ".nvmem2"); + #endif + + return true; +@@ -100,35 +110,35 @@ bool LoadRomFiles(const string& root) + void SaveRomFiles(const string& root) + { + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST +- sys_nvmem.Save(root, ROM_PREFIX, "nvmem.bin", "nvmem"); ++ sys_nvmem->Save(root, getRomPrefix(), "nvmem.bin", "nvmem"); + #else +- sys_nvmem.Save(get_game_save_prefix() + ".nvmem"); ++ sys_nvmem->Save(get_game_save_prefix() + ".nvmem"); + #endif + #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE +- sys_rom.Save(get_game_save_prefix() + ".nvmem2"); ++ sys_rom->Save(get_game_save_prefix() + ".nvmem2"); + #endif + } + + bool LoadHle(const string& root) { +- if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { ++ if (!sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { + INFO_LOG(FLASHROM, "No nvmem loaded"); + } + +- return reios_init(sys_rom.data, sys_nvmem.data); ++ return reios_init(sys_rom->data, sys_nvmem->data); + } + +-u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem.Read(addr,sz); } +-void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem.Write(addr,data,sz); } ++u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); } ++void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); } + + #if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2) + +-u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); } ++u32 ReadBios(u32 addr,u32 sz) { return sys_rom->Read(addr,sz); } + void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz); } + + #elif (DC_PLATFORM == DC_PLATFORM_ATOMISWAVE) + u32 ReadBios(u32 addr,u32 sz) + { +- return sys_rom.Read(addr, sz); ++ return sys_rom->Read(addr, sz); + } + + void WriteBios(u32 addr,u32 data,u32 sz) +@@ -136,9 +146,13 @@ void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] + if (sz != 1) + { + INFO_LOG(MEMORY, "Invalid access size @%08x data %x sz %d", addr, data, sz); ++// void print_blocks(); ++// print_blocks(); ++// INFO_LOG(MEMORY, "[flash]Write pc=%x pr=%x", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++// die("done"); + return; + } +- sys_rom.Write(addr, data, sz); ++ sys_rom->Write(addr, data, sz); + } + + #else +@@ -345,19 +359,59 @@ void DYNACALL WriteMem_area0(u32 addr,T data) + void sh4_area0_Init() + { + sb_Init(); ++ sh4_area0_Reset(true); + } + +-void sh4_area0_Reset(bool Manual) ++void sh4_area0_Reset(bool manual) + { +- sb_Reset(Manual); +- sys_rom.Reset(); +-#if defined(FLASH_SIZE) || defined(BBSRAM_SIZE) +- sys_nvmem.Reset(); +-#endif ++ if (manual) ++ { ++ if (sys_rom != NULL) ++ { ++ delete sys_rom; ++ sys_rom = NULL; ++ } ++ if (sys_nvmem != NULL) ++ { ++ delete sys_nvmem; ++ sys_nvmem = NULL; ++ } ++ switch (settings.platform.system) ++ { ++ case DC_PLATFORM_DREAMCAST: ++ sys_rom = new RomChip(settings.platform.bios_size); ++ sys_nvmem = new DCFlashChip(settings.platform.bios_size); ++ break; ++ case DC_PLATFORM_NAOMI: ++ sys_rom = new RomChip(settings.platform.bios_size); ++ sys_nvmem = new SRamChip(settings.platform.bbsram_size); ++ break; ++ case DC_PLATFORM_ATOMISWAVE: ++ sys_rom = new DCFlashChip(settings.platform.bios_size, settings.platform.bios_size / 2); ++ sys_nvmem = new SRamChip(settings.platform.bbsram_size); ++ break; ++ } ++ } ++ else ++ { ++ sys_rom->Reset(); ++ sys_nvmem->Reset(); ++ } ++ sb_Reset(manual); + } + + void sh4_area0_Term() + { ++ if (sys_rom != NULL) ++ { ++ delete sys_rom; ++ sys_rom = NULL; ++ } ++ if (sys_nvmem != NULL) ++ { ++ delete sys_nvmem; ++ sys_nvmem = NULL; ++ } + sb_Term(); + } + +diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp +index 1eb8d6b..bd2526e 100644 +--- a/core/hw/mem/_vmem.cpp ++++ b/core/hw/mem/_vmem.cpp +@@ -182,6 +182,10 @@ template + INLINE Trv DYNACALL _vmem_readt(u32 addr) + { + const u32 sz=sizeof(T); ++// if ((addr & 0x1ffffff0) == 0x0c19d3d0 || (addr & 0x1ffffff) == 0x0c1c0164) { ++// extern VLockedMemory mem_b; ++// printf("Read %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, *(u32*)&mem_b[addr & RAM_MASK]); ++// } + + u32 page=addr>>24; //1 op, shift/extract + unat iirf=(unat)_vmem_MemInfo_ptr[page]; //2 ops, insert + read [vmem table will be on reg ] +@@ -232,7 +236,45 @@ template + INLINE void DYNACALL _vmem_writet(u32 addr,T data) + { + const u32 sz=sizeof(T); +- ++/* ++//db if (addr == 0x8cd4F604 || addr == 0x8cd4F504 || addr == 0x8cd4F504) printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); ++ if ((addr & 0x1fffffff) == 0x0c19d3d0) { ++ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); ++ if (data == 0) ++ data = 0x8c600000; ++// void print_blocks(); ++// print_blocks(); ++// //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++// die("done"); ++ } ++ else if ((addr & 0x1fffffff) == 0x0c19d3d4) { ++ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); ++ if (data == 0) ++ data = 0x8c700000; ++ // void print_blocks(); ++ // print_blocks(); ++ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++ // die("done"); ++ } ++ else if ((addr & 0x1fffffff) == 0x0c19d3dc) { ++ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); ++ if (data == 0) ++ data = 0x8c780000; ++ // void print_blocks(); ++ // print_blocks(); ++ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++ // die("done"); ++ } ++ else if ((addr & 0x1fffffff) == 0x0c1c0164) { ++ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); ++// if (data == 0) ++// data = 0x8c780000; ++ // void print_blocks(); ++ // print_blocks(); ++ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++ // die("done"); ++ } ++*/ + u32 page=addr>>24; + unat iirf=(unat)_vmem_MemInfo_ptr[page]; + void* ptr=(void*)(iirf&~HANDLER_MAX); +@@ -299,31 +341,38 @@ void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet(Address + //default read handlers + u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss) + { +- DEBUG_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); ++ INFO_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); + return (u8)MEM_ERROR_RETURN_VALUE; + } + u16 DYNACALL _vmem_ReadMem16_not_mapped(u32 addresss) + { +- DEBUG_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); ++ INFO_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); + return (u16)MEM_ERROR_RETURN_VALUE; + } +-u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 addresss) ++u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 address) + { +- DEBUG_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", addresss); ++ INFO_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", address); ++// if (address == 0x3A507150) ++// { ++// void print_blocks(); ++// print_blocks(); ++// INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); ++// die("done"); ++// } + return (u32)MEM_ERROR_RETURN_VALUE; + } + //default write handers + void DYNACALL _vmem_WriteMem8_not_mapped(u32 addresss,u8 data) + { +- DEBUG_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); ++ INFO_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + } + void DYNACALL _vmem_WriteMem16_not_mapped(u32 addresss,u16 data) + { +- DEBUG_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); ++ INFO_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + } + void DYNACALL _vmem_WriteMem32_not_mapped(u32 addresss,u32 data) + { +- DEBUG_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); ++ INFO_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + } + //code to register handlers + //0 is considered error :) +diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp +index e40c893..12e26e3 100644 +--- a/core/hw/mem/vmem32.cpp ++++ b/core/hw/mem/vmem32.cpp +@@ -66,7 +66,7 @@ struct vram_lock { + u32 start; + u32 end; + }; +-static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; ++static std::vector vram_blocks[VRAM_SIZE_MAX / VRAM_PROT_SEGMENT]; + static u8 sram_mapped_pages[USER_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped + + bool vmem32_inited; +diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp +index 131559e..0f17b71 100644 +--- a/core/hw/naomi/naomi.cpp ++++ b/core/hw/naomi/naomi.cpp +@@ -8,6 +8,7 @@ + #include "hw/holly/holly_intc.h" + #include "hw/maple/maple_cfg.h" + #include "hw/sh4/sh4_sched.h" ++#include "hw/sh4/modules/dmac.h" + + #include "naomi.h" + #include "naomi_cart.h" +@@ -340,23 +341,6 @@ u16 NaomiGameIDRead() + return (GSerialBuffer&(1<<(31-GBufPos)))?1:0; + } + +- +- +- +-u32 _ReadMem_naomi(u32 Addr, u32 sz) +-{ +- verify(sz!=1); +- +- DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", Addr, sz); +- return 1; +- +-} +-void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) +-{ +- DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", Addr, data, sz); +-} +- +- + //DIMM board + //Uses interrupt ext#3 (holly_EXT_PCI) + +@@ -382,23 +366,22 @@ void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) + //n1 bios writes the value -1, meaning it expects the bit 0 to be set + //.// + +-u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? +-u32 reg_dimm_40; //parameters +-u32 reg_dimm_44; //parameters +-u32 reg_dimm_48; //parameters +- +-u32 reg_dimm_4c=0x11; //status/control reg ? ++u32 reg_dimm_command; // command, written, 0x1E03 some flag ? ++u32 reg_dimm_offsetl; ++u32 reg_dimm_parameterl; ++u32 reg_dimm_parameterh; ++u32 reg_dimm_status = 0x11; + + bool NaomiDataRead = false; + static bool aw_ram_test_skipped = false; + +-void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) ++void naomi_process(u32 command, u32 offsetl, u32 parameterl, u32 parameterh) + { +- DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", r3c, r40, r44, r48); +- DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",r3c >> 15,(r3c & 0x7e00) >> 9, r3c & 0x1FF); +- DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (r3c & 0xFF00) >> 8,r3c & 0xFF); ++ DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", command, offsetl, parameterl, parameterh); ++ DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",command >> 15,(command & 0x7e00) >> 9, command & 0x1FF); ++ DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (command & 0xFF00) >> 8,command & 0xFF); + +- u32 param=(r3c&0xFF); ++ u32 param=(command&0xFF); + if (param==0xFF) + { + DEBUG_LOG(NAOMI, "invalid opcode or smth ?"); +@@ -407,8 +390,8 @@ void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) + //else if (param!=3) + if (opcd<255) + { +- reg_dimm_3c=0x8000 | (opcd%12<<9) | (0x0); +- DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_3c); ++ reg_dimm_command=0x8000 | (opcd%12<<9) | (0x0); ++ DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_command); + asic_RaiseInterrupt(holly_EXP_PCI); + DEBUG_LOG(NAOMI, "Interrupt raised"); + opcd++; +@@ -437,8 +420,23 @@ void WriteMem_naomi(u32 Addr, u32 data, u32 sz) + } + + //Dma Start ++int naomi_schid; ++ ++int Naomi_DmaSchd(int i, int c, int j) ++{ ++ SB_GDSTARD = SB_GDSTAR + SB_GDLEN; ++ SB_GDLEND = SB_GDLEN; ++ SB_GDST = 0; ++ // interrupt not needed? SB_GDST is monitored ++ asic_RaiseInterrupt(holly_GDROM_DMA); ++// asic_RaiseInterrupt(holly_GDROM_CMD); ++ ++ return 0; ++} ++ + void Naomi_DmaStart(u32 addr, u32 data) + { ++// asic_CancelInterrupt(holly_GDROM_CMD); + if (SB_GDEN==0) + { + INFO_LOG(NAOMI, "Invalid (NAOMI)GD-DMA start, SB_GDEN=0. Ignoring it."); +@@ -451,11 +449,26 @@ void Naomi_DmaStart(u32 addr, u32 data) + if (SB_GDST==1) + { + verify(1 == SB_GDDIR ); +- +- SB_GDSTARD=SB_GDSTAR+SB_GDLEN; ++ if (false) // breaks doa2 (sz 15a15c & 3a7cc) if (SB_GDLEN & 0x1F) ++ { ++ ERROR_LOG(NAOMI, "SB_GDLEN has invalid value: %x", SB_GDLEN); ++ //die("NAOMI: SB_GDLEN has invalid size !"); ++ SB_GDSTARD = SB_GDSTAR; ++ SB_GDLEND = 0; ++ SB_GDST = 0; ++ return; ++ } ++ if (0x8201 != (DMAC_DMAOR.full & DMAOR_MASK)) ++ { ++ INFO_LOG(NAOMI, "NAOMI: DMAOR has invalid settings (%X)", DMAC_DMAOR.full); ++ //return; ++ } ++ DEBUG_LOG(NAOMI, "NAOMI-DMA start addr %08X len %d", SB_GDSTAR, SB_GDLEN); ++ ++// SB_GDSTARD=SB_GDSTAR+SB_GDLEN; + +- SB_GDLEND=SB_GDLEN; +- SB_GDST=0; ++// SB_GDLEND=SB_GDLEN; ++// SB_GDST=0; + if (CurrentCartridge != NULL) + { + u32 len = SB_GDLEN; +@@ -464,21 +477,28 @@ void Naomi_DmaStart(u32 addr, u32 data) + { + u32 block_len = len; + void* ptr = CurrentCartridge->GetDmaPtr(block_len); +- if (ptr != NULL) +- WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); ++ if (block_len == 0) ++ { ++ INFO_LOG(NAOMI, "Aborted DMA transfer. Read past end of cart?"); ++ break; ++ } ++ WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); + CurrentCartridge->AdvancePtr(block_len); + len -= block_len; + offset += block_len; + } + } + +- asic_RaiseInterrupt(holly_GDROM_DMA); ++// asic_RaiseInterrupt(holly_GDROM_DMA); ++// sh4_sched_request(naomi_schid, SB_GDLEN * 2); ++ Naomi_DmaSchd(0, 0, 0); + } + } + + + void Naomi_DmaEnable(u32 addr, u32 data) + { ++// asic_CancelInterrupt(holly_GDROM_CMD); + SB_GDEN=data&1; + if (SB_GDEN==0 && SB_GDST==1) + { +@@ -538,6 +558,8 @@ void naomi_reg_Init() + sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart); + + sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable); ++ ++ naomi_schid = sh4_sched_register(0, &Naomi_DmaSchd); + } + + void naomi_reg_Term() +@@ -573,82 +595,11 @@ void naomi_reg_Reset(bool Manual) + GLastCmd = 0; + SerStep = 0; + SerStep2 = 0; +-} +- +-void Update_naomi() +-{ +- /* +- if (naomi_updates>1) +- { +- naomi_updates--; +- } +- else if (naomi_updates==1) +- { +- naomi_updates=0; +- asic_RaiseInterrupt(holly_EXP_PCI); +- }*/ +-#if 0 +- if(!(SB_GDST&1) || !(SB_GDEN &1)) +- return; +- +- //SB_GDST=0; +- +- //TODO : Fix dmaor +- u32 dmaor = DMAC_DMAOR.full; +- +- u32 src = SB_GDSTARD, +- len = SB_GDLEN-SB_GDLEND ; +- +- //len=min(len,(u32)32); +- // do we need to do this for gdrom dma ? +- if(0x8201 != (dmaor &DMAOR_MASK)) { +- INFO_LOG(NAOMI, "GDROM: DMAOR has invalid settings (%X) !", dmaor); +- //return; +- } +- if(len & 0x1F) { +- INFO_LOG(NAOMI, "GDROM: SB_GDLEN has invalid size (%X) !", len); +- return; +- } +- +- if(0 == len) +- { +- INFO_LOG(NAOMI, "GDROM: Len: %X, Abnormal Termination !", len); +- } +- u32 len_backup=len; +- if( 1 == SB_GDDIR ) +- { +- WriteMemBlock_nommu_ptr(dst,NaomiRom+(DmaOffset&0x7ffffff),size); +- +- DmaCount=0xffff; +- } +- else +- INFO_LOG(NAOMI, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)"); +- +- //SB_GDLEN = 0x00000000; //13/5/2k7 -> acording to docs these regs are not updated by hardware +- //SB_GDSTAR = (src + len_backup); +- +- SB_GDLEND+= len_backup; +- SB_GDSTARD+= len_backup;//(src + len_backup)&0x1FFFFFFF; +- +- if (SB_GDLEND==SB_GDLEN) +- { +- //printf("Streamed GDMA end - %d bytes trasnfered\n",SB_GDLEND); +- SB_GDST=0;//done +- // The DMA end interrupt flag +- asic_RaiseInterrupt(holly_GDROM_DMA); +- } +- //Readed ALL sectors +- if (read_params.remaining_sectors==0) +- { +- u32 buff_size =read_buff.cache_size - read_buff.cache_index; +- //And all buffer :p +- if (buff_size==0) +- { +- verify(!SB_GDST&1) +- gd_set_state(gds_procpacketdone); +- } +- } +-#endif ++ reg_dimm_command = 0; ++ reg_dimm_offsetl = 0; ++ reg_dimm_parameterl = 0; ++ reg_dimm_parameterh = 0; ++ reg_dimm_status = 0x11; + } + + static u8 aw_maple_devs; +@@ -659,6 +610,10 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { + //printf("libExtDevice_ReadMem_A0_006 %d@%08x: %x\n", size, addr, mem600[addr]); + switch (addr) + { ++// case 0: ++// return 0; ++// case 4: ++// return 1; + case 0x280: + // 0x00600280 r 0000dcba + // a/b - 1P/2P coin inputs (JAMMA), active low +diff --git a/core/hw/naomi/naomi.h b/core/hw/naomi/naomi.h +index 8781f03..88ae8cb 100644 +--- a/core/hw/naomi/naomi.h ++++ b/core/hw/naomi/naomi.h +@@ -8,8 +8,6 @@ void naomi_reg_Init(); + void naomi_reg_Term(); + void naomi_reg_Reset(bool Manual); + +-void Update_naomi(); +- + u32 ReadMem_naomi(u32 Addr, u32 sz); + void WriteMem_naomi(u32 Addr, u32 data, u32 sz); + +@@ -20,21 +18,11 @@ u16 NaomiGameIDRead(); + void NaomiGameIDWrite(const u16 Data); + void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48); + +-typedef u16 (*getNaomiAxisFP)(); +- +-struct NaomiInputMapping { +- getNaomiAxisFP axis[8]; +- u8 button_mapping_byte[16]; +- u8 button_mapping_mask[16]; +-}; +- +-extern NaomiInputMapping Naomi_Mapping; +- +-extern u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? +-extern u32 reg_dimm_40; //parameters +-extern u32 reg_dimm_44; //parameters +-extern u32 reg_dimm_48; //parameters +-extern u32 reg_dimm_4c; //status/control reg ? ++extern u32 reg_dimm_command; // command, written, 0x1E03 some flag ? ++extern u32 reg_dimm_offsetl; ++extern u32 reg_dimm_parameterl; ++extern u32 reg_dimm_parameterh; ++extern u32 reg_dimm_status; + + extern bool NaomiDataRead; + extern u32 naomi_updates; +diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp +index 209df28..0a46132 100644 +--- a/core/hw/naomi/naomi_cart.cpp ++++ b/core/hw/naomi/naomi_cart.cpp +@@ -730,23 +730,26 @@ void NaomiCartridge::AdvancePtr(u32 size) { + u32 NaomiCartridge::ReadMem(u32 address, u32 size) + { + verify(size!=1); +- //printf("+naomi?WTF? ReadMem: %X, %d\n", address, size); ++ + switch(address & 255) + { +- case 0x3c: +- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); +- return reg_dimm_3c | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios +- case 0x40: +- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); +- return reg_dimm_40; +- case 0x44: +- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); +- return reg_dimm_44; +- case 0x48: +- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); +- return reg_dimm_48; ++ case 0x3c: // 5f703c: DIMM COMMAND ++ DEBUG_LOG(NAOMI, "DIMM COMMAND read<%d>", size); ++ return reg_dimm_command | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios ++// return 0xffff; ++ case 0x40: // 5f7040: DIMM OFFSETL ++ DEBUG_LOG(NAOMI, "DIMM OFFSETL read<%d>", size); ++ return reg_dimm_offsetl; ++ case 0x44: // 5f7044: DIMM PARAMETERL ++ DEBUG_LOG(NAOMI, "DIMM PARAMETERL read<%d>", size); ++ return reg_dimm_parameterl; ++ case 0x48: // 5f7048: DIMM PARAMETERH ++ DEBUG_LOG(NAOMI, "DIMM PARAMETERH read<%d>", size); ++ return reg_dimm_parameterh; ++ case 0x04C: // 5f704c: DIMM STATUS ++ DEBUG_LOG(NAOMI, "DIMM STATUS read<%d>", size); ++ return reg_dimm_status; + +- //These are known to be valid on normal ROMs and DIMM board + case NAOMI_ROM_OFFSETH_addr&255: + return RomPioOffset>>16 | (RomPioAutoIncrement << 15); + +@@ -786,7 +789,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) + return 1; + + +- //This should be valid + case NAOMI_DMA_OFFSETH_addr&255: + return DmaOffset>>16; + case NAOMI_DMA_OFFSETL_addr&255: +@@ -796,10 +798,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) + DEBUG_LOG(NAOMI, "naomi ReadBoardId: %X, %d", address, size); + return 1; + +- case 0x04C: +- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); +- return reg_dimm_4c; +- + case NAOMI_COMM2_CTRL_addr & 255: + DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL read"); + return comm_ctrl; +@@ -840,35 +838,34 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) + + void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) + { +- // printf("+naomi WriteMem: %X <= %X, %d\n", address, data, size); + switch(address & 255) + { +- case 0x3c: +- if (0x1E03==data) ++ case 0x3c: // 5f703c: DIMM COMMAND ++ if (0x1E03 == data) + { + /* +- if (!(reg_dimm_4c&0x100)) ++ if (!(reg_dimm_status & 0x100)) + asic_RaiseInterrupt(holly_EXP_PCI); +- reg_dimm_4c|=1;*/ ++ reg_dimm_status |= 1;*/ + } +- reg_dimm_3c=data; +- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); ++ reg_dimm_command = data; ++ DEBUG_LOG(NAOMI, "DIMM COMMAND Write: %X <= %X, %d", address, data, size); + return; + +- case 0x40: +- reg_dimm_40=data; +- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); ++ case 0x40: // 5f7040: DIMM OFFSETL ++ reg_dimm_offsetl = data; ++ DEBUG_LOG(NAOMI, "DIMM OFFSETL Write: %X <= %X, %d", address, data, size); + return; +- case 0x44: +- reg_dimm_44=data; +- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); ++ case 0x44: // 5f7044: DIMM PARAMETERL ++ reg_dimm_parameterl = data; ++ DEBUG_LOG(NAOMI, "DIMM PARAMETERL Write: %X <= %X, %d", address, data, size); + return; +- case 0x48: +- reg_dimm_48=data; +- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); ++ case 0x48: // 5f7048: DIMM PARAMETERH ++ reg_dimm_parameterh = data; ++ DEBUG_LOG(NAOMI, "DIMM PARAMETERH Write: %X <= %X, %d", address, data, size); + return; + +- case 0x4C: ++ case 0x4C: // 5f704c: DIMM STATUS + if (data&0x100) + { + asic_CancelInterrupt(holly_EXP_PCI); +@@ -879,10 +876,10 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) + /*FILE* ramd=fopen("c:\\ndc.ram.bin","wb"); + fwrite(mem_b.data,1,RAM_SIZE,ramd); + fclose(ramd);*/ +- naomi_process(reg_dimm_3c,reg_dimm_40,reg_dimm_44,reg_dimm_48); ++ naomi_process(reg_dimm_command, reg_dimm_offsetl, reg_dimm_parameterl, reg_dimm_parameterh); + } +- reg_dimm_4c=data&~0x100; +- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); ++ reg_dimm_status = data & ~0x100; ++ DEBUG_LOG(NAOMI, "DIMM STATUS Write: %X <= %X, %d", address, data, size); + return; + + //These are known to be valid on normal ROMs and DIMM board +diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp +index 26f9945..1884483 100644 +--- a/core/hw/sh4/dyna/blockmanager.cpp ++++ b/core/hw/sh4/dyna/blockmanager.cpp +@@ -412,15 +412,18 @@ void bm_Reset() + // Windows cannot lock/unlock a region spanning more than one VirtualAlloc or MapViewOfFile + // so we have to unlock each region individually + // No need for this mess in 4GB mode since windows doesn't use it +-#if RAM_SIZE == 16 * 1024 * 1024 +- mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); +- mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); +- mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); +- mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); +-#else +- mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); +- mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); +-#endif ++ if (settings.platform.ram_size == 16 * 1024 * 1024) ++ { ++ mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); ++ mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); ++ mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); ++ mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); ++ } ++ else ++ { ++ mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); ++ mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); ++ } + if (_nvmem_4gb_space()) + { + mem_region_unlock(virt_ram_base + 0x8C000000, 0x90000000 - 0x8C000000); +diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp +index 5926bb8..e616985 100644 +--- a/core/hw/sh4/dyna/driver.cpp ++++ b/core/hw/sh4/dyna/driver.cpp +@@ -284,6 +284,11 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) + DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) + { + u32 pc=next_pc; ++// if (next_pc == 0x8C046E82) ++// { ++// DEBUG_LOG(SH4, "r0 %08x r1 %08x r2 %08x r3 %08x r4 %08x r5 %08x r6 %08x r7 %08x pc %08x ", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], next_pc); ++// DEBUG_LOG(SH4, "r8 %08x r9 %08x r10 %08x r11 %08x r12 %08x r13 %08x r14 %08x r15 %08x", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); ++// } + + if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300) + recSh4_ClearCache(); +@@ -324,7 +329,14 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) + emit_ptr = NULL; + emit_ptr_limit = NULL; + } +- ++ /* ++ if (rbi->vaddr <= 0x8c018120 && rbi->vaddr + rbi->sh4_code_size > 0x8c018120) ++ //if (rbi->vaddr == 0x8c7e9c80) ++ { ++ extern void print_blocks(); ++ print_blocks(); ++ } ++ */ + return rbi->code; + } + +diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp +index 3a1c9e3..6b55a27 100644 +--- a/core/hw/sh4/interpr/sh4_interpreter.cpp ++++ b/core/hw/sh4/interpr/sh4_interpreter.cpp +@@ -32,9 +32,18 @@ + #define GetM(str) ((str>>4) & 0xf) + + static s32 l; ++static bool disassemble = false; + + static void ExecuteOpcode(u16 op) + { ++// if ((next_pc & 0x1ffffff0) == 0x0C0180F0) ++// disassemble = true; ++ if (disassemble) ++ { ++ char s[128]; ++ OpDesc[op]->Disassemble(s, next_pc - 2, op); ++ printf("%s\n", s); ++ } + if (sr.FD == 1 && OpDesc[op]->IsFloatingPoint()) + RaiseFPUDisableException(); + OpPtr[op](op); +diff --git a/core/hw/sh4/interpr/sh4_opcodes.cpp b/core/hw/sh4/interpr/sh4_opcodes.cpp +index 9ede446..074d942 100644 +--- a/core/hw/sh4/interpr/sh4_opcodes.cpp ++++ b/core/hw/sh4/interpr/sh4_opcodes.cpp +@@ -982,7 +982,7 @@ sh4op(i1011_iiii_iiii_iiii) + // trapa # + sh4op(i1100_0011_iiii_iiii) + { +- //printf("trapa 0x%X\n",(GetImm8(op) << 2)); ++ ERROR_LOG(GDROM, "TRAPA %d\n", (GetImm8(op) << 2)); + CCN_TRA = (GetImm8(op) << 2); + Do_Exception(next_pc,0x160,0x100); + } +diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp +index c1d685b..4c40584 100644 +--- a/core/hw/sh4/modules/fastmmu.cpp ++++ b/core/hw/sh4/modules/fastmmu.cpp +@@ -35,7 +35,7 @@ extern TLB_Entry UTLB[64]; + // Used when FullMMU is off + extern u32 sq_remap[64]; + +-//#define TRACE_WINCE_SYSCALLS ++#define TRACE_WINCE_SYSCALLS + + #include "wince.h" + +@@ -323,7 +323,7 @@ u32 mmu_data_translation(u32 va, u32& rv) + if (va == unresolved_unicode_string) + { + unresolved_unicode_string = 0; +- INFO_LOG(SH4, "RESOLVED %s", get_unicode_string(va).c_str()); ++ printf("RESOLVED %s\n", get_unicode_string(va).c_str()); + } + } + #endif +diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp +index d3aae1f..42931f6 100644 +--- a/core/hw/sh4/modules/mmu.cpp ++++ b/core/hw/sh4/modules/mmu.cpp +@@ -77,13 +77,15 @@ defining NO_MMU disables the full mmu emulation + template + u32 mmu_full_lookup(u32 va, u32& idx, u32& rv); + +-//#define TRACE_WINCE_SYSCALLS ++#define TRACE_WINCE_SYSCALLS + + #ifdef TRACE_WINCE_SYSCALLS + #include "wince.h" ++u32 unresolved_ascii_string; ++u32 unresolved_unicode_string; + #endif + +-#define printf_mmu(...) DEBUG_LOG(SH4, __VA_ARGS__) ++#define printf_mmu(...) //DEBUG_LOG(SH4, __VA_ARGS__) + + ReadMem8Func ReadMem8; + ReadMem16Func ReadMem16; +diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h +index d967df5..74bfcc4 100644 +--- a/core/hw/sh4/modules/wince.h ++++ b/core/hw/sh4/modules/wince.h +@@ -31,7 +31,7 @@ static bool read_mem32(u32 addr, u32& data) + { + u32 pa; + const TLB_Entry *entry; +- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) ++ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + return false; + data = ReadMem32_nommu(pa); + return true; +@@ -41,7 +41,7 @@ static bool read_mem16(u32 addr, u16& data) + { + u32 pa; + const TLB_Entry *entry; +- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) ++ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + return false; + data = ReadMem16_nommu(pa); + return true; +@@ -51,7 +51,7 @@ static bool read_mem8(u32 addr, u8& data) + { + u32 pa; + const TLB_Entry *entry; +- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) ++ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + return false; + data = ReadMem8_nommu(pa); + return true; +@@ -227,10 +227,10 @@ static const char *wince_methods[][256] = { + }, + }; + +-u32 unresolved_ascii_string; +-u32 unresolved_unicode_string; ++extern u32 unresolved_ascii_string; ++extern u32 unresolved_unicode_string; + +-std::string get_unicode_string(u32 addr) ++static inline std::string get_unicode_string(u32 addr) + { + std::string str; + while (true) +@@ -248,7 +248,7 @@ std::string get_unicode_string(u32 addr) + } + return str; + } +-std::string get_ascii_string(u32 addr) ++static inline std::string get_ascii_string(u32 addr) + { + std::string str; + while (true) +@@ -312,31 +312,33 @@ static bool print_wince_syscall(u32 address) + sprintf(method_buf, "[%d]", meth_id); + method = method_buf; + } +- INFO_LOG(SH4, "WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); ++ printf("WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); + if (address == 0xfffffd51) // SetLastError +- INFO_LOG(SH4, " dwErrCode = %x", r[4]); ++ printf(" dwErrCode = %x\n", r[4]); + else if (address == 0xffffd5ef) // CreateFile +- INFO_LOG(SH4, " lpFileName = %s", get_unicode_string(r[4]).c_str()); ++ printf(" lpFileName = %s\n", get_unicode_string(r[4]).c_str()); + else if (address == 0xfffffd97) // CreateProc +- INFO_LOG(SH4, " imageName = %s, commandLine = %s", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); ++ printf(" imageName = %s, commandLine = %s\n", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); + else if (!strcmp("DebugNotify", method)) +- INFO_LOG(SH4, " %x, %x\n", r[4], r[5]); ++ printf(" %x, %x\n", r[4], r[5]); + else if (address == 0xffffd5d3) // RegOpenKeyExW +- INFO_LOG(SH4, " hKey = %x, lpSubKey = %s", r[4], get_unicode_string(r[5]).c_str()); ++ printf(" hKey = %x, lpSubKey = %s\n", r[4], get_unicode_string(r[5]).c_str()); + else if (!strcmp("LoadLibraryW", method)) +- INFO_LOG(SH4, " fileName = %s", get_unicode_string(r[4]).c_str()); ++ printf(" fileName = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("GetProcAddressW", method)) +- INFO_LOG(SH4, " hModule = %x, procName = %s", r[4], get_unicode_string(r[5]).c_str()); ++ printf(" hModule = %x, procName = %s\n", r[4], get_unicode_string(r[5]).c_str()); + else if (!strcmp("NKvDbgPrintfW", method)) +- INFO_LOG(SH4, " fmt = %s", get_unicode_string(r[4]).c_str()); ++ printf(" fmt = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("OutputDebugStringW", method)) +- INFO_LOG(SH4, " str = %s", get_unicode_string(r[4]).c_str()); ++ printf(" str = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("RegisterAFSName", method)) +- INFO_LOG(SH4, " name = %s", get_unicode_string(r[4]).c_str()); ++ printf(" name = %s\n", get_unicode_string(r[4]).c_str()); + else if (!strcmp("CreateAPISet", method)) +- INFO_LOG(SH4, " name = %s", get_ascii_string(r[4]).c_str()); ++ printf(" name = %s\n", get_ascii_string(r[4]).c_str()); + else if (!strcmp("Register", method) && !strcmp("APISET", api)) +- INFO_LOG(SH4, " p = %x, id = %x", r[4], r[5]); ++ printf(" p = %x, id = %x\n", r[4], r[5]); ++ else ++ printf("\n"); + // might be useful to detect errors? (hidden & dangerous) + //if (!strcmp("GetProcName", method)) + // os_DebugBreak(); +diff --git a/core/hw/sh4/sh4_interrupts.cpp b/core/hw/sh4/sh4_interrupts.cpp +index bec7356..4f87d2f 100644 +--- a/core/hw/sh4/sh4_interrupts.cpp ++++ b/core/hw/sh4/sh4_interrupts.cpp +@@ -14,7 +14,7 @@ + #include "sh4_core.h" + #include "sh4_mmr.h" + #include "oslib/oslib.h" +- ++#include "hw/holly/sb.h" + /* + + */ +@@ -154,6 +154,7 @@ bool Do_Interrupt(u32 intEvn) + sr.RB = 1; + UpdateSR(); + next_pc = vbr + 0x600; ++ //DEBUG_LOG(SH4, "Do_Interrupt: v_pc %08X SB_ISTNRM %08x", next_pc, SB_ISTNRM); + + return true; + } +diff --git a/core/nullDC.cpp b/core/nullDC.cpp +index e193a94..b6cd7cf 100755 +--- a/core/nullDC.cpp ++++ b/core/nullDC.cpp +@@ -358,12 +358,62 @@ int reicast_init(int argc, char* argv[]) + #define DATA_PATH "/" + #endif + ++void set_platform(int platform) ++{ ++ switch (platform) ++ { ++ case DC_PLATFORM_DREAMCAST: ++ settings.platform.ram_size = 16 * 1024 * 1024; ++ settings.platform.vram_size = 8 * 1024 * 1024; ++ settings.platform.aram_size = 2 * 1024 * 1024; ++ settings.platform.bios_size = 2 * 1024 * 1024; ++ settings.platform.flash_size = 128 * 1024; ++ settings.platform.bbsram_size = 0; ++ break; ++ case DC_PLATFORM_NAOMI: ++ settings.platform.ram_size = 32 * 1024 * 1024; ++ settings.platform.vram_size = 16 * 1024 * 1024; ++ settings.platform.aram_size = 8 * 1024 * 1024; ++ settings.platform.bios_size = 2 * 1024 * 1024; ++ settings.platform.flash_size = 0; ++ settings.platform.bbsram_size = 32 * 1024; ++ break; ++ case DC_PLATFORM_ATOMISWAVE: ++ settings.platform.ram_size = 16 * 1024 * 1024; ++ settings.platform.vram_size = 8 * 1024 * 1024; ++ settings.platform.aram_size = 8 * 1024 * 1024; ++ settings.platform.bios_size = 128 * 1024; ++ settings.platform.flash_size = 0; ++ settings.platform.bbsram_size = 128 * 1024; ++ break; ++ default: ++ die("Unsupported platform"); ++ break; ++ } ++ settings.platform.system = platform; ++ settings.platform.ram_mask = settings.platform.ram_size - 1; ++ settings.platform.vram_mask = settings.platform.vram_size - 1; ++ settings.platform.aram_mask = settings.platform.aram_size - 1; ++} ++ + static int dc_init() + { + static bool init_done; + + if (init_done) + return 0; ++ ++ // FIXME ++#if DC_PLATFORM == DC_PLATFORM_DREAMCAST ++ set_platform(DC_PLATFORM_DREAMCAST); ++#elif DC_PLATFORM == DC_PLATFORM_NAOMI ++ set_platform(DC_PLATFORM_NAOMI); ++#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE ++ set_platform(DC_PLATFORM_ATOMISWAVE); ++#else ++#error Unsupported platform ++#endif ++ + if (plugins_Init()) + return -3; + #if FEAT_SHREC != DYNAREC_NONE +diff --git a/core/rec-x86/rec_x86_driver.cpp b/core/rec-x86/rec_x86_driver.cpp +index 3ddc683..8be81bf 100644 +--- a/core/rec-x86/rec_x86_driver.cpp ++++ b/core/rec-x86/rec_x86_driver.cpp +@@ -106,7 +106,11 @@ void x86_reg_alloc::FreezeXMM() + f32* slpc=thaw_regs; + while(*fpreg!=-1) + { +- if (SpanNRegfIntr(current_opid,*fpreg)) ++#ifdef OLD_REGALLOC ++ if (SpanNRegfIntr(current_opid,*fpreg)) ++#else ++ if (regf_used((x86_reg)*fpreg)) ++#endif + x86e->Emit(op_movss,slpc++,*fpreg); + fpreg++; + } +@@ -121,7 +125,11 @@ void x86_reg_alloc::ThawXMM() + f32* slpc=thaw_regs; + while(*fpreg!=-1) + { +- if (SpanNRegfIntr(current_opid,*fpreg)) ++#ifdef OLD_REGALLOC ++ if (SpanNRegfIntr(current_opid,*fpreg)) ++#else ++ if (regf_used((x86_reg)*fpreg)) ++#endif + x86e->Emit(op_movss,*fpreg,slpc++); + fpreg++; + } +@@ -157,7 +165,7 @@ void DYNACALL csc_fail(u32 addr,u32 addy) + { + u32 fail_idx=(csc_sidx>>1)|(csc_sidx<<31); + +- printf("Ret Mismatch: %08X instead of %08X!\n",addr,addy); ++ INFO_LOG(DYNAREC, "Ret Mismatch: %08X instead of %08X!", addr, addy); + } + } + void csc_pop(RuntimeBlockInfo* block) +@@ -218,10 +226,9 @@ void csc_pop(RuntimeBlockInfo* block) + + void DYNACALL PrintBlock(u32 pc) + { +- printf("block: 0x%08X\n",pc); ++ INFO_LOG(DYNAREC, "block: 0x%08X", pc); + for (int i=0;i<16;i++) +- printf("%08X ",r[i]); +- printf("\n"); ++ INFO_LOG(DYNAREC, "%08X ",r[i]); + } + + u32 cvld; +@@ -396,6 +403,7 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, + + reg.OpEnd(op); + } ++ reg.Cleanup(); + + block->relink_offset=x86e->x86_indx; + block->relink_data=0; +@@ -843,7 +851,7 @@ bool ngen_Rewrite(unat& addr,unat retadr,unat acc) + //found ! + + if ((acc >> 26) == 0x38 && !w) { +- printf("WARNING: SQ AREA READ, %08X from sh4:%08X. THIS IS UNDEFINED ON A REAL DREACMAST.\n", acc, bm_GetBlock(x86e->x86_buff)->addr); ++ INFO_LOG(DYNAREC, "WARNING: SQ AREA READ, %08X from sh4:%08X. THIS IS UNDEFINED ON A REAL DREACMAST.", acc, bm_GetBlock(x86e->x86_buff)->addr); + } + + if ((acc >> 26) == 0x38) //sq ? +diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp +index 3778baf..23efd76 100644 +--- a/core/rec-x86/rec_x86_il.cpp ++++ b/core/rec-x86/rec_x86_il.cpp +@@ -1,6 +1,6 @@ + #include "types.h" + +-#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 ++#if 1 //FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 + #include "rec_x86_ngen.h" + #include "hw/sh4/sh4_mmr.h" + #include "hw/sh4/sh4_rom.h" +@@ -9,8 +9,8 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ + { + //x86e->Emit(op_mov32,EAX,op->rs1.reg_ptr()); + +- verify(reg.IsAllocg(op->rs1._reg)); +- verify(reg.IsAllocg(op->rd._reg)); ++ verify(reg.IsAllocg(op->rs1)); ++ verify(reg.IsAllocg(op->rd)); + + x86_reg rs2; + if (op->rs2.is_r32i()) +@@ -40,7 +40,7 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ + } + else + { +- printf("%d \n",op->rs1.type); ++ ERROR_LOG(DYNAREC, "%d", op->rs1.type); + verify(false); + } + } +@@ -72,7 +72,7 @@ void ngen_fp_bin(shil_opcode* op,x86_opcode_class natop) + } + else + { +- printf("%d \n",op->rs2.type); ++ ERROR_LOG(DYNAREC, "%d", op->rs2.type); + verify(false); + } + if (op->rd._reg != op->rs1._reg) +@@ -258,10 +258,10 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + verify(op->rs1.is_imm() || reg.IsAllocg(op->rs1)); + verify(op->rs3.is_null() || op->rs3.is_imm() || reg.IsAllocg(op->rs3)); + +- for (u32 i = 0; i < op->rd.count(); i++) +- { +- verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg + i))); +- } ++// for (u32 i = 0; i < op->rd.count(); i++) ++// { ++// verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg + i))); ++// } + + u32 size = op->flags & 0x7f; + +@@ -373,9 +373,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + } + else + { ++#ifdef OLD_REGALLOC + x86e->Emit(op_movss, reg.mapfv(op->rd, 0), XMM0); + if (Lsz == 4) + x86e->Emit(op_movss, reg.mapfv(op->rd, 1), XMM1); ++#else ++ x86e->Emit(op_movss, op->rd.reg_ptr(), XMM0); ++ if (Lsz == 4) ++ x86e->Emit(op_movss, op->rd.reg_ptr() + 1, XMM1); ++#endif + } + break; + #endif +@@ -384,10 +390,10 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + if (size<=8) + { + ++#ifdef OPTIMIZATION_GRAVEYARD + if (size==8 && optimise) + { + die("unreachable"); +-#ifdef OPTIMIZATION_GRAVEYARD + verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + x86e->Emit(op_mov32,EDX,ECX); +@@ -395,8 +401,8 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EDX,x86_ptr(virt_ram_base))); + x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EDX,x86_ptr(4+virt_ram_base))); + break; +-#endif + } ++#endif + if (!isram) + { + reg.FreezeXMM(); +@@ -437,10 +443,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + } + else + { ++#ifdef OLD_REGALLOC + verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,0),EAX); + x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,1),EDX); ++#else ++ x86e->Emit(op_mov32, op->rd.reg_ptr(), EAX); ++ x86e->Emit(op_mov32, op->rd.reg_ptr() + 1, EDX); ++#endif + } + + } +@@ -452,7 +463,11 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + u32 size=op->flags&0x7f; + verify(reg.IsAllocg(op->rs1) || op->rs1.is_imm()); + +- verify(op->rs2.is_imm() || op->rs2.is_r32() || (op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1))); ++#ifdef OLD_REGALLOC ++ verify(op->rs2.is_imm() || op->rs2.is_r32() || (op->rs2.count() == 2 && reg.IsAllocf(op->rs2, 0) && reg.IsAllocf(op->rs2, 1))); ++#else ++ verify(op->rs2.is_imm() || op->rs2.is_r32() || op->rs2.count() == 2); ++#endif + + if (op->rs1.is_imm() && size<=4) + { +@@ -507,7 +522,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + } + else if (!op->rs3.is_null()) + { +- printf("rs3: %08X\n",op->rs3.type); ++ ERROR_LOG(DYNAREC, "rs3: %08X", op->rs3.type); + die("invalid rs3"); + } + +@@ -531,9 +546,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + x86e->Emit(op_mov32, EDX, reg.mapg(op->rs2)); + else + { ++#ifdef OLD_REGALLOC + x86e->Emit(op_movss, XMM0, reg.mapfv(op->rs2, 0)); + if (Lsz == 4) + x86e->Emit(op_movss, XMM1, reg.mapfv(op->rs2, 1)); ++#else ++ x86e->Emit(op_movss, XMM0, op->rs2.reg_ptr()); ++ if (Lsz == 4) ++ x86e->Emit(op_movss, XMM1, op->rs2.reg_ptr() + 1); ++#endif + } + + reg.FreezeXMM(); +@@ -599,13 +620,18 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + { + verify(op->rd.is_r64()); + verify(op->rs1.is_r64()); +- ++#ifdef OLD_REGALLOC + verify(reg.IsAllocf(op->rs1,0) && reg.IsAllocf(op->rs1,1)); + verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + +- + x86e->Emit(op_movaps,reg.mapfv(op->rd,0),reg.mapfv(op->rs1,0)); + x86e->Emit(op_movaps,reg.mapfv(op->rd,1),reg.mapfv(op->rs1,1)); ++#else ++ x86e->Emit(op_mov32, EAX, x86_ptr(op->rs1.reg_ptr())); ++ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr()), EAX); ++ x86e->Emit(op_mov32, EAX, x86_ptr(op->rs1.reg_ptr() + 1)); ++ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr() + 1), EAX); ++#endif + } + break; + +@@ -656,7 +682,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + if (reg.mapf(op->rd) != reg.mapf(op->rs1)) + x86e->Emit(op_movss,reg.mapf(op->rd),reg.mapf(op->rs1)); + else +- printf("Renamed fmov !\n"); ++ INFO_LOG(DYNAREC, "Renamed fmov !"); + break; + + } +@@ -839,15 +865,16 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + + case shop_sync_sr: + { ++#ifdef OLD_REGALLOC + //reg alloc should be flushed here. Add Check + for (int i=0;i<8;i++) + { + verify(!reg.IsAllocAny((Sh4RegType)(reg_r0+i))); + verify(!reg.IsAllocAny((Sh4RegType)(reg_r0_Bank+i))); + } +- + verify(!reg.IsAllocAny(reg_old_sr_status)); + verify(!reg.IsAllocAny(reg_sr_status)); ++#endif + + //reg alloc should be flushed here, add checks + x86e->Emit(op_call,x86_ptr_imm(UpdateSR)); +@@ -856,15 +883,16 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + + case shop_sync_fpscr: + { ++#ifdef OLD_REGALLOC + //reg alloc should be flushed here. Add Check + for (int i=0;i<16;i++) + { + verify(!reg.IsAllocAny((Sh4RegType)(reg_fr_0+i))); + verify(!reg.IsAllocAny((Sh4RegType)(reg_xf_0+i))); + } +- + verify(!reg.IsAllocAny(reg_old_fpscr)); + verify(!reg.IsAllocAny(reg_fpscr)); ++#endif + + + //reg alloc should be flushed here, add checks +@@ -956,12 +984,19 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool + //verify(op->rd.is_vector); //double ? vector(2) ? + + verify(reg.IsAllocg(op->rs1)); +- verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + + //sin/cos + x86e->Emit(op_movzx16to32,EAX,reg.mapg(op->rs1)); ++#ifdef OLD_REGALLOC ++ verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); + x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[0]))); + x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[1]))); ++#else ++ x86e->Emit(op_mov32, EAX, x86_mrm(EAX,sib_scale_8, x86_ptr(&sin_table->u[0]))); ++ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr()), EAX); ++ x86e->Emit(op_mov32, EAX, x86_mrm(EAX,sib_scale_8, x86_ptr(&sin_table->u[1]))); ++ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr() + 1), EAX); ++#endif + } + break; + +diff --git a/core/rec-x86/rec_x86_ngen.h b/core/rec-x86/rec_x86_ngen.h +index d68b5fc..bb6aeb7 100644 +--- a/core/rec-x86/rec_x86_ngen.h ++++ b/core/rec-x86/rec_x86_ngen.h +@@ -7,11 +7,17 @@ + #include "hw/sh4/sh4_core.h" + #include "hw/sh4/dyna/ngen.h" + #include "hw/sh4/sh4_mem.h" +-#include "hw/sh4/dyna/regalloc.h" + #include "emitter/x86_emitter.h" + #include "profiler/profiler.h" + #include "oslib/oslib.h" + ++#define OLD_REGALLOC ++#ifdef OLD_REGALLOC ++#include "hw/sh4/dyna/regalloc.h" ++#else ++#include "hw/sh4/dyna/ssa_regalloc.h" ++#endif ++ + void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool staging, bool optimise); + + #if BUILD_COMPILER == COMPILER_GCC +@@ -46,7 +52,11 @@ extern bool sse_3; + extern bool ssse_3; + extern bool mmx; + +-struct x86_reg_alloc: RegAlloc ++struct x86_reg_alloc : RegAlloc + { + virtual void Preload(u32 reg,x86_reg nreg); + virtual void Writeback(u32 reg,x86_reg nreg); +diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp +index e6aa10a..fba0ce9 100644 +--- a/core/rend/TexCache.cpp ++++ b/core/rend/TexCache.cpp +@@ -125,7 +125,7 @@ void palette_update() + + using namespace std; + +-vector VramLocks[VRAM_SIZE/PAGE_SIZE]; ++vector VramLocks[VRAM_SIZE_MAX / PAGE_SIZE]; + VLockedMemory vram; // vram 32-64b + + //List functions +diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp +index d6e5a5f..c569f89 100644 +--- a/core/rend/gl4/gldraw.cpp ++++ b/core/rend/gl4/gldraw.cpp +@@ -472,7 +472,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) + for (int render_pass = 0; render_pass < render_pass_count; render_pass++) + { + const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass]; +- ++// printf("PASS %d autosort %d\n", render_pass, current_pass.autosort); + // Check if we can skip this pass, in part or completely, in case nothing is drawn (Cosmic Smash) + bool skip_op_pt = true; + bool skip_tr = true; +diff --git a/core/rend/norend/norend.cpp b/core/rend/norend/norend.cpp +index 01d507d..83aecb7 100644 +--- a/core/rend/norend/norend.cpp ++++ b/core/rend/norend/norend.cpp +@@ -22,7 +22,7 @@ struct norend : Renderer + + bool Render() + { +- return true;//!pvrrc.isRTT; ++ return !pvrrc.isRTT; + } + + void Present() { } +diff --git a/core/serialize.cpp b/core/serialize.cpp +index 699757a..bb77f0e 100644 +--- a/core/serialize.cpp ++++ b/core/serialize.cpp +@@ -157,19 +157,8 @@ extern u32 SB_FFST; + //static HollyInterruptID dmatmp2; + //static HollyInterruptID OldDmaId; + +-//this is one-time init, no updates - don't need to serialize +-//extern RomChip sys_rom; +-#ifdef FLASH_SIZE +-extern DCFlashChip sys_nvmem; +-#endif +- +-#ifdef BBSRAM_SIZE +-extern SRamChip sys_nvmem; +-#endif +-//this is one-time init, no updates - don't need to serialize +-//extern _vmem_handler area0_handler; +- +- ++extern MemChip *sys_rom; ++extern MemChip *sys_nvmem; + + + //./core/hw/gdrom/gdrom_response.o +@@ -622,11 +611,11 @@ extern int SerStep; + extern int SerStep2; + extern unsigned char BSerial[]; + extern unsigned char GSerial[]; +-extern u32 reg_dimm_3c; //IO window ! writen, 0x1E03 some flag ? +-extern u32 reg_dimm_40; //parameters +-extern u32 reg_dimm_44; //parameters +-extern u32 reg_dimm_48; //parameters +-extern u32 reg_dimm_4c; //status/control reg ? ++extern u32 reg_dimm_command; ++extern u32 reg_dimm_offsetl; ++extern u32 reg_dimm_parameterl; ++extern u32 reg_dimm_parameterh; ++extern u32 reg_dimm_status; + extern bool NaomiDataRead; + + +@@ -831,20 +820,16 @@ bool dc_serialize(void **data, unsigned int *total_size) + REICAST_S(SB_FFST); + + +- +- //this is one-time init, no updates - don't need to serialize +- //extern RomChip sys_rom; +- REICAST_S(sys_nvmem.size); +- REICAST_S(sys_nvmem.mask); ++ sys_rom->Serialize(data, total_size); ++ sys_nvmem->Serialize(data, total_size); ++ /* ++ REICAST_S(sys_nvmem->size); ++ REICAST_S(sys_nvmem->mask); + #ifdef FLASH_SIZE +- REICAST_S(sys_nvmem.state); ++ REICAST_S(sys_nvmem->state); + #endif +- REICAST_SA(sys_nvmem.data,sys_nvmem.size); +- +- //this is one-time init, no updates - don't need to serialize +- //extern _vmem_handler area0_handler; +- +- ++ REICAST_SA(sys_nvmem->data, sys_nvmem->size); ++ */ + + + REICAST_SA(reply_11,16) ; +@@ -1079,11 +1064,11 @@ bool dc_serialize(void **data, unsigned int *total_size) + REICAST_S(SerStep2); + REICAST_SA(BSerial,69); + REICAST_SA(GSerial,69); +- REICAST_S(reg_dimm_3c); +- REICAST_S(reg_dimm_40); +- REICAST_S(reg_dimm_44); +- REICAST_S(reg_dimm_48); +- REICAST_S(reg_dimm_4c); ++ REICAST_S(reg_dimm_command); ++ REICAST_S(reg_dimm_offsetl); ++ REICAST_S(reg_dimm_parameterl); ++ REICAST_S(reg_dimm_parameterh); ++ REICAST_S(reg_dimm_status); + REICAST_S(NaomiDataRead); + + #if FEAT_SHREC == DYNAREC_CPP +@@ -1198,15 +1183,15 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) + REICAST_US(i); //LIBRETRO_S(sys_nvmem_sram.mask); + //LIBRETRO_SA(sys_nvmem_sram.data,sys_nvmem_sram.size); + +- REICAST_US(sys_nvmem.size); +- REICAST_US(sys_nvmem.mask); ++ REICAST_US(sys_nvmem->size); ++ REICAST_US(sys_nvmem->mask); + #if DC_PLATFORM == DC_PLATFORM_DREAMCAST +- REICAST_US(sys_nvmem.state); ++ REICAST_US(static_cast(sys_nvmem)->state); + #else + // FIXME + die("Naomi/Atomiswave libretro savestates are not supported"); + #endif +- REICAST_USA(sys_nvmem.data,sys_nvmem.size); ++ REICAST_USA(sys_nvmem->data, sys_nvmem->size); + + + //this is one-time init, no updates - don't need to serialize +@@ -1471,11 +1456,11 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) + REICAST_US(SerStep2); + REICAST_USA(BSerial,69); + REICAST_USA(GSerial,69); +- REICAST_US(reg_dimm_3c); +- REICAST_US(reg_dimm_40); +- REICAST_US(reg_dimm_44); +- REICAST_US(reg_dimm_48); +- REICAST_US(reg_dimm_4c); ++ REICAST_US(reg_dimm_command); ++ REICAST_US(reg_dimm_offsetl); ++ REICAST_US(reg_dimm_parameterl); ++ REICAST_US(reg_dimm_parameterh); ++ REICAST_US(reg_dimm_status); + REICAST_US(NaomiDataRead); + + REICAST_US(i); //LIBRETRO_S(cycle_counter); +@@ -1580,15 +1565,16 @@ bool dc_unserialize(void **data, unsigned int *total_size) + REICAST_US(SB_FFST_rc); + REICAST_US(SB_FFST); + +- //this is one-time init, no updates - don't need to serialize +- //extern RomChip sys_rom; ++ sys_rom->Unserialize(data, total_size); ++ sys_nvmem->Unserialize(data, total_size); ++ /* + REICAST_US(sys_nvmem.size); + REICAST_US(sys_nvmem.mask); + #ifdef FLASH_SIZE + REICAST_US(sys_nvmem.state); + #endif + REICAST_USA(sys_nvmem.data,sys_nvmem.size); +- ++ */ + + //this is one-time init, no updates - don't need to serialize + //extern _vmem_handler area0_handler; +@@ -1850,11 +1836,11 @@ bool dc_unserialize(void **data, unsigned int *total_size) + REICAST_US(SerStep2); + REICAST_USA(BSerial,69); + REICAST_USA(GSerial,69); +- REICAST_US(reg_dimm_3c); +- REICAST_US(reg_dimm_40); +- REICAST_US(reg_dimm_44); +- REICAST_US(reg_dimm_48); +- REICAST_US(reg_dimm_4c); ++ REICAST_US(reg_dimm_command); ++ REICAST_US(reg_dimm_offsetl); ++ REICAST_US(reg_dimm_parameterl); ++ REICAST_US(reg_dimm_parameterh); ++ REICAST_US(reg_dimm_status); + REICAST_US(NaomiDataRead); + + #if FEAT_SHREC == DYNAREC_CPP +diff --git a/core/types.h b/core/types.h +index cf55226..a179a01 100644 +--- a/core/types.h ++++ b/core/types.h +@@ -421,8 +421,8 @@ bool dc_unserialize(void **data, unsigned int *total_size); + #define REICAST_S(v) rc_serialize(&(v), sizeof(v), data, total_size) + #define REICAST_US(v) rc_unserialize(&(v), sizeof(v), data, total_size) + +-#define REICAST_SA(v_arr,num) rc_serialize(v_arr, sizeof(v_arr[0])*num, data, total_size) +-#define REICAST_USA(v_arr,num) rc_unserialize(v_arr, sizeof(v_arr[0])*num, data, total_size) ++#define REICAST_SA(v_arr,num) rc_serialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) ++#define REICAST_USA(v_arr,num) rc_unserialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) + + enum + { +@@ -606,6 +606,19 @@ enum LimitFPSEnum { + struct settings_t + { + struct { ++ int system; ++ u32 ram_size; ++ u32 ram_mask; ++ u32 vram_size; ++ u32 vram_mask; ++ u32 aram_size; ++ u32 aram_mask; ++ u32 bios_size; ++ u32 flash_size; ++ u32 bbsram_size; ++ } platform; ++ ++ struct { + bool UseReios; + } bios; + +@@ -738,6 +751,16 @@ struct settings_t + + extern settings_t settings; + ++#define RAM_SIZE settings.platform.ram_size ++#define RAM_MASK settings.platform.ram_mask ++#define ARAM_SIZE settings.platform.aram_size ++#define ARAM_MASK settings.platform.aram_mask ++#define VRAM_SIZE settings.platform.vram_size ++#define VRAM_MASK settings.platform.vram_mask ++#define BIOS_SIZE settings.platform.bios_size ++#define FLASH_SIZE settings.platform.flash_size ++#define BBSRAM_SIZE settings.platform.bbsram_size ++ + void InitSettings(); + void LoadSettings(bool game_specific); + void SaveSettings(); +diff --git a/shell/android-studio/reicast/build.gradle b/shell/android-studio/reicast/build.gradle +index 71d1d4e..78175ac 100644 +--- a/shell/android-studio/reicast/build.gradle ++++ b/shell/android-studio/reicast/build.gradle +@@ -1,6 +1,8 @@ + apply plugin: 'com.android.application' + apply plugin: 'com.github.triplet.play' + ++apply from: 'profiling.gradle' ++ + def getBuildId = { -> + def build_id = System.getenv("TRAVIS_JOB_ID") ?: "8" + return Integer.parseInt( build_id ) +@@ -38,7 +40,7 @@ android { + + ndk { + moduleName "dc" +- abiFilters 'armeabi-v7a', 'arm64-v8a' ++ abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86' + } + } + +@@ -70,11 +72,12 @@ android { + flavorDimensions "systemtype" + productFlavors { + dreamcast { ++ externalNativeBuild { ndkBuild { arguments "-j8" } } + } + naomi { + applicationId = "com.flycast.emulator.naomi" + versionNameSuffix " Naomi" +- externalNativeBuild { ndkBuild { arguments "NAOMI=1" } } ++ externalNativeBuild { ndkBuild { arguments "NAOMI=1", "-j8" } } + } + } + +@@ -87,6 +90,12 @@ android { + lintOptions { + abortOnError false + } ++ ++ packagingOptions{ ++ doNotStrip "*/armeabi/*.so" ++ doNotStrip "*/armeabi-v7a/*.so" ++ doNotStrip "*/arm64-v8a/*.so" ++ } + } + + afterEvaluate { +@@ -117,4 +126,3 @@ dependencies { + } + implementation fileTree(include: ['*.jar'], dir: 'libs') + } +- diff --git a/shell/android-studio/reicast/build.gradle b/shell/android-studio/reicast/build.gradle index 71d1d4e72..78175ac69 100644 --- a/shell/android-studio/reicast/build.gradle +++ b/shell/android-studio/reicast/build.gradle @@ -1,6 +1,8 @@ apply plugin: 'com.android.application' apply plugin: 'com.github.triplet.play' +apply from: 'profiling.gradle' + def getBuildId = { -> def build_id = System.getenv("TRAVIS_JOB_ID") ?: "8" return Integer.parseInt( build_id ) @@ -38,7 +40,7 @@ android { ndk { moduleName "dc" - abiFilters 'armeabi-v7a', 'arm64-v8a' + abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86' } } @@ -70,11 +72,12 @@ android { flavorDimensions "systemtype" productFlavors { dreamcast { + externalNativeBuild { ndkBuild { arguments "-j8" } } } naomi { applicationId = "com.flycast.emulator.naomi" versionNameSuffix " Naomi" - externalNativeBuild { ndkBuild { arguments "NAOMI=1" } } + externalNativeBuild { ndkBuild { arguments "NAOMI=1", "-j8" } } } } @@ -87,6 +90,12 @@ android { lintOptions { abortOnError false } + + packagingOptions{ + doNotStrip "*/armeabi/*.so" + doNotStrip "*/armeabi-v7a/*.so" + doNotStrip "*/arm64-v8a/*.so" + } } afterEvaluate { @@ -117,4 +126,3 @@ dependencies { } implementation fileTree(include: ['*.jar'], dir: 'libs') } - diff --git a/shell/android-studio/reicast/src/main/jni/src/Android.cpp b/shell/android-studio/reicast/src/main/jni/src/Android.cpp index 02e3f3026..b3d65565c 100644 --- a/shell/android-studio/reicast/src/main/jni/src/Android.cpp +++ b/shell/android-studio/reicast/src/main/jni/src/Android.cpp @@ -192,9 +192,6 @@ void common_linux_setup(); void os_SetupInput() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif } void os_SetWindowText(char const *Text) diff --git a/shell/apple/emulator-ios/emulator/ios_main.mm b/shell/apple/emulator-ios/emulator/ios_main.mm index d0a092504..593c65d30 100644 --- a/shell/apple/emulator-ios/emulator/ios_main.mm +++ b/shell/apple/emulator-ios/emulator/ios_main.mm @@ -89,9 +89,6 @@ void os_CreateWindow() { } void os_SetupInput() { -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif } void UpdateInputState(u32 port) { diff --git a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm index adca53d51..432dd40d3 100644 --- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm +++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm @@ -64,10 +64,6 @@ void os_SetupInput() { GamepadDevice::Register(kb_gamepad); mouse_gamepad = std::make_shared(0); GamepadDevice::Register(mouse_gamepad); - -#if DC_PLATFORM == DC_PLATFORM_DREAMCAST - mcfg_CreateDevices(); -#endif } void* libPvr_GetRenderTarget() { diff --git a/shell/linux/.gdb_history b/shell/linux/.gdb_history new file mode 100644 index 000000000..09bfdd8b0 --- /dev/null +++ b/shell/linux/.gdb_history @@ -0,0 +1,42 @@ +r +q +r +bt +r +bt +info threads +q +r +bt +q +break GetFile +r +bt +q +r +bt +up +up +up +up +up +up +p buffer +p data +p offset +up +p child_archive +p *child_archive +p *parent_archive +q +r +q +break mcfg_CreateDevices +r +q +r +q +r +q +r +q diff --git a/shell/linux/flycast.log b/shell/linux/flycast.log new file mode 100644 index 000000000..e69de29bb From 449d150eba52ec14cf11748c52d70c33213aeeaf Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 10 Jul 2019 09:57:08 +0200 Subject: [PATCH 134/158] android: build fix clean up files comitted by mistake --- .cproject | 42 - .project | 27 - .settings/language.settings.xml | 15 - core/deps/vixl/platform-vixl.h | 2 +- core/hw/arm7/arm64.cpp | 6 - core/hw/flashrom/flashrom.h | 8 +- core/rec-ARM/ngen_arm.S | 7 - p.patch | 1994 --------------------- shell/android-studio/reicast/build.gradle | 13 +- shell/linux/.gdb_history | 42 - shell/linux/flycast.log | 0 11 files changed, 7 insertions(+), 2149 deletions(-) delete mode 100644 .cproject delete mode 100644 .project delete mode 100644 .settings/language.settings.xml delete mode 100644 p.patch delete mode 100644 shell/linux/.gdb_history delete mode 100644 shell/linux/flycast.log diff --git a/.cproject b/.cproject deleted file mode 100644 index ba11c3feb..000000000 --- a/.cproject +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index dd1c00db8..000000000 --- a/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - flycast-unified - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml deleted file mode 100644 index 4762844a1..000000000 --- a/.settings/language.settings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/core/deps/vixl/platform-vixl.h b/core/deps/vixl/platform-vixl.h index 8da090c85..b59e536d8 100644 --- a/core/deps/vixl/platform-vixl.h +++ b/core/deps/vixl/platform-vixl.h @@ -33,7 +33,7 @@ extern "C" { } #define VIXL_CODE_BUFFER_MALLOC -#define VIXL_DEBUG +//#define VIXL_DEBUG #if defined(_ANDROID) && defined(VIXL_DEBUG) #include diff --git a/core/hw/arm7/arm64.cpp b/core/hw/arm7/arm64.cpp index 5e86900ca..27f65c51e 100644 --- a/core/hw/arm7/arm64.cpp +++ b/core/hw/arm7/arm64.cpp @@ -501,13 +501,7 @@ __asm__ ( ".hidden arm_dispatch \n" "arm_dispatch: \n\t" "ldp w0, w1, [x28, #184] \n\t" // load Next PC, interrupt -#if ARAM_SIZE == 2*1024*1024 - "ubfx w2, w0, #2, #19 \n\t" // w2 = pc >> 2. Note: assuming address space == 2 MB (21 bits) -#elif ARAM_SIZE == 8*1024*1024 "ubfx w2, w0, #2, #21 \n\t" // w2 = pc >> 2. Note: assuming address space == 8 MB (23 bits) -#else -#error Unsupported AICA RAM size -#endif "cbnz w1, arm_dofiq \n\t" // if interrupt pending, handle it "add x2, x26, x2, lsl #3 \n\t" // x2 = EntryPoints + pc << 1 diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index b2674b357..c47e596d4 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -158,13 +158,13 @@ struct SRamChip : MemChip } } - virtual bool Serialize(void **data, unsigned int *total_size) + virtual bool Serialize(void **data, unsigned int *total_size) override { REICAST_SA(&this->data[write_protect_size], size - write_protect_size); return true; } - virtual bool Unserialize(void **data, unsigned int *total_size) + virtual bool Unserialize(void **data, unsigned int *total_size) override { REICAST_USA(&this->data[write_protect_size], size - write_protect_size); return true; @@ -642,14 +642,14 @@ private: return result; } - virtual bool Serialize(void **data, unsigned int *total_size) + virtual bool Serialize(void **data, unsigned int *total_size) override { REICAST_SA(&this->data[write_protect_size], size - write_protect_size); REICAST_S(state); return true; } - virtual bool Unserialize(void **data, unsigned int *total_size) + virtual bool Unserialize(void **data, unsigned int *total_size) override { REICAST_USA(&this->data[write_protect_size], size - write_protect_size); REICAST_US(state); diff --git a/core/rec-ARM/ngen_arm.S b/core/rec-ARM/ngen_arm.S index 55fbc8fad..e77087872 100644 --- a/core/rec-ARM/ngen_arm.S +++ b/core/rec-ARM/ngen_arm.S @@ -242,14 +242,7 @@ push {r4,r5,r8,r9,lr} HIDDEN(arm_dispatch) CSYM(arm_dispatch): ldrd r0,r1,[r8,#184] @load: Next PC, interrupt - -#if ARAM_SIZE == 2*1024*1024 - ubfx r2,r0,#2,#19 @ assuming 2 MB address space max (21 bits) -#elif ARAM_SIZE == 8*1024*1024 ubfx r2,r0,#2,#21 @ assuming 8 MB address space max (23 bits) -#else -#error Unsupported AICA RAM size -#endif cmp r1,#0 bne arm_dofiq diff --git a/p.patch b/p.patch deleted file mode 100644 index 83b53818e..000000000 --- a/p.patch +++ /dev/null @@ -1,1994 +0,0 @@ -diff --git a/core/build.h b/core/build.h -index 3ba546c..398c301 100755 ---- a/core/build.h -+++ b/core/build.h -@@ -345,7 +345,7 @@ - #define RAM_SIZE_MAX (32*1024*1024) - #define VRAM_SIZE_MAX (16*1024*1024) - #define ARAM_SIZE_MAX (8*1024*1024) -- -+/* - #if (DC_PLATFORM==DC_PLATFORM_DREAMCAST) - - #define BUILD_DREAMCAST 1 -@@ -433,7 +433,7 @@ - #ifdef BBSRAM_SIZE - #define BBSRAM_MASK (BBSRAM_SIZE-1) - #endif -- -+*/ - #define GD_CLOCK 33868800 //GDROM XTAL -- 768fs - - #define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs -diff --git a/core/deps/vixl/platform-vixl.h b/core/deps/vixl/platform-vixl.h -index ad8d057..8da090c 100644 ---- a/core/deps/vixl/platform-vixl.h -+++ b/core/deps/vixl/platform-vixl.h -@@ -33,7 +33,7 @@ extern "C" { - } - - #define VIXL_CODE_BUFFER_MALLOC -- -+#define VIXL_DEBUG - - #if defined(_ANDROID) && defined(VIXL_DEBUG) - #include -diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h -index 807f128..7dd03a9 100644 ---- a/core/hw/flashrom/flashrom.h -+++ b/core/hw/flashrom/flashrom.h -@@ -40,6 +40,11 @@ struct MemChip - return rv; - } - -+ virtual void Write(u32 addr, u32 data, u32 size) -+ { -+ die("Method not supported"); -+ } -+ - bool Load(const string& file) - { - FILE* f=fopen(file.c_str(),"rb"); -@@ -119,20 +124,20 @@ struct MemChip - INFO_LOG(FLASHROM, "Saved %s as %s", path, title.c_str()); - } - virtual void Reset() {} -+ virtual bool Serialize(void **data, unsigned int *total_size) { return true; } -+ virtual bool Unserialize(void **data, unsigned int *total_size) { return true; } - }; -+ - struct RomChip : MemChip - { - RomChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} -- void Write(u32 addr,u32 data,u32 sz) -- { -- die("Write to RomChip is not possible, address=%x, data=%x, size=%d"); -- } - }; -+ - struct SRamChip : MemChip - { - SRamChip(u32 sz, u32 write_protect_size = 0) : MemChip(sz, write_protect_size) {} - -- void Write(u32 addr,u32 val,u32 sz) -+ void Write(u32 addr,u32 val,u32 sz) override - { - addr&=mask; - if (addr < write_protect_size) -@@ -152,6 +157,18 @@ struct SRamChip : MemChip - die("invalid access size"); - } - } -+ -+ virtual bool Serialize(void **data, unsigned int *total_size) -+ { -+ REICAST_SA(&this->data[write_protect_size], size - write_protect_size); -+ return true; -+ } -+ -+ virtual bool Unserialize(void **data, unsigned int *total_size) -+ { -+ REICAST_USA(&this->data[write_protect_size], size - write_protect_size); -+ return true; -+ } - }; - - // -@@ -262,7 +279,7 @@ struct DCFlashChip : MemChip - } - - -- void Write(u32 addr,u32 val,u32 sz) -+ void Write(u32 addr,u32 val,u32 sz) override - { - if (sz != 1) - die("invalid access size"); -@@ -283,7 +300,19 @@ struct DCFlashChip : MemChip - state = FS_ReadAMDID1; - break; - default: -- EMUERROR("Unknown FlashWrite mode: %x\n", val); -+ INFO_LOG(FLASHROM, "Unknown FlashWrite mode: %x\n", val); -+/* -+ void print_blocks(); -+ print_blocks(); -+#define r p_sh4rcb->cntx.r -+#define next_pc p_sh4rcb->cntx.pc -+ DEBUG_LOG(SH4, "r0 %08x r1 %08x r2 %08x r3 %08x r4 %08x r5 %08x r6 %08x r7 %08x pc %08x ", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], next_pc); -+ DEBUG_LOG(SH4, "r8 %08x r9 %08x r10 %08x r11 %08x r12 %08x r13 %08x r14 %08x r15 %08x", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); -+#undef r -+#undef next_pc -+ INFO_LOG(MEMORY, "[flash]Write pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+ die("done"); -+*/ - break; - } - break; -@@ -627,4 +656,18 @@ private: - - return result; - } -+ -+ virtual bool Serialize(void **data, unsigned int *total_size) -+ { -+ REICAST_SA(&this->data[write_protect_size], size - write_protect_size); -+ REICAST_S(state); -+ return true; -+ } -+ -+ virtual bool Unserialize(void **data, unsigned int *total_size) -+ { -+ REICAST_USA(&this->data[write_protect_size], size - write_protect_size); -+ REICAST_US(state); -+ return true; -+ } - }; -diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp -index cf675d9..9cccf3e 100644 ---- a/core/hw/gdrom/gdromv3.cpp -+++ b/core/hw/gdrom/gdromv3.cpp -@@ -115,6 +115,27 @@ void FillReadBuffer() - libGDR_ReadSector(read_buff.cache,read_params.start_sector,count,read_params.sector_type); - read_params.start_sector+=count; - read_params.remaining_sectors-=count; -+/* -+ static const u8 pattern[] = { -+ // debug 0x01, 0xe5, 0x07, 0xe4, //0x01, 0xe5, //0x10, 0xe6, //0x00, 0xe7 -+ //0x08, 0xe4, 0x74, 0x1f, 0x01, 0xe5, 0x75, 0x1f -+ //0x43, 0x6b, 0x53, 0x6d, 0x63, 0x6c, 0xec, 0x7f -+ 0x20, 0x62, 0x2c, 0x62, 0x37, 0x32, 0x01, 0x8b -+ }; -+ for (int i = 0; i < read_buff.cache_size - sizeof(pattern); i++) -+ { -+ if (!memcmp(&read_buff.cache[i], pattern, sizeof(pattern))) -+ { -+// read_buff.cache[i + 0] = 0x00; -+// read_buff.cache[i + 1] = 0xeb; -+// read_buff.cache[i + 2] = 0x00; -+// read_buff.cache[i + 3] = 0xed; -+// read_buff.cache[i + 6] = 0x09; -+// read_buff.cache[i + 7] = 0x00; -+ ERROR_LOG(GDROM, "Pattern found"); -+ } -+ } -+*/ - } - - -@@ -755,7 +776,7 @@ void gd_process_spi_cmd() - subc_info[1]=0x15;//15h No audio status information - } - -- subc_info[1]=0x15; -+// subc_info[1]=0x15; - - if (format==0) - { -@@ -1029,14 +1050,14 @@ int GDRomschd(int i, int c, int j) - { - while(len) - { -- u32 buff_size =read_buff.cache_size; -- if (buff_size==0) -+ u32 buff_size = read_buff.cache_size; -+ if (buff_size == 0) - { - verify(read_params.remaining_sectors>0); - //buffer is empty , fill it :) - FillReadBuffer(); -+ buff_size = read_buff.cache_size; - } -- - //transfer up to len bytes - if (buff_size>len) - { -diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp -index a3f50bc..7fc081c 100644 ---- a/core/hw/holly/sb.cpp -+++ b/core/hw/holly/sb.cpp -@@ -426,14 +426,14 @@ void sb_Init() - sb_rio_register(SB_GDDIR_addr,RIO_DATA); - - -- -+//#if 0 - //0x005F7414 SB_GDEN RW GD-DMA enable - sb_rio_register(SB_GDEN_addr,RIO_DATA); - - - //0x005F7418 SB_GDST RW GD-DMA start - sb_rio_register(SB_GDST_addr,RIO_DATA); -- -+//#endif - - - //0x005F7480 SB_G1RRC W System ROM read access timing -diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp -index 77728c1..bc9b8d0 100644 ---- a/core/hw/holly/sb_mem.cpp -+++ b/core/hw/holly/sb_mem.cpp -@@ -18,26 +18,36 @@ - #include "hw/flashrom/flashrom.h" - #include "reios/reios.h" - --#if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE --DCFlashChip sys_rom(BIOS_SIZE, BIOS_SIZE / 2); --#else --RomChip sys_rom(BIOS_SIZE); --#endif -+MemChip *sys_rom; -+MemChip *sys_nvmem; - --#ifdef FLASH_SIZE --DCFlashChip sys_nvmem(FLASH_SIZE); --#endif -+extern bool bios_loaded; - --#ifdef BBSRAM_SIZE --SRamChip sys_nvmem(BBSRAM_SIZE); --#endif -+static std::string getRomPrefix() -+{ -+ switch (settings.platform.system) -+ { -+ case DC_PLATFORM_DREAMCAST: -+ return "dc_"; -+ case DC_PLATFORM_NAOMI: -+ return "naomi_"; -+ case DC_PLATFORM_ATOMISWAVE: -+ return "aw_"; -+ default: -+ die("Unsupported platform"); -+ return ""; -+ } -+} - --extern bool bios_loaded; -+static bool nvmemOptional() -+{ -+ return settings.platform.system != DC_PLATFORM_DREAMCAST; -+} - - bool LoadRomFiles(const string& root) - { - #if DC_PLATFORM != DC_PLATFORM_ATOMISWAVE -- if (!sys_rom.Load(root, ROM_PREFIX, "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin" ROM_NAMES, "bootrom")) -+ if (!sys_rom->Load(root, getRomPrefix(), "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin", "bootrom")) - { - #if DC_PLATFORM == DC_PLATFORM_DREAMCAST - // Dreamcast absolutely needs a BIOS -@@ -49,12 +59,12 @@ bool LoadRomFiles(const string& root) - bios_loaded = true; - #endif - #if DC_PLATFORM == DC_PLATFORM_DREAMCAST -- if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) -+ if (!sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) - #else -- if (!sys_nvmem.Load(get_game_save_prefix() + ".nvmem")) -+ if (!sys_nvmem->Load(get_game_save_prefix() + ".nvmem")) - #endif - { -- if (NVR_OPTIONAL) -+ if (nvmemOptional()) - { - INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); - } -@@ -67,7 +77,7 @@ bool LoadRomFiles(const string& root) - - #if DC_PLATFORM == DC_PLATFORM_DREAMCAST - struct flash_syscfg_block syscfg; -- int res = sys_nvmem.ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); -+ int res = static_cast(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); - - if (!res) - { -@@ -85,13 +95,13 @@ bool LoadRomFiles(const string& root) - if (settings.dreamcast.language <= 5) - syscfg.lang = settings.dreamcast.language; - -- if (sys_nvmem.WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) -+ if (static_cast(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) - WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); - - #endif - - #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE -- sys_rom.Load(get_game_save_prefix() + ".nvmem2"); -+ sys_rom->Load(get_game_save_prefix() + ".nvmem2"); - #endif - - return true; -@@ -100,35 +110,35 @@ bool LoadRomFiles(const string& root) - void SaveRomFiles(const string& root) - { - #if DC_PLATFORM == DC_PLATFORM_DREAMCAST -- sys_nvmem.Save(root, ROM_PREFIX, "nvmem.bin", "nvmem"); -+ sys_nvmem->Save(root, getRomPrefix(), "nvmem.bin", "nvmem"); - #else -- sys_nvmem.Save(get_game_save_prefix() + ".nvmem"); -+ sys_nvmem->Save(get_game_save_prefix() + ".nvmem"); - #endif - #if DC_PLATFORM == DC_PLATFORM_ATOMISWAVE -- sys_rom.Save(get_game_save_prefix() + ".nvmem2"); -+ sys_rom->Save(get_game_save_prefix() + ".nvmem2"); - #endif - } - - bool LoadHle(const string& root) { -- if (!sys_nvmem.Load(root, ROM_PREFIX, "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { -+ if (!sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram")) { - INFO_LOG(FLASHROM, "No nvmem loaded"); - } - -- return reios_init(sys_rom.data, sys_nvmem.data); -+ return reios_init(sys_rom->data, sys_nvmem->data); - } - --u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem.Read(addr,sz); } --void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem.Write(addr,data,sz); } -+u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); } -+void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); } - - #if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2) - --u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); } -+u32 ReadBios(u32 addr,u32 sz) { return sys_rom->Read(addr,sz); } - void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz); } - - #elif (DC_PLATFORM == DC_PLATFORM_ATOMISWAVE) - u32 ReadBios(u32 addr,u32 sz) - { -- return sys_rom.Read(addr, sz); -+ return sys_rom->Read(addr, sz); - } - - void WriteBios(u32 addr,u32 data,u32 sz) -@@ -136,9 +146,13 @@ void WriteBios(u32 addr,u32 data,u32 sz) { INFO_LOG(MEMORY, "Write to [Boot ROM] - if (sz != 1) - { - INFO_LOG(MEMORY, "Invalid access size @%08x data %x sz %d", addr, data, sz); -+// void print_blocks(); -+// print_blocks(); -+// INFO_LOG(MEMORY, "[flash]Write pc=%x pr=%x", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+// die("done"); - return; - } -- sys_rom.Write(addr, data, sz); -+ sys_rom->Write(addr, data, sz); - } - - #else -@@ -345,19 +359,59 @@ void DYNACALL WriteMem_area0(u32 addr,T data) - void sh4_area0_Init() - { - sb_Init(); -+ sh4_area0_Reset(true); - } - --void sh4_area0_Reset(bool Manual) -+void sh4_area0_Reset(bool manual) - { -- sb_Reset(Manual); -- sys_rom.Reset(); --#if defined(FLASH_SIZE) || defined(BBSRAM_SIZE) -- sys_nvmem.Reset(); --#endif -+ if (manual) -+ { -+ if (sys_rom != NULL) -+ { -+ delete sys_rom; -+ sys_rom = NULL; -+ } -+ if (sys_nvmem != NULL) -+ { -+ delete sys_nvmem; -+ sys_nvmem = NULL; -+ } -+ switch (settings.platform.system) -+ { -+ case DC_PLATFORM_DREAMCAST: -+ sys_rom = new RomChip(settings.platform.bios_size); -+ sys_nvmem = new DCFlashChip(settings.platform.bios_size); -+ break; -+ case DC_PLATFORM_NAOMI: -+ sys_rom = new RomChip(settings.platform.bios_size); -+ sys_nvmem = new SRamChip(settings.platform.bbsram_size); -+ break; -+ case DC_PLATFORM_ATOMISWAVE: -+ sys_rom = new DCFlashChip(settings.platform.bios_size, settings.platform.bios_size / 2); -+ sys_nvmem = new SRamChip(settings.platform.bbsram_size); -+ break; -+ } -+ } -+ else -+ { -+ sys_rom->Reset(); -+ sys_nvmem->Reset(); -+ } -+ sb_Reset(manual); - } - - void sh4_area0_Term() - { -+ if (sys_rom != NULL) -+ { -+ delete sys_rom; -+ sys_rom = NULL; -+ } -+ if (sys_nvmem != NULL) -+ { -+ delete sys_nvmem; -+ sys_nvmem = NULL; -+ } - sb_Term(); - } - -diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp -index 1eb8d6b..bd2526e 100644 ---- a/core/hw/mem/_vmem.cpp -+++ b/core/hw/mem/_vmem.cpp -@@ -182,6 +182,10 @@ template - INLINE Trv DYNACALL _vmem_readt(u32 addr) - { - const u32 sz=sizeof(T); -+// if ((addr & 0x1ffffff0) == 0x0c19d3d0 || (addr & 0x1ffffff) == 0x0c1c0164) { -+// extern VLockedMemory mem_b; -+// printf("Read %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, *(u32*)&mem_b[addr & RAM_MASK]); -+// } - - u32 page=addr>>24; //1 op, shift/extract - unat iirf=(unat)_vmem_MemInfo_ptr[page]; //2 ops, insert + read [vmem table will be on reg ] -@@ -232,7 +236,45 @@ template - INLINE void DYNACALL _vmem_writet(u32 addr,T data) - { - const u32 sz=sizeof(T); -- -+/* -+//db if (addr == 0x8cd4F604 || addr == 0x8cd4F504 || addr == 0x8cd4F504) printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); -+ if ((addr & 0x1fffffff) == 0x0c19d3d0) { -+ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); -+ if (data == 0) -+ data = 0x8c600000; -+// void print_blocks(); -+// print_blocks(); -+// //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+// die("done"); -+ } -+ else if ((addr & 0x1fffffff) == 0x0c19d3d4) { -+ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); -+ if (data == 0) -+ data = 0x8c700000; -+ // void print_blocks(); -+ // print_blocks(); -+ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+ // die("done"); -+ } -+ else if ((addr & 0x1fffffff) == 0x0c19d3dc) { -+ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); -+ if (data == 0) -+ data = 0x8c780000; -+ // void print_blocks(); -+ // print_blocks(); -+ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+ // die("done"); -+ } -+ else if ((addr & 0x1fffffff) == 0x0c1c0164) { -+ printf("Write %08x pc %08x v %x\n", addr, p_sh4rcb->cntx.pc, (u32)data); -+// if (data == 0) -+// data = 0x8c780000; -+ // void print_blocks(); -+ // print_blocks(); -+ // //INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+ // die("done"); -+ } -+*/ - u32 page=addr>>24; - unat iirf=(unat)_vmem_MemInfo_ptr[page]; - void* ptr=(void*)(iirf&~HANDLER_MAX); -@@ -299,31 +341,38 @@ void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet(Address - //default read handlers - u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss) - { -- DEBUG_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); -+ INFO_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); - return (u8)MEM_ERROR_RETURN_VALUE; - } - u16 DYNACALL _vmem_ReadMem16_not_mapped(u32 addresss) - { -- DEBUG_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); -+ INFO_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); - return (u16)MEM_ERROR_RETURN_VALUE; - } --u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 addresss) -+u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 address) - { -- DEBUG_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", addresss); -+ INFO_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", address); -+// if (address == 0x3A507150) -+// { -+// void print_blocks(); -+// print_blocks(); -+// INFO_LOG(MEMORY, "[sh4]Read32 pc=%x pr=%x\n", p_sh4rcb->cntx.pc, p_sh4rcb->cntx.pr); -+// die("done"); -+// } - return (u32)MEM_ERROR_RETURN_VALUE; - } - //default write handers - void DYNACALL _vmem_WriteMem8_not_mapped(u32 addresss,u8 data) - { -- DEBUG_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); -+ INFO_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); - } - void DYNACALL _vmem_WriteMem16_not_mapped(u32 addresss,u16 data) - { -- DEBUG_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); -+ INFO_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); - } - void DYNACALL _vmem_WriteMem32_not_mapped(u32 addresss,u32 data) - { -- DEBUG_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); -+ INFO_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); - } - //code to register handlers - //0 is considered error :) -diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp -index e40c893..12e26e3 100644 ---- a/core/hw/mem/vmem32.cpp -+++ b/core/hw/mem/vmem32.cpp -@@ -66,7 +66,7 @@ struct vram_lock { - u32 start; - u32 end; - }; --static std::vector vram_blocks[VRAM_SIZE / VRAM_PROT_SEGMENT]; -+static std::vector vram_blocks[VRAM_SIZE_MAX / VRAM_PROT_SEGMENT]; - static u8 sram_mapped_pages[USER_SPACE / PAGE_SIZE / 8]; // bit set to 1 if page is mapped - - bool vmem32_inited; -diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp -index 131559e..0f17b71 100644 ---- a/core/hw/naomi/naomi.cpp -+++ b/core/hw/naomi/naomi.cpp -@@ -8,6 +8,7 @@ - #include "hw/holly/holly_intc.h" - #include "hw/maple/maple_cfg.h" - #include "hw/sh4/sh4_sched.h" -+#include "hw/sh4/modules/dmac.h" - - #include "naomi.h" - #include "naomi_cart.h" -@@ -340,23 +341,6 @@ u16 NaomiGameIDRead() - return (GSerialBuffer&(1<<(31-GBufPos)))?1:0; - } - -- -- -- --u32 _ReadMem_naomi(u32 Addr, u32 sz) --{ -- verify(sz!=1); -- -- DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", Addr, sz); -- return 1; -- --} --void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) --{ -- DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", Addr, data, sz); --} -- -- - //DIMM board - //Uses interrupt ext#3 (holly_EXT_PCI) - -@@ -382,23 +366,22 @@ void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) - //n1 bios writes the value -1, meaning it expects the bit 0 to be set - //.// - --u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? --u32 reg_dimm_40; //parameters --u32 reg_dimm_44; //parameters --u32 reg_dimm_48; //parameters -- --u32 reg_dimm_4c=0x11; //status/control reg ? -+u32 reg_dimm_command; // command, written, 0x1E03 some flag ? -+u32 reg_dimm_offsetl; -+u32 reg_dimm_parameterl; -+u32 reg_dimm_parameterh; -+u32 reg_dimm_status = 0x11; - - bool NaomiDataRead = false; - static bool aw_ram_test_skipped = false; - --void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) -+void naomi_process(u32 command, u32 offsetl, u32 parameterl, u32 parameterh) - { -- DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", r3c, r40, r44, r48); -- DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",r3c >> 15,(r3c & 0x7e00) >> 9, r3c & 0x1FF); -- DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (r3c & 0xFF00) >> 8,r3c & 0xFF); -+ DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", command, offsetl, parameterl, parameterh); -+ DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",command >> 15,(command & 0x7e00) >> 9, command & 0x1FF); -+ DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (command & 0xFF00) >> 8,command & 0xFF); - -- u32 param=(r3c&0xFF); -+ u32 param=(command&0xFF); - if (param==0xFF) - { - DEBUG_LOG(NAOMI, "invalid opcode or smth ?"); -@@ -407,8 +390,8 @@ void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) - //else if (param!=3) - if (opcd<255) - { -- reg_dimm_3c=0x8000 | (opcd%12<<9) | (0x0); -- DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_3c); -+ reg_dimm_command=0x8000 | (opcd%12<<9) | (0x0); -+ DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_command); - asic_RaiseInterrupt(holly_EXP_PCI); - DEBUG_LOG(NAOMI, "Interrupt raised"); - opcd++; -@@ -437,8 +420,23 @@ void WriteMem_naomi(u32 Addr, u32 data, u32 sz) - } - - //Dma Start -+int naomi_schid; -+ -+int Naomi_DmaSchd(int i, int c, int j) -+{ -+ SB_GDSTARD = SB_GDSTAR + SB_GDLEN; -+ SB_GDLEND = SB_GDLEN; -+ SB_GDST = 0; -+ // interrupt not needed? SB_GDST is monitored -+ asic_RaiseInterrupt(holly_GDROM_DMA); -+// asic_RaiseInterrupt(holly_GDROM_CMD); -+ -+ return 0; -+} -+ - void Naomi_DmaStart(u32 addr, u32 data) - { -+// asic_CancelInterrupt(holly_GDROM_CMD); - if (SB_GDEN==0) - { - INFO_LOG(NAOMI, "Invalid (NAOMI)GD-DMA start, SB_GDEN=0. Ignoring it."); -@@ -451,11 +449,26 @@ void Naomi_DmaStart(u32 addr, u32 data) - if (SB_GDST==1) - { - verify(1 == SB_GDDIR ); -- -- SB_GDSTARD=SB_GDSTAR+SB_GDLEN; -+ if (false) // breaks doa2 (sz 15a15c & 3a7cc) if (SB_GDLEN & 0x1F) -+ { -+ ERROR_LOG(NAOMI, "SB_GDLEN has invalid value: %x", SB_GDLEN); -+ //die("NAOMI: SB_GDLEN has invalid size !"); -+ SB_GDSTARD = SB_GDSTAR; -+ SB_GDLEND = 0; -+ SB_GDST = 0; -+ return; -+ } -+ if (0x8201 != (DMAC_DMAOR.full & DMAOR_MASK)) -+ { -+ INFO_LOG(NAOMI, "NAOMI: DMAOR has invalid settings (%X)", DMAC_DMAOR.full); -+ //return; -+ } -+ DEBUG_LOG(NAOMI, "NAOMI-DMA start addr %08X len %d", SB_GDSTAR, SB_GDLEN); -+ -+// SB_GDSTARD=SB_GDSTAR+SB_GDLEN; - -- SB_GDLEND=SB_GDLEN; -- SB_GDST=0; -+// SB_GDLEND=SB_GDLEN; -+// SB_GDST=0; - if (CurrentCartridge != NULL) - { - u32 len = SB_GDLEN; -@@ -464,21 +477,28 @@ void Naomi_DmaStart(u32 addr, u32 data) - { - u32 block_len = len; - void* ptr = CurrentCartridge->GetDmaPtr(block_len); -- if (ptr != NULL) -- WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); -+ if (block_len == 0) -+ { -+ INFO_LOG(NAOMI, "Aborted DMA transfer. Read past end of cart?"); -+ break; -+ } -+ WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); - CurrentCartridge->AdvancePtr(block_len); - len -= block_len; - offset += block_len; - } - } - -- asic_RaiseInterrupt(holly_GDROM_DMA); -+// asic_RaiseInterrupt(holly_GDROM_DMA); -+// sh4_sched_request(naomi_schid, SB_GDLEN * 2); -+ Naomi_DmaSchd(0, 0, 0); - } - } - - - void Naomi_DmaEnable(u32 addr, u32 data) - { -+// asic_CancelInterrupt(holly_GDROM_CMD); - SB_GDEN=data&1; - if (SB_GDEN==0 && SB_GDST==1) - { -@@ -538,6 +558,8 @@ void naomi_reg_Init() - sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart); - - sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable); -+ -+ naomi_schid = sh4_sched_register(0, &Naomi_DmaSchd); - } - - void naomi_reg_Term() -@@ -573,82 +595,11 @@ void naomi_reg_Reset(bool Manual) - GLastCmd = 0; - SerStep = 0; - SerStep2 = 0; --} -- --void Update_naomi() --{ -- /* -- if (naomi_updates>1) -- { -- naomi_updates--; -- } -- else if (naomi_updates==1) -- { -- naomi_updates=0; -- asic_RaiseInterrupt(holly_EXP_PCI); -- }*/ --#if 0 -- if(!(SB_GDST&1) || !(SB_GDEN &1)) -- return; -- -- //SB_GDST=0; -- -- //TODO : Fix dmaor -- u32 dmaor = DMAC_DMAOR.full; -- -- u32 src = SB_GDSTARD, -- len = SB_GDLEN-SB_GDLEND ; -- -- //len=min(len,(u32)32); -- // do we need to do this for gdrom dma ? -- if(0x8201 != (dmaor &DMAOR_MASK)) { -- INFO_LOG(NAOMI, "GDROM: DMAOR has invalid settings (%X) !", dmaor); -- //return; -- } -- if(len & 0x1F) { -- INFO_LOG(NAOMI, "GDROM: SB_GDLEN has invalid size (%X) !", len); -- return; -- } -- -- if(0 == len) -- { -- INFO_LOG(NAOMI, "GDROM: Len: %X, Abnormal Termination !", len); -- } -- u32 len_backup=len; -- if( 1 == SB_GDDIR ) -- { -- WriteMemBlock_nommu_ptr(dst,NaomiRom+(DmaOffset&0x7ffffff),size); -- -- DmaCount=0xffff; -- } -- else -- INFO_LOG(NAOMI, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)"); -- -- //SB_GDLEN = 0x00000000; //13/5/2k7 -> acording to docs these regs are not updated by hardware -- //SB_GDSTAR = (src + len_backup); -- -- SB_GDLEND+= len_backup; -- SB_GDSTARD+= len_backup;//(src + len_backup)&0x1FFFFFFF; -- -- if (SB_GDLEND==SB_GDLEN) -- { -- //printf("Streamed GDMA end - %d bytes trasnfered\n",SB_GDLEND); -- SB_GDST=0;//done -- // The DMA end interrupt flag -- asic_RaiseInterrupt(holly_GDROM_DMA); -- } -- //Readed ALL sectors -- if (read_params.remaining_sectors==0) -- { -- u32 buff_size =read_buff.cache_size - read_buff.cache_index; -- //And all buffer :p -- if (buff_size==0) -- { -- verify(!SB_GDST&1) -- gd_set_state(gds_procpacketdone); -- } -- } --#endif -+ reg_dimm_command = 0; -+ reg_dimm_offsetl = 0; -+ reg_dimm_parameterl = 0; -+ reg_dimm_parameterh = 0; -+ reg_dimm_status = 0x11; - } - - static u8 aw_maple_devs; -@@ -659,6 +610,10 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { - //printf("libExtDevice_ReadMem_A0_006 %d@%08x: %x\n", size, addr, mem600[addr]); - switch (addr) - { -+// case 0: -+// return 0; -+// case 4: -+// return 1; - case 0x280: - // 0x00600280 r 0000dcba - // a/b - 1P/2P coin inputs (JAMMA), active low -diff --git a/core/hw/naomi/naomi.h b/core/hw/naomi/naomi.h -index 8781f03..88ae8cb 100644 ---- a/core/hw/naomi/naomi.h -+++ b/core/hw/naomi/naomi.h -@@ -8,8 +8,6 @@ void naomi_reg_Init(); - void naomi_reg_Term(); - void naomi_reg_Reset(bool Manual); - --void Update_naomi(); -- - u32 ReadMem_naomi(u32 Addr, u32 sz); - void WriteMem_naomi(u32 Addr, u32 data, u32 sz); - -@@ -20,21 +18,11 @@ u16 NaomiGameIDRead(); - void NaomiGameIDWrite(const u16 Data); - void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48); - --typedef u16 (*getNaomiAxisFP)(); -- --struct NaomiInputMapping { -- getNaomiAxisFP axis[8]; -- u8 button_mapping_byte[16]; -- u8 button_mapping_mask[16]; --}; -- --extern NaomiInputMapping Naomi_Mapping; -- --extern u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? --extern u32 reg_dimm_40; //parameters --extern u32 reg_dimm_44; //parameters --extern u32 reg_dimm_48; //parameters --extern u32 reg_dimm_4c; //status/control reg ? -+extern u32 reg_dimm_command; // command, written, 0x1E03 some flag ? -+extern u32 reg_dimm_offsetl; -+extern u32 reg_dimm_parameterl; -+extern u32 reg_dimm_parameterh; -+extern u32 reg_dimm_status; - - extern bool NaomiDataRead; - extern u32 naomi_updates; -diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp -index 209df28..0a46132 100644 ---- a/core/hw/naomi/naomi_cart.cpp -+++ b/core/hw/naomi/naomi_cart.cpp -@@ -730,23 +730,26 @@ void NaomiCartridge::AdvancePtr(u32 size) { - u32 NaomiCartridge::ReadMem(u32 address, u32 size) - { - verify(size!=1); -- //printf("+naomi?WTF? ReadMem: %X, %d\n", address, size); -+ - switch(address & 255) - { -- case 0x3c: -- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); -- return reg_dimm_3c | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios -- case 0x40: -- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); -- return reg_dimm_40; -- case 0x44: -- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); -- return reg_dimm_44; -- case 0x48: -- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); -- return reg_dimm_48; -+ case 0x3c: // 5f703c: DIMM COMMAND -+ DEBUG_LOG(NAOMI, "DIMM COMMAND read<%d>", size); -+ return reg_dimm_command | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios -+// return 0xffff; -+ case 0x40: // 5f7040: DIMM OFFSETL -+ DEBUG_LOG(NAOMI, "DIMM OFFSETL read<%d>", size); -+ return reg_dimm_offsetl; -+ case 0x44: // 5f7044: DIMM PARAMETERL -+ DEBUG_LOG(NAOMI, "DIMM PARAMETERL read<%d>", size); -+ return reg_dimm_parameterl; -+ case 0x48: // 5f7048: DIMM PARAMETERH -+ DEBUG_LOG(NAOMI, "DIMM PARAMETERH read<%d>", size); -+ return reg_dimm_parameterh; -+ case 0x04C: // 5f704c: DIMM STATUS -+ DEBUG_LOG(NAOMI, "DIMM STATUS read<%d>", size); -+ return reg_dimm_status; - -- //These are known to be valid on normal ROMs and DIMM board - case NAOMI_ROM_OFFSETH_addr&255: - return RomPioOffset>>16 | (RomPioAutoIncrement << 15); - -@@ -786,7 +789,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) - return 1; - - -- //This should be valid - case NAOMI_DMA_OFFSETH_addr&255: - return DmaOffset>>16; - case NAOMI_DMA_OFFSETL_addr&255: -@@ -796,10 +798,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) - DEBUG_LOG(NAOMI, "naomi ReadBoardId: %X, %d", address, size); - return 1; - -- case 0x04C: -- DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); -- return reg_dimm_4c; -- - case NAOMI_COMM2_CTRL_addr & 255: - DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL read"); - return comm_ctrl; -@@ -840,35 +838,34 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) - - void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) - { -- // printf("+naomi WriteMem: %X <= %X, %d\n", address, data, size); - switch(address & 255) - { -- case 0x3c: -- if (0x1E03==data) -+ case 0x3c: // 5f703c: DIMM COMMAND -+ if (0x1E03 == data) - { - /* -- if (!(reg_dimm_4c&0x100)) -+ if (!(reg_dimm_status & 0x100)) - asic_RaiseInterrupt(holly_EXP_PCI); -- reg_dimm_4c|=1;*/ -+ reg_dimm_status |= 1;*/ - } -- reg_dimm_3c=data; -- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); -+ reg_dimm_command = data; -+ DEBUG_LOG(NAOMI, "DIMM COMMAND Write: %X <= %X, %d", address, data, size); - return; - -- case 0x40: -- reg_dimm_40=data; -- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); -+ case 0x40: // 5f7040: DIMM OFFSETL -+ reg_dimm_offsetl = data; -+ DEBUG_LOG(NAOMI, "DIMM OFFSETL Write: %X <= %X, %d", address, data, size); - return; -- case 0x44: -- reg_dimm_44=data; -- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); -+ case 0x44: // 5f7044: DIMM PARAMETERL -+ reg_dimm_parameterl = data; -+ DEBUG_LOG(NAOMI, "DIMM PARAMETERL Write: %X <= %X, %d", address, data, size); - return; -- case 0x48: -- reg_dimm_48=data; -- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); -+ case 0x48: // 5f7048: DIMM PARAMETERH -+ reg_dimm_parameterh = data; -+ DEBUG_LOG(NAOMI, "DIMM PARAMETERH Write: %X <= %X, %d", address, data, size); - return; - -- case 0x4C: -+ case 0x4C: // 5f704c: DIMM STATUS - if (data&0x100) - { - asic_CancelInterrupt(holly_EXP_PCI); -@@ -879,10 +876,10 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) - /*FILE* ramd=fopen("c:\\ndc.ram.bin","wb"); - fwrite(mem_b.data,1,RAM_SIZE,ramd); - fclose(ramd);*/ -- naomi_process(reg_dimm_3c,reg_dimm_40,reg_dimm_44,reg_dimm_48); -+ naomi_process(reg_dimm_command, reg_dimm_offsetl, reg_dimm_parameterl, reg_dimm_parameterh); - } -- reg_dimm_4c=data&~0x100; -- DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); -+ reg_dimm_status = data & ~0x100; -+ DEBUG_LOG(NAOMI, "DIMM STATUS Write: %X <= %X, %d", address, data, size); - return; - - //These are known to be valid on normal ROMs and DIMM board -diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp -index 26f9945..1884483 100644 ---- a/core/hw/sh4/dyna/blockmanager.cpp -+++ b/core/hw/sh4/dyna/blockmanager.cpp -@@ -412,15 +412,18 @@ void bm_Reset() - // Windows cannot lock/unlock a region spanning more than one VirtualAlloc or MapViewOfFile - // so we have to unlock each region individually - // No need for this mess in 4GB mode since windows doesn't use it --#if RAM_SIZE == 16 * 1024 * 1024 -- mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); -- mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); -- mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); -- mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); --#else -- mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); -- mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); --#endif -+ if (settings.platform.ram_size == 16 * 1024 * 1024) -+ { -+ mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); -+ mem_region_unlock(virt_ram_base + 0x0D000000, RAM_SIZE); -+ mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); -+ mem_region_unlock(virt_ram_base + 0x0F000000, RAM_SIZE); -+ } -+ else -+ { -+ mem_region_unlock(virt_ram_base + 0x0C000000, RAM_SIZE); -+ mem_region_unlock(virt_ram_base + 0x0E000000, RAM_SIZE); -+ } - if (_nvmem_4gb_space()) - { - mem_region_unlock(virt_ram_base + 0x8C000000, 0x90000000 - 0x8C000000); -diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp -index 5926bb8..e616985 100644 ---- a/core/hw/sh4/dyna/driver.cpp -+++ b/core/hw/sh4/dyna/driver.cpp -@@ -284,6 +284,11 @@ bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) - DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) - { - u32 pc=next_pc; -+// if (next_pc == 0x8C046E82) -+// { -+// DEBUG_LOG(SH4, "r0 %08x r1 %08x r2 %08x r3 %08x r4 %08x r5 %08x r6 %08x r7 %08x pc %08x ", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], next_pc); -+// DEBUG_LOG(SH4, "r8 %08x r9 %08x r10 %08x r11 %08x r12 %08x r13 %08x r14 %08x r15 %08x", r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); -+// } - - if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300) - recSh4_ClearCache(); -@@ -324,7 +329,14 @@ DynarecCodeEntryPtr rdv_CompilePC(u32 blockcheck_failures) - emit_ptr = NULL; - emit_ptr_limit = NULL; - } -- -+ /* -+ if (rbi->vaddr <= 0x8c018120 && rbi->vaddr + rbi->sh4_code_size > 0x8c018120) -+ //if (rbi->vaddr == 0x8c7e9c80) -+ { -+ extern void print_blocks(); -+ print_blocks(); -+ } -+ */ - return rbi->code; - } - -diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp -index 3a1c9e3..6b55a27 100644 ---- a/core/hw/sh4/interpr/sh4_interpreter.cpp -+++ b/core/hw/sh4/interpr/sh4_interpreter.cpp -@@ -32,9 +32,18 @@ - #define GetM(str) ((str>>4) & 0xf) - - static s32 l; -+static bool disassemble = false; - - static void ExecuteOpcode(u16 op) - { -+// if ((next_pc & 0x1ffffff0) == 0x0C0180F0) -+// disassemble = true; -+ if (disassemble) -+ { -+ char s[128]; -+ OpDesc[op]->Disassemble(s, next_pc - 2, op); -+ printf("%s\n", s); -+ } - if (sr.FD == 1 && OpDesc[op]->IsFloatingPoint()) - RaiseFPUDisableException(); - OpPtr[op](op); -diff --git a/core/hw/sh4/interpr/sh4_opcodes.cpp b/core/hw/sh4/interpr/sh4_opcodes.cpp -index 9ede446..074d942 100644 ---- a/core/hw/sh4/interpr/sh4_opcodes.cpp -+++ b/core/hw/sh4/interpr/sh4_opcodes.cpp -@@ -982,7 +982,7 @@ sh4op(i1011_iiii_iiii_iiii) - // trapa # - sh4op(i1100_0011_iiii_iiii) - { -- //printf("trapa 0x%X\n",(GetImm8(op) << 2)); -+ ERROR_LOG(GDROM, "TRAPA %d\n", (GetImm8(op) << 2)); - CCN_TRA = (GetImm8(op) << 2); - Do_Exception(next_pc,0x160,0x100); - } -diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp -index c1d685b..4c40584 100644 ---- a/core/hw/sh4/modules/fastmmu.cpp -+++ b/core/hw/sh4/modules/fastmmu.cpp -@@ -35,7 +35,7 @@ extern TLB_Entry UTLB[64]; - // Used when FullMMU is off - extern u32 sq_remap[64]; - --//#define TRACE_WINCE_SYSCALLS -+#define TRACE_WINCE_SYSCALLS - - #include "wince.h" - -@@ -323,7 +323,7 @@ u32 mmu_data_translation(u32 va, u32& rv) - if (va == unresolved_unicode_string) - { - unresolved_unicode_string = 0; -- INFO_LOG(SH4, "RESOLVED %s", get_unicode_string(va).c_str()); -+ printf("RESOLVED %s\n", get_unicode_string(va).c_str()); - } - } - #endif -diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp -index d3aae1f..42931f6 100644 ---- a/core/hw/sh4/modules/mmu.cpp -+++ b/core/hw/sh4/modules/mmu.cpp -@@ -77,13 +77,15 @@ defining NO_MMU disables the full mmu emulation - template - u32 mmu_full_lookup(u32 va, u32& idx, u32& rv); - --//#define TRACE_WINCE_SYSCALLS -+#define TRACE_WINCE_SYSCALLS - - #ifdef TRACE_WINCE_SYSCALLS - #include "wince.h" -+u32 unresolved_ascii_string; -+u32 unresolved_unicode_string; - #endif - --#define printf_mmu(...) DEBUG_LOG(SH4, __VA_ARGS__) -+#define printf_mmu(...) //DEBUG_LOG(SH4, __VA_ARGS__) - - ReadMem8Func ReadMem8; - ReadMem16Func ReadMem16; -diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h -index d967df5..74bfcc4 100644 ---- a/core/hw/sh4/modules/wince.h -+++ b/core/hw/sh4/modules/wince.h -@@ -31,7 +31,7 @@ static bool read_mem32(u32 addr, u32& data) - { - u32 pa; - const TLB_Entry *entry; -- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) -+ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) - return false; - data = ReadMem32_nommu(pa); - return true; -@@ -41,7 +41,7 @@ static bool read_mem16(u32 addr, u16& data) - { - u32 pa; - const TLB_Entry *entry; -- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) -+ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) - return false; - data = ReadMem16_nommu(pa); - return true; -@@ -51,7 +51,7 @@ static bool read_mem8(u32 addr, u8& data) - { - u32 pa; - const TLB_Entry *entry; -- if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) -+ if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) - return false; - data = ReadMem8_nommu(pa); - return true; -@@ -227,10 +227,10 @@ static const char *wince_methods[][256] = { - }, - }; - --u32 unresolved_ascii_string; --u32 unresolved_unicode_string; -+extern u32 unresolved_ascii_string; -+extern u32 unresolved_unicode_string; - --std::string get_unicode_string(u32 addr) -+static inline std::string get_unicode_string(u32 addr) - { - std::string str; - while (true) -@@ -248,7 +248,7 @@ std::string get_unicode_string(u32 addr) - } - return str; - } --std::string get_ascii_string(u32 addr) -+static inline std::string get_ascii_string(u32 addr) - { - std::string str; - while (true) -@@ -312,31 +312,33 @@ static bool print_wince_syscall(u32 address) - sprintf(method_buf, "[%d]", meth_id); - method = method_buf; - } -- INFO_LOG(SH4, "WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); -+ printf("WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); - if (address == 0xfffffd51) // SetLastError -- INFO_LOG(SH4, " dwErrCode = %x", r[4]); -+ printf(" dwErrCode = %x\n", r[4]); - else if (address == 0xffffd5ef) // CreateFile -- INFO_LOG(SH4, " lpFileName = %s", get_unicode_string(r[4]).c_str()); -+ printf(" lpFileName = %s\n", get_unicode_string(r[4]).c_str()); - else if (address == 0xfffffd97) // CreateProc -- INFO_LOG(SH4, " imageName = %s, commandLine = %s", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); -+ printf(" imageName = %s, commandLine = %s\n", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); - else if (!strcmp("DebugNotify", method)) -- INFO_LOG(SH4, " %x, %x\n", r[4], r[5]); -+ printf(" %x, %x\n", r[4], r[5]); - else if (address == 0xffffd5d3) // RegOpenKeyExW -- INFO_LOG(SH4, " hKey = %x, lpSubKey = %s", r[4], get_unicode_string(r[5]).c_str()); -+ printf(" hKey = %x, lpSubKey = %s\n", r[4], get_unicode_string(r[5]).c_str()); - else if (!strcmp("LoadLibraryW", method)) -- INFO_LOG(SH4, " fileName = %s", get_unicode_string(r[4]).c_str()); -+ printf(" fileName = %s\n", get_unicode_string(r[4]).c_str()); - else if (!strcmp("GetProcAddressW", method)) -- INFO_LOG(SH4, " hModule = %x, procName = %s", r[4], get_unicode_string(r[5]).c_str()); -+ printf(" hModule = %x, procName = %s\n", r[4], get_unicode_string(r[5]).c_str()); - else if (!strcmp("NKvDbgPrintfW", method)) -- INFO_LOG(SH4, " fmt = %s", get_unicode_string(r[4]).c_str()); -+ printf(" fmt = %s\n", get_unicode_string(r[4]).c_str()); - else if (!strcmp("OutputDebugStringW", method)) -- INFO_LOG(SH4, " str = %s", get_unicode_string(r[4]).c_str()); -+ printf(" str = %s\n", get_unicode_string(r[4]).c_str()); - else if (!strcmp("RegisterAFSName", method)) -- INFO_LOG(SH4, " name = %s", get_unicode_string(r[4]).c_str()); -+ printf(" name = %s\n", get_unicode_string(r[4]).c_str()); - else if (!strcmp("CreateAPISet", method)) -- INFO_LOG(SH4, " name = %s", get_ascii_string(r[4]).c_str()); -+ printf(" name = %s\n", get_ascii_string(r[4]).c_str()); - else if (!strcmp("Register", method) && !strcmp("APISET", api)) -- INFO_LOG(SH4, " p = %x, id = %x", r[4], r[5]); -+ printf(" p = %x, id = %x\n", r[4], r[5]); -+ else -+ printf("\n"); - // might be useful to detect errors? (hidden & dangerous) - //if (!strcmp("GetProcName", method)) - // os_DebugBreak(); -diff --git a/core/hw/sh4/sh4_interrupts.cpp b/core/hw/sh4/sh4_interrupts.cpp -index bec7356..4f87d2f 100644 ---- a/core/hw/sh4/sh4_interrupts.cpp -+++ b/core/hw/sh4/sh4_interrupts.cpp -@@ -14,7 +14,7 @@ - #include "sh4_core.h" - #include "sh4_mmr.h" - #include "oslib/oslib.h" -- -+#include "hw/holly/sb.h" - /* - - */ -@@ -154,6 +154,7 @@ bool Do_Interrupt(u32 intEvn) - sr.RB = 1; - UpdateSR(); - next_pc = vbr + 0x600; -+ //DEBUG_LOG(SH4, "Do_Interrupt: v_pc %08X SB_ISTNRM %08x", next_pc, SB_ISTNRM); - - return true; - } -diff --git a/core/nullDC.cpp b/core/nullDC.cpp -index e193a94..b6cd7cf 100755 ---- a/core/nullDC.cpp -+++ b/core/nullDC.cpp -@@ -358,12 +358,62 @@ int reicast_init(int argc, char* argv[]) - #define DATA_PATH "/" - #endif - -+void set_platform(int platform) -+{ -+ switch (platform) -+ { -+ case DC_PLATFORM_DREAMCAST: -+ settings.platform.ram_size = 16 * 1024 * 1024; -+ settings.platform.vram_size = 8 * 1024 * 1024; -+ settings.platform.aram_size = 2 * 1024 * 1024; -+ settings.platform.bios_size = 2 * 1024 * 1024; -+ settings.platform.flash_size = 128 * 1024; -+ settings.platform.bbsram_size = 0; -+ break; -+ case DC_PLATFORM_NAOMI: -+ settings.platform.ram_size = 32 * 1024 * 1024; -+ settings.platform.vram_size = 16 * 1024 * 1024; -+ settings.platform.aram_size = 8 * 1024 * 1024; -+ settings.platform.bios_size = 2 * 1024 * 1024; -+ settings.platform.flash_size = 0; -+ settings.platform.bbsram_size = 32 * 1024; -+ break; -+ case DC_PLATFORM_ATOMISWAVE: -+ settings.platform.ram_size = 16 * 1024 * 1024; -+ settings.platform.vram_size = 8 * 1024 * 1024; -+ settings.platform.aram_size = 8 * 1024 * 1024; -+ settings.platform.bios_size = 128 * 1024; -+ settings.platform.flash_size = 0; -+ settings.platform.bbsram_size = 128 * 1024; -+ break; -+ default: -+ die("Unsupported platform"); -+ break; -+ } -+ settings.platform.system = platform; -+ settings.platform.ram_mask = settings.platform.ram_size - 1; -+ settings.platform.vram_mask = settings.platform.vram_size - 1; -+ settings.platform.aram_mask = settings.platform.aram_size - 1; -+} -+ - static int dc_init() - { - static bool init_done; - - if (init_done) - return 0; -+ -+ // FIXME -+#if DC_PLATFORM == DC_PLATFORM_DREAMCAST -+ set_platform(DC_PLATFORM_DREAMCAST); -+#elif DC_PLATFORM == DC_PLATFORM_NAOMI -+ set_platform(DC_PLATFORM_NAOMI); -+#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE -+ set_platform(DC_PLATFORM_ATOMISWAVE); -+#else -+#error Unsupported platform -+#endif -+ - if (plugins_Init()) - return -3; - #if FEAT_SHREC != DYNAREC_NONE -diff --git a/core/rec-x86/rec_x86_driver.cpp b/core/rec-x86/rec_x86_driver.cpp -index 3ddc683..8be81bf 100644 ---- a/core/rec-x86/rec_x86_driver.cpp -+++ b/core/rec-x86/rec_x86_driver.cpp -@@ -106,7 +106,11 @@ void x86_reg_alloc::FreezeXMM() - f32* slpc=thaw_regs; - while(*fpreg!=-1) - { -- if (SpanNRegfIntr(current_opid,*fpreg)) -+#ifdef OLD_REGALLOC -+ if (SpanNRegfIntr(current_opid,*fpreg)) -+#else -+ if (regf_used((x86_reg)*fpreg)) -+#endif - x86e->Emit(op_movss,slpc++,*fpreg); - fpreg++; - } -@@ -121,7 +125,11 @@ void x86_reg_alloc::ThawXMM() - f32* slpc=thaw_regs; - while(*fpreg!=-1) - { -- if (SpanNRegfIntr(current_opid,*fpreg)) -+#ifdef OLD_REGALLOC -+ if (SpanNRegfIntr(current_opid,*fpreg)) -+#else -+ if (regf_used((x86_reg)*fpreg)) -+#endif - x86e->Emit(op_movss,*fpreg,slpc++); - fpreg++; - } -@@ -157,7 +165,7 @@ void DYNACALL csc_fail(u32 addr,u32 addy) - { - u32 fail_idx=(csc_sidx>>1)|(csc_sidx<<31); - -- printf("Ret Mismatch: %08X instead of %08X!\n",addr,addy); -+ INFO_LOG(DYNAREC, "Ret Mismatch: %08X instead of %08X!", addr, addy); - } - } - void csc_pop(RuntimeBlockInfo* block) -@@ -218,10 +226,9 @@ void csc_pop(RuntimeBlockInfo* block) - - void DYNACALL PrintBlock(u32 pc) - { -- printf("block: 0x%08X\n",pc); -+ INFO_LOG(DYNAREC, "block: 0x%08X", pc); - for (int i=0;i<16;i++) -- printf("%08X ",r[i]); -- printf("\n"); -+ INFO_LOG(DYNAREC, "%08X ",r[i]); - } - - u32 cvld; -@@ -396,6 +403,7 @@ void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, - - reg.OpEnd(op); - } -+ reg.Cleanup(); - - block->relink_offset=x86e->x86_indx; - block->relink_data=0; -@@ -843,7 +851,7 @@ bool ngen_Rewrite(unat& addr,unat retadr,unat acc) - //found ! - - if ((acc >> 26) == 0x38 && !w) { -- printf("WARNING: SQ AREA READ, %08X from sh4:%08X. THIS IS UNDEFINED ON A REAL DREACMAST.\n", acc, bm_GetBlock(x86e->x86_buff)->addr); -+ INFO_LOG(DYNAREC, "WARNING: SQ AREA READ, %08X from sh4:%08X. THIS IS UNDEFINED ON A REAL DREACMAST.", acc, bm_GetBlock(x86e->x86_buff)->addr); - } - - if ((acc >> 26) == 0x38) //sq ? -diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp -index 3778baf..23efd76 100644 ---- a/core/rec-x86/rec_x86_il.cpp -+++ b/core/rec-x86/rec_x86_il.cpp -@@ -1,6 +1,6 @@ - #include "types.h" - --#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 -+#if 1 //FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86 - #include "rec_x86_ngen.h" - #include "hw/sh4/sh4_mmr.h" - #include "hw/sh4/sh4_rom.h" -@@ -9,8 +9,8 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ - { - //x86e->Emit(op_mov32,EAX,op->rs1.reg_ptr()); - -- verify(reg.IsAllocg(op->rs1._reg)); -- verify(reg.IsAllocg(op->rd._reg)); -+ verify(reg.IsAllocg(op->rs1)); -+ verify(reg.IsAllocg(op->rd)); - - x86_reg rs2; - if (op->rs2.is_r32i()) -@@ -40,7 +40,7 @@ void ngen_Bin(shil_opcode* op,x86_opcode_class natop,bool has_imm=true,bool has_ - } - else - { -- printf("%d \n",op->rs1.type); -+ ERROR_LOG(DYNAREC, "%d", op->rs1.type); - verify(false); - } - } -@@ -72,7 +72,7 @@ void ngen_fp_bin(shil_opcode* op,x86_opcode_class natop) - } - else - { -- printf("%d \n",op->rs2.type); -+ ERROR_LOG(DYNAREC, "%d", op->rs2.type); - verify(false); - } - if (op->rd._reg != op->rs1._reg) -@@ -258,10 +258,10 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - verify(op->rs1.is_imm() || reg.IsAllocg(op->rs1)); - verify(op->rs3.is_null() || op->rs3.is_imm() || reg.IsAllocg(op->rs3)); - -- for (u32 i = 0; i < op->rd.count(); i++) -- { -- verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg + i))); -- } -+// for (u32 i = 0; i < op->rd.count(); i++) -+// { -+// verify(reg.IsAllocAny((Sh4RegType)(op->rd._reg + i))); -+// } - - u32 size = op->flags & 0x7f; - -@@ -373,9 +373,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - } - else - { -+#ifdef OLD_REGALLOC - x86e->Emit(op_movss, reg.mapfv(op->rd, 0), XMM0); - if (Lsz == 4) - x86e->Emit(op_movss, reg.mapfv(op->rd, 1), XMM1); -+#else -+ x86e->Emit(op_movss, op->rd.reg_ptr(), XMM0); -+ if (Lsz == 4) -+ x86e->Emit(op_movss, op->rd.reg_ptr() + 1, XMM1); -+#endif - } - break; - #endif -@@ -384,10 +390,10 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - if (size<=8) - { - -+#ifdef OPTIMIZATION_GRAVEYARD - if (size==8 && optimise) - { - die("unreachable"); --#ifdef OPTIMIZATION_GRAVEYARD - verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); - - x86e->Emit(op_mov32,EDX,ECX); -@@ -395,8 +401,8 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EDX,x86_ptr(virt_ram_base))); - x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EDX,x86_ptr(4+virt_ram_base))); - break; --#endif - } -+#endif - if (!isram) - { - reg.FreezeXMM(); -@@ -437,10 +443,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - } - else - { -+#ifdef OLD_REGALLOC - verify(op->rd.count()==2 && reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); - - x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,0),EAX); - x86e->Emit(op_movd_xmm_from_r32,reg.mapfv(op->rd,1),EDX); -+#else -+ x86e->Emit(op_mov32, op->rd.reg_ptr(), EAX); -+ x86e->Emit(op_mov32, op->rd.reg_ptr() + 1, EDX); -+#endif - } - - } -@@ -452,7 +463,11 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - u32 size=op->flags&0x7f; - verify(reg.IsAllocg(op->rs1) || op->rs1.is_imm()); - -- verify(op->rs2.is_imm() || op->rs2.is_r32() || (op->rs2.count()==2 && reg.IsAllocf(op->rs2,0) && reg.IsAllocf(op->rs2,1))); -+#ifdef OLD_REGALLOC -+ verify(op->rs2.is_imm() || op->rs2.is_r32() || (op->rs2.count() == 2 && reg.IsAllocf(op->rs2, 0) && reg.IsAllocf(op->rs2, 1))); -+#else -+ verify(op->rs2.is_imm() || op->rs2.is_r32() || op->rs2.count() == 2); -+#endif - - if (op->rs1.is_imm() && size<=4) - { -@@ -507,7 +522,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - } - else if (!op->rs3.is_null()) - { -- printf("rs3: %08X\n",op->rs3.type); -+ ERROR_LOG(DYNAREC, "rs3: %08X", op->rs3.type); - die("invalid rs3"); - } - -@@ -531,9 +546,15 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - x86e->Emit(op_mov32, EDX, reg.mapg(op->rs2)); - else - { -+#ifdef OLD_REGALLOC - x86e->Emit(op_movss, XMM0, reg.mapfv(op->rs2, 0)); - if (Lsz == 4) - x86e->Emit(op_movss, XMM1, reg.mapfv(op->rs2, 1)); -+#else -+ x86e->Emit(op_movss, XMM0, op->rs2.reg_ptr()); -+ if (Lsz == 4) -+ x86e->Emit(op_movss, XMM1, op->rs2.reg_ptr() + 1); -+#endif - } - - reg.FreezeXMM(); -@@ -599,13 +620,18 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - { - verify(op->rd.is_r64()); - verify(op->rs1.is_r64()); -- -+#ifdef OLD_REGALLOC - verify(reg.IsAllocf(op->rs1,0) && reg.IsAllocf(op->rs1,1)); - verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); - -- - x86e->Emit(op_movaps,reg.mapfv(op->rd,0),reg.mapfv(op->rs1,0)); - x86e->Emit(op_movaps,reg.mapfv(op->rd,1),reg.mapfv(op->rs1,1)); -+#else -+ x86e->Emit(op_mov32, EAX, x86_ptr(op->rs1.reg_ptr())); -+ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr()), EAX); -+ x86e->Emit(op_mov32, EAX, x86_ptr(op->rs1.reg_ptr() + 1)); -+ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr() + 1), EAX); -+#endif - } - break; - -@@ -656,7 +682,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - if (reg.mapf(op->rd) != reg.mapf(op->rs1)) - x86e->Emit(op_movss,reg.mapf(op->rd),reg.mapf(op->rs1)); - else -- printf("Renamed fmov !\n"); -+ INFO_LOG(DYNAREC, "Renamed fmov !"); - break; - - } -@@ -839,15 +865,16 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - - case shop_sync_sr: - { -+#ifdef OLD_REGALLOC - //reg alloc should be flushed here. Add Check - for (int i=0;i<8;i++) - { - verify(!reg.IsAllocAny((Sh4RegType)(reg_r0+i))); - verify(!reg.IsAllocAny((Sh4RegType)(reg_r0_Bank+i))); - } -- - verify(!reg.IsAllocAny(reg_old_sr_status)); - verify(!reg.IsAllocAny(reg_sr_status)); -+#endif - - //reg alloc should be flushed here, add checks - x86e->Emit(op_call,x86_ptr_imm(UpdateSR)); -@@ -856,15 +883,16 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - - case shop_sync_fpscr: - { -+#ifdef OLD_REGALLOC - //reg alloc should be flushed here. Add Check - for (int i=0;i<16;i++) - { - verify(!reg.IsAllocAny((Sh4RegType)(reg_fr_0+i))); - verify(!reg.IsAllocAny((Sh4RegType)(reg_xf_0+i))); - } -- - verify(!reg.IsAllocAny(reg_old_fpscr)); - verify(!reg.IsAllocAny(reg_fpscr)); -+#endif - - - //reg alloc should be flushed here, add checks -@@ -956,12 +984,19 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool - //verify(op->rd.is_vector); //double ? vector(2) ? - - verify(reg.IsAllocg(op->rs1)); -- verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); - - //sin/cos - x86e->Emit(op_movzx16to32,EAX,reg.mapg(op->rs1)); -+#ifdef OLD_REGALLOC -+ verify(reg.IsAllocf(op->rd,0) && reg.IsAllocf(op->rd,1)); - x86e->Emit(op_movss,reg.mapfv(op->rd,0),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[0]))); - x86e->Emit(op_movss,reg.mapfv(op->rd,1),x86_mrm(EAX,sib_scale_8,x86_ptr(&sin_table->u[1]))); -+#else -+ x86e->Emit(op_mov32, EAX, x86_mrm(EAX,sib_scale_8, x86_ptr(&sin_table->u[0]))); -+ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr()), EAX); -+ x86e->Emit(op_mov32, EAX, x86_mrm(EAX,sib_scale_8, x86_ptr(&sin_table->u[1]))); -+ x86e->Emit(op_mov32, x86_ptr(op->rd.reg_ptr() + 1), EAX); -+#endif - } - break; - -diff --git a/core/rec-x86/rec_x86_ngen.h b/core/rec-x86/rec_x86_ngen.h -index d68b5fc..bb6aeb7 100644 ---- a/core/rec-x86/rec_x86_ngen.h -+++ b/core/rec-x86/rec_x86_ngen.h -@@ -7,11 +7,17 @@ - #include "hw/sh4/sh4_core.h" - #include "hw/sh4/dyna/ngen.h" - #include "hw/sh4/sh4_mem.h" --#include "hw/sh4/dyna/regalloc.h" - #include "emitter/x86_emitter.h" - #include "profiler/profiler.h" - #include "oslib/oslib.h" - -+#define OLD_REGALLOC -+#ifdef OLD_REGALLOC -+#include "hw/sh4/dyna/regalloc.h" -+#else -+#include "hw/sh4/dyna/ssa_regalloc.h" -+#endif -+ - void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool staging, bool optimise); - - #if BUILD_COMPILER == COMPILER_GCC -@@ -46,7 +52,11 @@ extern bool sse_3; - extern bool ssse_3; - extern bool mmx; - --struct x86_reg_alloc: RegAlloc -+struct x86_reg_alloc : RegAlloc - { - virtual void Preload(u32 reg,x86_reg nreg); - virtual void Writeback(u32 reg,x86_reg nreg); -diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp -index e6aa10a..fba0ce9 100644 ---- a/core/rend/TexCache.cpp -+++ b/core/rend/TexCache.cpp -@@ -125,7 +125,7 @@ void palette_update() - - using namespace std; - --vector VramLocks[VRAM_SIZE/PAGE_SIZE]; -+vector VramLocks[VRAM_SIZE_MAX / PAGE_SIZE]; - VLockedMemory vram; // vram 32-64b - - //List functions -diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp -index d6e5a5f..c569f89 100644 ---- a/core/rend/gl4/gldraw.cpp -+++ b/core/rend/gl4/gldraw.cpp -@@ -472,7 +472,7 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height) - for (int render_pass = 0; render_pass < render_pass_count; render_pass++) - { - const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass]; -- -+// printf("PASS %d autosort %d\n", render_pass, current_pass.autosort); - // Check if we can skip this pass, in part or completely, in case nothing is drawn (Cosmic Smash) - bool skip_op_pt = true; - bool skip_tr = true; -diff --git a/core/rend/norend/norend.cpp b/core/rend/norend/norend.cpp -index 01d507d..83aecb7 100644 ---- a/core/rend/norend/norend.cpp -+++ b/core/rend/norend/norend.cpp -@@ -22,7 +22,7 @@ struct norend : Renderer - - bool Render() - { -- return true;//!pvrrc.isRTT; -+ return !pvrrc.isRTT; - } - - void Present() { } -diff --git a/core/serialize.cpp b/core/serialize.cpp -index 699757a..bb77f0e 100644 ---- a/core/serialize.cpp -+++ b/core/serialize.cpp -@@ -157,19 +157,8 @@ extern u32 SB_FFST; - //static HollyInterruptID dmatmp2; - //static HollyInterruptID OldDmaId; - --//this is one-time init, no updates - don't need to serialize --//extern RomChip sys_rom; --#ifdef FLASH_SIZE --extern DCFlashChip sys_nvmem; --#endif -- --#ifdef BBSRAM_SIZE --extern SRamChip sys_nvmem; --#endif --//this is one-time init, no updates - don't need to serialize --//extern _vmem_handler area0_handler; -- -- -+extern MemChip *sys_rom; -+extern MemChip *sys_nvmem; - - - //./core/hw/gdrom/gdrom_response.o -@@ -622,11 +611,11 @@ extern int SerStep; - extern int SerStep2; - extern unsigned char BSerial[]; - extern unsigned char GSerial[]; --extern u32 reg_dimm_3c; //IO window ! writen, 0x1E03 some flag ? --extern u32 reg_dimm_40; //parameters --extern u32 reg_dimm_44; //parameters --extern u32 reg_dimm_48; //parameters --extern u32 reg_dimm_4c; //status/control reg ? -+extern u32 reg_dimm_command; -+extern u32 reg_dimm_offsetl; -+extern u32 reg_dimm_parameterl; -+extern u32 reg_dimm_parameterh; -+extern u32 reg_dimm_status; - extern bool NaomiDataRead; - - -@@ -831,20 +820,16 @@ bool dc_serialize(void **data, unsigned int *total_size) - REICAST_S(SB_FFST); - - -- -- //this is one-time init, no updates - don't need to serialize -- //extern RomChip sys_rom; -- REICAST_S(sys_nvmem.size); -- REICAST_S(sys_nvmem.mask); -+ sys_rom->Serialize(data, total_size); -+ sys_nvmem->Serialize(data, total_size); -+ /* -+ REICAST_S(sys_nvmem->size); -+ REICAST_S(sys_nvmem->mask); - #ifdef FLASH_SIZE -- REICAST_S(sys_nvmem.state); -+ REICAST_S(sys_nvmem->state); - #endif -- REICAST_SA(sys_nvmem.data,sys_nvmem.size); -- -- //this is one-time init, no updates - don't need to serialize -- //extern _vmem_handler area0_handler; -- -- -+ REICAST_SA(sys_nvmem->data, sys_nvmem->size); -+ */ - - - REICAST_SA(reply_11,16) ; -@@ -1079,11 +1064,11 @@ bool dc_serialize(void **data, unsigned int *total_size) - REICAST_S(SerStep2); - REICAST_SA(BSerial,69); - REICAST_SA(GSerial,69); -- REICAST_S(reg_dimm_3c); -- REICAST_S(reg_dimm_40); -- REICAST_S(reg_dimm_44); -- REICAST_S(reg_dimm_48); -- REICAST_S(reg_dimm_4c); -+ REICAST_S(reg_dimm_command); -+ REICAST_S(reg_dimm_offsetl); -+ REICAST_S(reg_dimm_parameterl); -+ REICAST_S(reg_dimm_parameterh); -+ REICAST_S(reg_dimm_status); - REICAST_S(NaomiDataRead); - - #if FEAT_SHREC == DYNAREC_CPP -@@ -1198,15 +1183,15 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) - REICAST_US(i); //LIBRETRO_S(sys_nvmem_sram.mask); - //LIBRETRO_SA(sys_nvmem_sram.data,sys_nvmem_sram.size); - -- REICAST_US(sys_nvmem.size); -- REICAST_US(sys_nvmem.mask); -+ REICAST_US(sys_nvmem->size); -+ REICAST_US(sys_nvmem->mask); - #if DC_PLATFORM == DC_PLATFORM_DREAMCAST -- REICAST_US(sys_nvmem.state); -+ REICAST_US(static_cast(sys_nvmem)->state); - #else - // FIXME - die("Naomi/Atomiswave libretro savestates are not supported"); - #endif -- REICAST_USA(sys_nvmem.data,sys_nvmem.size); -+ REICAST_USA(sys_nvmem->data, sys_nvmem->size); - - - //this is one-time init, no updates - don't need to serialize -@@ -1471,11 +1456,11 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) - REICAST_US(SerStep2); - REICAST_USA(BSerial,69); - REICAST_USA(GSerial,69); -- REICAST_US(reg_dimm_3c); -- REICAST_US(reg_dimm_40); -- REICAST_US(reg_dimm_44); -- REICAST_US(reg_dimm_48); -- REICAST_US(reg_dimm_4c); -+ REICAST_US(reg_dimm_command); -+ REICAST_US(reg_dimm_offsetl); -+ REICAST_US(reg_dimm_parameterl); -+ REICAST_US(reg_dimm_parameterh); -+ REICAST_US(reg_dimm_status); - REICAST_US(NaomiDataRead); - - REICAST_US(i); //LIBRETRO_S(cycle_counter); -@@ -1580,15 +1565,16 @@ bool dc_unserialize(void **data, unsigned int *total_size) - REICAST_US(SB_FFST_rc); - REICAST_US(SB_FFST); - -- //this is one-time init, no updates - don't need to serialize -- //extern RomChip sys_rom; -+ sys_rom->Unserialize(data, total_size); -+ sys_nvmem->Unserialize(data, total_size); -+ /* - REICAST_US(sys_nvmem.size); - REICAST_US(sys_nvmem.mask); - #ifdef FLASH_SIZE - REICAST_US(sys_nvmem.state); - #endif - REICAST_USA(sys_nvmem.data,sys_nvmem.size); -- -+ */ - - //this is one-time init, no updates - don't need to serialize - //extern _vmem_handler area0_handler; -@@ -1850,11 +1836,11 @@ bool dc_unserialize(void **data, unsigned int *total_size) - REICAST_US(SerStep2); - REICAST_USA(BSerial,69); - REICAST_USA(GSerial,69); -- REICAST_US(reg_dimm_3c); -- REICAST_US(reg_dimm_40); -- REICAST_US(reg_dimm_44); -- REICAST_US(reg_dimm_48); -- REICAST_US(reg_dimm_4c); -+ REICAST_US(reg_dimm_command); -+ REICAST_US(reg_dimm_offsetl); -+ REICAST_US(reg_dimm_parameterl); -+ REICAST_US(reg_dimm_parameterh); -+ REICAST_US(reg_dimm_status); - REICAST_US(NaomiDataRead); - - #if FEAT_SHREC == DYNAREC_CPP -diff --git a/core/types.h b/core/types.h -index cf55226..a179a01 100644 ---- a/core/types.h -+++ b/core/types.h -@@ -421,8 +421,8 @@ bool dc_unserialize(void **data, unsigned int *total_size); - #define REICAST_S(v) rc_serialize(&(v), sizeof(v), data, total_size) - #define REICAST_US(v) rc_unserialize(&(v), sizeof(v), data, total_size) - --#define REICAST_SA(v_arr,num) rc_serialize(v_arr, sizeof(v_arr[0])*num, data, total_size) --#define REICAST_USA(v_arr,num) rc_unserialize(v_arr, sizeof(v_arr[0])*num, data, total_size) -+#define REICAST_SA(v_arr,num) rc_serialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) -+#define REICAST_USA(v_arr,num) rc_unserialize((v_arr), sizeof((v_arr)[0])*(num), data, total_size) - - enum - { -@@ -606,6 +606,19 @@ enum LimitFPSEnum { - struct settings_t - { - struct { -+ int system; -+ u32 ram_size; -+ u32 ram_mask; -+ u32 vram_size; -+ u32 vram_mask; -+ u32 aram_size; -+ u32 aram_mask; -+ u32 bios_size; -+ u32 flash_size; -+ u32 bbsram_size; -+ } platform; -+ -+ struct { - bool UseReios; - } bios; - -@@ -738,6 +751,16 @@ struct settings_t - - extern settings_t settings; - -+#define RAM_SIZE settings.platform.ram_size -+#define RAM_MASK settings.platform.ram_mask -+#define ARAM_SIZE settings.platform.aram_size -+#define ARAM_MASK settings.platform.aram_mask -+#define VRAM_SIZE settings.platform.vram_size -+#define VRAM_MASK settings.platform.vram_mask -+#define BIOS_SIZE settings.platform.bios_size -+#define FLASH_SIZE settings.platform.flash_size -+#define BBSRAM_SIZE settings.platform.bbsram_size -+ - void InitSettings(); - void LoadSettings(bool game_specific); - void SaveSettings(); -diff --git a/shell/android-studio/reicast/build.gradle b/shell/android-studio/reicast/build.gradle -index 71d1d4e..78175ac 100644 ---- a/shell/android-studio/reicast/build.gradle -+++ b/shell/android-studio/reicast/build.gradle -@@ -1,6 +1,8 @@ - apply plugin: 'com.android.application' - apply plugin: 'com.github.triplet.play' - -+apply from: 'profiling.gradle' -+ - def getBuildId = { -> - def build_id = System.getenv("TRAVIS_JOB_ID") ?: "8" - return Integer.parseInt( build_id ) -@@ -38,7 +40,7 @@ android { - - ndk { - moduleName "dc" -- abiFilters 'armeabi-v7a', 'arm64-v8a' -+ abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86' - } - } - -@@ -70,11 +72,12 @@ android { - flavorDimensions "systemtype" - productFlavors { - dreamcast { -+ externalNativeBuild { ndkBuild { arguments "-j8" } } - } - naomi { - applicationId = "com.flycast.emulator.naomi" - versionNameSuffix " Naomi" -- externalNativeBuild { ndkBuild { arguments "NAOMI=1" } } -+ externalNativeBuild { ndkBuild { arguments "NAOMI=1", "-j8" } } - } - } - -@@ -87,6 +90,12 @@ android { - lintOptions { - abortOnError false - } -+ -+ packagingOptions{ -+ doNotStrip "*/armeabi/*.so" -+ doNotStrip "*/armeabi-v7a/*.so" -+ doNotStrip "*/arm64-v8a/*.so" -+ } - } - - afterEvaluate { -@@ -117,4 +126,3 @@ dependencies { - } - implementation fileTree(include: ['*.jar'], dir: 'libs') - } -- diff --git a/shell/android-studio/reicast/build.gradle b/shell/android-studio/reicast/build.gradle index 78175ac69..40dfbbc91 100644 --- a/shell/android-studio/reicast/build.gradle +++ b/shell/android-studio/reicast/build.gradle @@ -1,8 +1,6 @@ apply plugin: 'com.android.application' apply plugin: 'com.github.triplet.play' -apply from: 'profiling.gradle' - def getBuildId = { -> def build_id = System.getenv("TRAVIS_JOB_ID") ?: "8" return Integer.parseInt( build_id ) @@ -40,7 +38,7 @@ android { ndk { moduleName "dc" - abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86' + abiFilters 'armeabi-v7a', 'arm64-v8a' } } @@ -72,12 +70,11 @@ android { flavorDimensions "systemtype" productFlavors { dreamcast { - externalNativeBuild { ndkBuild { arguments "-j8" } } } naomi { applicationId = "com.flycast.emulator.naomi" versionNameSuffix " Naomi" - externalNativeBuild { ndkBuild { arguments "NAOMI=1", "-j8" } } + externalNativeBuild { ndkBuild { arguments "NAOMI=1" } } } } @@ -90,12 +87,6 @@ android { lintOptions { abortOnError false } - - packagingOptions{ - doNotStrip "*/armeabi/*.so" - doNotStrip "*/armeabi-v7a/*.so" - doNotStrip "*/arm64-v8a/*.so" - } } afterEvaluate { diff --git a/shell/linux/.gdb_history b/shell/linux/.gdb_history deleted file mode 100644 index 09bfdd8b0..000000000 --- a/shell/linux/.gdb_history +++ /dev/null @@ -1,42 +0,0 @@ -r -q -r -bt -r -bt -info threads -q -r -bt -q -break GetFile -r -bt -q -r -bt -up -up -up -up -up -up -p buffer -p data -p offset -up -p child_archive -p *child_archive -p *parent_archive -q -r -q -break mcfg_CreateDevices -r -q -r -q -r -q -r -q diff --git a/shell/linux/flycast.log b/shell/linux/flycast.log deleted file mode 100644 index e69de29bb..000000000 From 58cb50f58790672d82b0666a9f6739f99277e123 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 10 Jul 2019 17:25:11 +0200 Subject: [PATCH 135/158] fix reset hang on naomi --- core/hw/aica/aica.cpp | 10 ++++----- core/hw/aica/aica_if.cpp | 4 ++-- core/hw/arm7/arm7.cpp | 6 ++++++ core/hw/arm7/arm_mem.h | 4 ++++ core/hw/arm7/vbaARM.cpp | 2 +- core/hw/gdrom/gdromv3.cpp | 2 +- core/hw/holly/holly_intc.cpp | 2 +- core/hw/holly/sb.cpp | 27 ++++++++++++++++++------- core/hw/holly/sb_mem.cpp | 6 +++--- core/hw/maple/maple_cfg.cpp | 4 ---- core/hw/maple/maple_if.cpp | 2 +- core/hw/naomi/naomi.cpp | 4 +++- core/hw/pvr/drkPvr.cpp | 6 +++--- core/hw/pvr/pvr_regs.cpp | 4 +++- core/hw/pvr/pvr_sb_regs.cpp | 2 +- core/hw/pvr/spg.cpp | 2 +- core/hw/sh4/dyna/driver.cpp | 4 ++-- core/hw/sh4/interpr/sh4_interpreter.cpp | 2 +- core/hw/sh4/modules/serial.cpp | 2 +- core/hw/sh4/sh4_if.h | 2 +- core/hw/sh4/sh4_interpreter.h | 2 +- core/hw/sh4/sh4_interrupts.cpp | 4 ++-- core/hw/sh4/sh4_mem.cpp | 6 +++--- core/imgread/ImgReader.cpp | 4 ++-- core/nullDC.cpp | 21 +++++++++---------- 25 files changed, 77 insertions(+), 57 deletions(-) diff --git a/core/hw/aica/aica.cpp b/core/hw/aica/aica.cpp index 381616838..f07065332 100644 --- a/core/hw/aica/aica.cpp +++ b/core/hw/aica/aica.cpp @@ -199,18 +199,18 @@ s32 libAICA_Init() MCIRE=(InterruptInfo*)&aica_reg[0x28B4+8]; sgc_Init(); - for (int i=0;i<3;i++) - timers[i].Init(aica_reg,i); return rv_ok; } -void libAICA_Reset(bool manual) +void libAICA_Reset(bool hard) { - if (!manual) + if (hard) init_mem(); sgc_Init(); - aica_Reset(manual); + for (int i = 0; i < 3; i++) + timers[i].Init(aica_reg, i); + aica_Reset(hard); } void libAICA_Term() diff --git a/core/hw/aica/aica_if.cpp b/core/hw/aica/aica_if.cpp index e66171a5f..27cc79d90 100644 --- a/core/hw/aica/aica_if.cpp +++ b/core/hw/aica/aica_if.cpp @@ -157,7 +157,7 @@ void aica_Init() RealTimeClock = GetRTC_now(); } -void aica_Reset(bool Manual) +void aica_Reset(bool hard) { aica_Init(); VREG = 0; @@ -357,7 +357,7 @@ void aica_sb_Init() dma_sched_id = sh4_sched_register(0, &dma_end_sched); } -void aica_sb_Reset(bool Manual) +void aica_sb_Reset(bool hard) { } diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index b79a273de..322d23e05 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -311,6 +311,12 @@ void arm_Reset() #if FEAT_AREC != DYNAREC_NONE FlushCache(); #endif + aica_interr = false; + aica_reg_L = 0; + e68k_out = false; + e68k_reg_L = 0; + e68k_reg_M = 0; + Arm7Enabled = false; // clean registers memset(&arm_Reg[0], 0, sizeof(arm_Reg)); diff --git a/core/hw/arm7/arm_mem.h b/core/hw/arm7/arm_mem.h index 10db8a668..20697062b 100644 --- a/core/hw/arm7/arm_mem.h +++ b/core/hw/arm7/arm_mem.h @@ -59,6 +59,10 @@ void sh4_WriteMem_reg(u32 addr,u32 data,u32 size); #define AICA_RAM_SIZE (ARAM_SIZE) #define AICA_RAM_MASK (ARAM_MASK) +extern bool aica_interr; +extern u32 aica_reg_L; extern bool e68k_out; +extern u32 e68k_reg_L; +extern u32 e68k_reg_M; void update_armintc(); diff --git a/core/hw/arm7/vbaARM.cpp b/core/hw/arm7/vbaARM.cpp index 037c7b28c..70fb35162 100644 --- a/core/hw/arm7/vbaARM.cpp +++ b/core/hw/arm7/vbaARM.cpp @@ -21,7 +21,7 @@ void libARM_Term() } //It's supposed to reset anything -void libARM_Reset(bool Manual) +void libARM_Reset(bool hard) { arm_Reset(); arm_SetEnabled(false); diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index 8e3bb6a37..351b98ded 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -1129,7 +1129,7 @@ void gdrom_reg_Term() } -void gdrom_reg_Reset(bool Manual) +void gdrom_reg_Reset(bool hard) { sb_rio_register(SB_GDST_addr, RIO_WF, 0, &GDROM_DmaStart); sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &GDROM_DmaEnable); diff --git a/core/hw/holly/holly_intc.cpp b/core/hw/holly/holly_intc.cpp index fc73b3183..b75df3596 100644 --- a/core/hw/holly/holly_intc.cpp +++ b/core/hw/holly/holly_intc.cpp @@ -248,7 +248,7 @@ void asic_reg_Term() } //Reset -> Reset - Initialise to default values -void asic_reg_Reset(bool Manual) +void asic_reg_Reset(bool hard) { } diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index dd237c4e6..f0e498050 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -785,17 +785,30 @@ void sb_Init() #endif } -void sb_Reset(bool Manual) +void sb_Reset(bool hard) { + if (hard) + { + for (u32 i = 0; i < sb_regs.Size; i++) + { + if (!(sb_regs[i].flags & (REG_RO|REG_WO|REG_RF))) + sb_regs[i].data32 = 0; + } + } + SB_ISTNRM = 0; + SB_FFST_rc = 0; + SB_FFST = 0; #ifdef ENABLE_MODEM ModemTerm(); #endif - asic_reg_Reset(Manual); - gdrom_reg_Reset(Manual); - naomi_reg_Reset(Manual); - pvr_sb_Reset(Manual); - maple_Reset(Manual); - aica_sb_Reset(Manual); + asic_reg_Reset(hard); + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + gdrom_reg_Reset(hard); + else + naomi_reg_Reset(hard); + pvr_sb_Reset(hard); + maple_Reset(hard); + aica_sb_Reset(hard); } void sb_Term() diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index cee5a6fce..b58c036c5 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -348,9 +348,9 @@ void sh4_area0_Init() sb_Init(); } -void sh4_area0_Reset(bool manual) +void sh4_area0_Reset(bool hard) { - if (manual) + if (hard) { if (sys_rom != NULL) { @@ -384,7 +384,7 @@ void sh4_area0_Reset(bool manual) sys_rom->Reset(); sys_nvmem->Reset(); } - sb_Reset(manual); + sb_Reset(hard); } void sh4_area0_Term() diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index d3b4a8661..b71fd2f5e 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -137,7 +137,6 @@ void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num = -1) void mcfg_CreateNAOMIJamma() { - printf("mcfg_CreateNAOMIJamma\n"); mcfg_DestroyDevices(); mcfg_Create(MDT_NaomiJamma, 0, 5); // mcfg_Create(MDT_Keyboard, 2, 5); @@ -145,7 +144,6 @@ void mcfg_CreateNAOMIJamma() void mcfg_CreateAtomisWaveControllers() { - printf("mcfg_CreateAtomisWaveControllers\n"); mcfg_DestroyDevices(); // Looks like two controllers needs to be on bus 0 and 1 for digital inputs // Then other devices on port 2 and 3 for analog axes, light guns, ... @@ -181,7 +179,6 @@ void mcfg_CreateAtomisWaveControllers() void mcfg_CreateDevices() { - printf("mcfg_CreateDevices\n"); for (int bus = 0; bus < MAPLE_PORTS; ++bus) { switch ((MapleDeviceType)settings.input.maple_devices[bus]) @@ -213,7 +210,6 @@ void mcfg_CreateDevices() void mcfg_DestroyDevices() { - printf("mcfg_DestroyDevices\n"); for (int i = 0; i < MAPLE_PORTS; i++) for (int j=0;j<=5;j++) { diff --git a/core/hw/maple/maple_if.cpp b/core/hw/maple/maple_if.cpp index e3a002b71..bb8d3a54e 100644 --- a/core/hw/maple/maple_if.cpp +++ b/core/hw/maple/maple_if.cpp @@ -259,7 +259,7 @@ void maple_Init() maple_schid=sh4_sched_register(0,&maple_schd); } -void maple_Reset(bool Manual) +void maple_Reset(bool hard) { maple_ddt_pending_reset=false; SB_MDTSEL = 0x00000000; diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index bf9999864..e8003a093 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -549,10 +549,12 @@ void naomi_reg_Term() } #endif } -void naomi_reg_Reset(bool Manual) +void naomi_reg_Reset(bool hard) { sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart); sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable); + SB_GDST = 0; + SB_GDEN = 0; NaomiDataRead = false; aw_ram_test_skipped = false; diff --git a/core/hw/pvr/drkPvr.cpp b/core/hw/pvr/drkPvr.cpp index 0e809b974..60241e89e 100644 --- a/core/hw/pvr/drkPvr.cpp +++ b/core/hw/pvr/drkPvr.cpp @@ -24,10 +24,10 @@ void libPvr_LockedBlockWrite (vram_block* block,u32 addr) } -void libPvr_Reset(bool Manual) +void libPvr_Reset(bool hard) { - Regs_Reset(Manual); - spg_Reset(Manual); + Regs_Reset(hard); + spg_Reset(hard); } s32 libPvr_Init() diff --git a/core/hw/pvr/pvr_regs.cpp b/core/hw/pvr/pvr_regs.cpp index 25df7767d..0acce010a 100644 --- a/core/hw/pvr/pvr_regs.cpp +++ b/core/hw/pvr/pvr_regs.cpp @@ -118,8 +118,10 @@ void pvr_WriteReg(u32 paddr,u32 data) PvrReg(addr,u32)=data; } -void Regs_Reset(bool Manual) +void Regs_Reset(bool hard) { + if (hard) + memset(&pvr_regs[0], 0, sizeof(pvr_regs)); ID = 0x17FD11DB; REVISION = 0x00000011; SOFTRESET = 0x00000007; diff --git a/core/hw/pvr/pvr_sb_regs.cpp b/core/hw/pvr/pvr_sb_regs.cpp index dfdfbd785..c850f2f0c 100644 --- a/core/hw/pvr/pvr_sb_regs.cpp +++ b/core/hw/pvr/pvr_sb_regs.cpp @@ -144,6 +144,6 @@ void pvr_sb_Term() { } //Reset -> Reset - Initialise -void pvr_sb_Reset(bool Manual) +void pvr_sb_Reset(bool hard) { } diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index d0572e9d3..51cb67b26 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -286,7 +286,7 @@ void spg_Term() { } -void spg_Reset(bool Manual) +void spg_Reset(bool hard) { CalculateSync(); } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 5926bb842..d75980f02 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -504,9 +504,9 @@ void recSh4_Skip() Sh4_int_Skip(); } -void recSh4_Reset(bool Manual) +void recSh4_Reset(bool hard) { - Sh4_int_Reset(Manual); + Sh4_int_Reset(hard); recSh4_ClearCache(); bm_Reset(); } diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index 3a1c9e3c2..2b6a9e8dc 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -124,7 +124,7 @@ void Sh4_int_Skip() } } -void Sh4_int_Reset(bool Manual) +void Sh4_int_Reset(bool hard) { if (sh4_int_bCpuRun) { diff --git a/core/hw/sh4/modules/serial.cpp b/core/hw/sh4/modules/serial.cpp index 90c87f520..1de2af856 100644 --- a/core/hw/sh4/modules/serial.cpp +++ b/core/hw/sh4/modules/serial.cpp @@ -138,7 +138,7 @@ void serial_reset() */ SCIF_SCSMR2.full=0x0000; SCIF_SCBRR2=0xFF; - SCIF_SCFSR2.full=0x000; + SCIF_SCFSR2.full=0x060; SCIF_SCFCR2.full=0x000; SCIF_SCFDR2.full=0x000; SCIF_SCSPTR2.full=0x000; diff --git a/core/hw/sh4/sh4_if.h b/core/hw/sh4/sh4_if.h index be40f47a2..069e80acd 100644 --- a/core/hw/sh4/sh4_if.h +++ b/core/hw/sh4/sh4_if.h @@ -218,7 +218,7 @@ typedef void StopFP(); typedef void StartFP(); typedef void StepFP(); typedef void SkipFP(); -typedef void ResetFP(bool Manual); +typedef void ResetFP(bool hard); typedef void InitFP(); typedef void TermFP(); typedef bool IsCpuRunningFP(); diff --git a/core/hw/sh4/sh4_interpreter.h b/core/hw/sh4/sh4_interpreter.h index 8a22caa83..9a4a0c7ff 100644 --- a/core/hw/sh4/sh4_interpreter.h +++ b/core/hw/sh4/sh4_interpreter.h @@ -44,7 +44,7 @@ void Sh4_int_Stop(); void Sh4_int_Start(); void Sh4_int_Step(); void Sh4_int_Skip(); -void Sh4_int_Reset(bool Manual); +void Sh4_int_Reset(bool hard); void Sh4_int_Init(); void Sh4_int_Term(); bool Sh4_int_IsCpuRunning(); diff --git a/core/hw/sh4/sh4_interrupts.cpp b/core/hw/sh4/sh4_interrupts.cpp index bec73565b..a05536fb7 100644 --- a/core/hw/sh4/sh4_interrupts.cpp +++ b/core/hw/sh4/sh4_interrupts.cpp @@ -20,7 +20,7 @@ */ //these are fixed -u16 IRLPriority=0x0246; +/* TODO const */ u16 IRLPriority=0x0246; #define IRLP9 &IRLPriority,0 #define IRLP11 &IRLPriority,4 #define IRLP13 &IRLPriority,8 @@ -31,7 +31,7 @@ u16 IRLPriority=0x0246; struct InterptSourceList_Entry { - u16* PrioReg; + const u16* PrioReg; u32 Shift; u32 IntEvnCode; diff --git a/core/hw/sh4/sh4_mem.cpp b/core/hw/sh4/sh4_mem.cpp index a61a7f85d..40bcd3a2b 100644 --- a/core/hw/sh4/sh4_mem.cpp +++ b/core/hw/sh4/sh4_mem.cpp @@ -193,17 +193,17 @@ void mem_Init() } //Reset Sysmem/Regs -- Pvr is not changed , bios/flash are not zeroed out -void mem_Reset(bool Manual) +void mem_Reset(bool hard) { //mem is reseted on hard restart(power on) , not manual... - if (!Manual) + if (hard) { //fill mem w/ 0's mem_b.Zero(); } //Reset registers - sh4_area0_Reset(Manual); + sh4_area0_Reset(hard); sh4_mmr_reset(); MMU_reset(); } diff --git a/core/imgread/ImgReader.cpp b/core/imgread/ImgReader.cpp index ea2ea0bf8..09e6be56d 100644 --- a/core/imgread/ImgReader.cpp +++ b/core/imgread/ImgReader.cpp @@ -61,8 +61,8 @@ void EXPORT_CALL handle_SwitchDisc(u32 id,void* w,void* p) //new disc is in } */ -//It's supposed to reset everything (if not a manual reset) -void libGDR_Reset(bool Manual) +//It's supposed to reset everything (if not a soft reset) +void libGDR_Reset(bool hard) { libCore_gdrom_disc_change(); } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 291274269..5031f5369 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -120,13 +120,13 @@ void plugins_Term() libPvr_Term(); } -void plugins_Reset(bool Manual) +void plugins_Reset(bool hard) { reios_reset(); - libPvr_Reset(Manual); - libGDR_Reset(Manual); - libAICA_Reset(Manual); - libARM_Reset(Manual); + libPvr_Reset(hard); + libGDR_Reset(hard); + libAICA_Reset(hard); + libARM_Reset(hard); //libExtDevice_Reset(Manual); } @@ -306,12 +306,12 @@ void LoadSpecialSettings() } } -void dc_reset(bool manual) +void dc_reset(bool hard) { - plugins_Reset(manual); - mem_Reset(manual); + plugins_Reset(hard); + mem_Reset(hard); - sh4_cpu.Reset(manual); + sh4_cpu.Reset(hard); } static bool reset_requested; @@ -366,7 +366,6 @@ void set_platform(int platform) switch (platform) { case DC_PLATFORM_DREAMCAST: - printf("Starting Dreamcast game\n"); settings.platform.ram_size = 16 * 1024 * 1024; settings.platform.vram_size = 8 * 1024 * 1024; settings.platform.aram_size = 2 * 1024 * 1024; @@ -375,7 +374,6 @@ void set_platform(int platform) settings.platform.bbsram_size = 0; break; case DC_PLATFORM_NAOMI: - printf("Starting Naomi game\n"); settings.platform.ram_size = 32 * 1024 * 1024; settings.platform.vram_size = 16 * 1024 * 1024; settings.platform.aram_size = 8 * 1024 * 1024; @@ -384,7 +382,6 @@ void set_platform(int platform) settings.platform.bbsram_size = 32 * 1024; break; case DC_PLATFORM_ATOMISWAVE: - printf("Starting Atomiswave game\n"); settings.platform.ram_size = 16 * 1024 * 1024; settings.platform.vram_size = 8 * 1024 * 1024; settings.platform.aram_size = 8 * 1024 * 1024; From ad98e583c89b2698e4249973e439657ea4c8aed2 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 10 Jul 2019 18:58:55 +0200 Subject: [PATCH 136/158] win32: fix vmem reset --- core/hw/mem/_vmem.cpp | 4 ++-- core/hw/mem/_vmem.h | 2 ++ core/linux/posix_vmem.cpp | 8 ++++++++ core/windows/win_vmem.cpp | 36 +++++++++++++++++++++++++++++------- core/windows/winmain.cpp | 2 +- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index a49bcc8bc..b294ccda6 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -523,7 +523,7 @@ bool _vmem_reserve() { return true; } -void _vmem_term_mappings() +static void _vmem_term_mappings() { if (vmemstatus == MemTypeError) { if (p_sh4rcb != NULL) @@ -549,7 +549,7 @@ void _vmem_term_mappings() } else { - //vmem_platform_destroy(); // FIXME Needed for Windows + vmem_platform_delete_mappings(); } } diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index d83705497..007d92f4f 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -22,6 +22,8 @@ void vmem_platform_reset_mem(void *ptr, unsigned size_bytes); void vmem_platform_ondemand_page(void *address, unsigned size_bytes); // To create the mappings in the address space. void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps); +// Delete (unmap) the previously mapped regions +void vmem_platform_delete_mappings(); // Just tries to wipe as much as possible in the relevant area. void vmem_platform_destroy(); // Given a block of data in the .text section, prepares it for JIT action. diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index 921dfd16c..c3b963504 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -235,6 +235,14 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma } } +void vmem_platform_delete_mappings() +{ + if (vmem_4gb_space) + vmem_platform_reset_mem(virt_ram_base, 0x100000000); + else + vmem_platform_reset_mem(virt_ram_base, 0x20000000); +} + // Prepares the code region for JIT operations, thus marking it as RWX bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code_area_rwx) { // Try to map is as RWX, this fails apparently on OSX (and perhaps other systems?) diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp index c5e195746..42cb06d45 100644 --- a/core/windows/win_vmem.cpp +++ b/core/windows/win_vmem.cpp @@ -58,6 +58,9 @@ HANDLE mem_handle = INVALID_HANDLE_VALUE; static HANDLE mem_handle2 = INVALID_HANDLE_VALUE; static char * base_alloc = NULL; +static std::vector unmapped_regions; +static std::vector mapped_regions; + // Implement vmem initialization for RAM, ARAM, VRAM and SH4 context, fpcb etc. // The function supports allocating 512MB or 4GB addr spaces. @@ -75,6 +78,19 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { *sh4rcb_addr = &base_alloc[0]; *vmem_base_addr = &base_alloc[sizeof(Sh4RCB)]; + VirtualFree(base_alloc, 0, MEM_RELEASE); + // Map the SH4CB block too + void *base_ptr = VirtualAlloc(base_alloc, sizeof(Sh4RCB), MEM_RESERVE, PAGE_NOACCESS); + verify(base_ptr == base_alloc); + // Map the rest of the context + void *cntx_ptr = VirtualAlloc((u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb), sizeof(Sh4RCB) - sizeof(p_sh4rcb->fpcb), MEM_COMMIT, PAGE_READWRITE); + verify(cntx_ptr == (u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb)); + + // Reserve the rest of the memory but don't commit it + void *ptr = VirtualAlloc(*vmem_base_addr, memsize - sizeof(Sh4RCB), MEM_RESERVE, PAGE_NOACCESS); + verify(ptr == *vmem_base_addr); + unmapped_regions.push_back(ptr); + return MemType512MB; } @@ -100,13 +116,7 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma // we unmap the whole thing only to remap it later. // Unmap the whole section - VirtualFree(base_alloc, 0, MEM_RELEASE); - - // Map the SH4CB block too - void *base_ptr = VirtualAlloc(base_alloc, sizeof(Sh4RCB), MEM_RESERVE, PAGE_NOACCESS); - verify(base_ptr == base_alloc); - void *cntx_ptr = VirtualAlloc((u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb), sizeof(Sh4RCB) - sizeof(p_sh4rcb->fpcb), MEM_COMMIT, PAGE_READWRITE); - verify(cntx_ptr == (u8*)p_sh4rcb + sizeof(p_sh4rcb->fpcb)); + vmem_platform_delete_mappings(); for (unsigned i = 0; i < nummaps; i++) { unsigned address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; @@ -116,6 +126,7 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma // Unmapped stuff goes with a protected area or memory. Prevent anything from allocating here void *ptr = VirtualAlloc(&virt_ram_base[vmem_maps[i].start_address], address_range_size, MEM_RESERVE, PAGE_NOACCESS); verify(ptr == &virt_ram_base[vmem_maps[i].start_address]); + unmapped_regions.push_back(ptr); } else { // Calculate the number of mirrors @@ -129,11 +140,22 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma void *ptr = MapViewOfFileEx(mem_handle, protection, 0, vmem_maps[i].memoffset, vmem_maps[i].memsize, &virt_ram_base[offset]); verify(ptr == &virt_ram_base[offset]); + mapped_regions.push_back(ptr); } } } } +void vmem_platform_delete_mappings() +{ + for (void *p : mapped_regions) + mem_region_unmap_file(p, 0); + mapped_regions.clear(); + for (void *p : unmapped_regions) + mem_region_release(p, 0); + unmapped_regions.clear(); +} + typedef void* (*mapper_fn) (void *addr, unsigned size); // This is a tempalted function since it's used twice diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index ed9825833..5aa8d399e 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -178,7 +178,7 @@ LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) #endif else { - ERROR_LOG(COMMON, "[GPF]Unhandled access to : %p\n", address); + ERROR_LOG(COMMON, "[GPF]Unhandled access to : %p", address); } return EXCEPTION_CONTINUE_SEARCH; From 52859111332eb436f105ae0f416f4c411661b996 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 10 Jul 2019 20:17:59 +0200 Subject: [PATCH 137/158] Mirror writable aica ram to 8mb in 512mb vmem mode Fixes switching from dc to naomi on windows Should help games reading past end of aica ram (HeadHunter and others) --- core/hw/mem/_vmem.cpp | 7 ++----- core/hw/mem/_vmem.h | 2 -- core/linux/posix_vmem.cpp | 8 -------- core/windows/win_vmem.cpp | 23 +++++++++++------------ 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index b294ccda6..4f23bed76 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -547,10 +547,6 @@ static void _vmem_term_mappings() aica_ram.data = NULL; } } - else - { - vmem_platform_delete_mappings(); - } } void _vmem_init_mappings() @@ -583,7 +579,6 @@ void _vmem_init_mappings() const vmem_mapping mem_mappings[] = { {0x00000000, 0x00800000, 0, 0, false}, // Area 0 -> unused {0x00800000, 0x01000000, MAP_ARAM_START_OFFSET, ARAM_SIZE, false}, // Aica - {0x20000000, 0x20000000+ARAM_SIZE, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, {0x01000000, 0x04000000, 0, 0, false}, // More unused {0x04000000, 0x05000000, MAP_VRAM_START_OFFSET, VRAM_SIZE, true}, // Area 1 (vram, 16MB, wrapped on DC as 2x8MB) {0x05000000, 0x06000000, 0, 0, false}, // 32 bit path (unused) @@ -592,6 +587,8 @@ void _vmem_init_mappings() {0x08000000, 0x0C000000, 0, 0, false}, // Area 2 {0x0C000000, 0x10000000, MAP_RAM_START_OFFSET, RAM_SIZE, true}, // Area 3 (main RAM + 3 mirrors) {0x10000000, 0x20000000, 0, 0, false}, // Area 4-7 (unused) + // This is outside of the 512MB addr space + {0x20000000, 0x20800000, MAP_ARAM_START_OFFSET, ARAM_SIZE, true}, // writable aica ram }; vmem_platform_create_mappings(&mem_mappings[0], ARRAY_SIZE(mem_mappings)); diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index 007d92f4f..d83705497 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -22,8 +22,6 @@ void vmem_platform_reset_mem(void *ptr, unsigned size_bytes); void vmem_platform_ondemand_page(void *address, unsigned size_bytes); // To create the mappings in the address space. void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned nummaps); -// Delete (unmap) the previously mapped regions -void vmem_platform_delete_mappings(); // Just tries to wipe as much as possible in the relevant area. void vmem_platform_destroy(); // Given a block of data in the .text section, prepares it for JIT action. diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index c3b963504..921dfd16c 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -235,14 +235,6 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma } } -void vmem_platform_delete_mappings() -{ - if (vmem_4gb_space) - vmem_platform_reset_mem(virt_ram_base, 0x100000000); - else - vmem_platform_reset_mem(virt_ram_base, 0x20000000); -} - // Prepares the code region for JIT operations, thus marking it as RWX bool vmem_platform_prepare_jit_block(void *code_area, unsigned size, void **code_area_rwx) { // Try to map is as RWX, this fails apparently on OSX (and perhaps other systems?) diff --git a/core/windows/win_vmem.cpp b/core/windows/win_vmem.cpp index 42cb06d45..fbd5aa953 100644 --- a/core/windows/win_vmem.cpp +++ b/core/windows/win_vmem.cpp @@ -66,7 +66,11 @@ static std::vector mapped_regions; // Plase read the POSIX implementation for more information. On Windows this is // rather straightforward. -VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { +VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) +{ + unmapped_regions.reserve(32); + mapped_regions.reserve(32); + // Firt let's try to allocate the in-memory file mem_handle = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, RAM_SIZE_MAX + VRAM_SIZE_MAX + ARAM_SIZE_MAX, 0); @@ -116,7 +120,12 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma // we unmap the whole thing only to remap it later. // Unmap the whole section - vmem_platform_delete_mappings(); + for (void *p : mapped_regions) + mem_region_unmap_file(p, 0); + mapped_regions.clear(); + for (void *p : unmapped_regions) + mem_region_release(p, 0); + unmapped_regions.clear(); for (unsigned i = 0; i < nummaps; i++) { unsigned address_range_size = vmem_maps[i].end_address - vmem_maps[i].start_address; @@ -146,16 +155,6 @@ void vmem_platform_create_mappings(const vmem_mapping *vmem_maps, unsigned numma } } -void vmem_platform_delete_mappings() -{ - for (void *p : mapped_regions) - mem_region_unmap_file(p, 0); - mapped_regions.clear(); - for (void *p : unmapped_regions) - mem_region_release(p, 0); - unmapped_regions.clear(); -} - typedef void* (*mapper_fn) (void *addr, unsigned size); // This is a tempalted function since it's used twice From cb35c80ee74a09a57c5bcbec81b516db44a7dced Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 10 Jul 2019 22:23:26 +0200 Subject: [PATCH 138/158] gl4: still need to update the depth buffer for TRs --- core/rend/gl4/gldraw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index ac207c6ad..f313cabe4 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -103,7 +103,7 @@ static void SetTextureRepeatMode(int index, GLuint dir, u32 clamp, u32 mirror) } template - static void SetGPState(PolyParam* gp, int pass) + static void SetGPState(const PolyParam* gp, int pass) { if (gp->pcw.Texture && gp->tsp.FilterMode > 1) { @@ -234,11 +234,11 @@ template SetCull(gp->isp.CullMode ^ gcflip); //set Z mode, only if required - if (Type == ListType_Punch_Through) + if (Type == ListType_Punch_Through || (pass == 0 && SortingEnabled)) { glcache.DepthFunc(Zfunction[6]); // Greater or equal } - else if (Type == ListType_Opaque) + else if (Type == ListType_Opaque || (pass == 0 && !SortingEnabled)) { glcache.DepthFunc(Zfunction[gp->isp.DepthMode]); } From eb385649223c9dcb2ed3e78f90f996652691a349 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 11 Jul 2019 19:23:21 +0200 Subject: [PATCH 139/158] use exceptions for startup errors --- core/hw/naomi/naomi_cart.cpp | 388 ++++++++++++++++------------------- core/hw/naomi/naomi_cart.h | 8 +- core/nullDC.cpp | 35 +--- core/rend/gui.cpp | 31 +-- core/types.h | 61 +----- 5 files changed, 205 insertions(+), 318 deletions(-) diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index d39eaa34c..0a3d3353d 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -19,6 +19,7 @@ // license:BSD-3-Clause // copyright-holders:MetalliC +#include #include "naomi_cart.h" #include "naomi_regs.h" #include "cfg/cfg.h" @@ -76,7 +77,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive #else std::string basepath = get_readonly_data_path("/"); #endif - Archive *bios_archive = OpenArchive((basepath + filename).c_str()); + std::unique_ptr bios_archive(OpenArchive((basepath + filename).c_str())); bool found_region = false; @@ -99,60 +100,56 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive } else { - ArchiveFile *file = NULL; + std::unique_ptr file; if (child_archive != NULL) - file = child_archive->OpenFile(bios->blobs[romid].filename); - if (file == NULL && parent_archive != NULL) - file = parent_archive->OpenFile(bios->blobs[romid].filename); - if (file == NULL && bios_archive != NULL) - file = bios_archive->OpenFile(bios->blobs[romid].filename); + file.reset(child_archive->OpenFile(bios->blobs[romid].filename)); + if (!file && parent_archive != NULL) + file.reset(parent_archive->OpenFile(bios->blobs[romid].filename)); + if (!file && bios_archive != NULL) + file.reset(bios_archive->OpenFile(bios->blobs[romid].filename)); if (!file) { - ERROR_LOG(NAOMI, "%s: Cannot open %s", filename, bios->blobs[romid].filename); - goto error; + WARN_LOG(NAOMI, "%s: Cannot open %s", filename, bios->blobs[romid].filename); + return false; } - if (bios->blobs[romid].blob_type == Normal) + switch (bios->blobs[romid].blob_type) { - verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); - u32 read = file->Read(sys_rom->data + bios->blobs[romid].offset, bios->blobs[romid].length); - DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); - } - else if (bios->blobs[romid].blob_type == InterleavedWord) - { - u8 *buf = (u8 *)malloc(bios->blobs[romid].length); - if (buf == NULL) + case Normal: { - ERROR_LOG(NAOMI, "malloc failed"); - delete file; - goto error; + verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); + u32 read = file->Read(sys_rom->data + bios->blobs[romid].offset, bios->blobs[romid].length); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); } - verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); - u32 read = file->Read(buf, bios->blobs[romid].length); - u16 *to = (u16 *)(sys_rom->data + bios->blobs[romid].offset); - u16 *from = (u16 *)buf; - for (int i = bios->blobs[romid].length / 2; --i >= 0; to++) - *to++ = *from++; - free(buf); - DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); - } - else + break; + + case InterleavedWord: + { + u8 *buf = (u8 *)malloc(bios->blobs[romid].length); + if (buf == NULL) + throw NaomiCartException(std::string("Memory allocation failed")); + + verify(bios->blobs[romid].offset + bios->blobs[romid].length <= BIOS_SIZE); + u32 read = file->Read(buf, bios->blobs[romid].length); + u16 *to = (u16 *)(sys_rom->data + bios->blobs[romid].offset); + u16 *from = (u16 *)buf; + for (int i = bios->blobs[romid].length / 2; --i >= 0; to++) + *to++ = *from++; + free(buf); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", bios->blobs[romid].filename, read, bios->blobs[romid].offset); + } + break; + + default: die("Unknown blob type\n"); - delete file; + break; + } } } - if (bios_archive != NULL) - delete bios_archive; - if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) // Reload the writeable portion of the FlashROM sys_rom->Reload(); return found_region; - -error: - if (bios_archive != NULL) - delete bios_archive; - return false; } static Game *FindGame(const char *filename) @@ -182,22 +179,21 @@ static Game *FindGame(const char *filename) return &Games[gameid]; } -static bool naomi_cart_LoadZip(char *filename) +static void naomi_cart_LoadZip(const char *filename) { Game *game = FindGame(filename); if (game == NULL) - { - ERROR_LOG(NAOMI, "Unknown game %s", filename); - return false; - } - Archive *archive = OpenArchive(filename); + throw NaomiCartException("Unknown game"); + + // Open archive and parent archive if any + std::unique_ptr archive(OpenArchive(filename)); if (archive != NULL) INFO_LOG(NAOMI, "Opened %s", filename); - Archive *parent_archive = NULL; + std::unique_ptr parent_archive; if (game->parent_name != NULL) { - parent_archive = OpenArchive((get_game_dir() + game->parent_name).c_str()); + parent_archive.reset(OpenArchive((get_game_dir() + game->parent_name).c_str())); if (parent_archive != NULL) INFO_LOG(NAOMI, "Opened %s", game->parent_name); } @@ -205,166 +201,155 @@ static bool naomi_cart_LoadZip(char *filename) if (archive == NULL && parent_archive == NULL) { if (game->parent_name != NULL) - ERROR_LOG(NAOMI, "Cannot open %s or %s", filename, game->parent_name); + throw NaomiCartException(std::string("Cannot open ") + filename + std::string(" or ") + game->parent_name); else - ERROR_LOG(NAOMI, "Cannot open %s", filename); - return false; + throw NaomiCartException(std::string("Cannot open ") + filename); } + // Load the BIOS const char *bios = "naomi"; if (game->bios != NULL) bios = game->bios; u32 region_flag = settings.dreamcast.region; if (region_flag > game->region_flag) region_flag = game->region_flag; - if (!naomi_LoadBios(bios, archive, parent_archive, region_flag)) + if (!naomi_LoadBios(bios, archive.get(), parent_archive.get(), region_flag)) { WARN_LOG(NAOMI, "Warning: Region %d bios not found in %s", region_flag, bios); - if (!naomi_LoadBios(bios, archive, parent_archive, -1)) + if (!naomi_LoadBios(bios, archive.get(), parent_archive.get(), -1)) { // If a specific BIOS is needed for this game, fail. if (game->bios != NULL || !bios_loaded) - { - ERROR_LOG(NAOMI, "Error: cannot load BIOS. Exiting"); - return false; - } + throw NaomiCartException(std::string("Error: cannot load BIOS ") + (game->bios != NULL ? game->bios : "naomi.zip")); + // otherwise use the default BIOS } } bios_loaded = true; - switch (game->cart_type) - { - case M1: - CurrentCartridge = new M1Cartridge(game->size); - break; - case M2: - CurrentCartridge = new M2Cartridge(game->size); - break; - case M4: - CurrentCartridge = new M4Cartridge(game->size); - break; - case AW: - CurrentCartridge = new AWCartridge(game->size); - break; - case GD: + // Now load the cartridge data + try { + switch (game->cart_type) { - GDCartridge *gdcart = new GDCartridge(game->size); - gdcart->SetGDRomName(game->gdrom_name); - CurrentCartridge = gdcart; - } - break; - default: - die("Unsupported cartridge type\n"); - break; - } - CurrentCartridge->SetKey(game->key); - NaomiGameInputs = game->inputs; - - for (int romid = 0; game->blobs[romid].filename != NULL; romid++) - { - u32 len = game->blobs[romid].length; - - if (game->blobs[romid].blob_type == Copy) - { - u8 *dst = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); - u8 *src = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].src_offset, len); - memcpy(dst, src, game->blobs[romid].length); - DEBUG_LOG(NAOMI, "Copied: %x bytes from %07x to %07x", game->blobs[romid].length, game->blobs[romid].src_offset, game->blobs[romid].offset); - } - else - { - ArchiveFile* file = NULL; - if (archive != NULL) - file = archive->OpenFile(game->blobs[romid].filename); - if (file == NULL && parent_archive != NULL) - file = parent_archive->OpenFile(game->blobs[romid].filename); - if (!file) { - WARN_LOG(NAOMI, "%s: Cannot open %s", filename, game->blobs[romid].filename); - if (game->blobs[romid].blob_type != Eeprom) - // Default eeprom file is optional - goto error; - else - continue; + case M1: + CurrentCartridge = new M1Cartridge(game->size); + break; + case M2: + CurrentCartridge = new M2Cartridge(game->size); + break; + case M4: + CurrentCartridge = new M4Cartridge(game->size); + break; + case AW: + CurrentCartridge = new AWCartridge(game->size); + break; + case GD: + { + GDCartridge *gdcart = new GDCartridge(game->size); + gdcart->SetGDRomName(game->gdrom_name); + CurrentCartridge = gdcart; } - if (game->blobs[romid].blob_type == Normal) + break; + default: + die("Unsupported cartridge type\n"); + break; + } + CurrentCartridge->SetKey(game->key); + NaomiGameInputs = game->inputs; + + for (int romid = 0; game->blobs[romid].filename != NULL; romid++) + { + u32 len = game->blobs[romid].length; + + if (game->blobs[romid].blob_type == Copy) { u8 *dst = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); - u32 read = file->Read(dst, game->blobs[romid].length); - DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); - } - else if (game->blobs[romid].blob_type == InterleavedWord) - { - u8 *buf = (u8 *)malloc(game->blobs[romid].length); - if (buf == NULL) - { - ERROR_LOG(NAOMI, "malloc failed"); - delete file; - goto error; - } - u32 read = file->Read(buf, game->blobs[romid].length); - u16 *to = (u16 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); - u16 *from = (u16 *)buf; - for (int i = game->blobs[romid].length / 2; --i >= 0; to++) - *to++ = *from++; - free(buf); - DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); - } - else if (game->blobs[romid].blob_type == Key) - { - u8 *buf = (u8 *)malloc(game->blobs[romid].length); - if (buf == NULL) - { - ERROR_LOG(NAOMI, "malloc failed"); - delete file; - goto error; - } - u32 read = file->Read(buf, game->blobs[romid].length); - CurrentCartridge->SetKeyData(buf); - DEBUG_LOG(NAOMI, "Loaded %s: %x bytes cart key", game->blobs[romid].filename, read); - } - else if (game->blobs[romid].blob_type == Eeprom) - { - naomi_default_eeprom = (u8 *)malloc(game->blobs[romid].length); - if (naomi_default_eeprom == NULL) - { - ERROR_LOG(NAOMI, "malloc failed"); - delete file; - goto error; - } - u32 read = file->Read(naomi_default_eeprom, game->blobs[romid].length); - DEBUG_LOG(NAOMI, "Loaded %s: %x bytes default eeprom", game->blobs[romid].filename, read); + u8 *src = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].src_offset, len); + memcpy(dst, src, game->blobs[romid].length); + DEBUG_LOG(NAOMI, "Copied: %x bytes from %07x to %07x", game->blobs[romid].length, game->blobs[romid].src_offset, game->blobs[romid].offset); } else - die("Unknown blob type\n"); - delete file; + { + std::unique_ptr file; + if (archive != NULL) + file.reset(archive->OpenFile(game->blobs[romid].filename)); + if (file == NULL && parent_archive != NULL) + file.reset(parent_archive->OpenFile(game->blobs[romid].filename)); + if (!file) { + WARN_LOG(NAOMI, "%s: Cannot open %s", filename, game->blobs[romid].filename); + if (game->blobs[romid].blob_type != Eeprom) + // Default eeprom file is optional + throw NaomiCartException(std::string("Cannot find ") + game->blobs[romid].filename); + else + continue; + } + switch (game->blobs[romid].blob_type) + { + case Normal: + { + u8 *dst = (u8 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); + u32 read = file->Read(dst, game->blobs[romid].length); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); + } + break; + + case InterleavedWord: + { + u8 *buf = (u8 *)malloc(game->blobs[romid].length); + if (buf == NULL) + throw NaomiCartException(std::string("Memory allocation failed")); + + u32 read = file->Read(buf, game->blobs[romid].length); + u16 *to = (u16 *)CurrentCartridge->GetPtr(game->blobs[romid].offset, len); + u16 *from = (u16 *)buf; + for (int i = game->blobs[romid].length / 2; --i >= 0; to++) + *to++ = *from++; + free(buf); + DEBUG_LOG(NAOMI, "Mapped %s: %x bytes (interleaved word) at %07x", game->blobs[romid].filename, read, game->blobs[romid].offset); + } + break; + + case Key: + { + u8 *buf = (u8 *)malloc(game->blobs[romid].length); + if (buf == NULL) + throw NaomiCartException(std::string("Memory allocation failed")); + + u32 read = file->Read(buf, game->blobs[romid].length); + CurrentCartridge->SetKeyData(buf); + DEBUG_LOG(NAOMI, "Loaded %s: %x bytes cart key", game->blobs[romid].filename, read); + } + break; + + case Eeprom: + { + naomi_default_eeprom = (u8 *)malloc(game->blobs[romid].length); + if (naomi_default_eeprom == NULL) + throw NaomiCartException(std::string("Memory allocation failed")); + + u32 read = file->Read(naomi_default_eeprom, game->blobs[romid].length); + DEBUG_LOG(NAOMI, "Loaded %s: %x bytes default eeprom", game->blobs[romid].filename, read); + } + break; + + default: + die("Unknown blob type\n"); + break; + } + } } - } - if (archive != NULL) - delete archive; - if (parent_archive != NULL) - delete parent_archive; - try { CurrentCartridge->Init(); - } catch (NaomiCartException& e) { - ERROR_LOG(NAOMI, "%s", e.reason.c_str()); - return false; + + strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); + NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id); + + } catch (ReicastException& ex) { + delete CurrentCartridge; + CurrentCartridge = NULL; + + throw ex; } - - strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); - NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id); - - return true; - -error: - if (archive != NULL) - delete archive; - if (parent_archive != NULL) - delete parent_archive; - delete CurrentCartridge; - CurrentCartridge = NULL; - return false; } #if HOST_OS == OS_WINDOWS @@ -373,7 +358,7 @@ error: #define CloseFile(f) close(f) #endif -bool naomi_cart_LoadRom(char* file) +void naomi_cart_LoadRom(const char* file) { INFO_LOG(NAOMI, "nullDC-Naomi rom loader v1.2"); @@ -396,12 +381,15 @@ bool naomi_cart_LoadRom(char* file) u32 setsize = 0; bool raw_bin_file = false; - char *pdot = strrchr(file, '.'); + const char *pdot = strrchr(file, '.'); if (pdot != NULL && (!strcmp(pdot, ".zip") || !strcmp(pdot, ".ZIP") || !strcmp(pdot, ".7z") || !strcmp(pdot, ".7Z"))) - return naomi_cart_LoadZip(file); + { + naomi_cart_LoadZip(file); + return; + } // Try to load BIOS from naomi.zip if (!naomi_LoadBios("naomi", NULL, NULL, settings.dreamcast.region)) @@ -410,10 +398,7 @@ bool naomi_cart_LoadRom(char* file) if (!naomi_LoadBios("naomi", NULL, NULL, -1)) { if (!bios_loaded) - { - ERROR_LOG(NAOMI, "Error: cannot load BIOS. Exiting"); - return false; - } + throw new ReicastException("Error: cannot load BIOS from naomi.zip"); } } @@ -426,13 +411,13 @@ bool naomi_cart_LoadRom(char* file) FILE* fl = fopen(t, "r"); if (!fl) - return false; + throw new ReicastException("Error: can't open " + std::string(t)); char* line = fgets(t, 512, fl); if (!line) { fclose(fl); - return false; + throw new ReicastException("Error: Invalid LST file"); } char* eon = strstr(line, "\n"); @@ -447,7 +432,7 @@ bool naomi_cart_LoadRom(char* file) if (!line) { fclose(fl); - return false; + throw new ReicastException("Error: Invalid LST file"); } RomSize = 0; @@ -476,7 +461,7 @@ bool naomi_cart_LoadRom(char* file) // BIN loading FILE* fp = fopen(t, "rb"); if (fp == NULL) - return false; + throw new ReicastException("Error: can't open " + std::string(t)); fseek(fp, 0, SEEK_END); u32 file_size = ftell(fp); @@ -569,7 +554,7 @@ bool naomi_cart_LoadRom(char* file) for (size_t i = 0; i < files.size(); i++) if (RomCacheMap[i] != INVALID_FD) CloseFile(RomCacheMap[i]); - return false; + throw new ReicastException("Error: Failed to load BIN/DAT file"); } //We have all file mapping objects, we start to map the ram @@ -592,7 +577,7 @@ bool naomi_cart_LoadRom(char* file) if (!mapped) { ERROR_LOG(NAOMI, "-Mapping ROM FAILED: %s @ %08x size %x", files[i].c_str(), fstart[i], fsize[i]); - return false; + throw new ReicastException("Memory mapping of ROM failed"); } } } @@ -604,7 +589,7 @@ bool naomi_cart_LoadRom(char* file) strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str()); NOTICE_LOG(NAOMI, "NAOMI GAME ID [%s]", naomi_game_id); - return true; + return; } void naomi_cart_Close() @@ -626,23 +611,6 @@ void naomi_cart_Close() bios_loaded = false; } -bool naomi_cart_SelectFile() -{ - char SelectedFile[512]; - - cfgLoadStr("config", "image", SelectedFile, "null"); - - if (!naomi_cart_LoadRom(SelectedFile)) - { - ERROR_LOG(NAOMI, "Cannot load %s: error %d", SelectedFile, errno); - cfgSetVirtual("config", "image", ""); - - return false; - } - - return true; -} - int naomi_cart_GetPlatform(const char *path) { Game *game = FindGame(path); diff --git a/core/hw/naomi/naomi_cart.h b/core/hw/naomi/naomi_cart.h index c1319a98b..e4364a8fc 100644 --- a/core/hw/naomi/naomi_cart.h +++ b/core/hw/naomi/naomi_cart.h @@ -85,15 +85,13 @@ private: u8 naomi_cart_ram[64 * 1024]; }; -class NaomiCartException +class NaomiCartException : public ReicastException { public: - NaomiCartException(std::string reason) : reason(reason) {} - - std::string reason; + NaomiCartException(std::string reason) : ReicastException(reason) {} }; -bool naomi_cart_SelectFile(); +void naomi_cart_LoadRom(const char* file); void naomi_cart_Close(); int naomi_cart_GetPlatform(const char *path); diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 5031f5369..cb7134a1b 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -400,18 +400,18 @@ void set_platform(int platform) _vmem_init_mappings(); } -static int dc_init() +static void dc_init() { static bool init_done; if (init_done) - return 0; + return; // Default platform set_platform(DC_PLATFORM_DREAMCAST); - if (plugins_Init()) - return -3; + plugins_Init(); + #if FEAT_SHREC != DYNAREC_NONE Get_Sh4Recompiler(&sh4_cpu); sh4_cpu.Init(); // Also initialize the interpreter @@ -430,8 +430,6 @@ static int dc_init() mem_Init(); init_done = true; - - return 0; } bool game_started; @@ -453,14 +451,12 @@ static int get_game_platform(const char *path) return DC_PLATFORM_DREAMCAST; } -int dc_start_game(const char *path) +void dc_start_game(const char *path) { if (path != NULL) cfgSetVirtual("config", "image", path); - int rc = dc_init(); - if (rc != 0) - return rc; + dc_init(); set_platform(get_game_platform(path)); mem_map_default(); @@ -476,20 +472,14 @@ int dc_start_game(const char *path) if (settings.bios.UseReios) { if (!LoadHle(get_readonly_data_path(DATA_PATH))) - { - ERROR_LOG(BOOT, "Cannot init HLE BIOS"); - return -5; - } - else - { - NOTICE_LOG(BOOT, "Did not load bios, using reios"); - } + throw ReicastException("Failed to initialize HLE BIOS"); + + NOTICE_LOG(BOOT, "Did not load BIOS, using reios"); } else #endif { - ERROR_LOG(BOOT, "Cannot find BIOS files"); - return -5; + throw ReicastException("Cannot find BIOS files"); } } } @@ -512,8 +502,7 @@ int dc_start_game(const char *path) } else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) { - if (!naomi_cart_SelectFile()) - return -6; + naomi_cart_LoadRom(path); LoadCustom(); if (settings.platform.system == DC_PLATFORM_NAOMI) mcfg_CreateNAOMIJamma(); @@ -522,8 +511,6 @@ int dc_start_game(const char *path) } game_started = true; dc_resume(); - - return 0; } bool dc_is_running() diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index e61a8679a..e87b3a4fd 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -49,7 +49,7 @@ extern void dc_savestate(); extern void dc_stop(); extern void dc_reset(bool manual); extern void dc_resume(); -extern int dc_start_game(const char *path); +extern void dc_start_game(const char *path); extern void UpdateInputState(u32 port); extern bool game_started; @@ -349,14 +349,6 @@ static void gui_display_commands() cfgSetVirtual("config", "image", ""); } -#if 0 - ImGui::NextColumn(); - if (ImGui::Button("RenderDone Int", ImVec2(150 * scaling, 50 * scaling))) - { - asic_RaiseInterrupt(holly_RENDER_DONE); - gui_state = Closed; - } -#endif ImGui::End(); ImGui::Render(); @@ -1413,25 +1405,14 @@ static void gui_display_demo() static void gui_start_game(const std::string& path) { - int rc = dc_start_game(path.empty() ? NULL : path.c_str()); - if (rc != 0) - { + try { + dc_start_game(path.empty() ? NULL : path.c_str()); + } catch (ReicastException& ex) { + ERROR_LOG(BOOT, "%s", ex.reason.c_str()); + error_msg = ex.reason; gui_state = Main; game_started = false; cfgSetVirtual("config", "image", ""); - switch (rc) { - case -3: - error_msg = "Audio/video initialization failed"; - break; - case -5: - error_msg = "Cannot find BIOS files"; - break; - case -6: - error_msg = "Cannot load NAOMI rom or BIOS"; - break; - default: - break; - } } } diff --git a/core/types.h b/core/types.h index a179a01d8..38b153058 100644 --- a/core/types.h +++ b/core/types.h @@ -271,60 +271,6 @@ void libARM_InterruptChange(u32 bits,u32 L); void libCore_CDDA_Sector(s16* sector); -//passed on AICA init call - - -//Ram/Regs are managed by plugin , exept RTC regs (managed by main emu) - -//****************************************************** -//******************** ARM Sound CPU ******************* -//****************************************************** - -//****************************************************** -//****************** Maple devices ****************** -//****************************************************** - - -enum MapleDeviceCreationFlags -{ - MDCF_None=0, - MDCF_Hotplug=1 -}; - -struct maple_subdevice_instance; -struct maple_device_instance; - -//buffer_out_len and responce need to be filled w/ proper info by the plugin -//buffer_in must not be edited (its direct pointer on ram) -//output buffer must contain the frame data , the frame header is generated by the maple routing code -//typedef u32 FASTCALL MapleSubDeviceDMAFP(void* device_instance,u32 Command,u32* buffer_in,u32 buffer_in_len,u32* buffer_out,u32& buffer_out_len); -typedef u32 MapleDeviceDMAFP(void* device_instance,u32 Command,u32* buffer_in,u32 buffer_in_len,u32* buffer_out,u32& buffer_out_len); - -struct maple_subdevice_instance -{ - //port - u8 port; - //user data - void* data; - //MapleDeviceDMA - MapleDeviceDMAFP* dma; - bool connected; - u32 reserved; //reserved for the emu , DO NOT EDIT -}; -struct maple_device_instance -{ - //port - u8 port; - //user data - void* data; - //MapleDeviceDMA - MapleDeviceDMAFP* dma; - bool connected; - - maple_subdevice_instance subdevices[5]; -}; - - //includes from CRT #include #include @@ -914,3 +860,10 @@ struct OnLoad #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif +class ReicastException +{ +public: + ReicastException(std::string reason) : reason(reason) {} + + std::string reason; +}; From 4884dbc4006c5b75e30bfa9741b6e4279fbd274a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 11 Jul 2019 19:55:03 +0200 Subject: [PATCH 140/158] get rid of DC_PLATFORM and build flavors --- core/build.h | 9 --------- core/types.h | 13 +------------ shell/android-studio/reicast/build.gradle | 5 ----- shell/cmake/config.cmake | 8 -------- shell/linux/Makefile | 23 +++-------------------- 5 files changed, 4 insertions(+), 54 deletions(-) diff --git a/core/build.h b/core/build.h index c74634071..f3e06236e 100755 --- a/core/build.h +++ b/core/build.h @@ -227,11 +227,6 @@ #error Invalid Target: TARGET_* not defined #endif -#if defined(TARGET_NAOMI) - #define DC_PLATFORM DC_PLATFORM_NAOMI - #undef TARGET_NAOMI -#endif - #if defined(TARGET_NO_REC) #define FEAT_SHREC DYNAREC_NONE #define FEAT_AREC DYNAREC_NONE @@ -267,10 +262,6 @@ //defaults -#ifndef DC_PLATFORM - #define DC_PLATFORM DC_PLATFORM_DREAMCAST -#endif - #ifndef FEAT_SHREC #define FEAT_SHREC DYNAREC_JIT #endif diff --git a/core/types.h b/core/types.h index 38b153058..8ce7eccdc 100644 --- a/core/types.h +++ b/core/types.h @@ -339,18 +339,7 @@ using namespace std; #endif -#if DC_PLATFORM==DC_PLATFORM_DREAMCAST - #define VER_EMUNAME "Flycast" -#elif DC_PLATFORM==DC_PLATFORM_DEV_UNIT - #define VER_EMUNAME "Flycast-DevKit-SET5.21" -#elif DC_PLATFORM==DC_PLATFORM_NAOMI - #define VER_EMUNAME "Flycast-Naomi" -#elif DC_PLATFORM==DC_PLATFORM_ATOMISWAVE - #define VER_EMUNAME "Flycast-AtomisWave" -#else - #error unknown target platform -#endif - +#define VER_EMUNAME "Flycast" #define VER_FULLNAME VER_EMUNAME " git" _X_x_X_MMU_VER_STR " (built " __DATE__ "@" __TIME__ ")" #define VER_SHORTNAME VER_EMUNAME " git" _X_x_X_MMU_VER_STR diff --git a/shell/android-studio/reicast/build.gradle b/shell/android-studio/reicast/build.gradle index 40dfbbc91..f097fd3ea 100644 --- a/shell/android-studio/reicast/build.gradle +++ b/shell/android-studio/reicast/build.gradle @@ -71,11 +71,6 @@ android { productFlavors { dreamcast { } - naomi { - applicationId = "com.flycast.emulator.naomi" - versionNameSuffix " Naomi" - externalNativeBuild { ndkBuild { arguments "NAOMI=1" } } - } } externalNativeBuild { diff --git a/shell/cmake/config.cmake b/shell/cmake/config.cmake index 2c0967191..a45b611eb 100644 --- a/shell/cmake/config.cmake +++ b/shell/cmake/config.cmake @@ -311,14 +311,6 @@ set(CMAKE_C_FLAGS " ${_C_FLAGS}") # ${CMAKE_C_FLAGS} -- these hold default VC set(CMAKE_CXX_FLAGS " ${_CXX_FLAGS}") # ${CMAKE_CXX_FLAGS} - -#if defined(TARGET_NAOMI) - #define DC_PLATFORM DC_PLATFORM_NAOMI - #undef TARGET_NAOMI -#endif - - - #if defined(TARGET_NO_NIXPROF) #define FEAT_HAS_NIXPROF 0 #endif diff --git a/shell/linux/Makefile b/shell/linux/Makefile index 9c8caa2f8..b34bf5533 100644 --- a/shell/linux/Makefile +++ b/shell/linux/Makefile @@ -400,26 +400,9 @@ ifdef DEBUGFAST endif EXECUTABLE_STRIPPED=nosym-reicast.$(PLATFORM_EXT) -ifdef NAOMI - CFLAGS += -D TARGET_NAOMI - DC_PLATFORM=naomi - EXECUTABLE=reicast_naomi.$(PLATFORM_EXT) - EXECUTABLE_NAME=reicast-naomi -else ifdef ATOMISWAVE - CFLAGS += -D DC_PLATFORM=DC_PLATFORM_ATOMISWAVE - DC_PLATFORM=atomiswave - EXECUTABLE=reicast_awave.$(PLATFORM_EXT) - EXECUTABLE_NAME=reicast-awave -else ifdef DISPFRAME - CFLAGS += -D TARGET_DISPFRAME #-D TARGET_NAOMI - DC_PLATFORM=dispframe - EXECUTABLE=dispframe.$(PLATFORM_EXT) - EXECUTABLE_NAME=dispframe -else - DC_PLATFORM=dreamcast - EXECUTABLE=reicast.$(PLATFORM_EXT) - EXECUTABLE_NAME=reicast -endif +DC_PLATFORM=dreamcast +EXECUTABLE=reicast.$(PLATFORM_EXT) +EXECUTABLE_NAME=reicast ifndef NOT_ARM AS=${CC_PREFIX}gcc From 60ec054b594d3124b24a18a10454a171f8fdc7a1 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 12 Jul 2019 15:34:10 +0200 Subject: [PATCH 141/158] support for VQ compressed paletted textures --- core/rend/TexCache.h | 7 +++++++ core/rend/gles/gles.h | 5 ++--- core/rend/gles/gltex.cpp | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/core/rend/TexCache.h b/core/rend/TexCache.h index cfda1fd84..b126b2c3d 100644 --- a/core/rend/TexCache.h +++ b/core/rend/TexCache.h @@ -608,10 +608,17 @@ template void texture_VQ, u16>(PixelBuffer* pb,u8* p_in, #define tex4444_VQ texture_VQ, u16> #define texYUV422_VQ texture_VQ, u32> #define texBMP_VQ texture_VQ, u16> +// According to the documentation, a texture cannot be compressed and use +// a palette at the same time. However the hardware displays them +// just fine. +#define texPAL4_VQ texture_VQ, u16> +#define texPAL8_VQ texture_VQ, u16> #define tex565_VQ32 texture_VQ, u32> #define tex1555_VQ32 texture_VQ, u32> #define tex4444_VQ32 texture_VQ, u32> +#define texPAL4_VQ32 texture_VQ, u32> +#define texPAL8_VQ32 texture_VQ, u32> void DePosterize(u32* source, u32* dest, int width, int height); void UpscalexBRZ(int factor, u32* source, u32* dest, int width, int height, bool has_alpha); diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 430734527..46fea628c 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -269,11 +269,10 @@ struct TextureCacheData u32 Updates; + u32 palette_index; //used for palette updates u32 palette_hash; // Palette hash at time of last update - u32 indirect_color_ptr; //palette color table index for pal. tex - //VQ quantizers table for VQ tex - //a texture can't be both VQ and PAL at the same time + u32 vq_codebook; // VQ quantizers table for compressed textures u32 texture_hash; // xxhash of texture data, used for custom textures u32 old_texture_hash; // legacy hash u8* volatile custom_image_data; // loaded custom image data diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index e83c6a882..8f6507830 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -53,8 +53,8 @@ PvrTexInfo format[8]= {"4444", 16, GL_UNSIGNED_SHORT_4_4_4_4, tex4444_PL, tex4444_TW, tex4444_VQ, tex4444_PL32, tex4444_TW32, tex4444_VQ32 }, //4444 {"yuv", 16, GL_UNSIGNED_BYTE, NULL, NULL, NULL, texYUV422_PL, texYUV422_TW, texYUV422_VQ }, //yuv {"bumpmap", 16, GL_UNSIGNED_SHORT_4_4_4_4, texBMP_PL, texBMP_TW, texBMP_VQ, NULL}, //bump map - {"pal4", 4, 0, 0, texPAL4_TW, 0, NULL, texPAL4_TW32, NULL }, //pal4 - {"pal8", 8, 0, 0, texPAL8_TW, 0, NULL, texPAL8_TW32, NULL }, //pal8 + {"pal4", 4, 0, 0, texPAL4_TW, texPAL4_VQ, NULL, texPAL4_TW32, texPAL4_VQ32 }, //pal4 + {"pal8", 8, 0, 0, texPAL8_TW, texPAL8_VQ, NULL, texPAL8_TW32, texPAL8_VQ32 }, //pal8 {"ns/1555", 0}, // Not supported (1555) }; @@ -168,14 +168,14 @@ void TextureCacheData::Create(bool isGL) h=8<bpp==4) - indirect_color_ptr=tcw.PalSelect<<4; - else if (tex->bpp==8) - indirect_color_ptr=(tcw.PalSelect>>4)<<8; + if (tex->bpp == 4) + palette_index = tcw.PalSelect << 4; + else if (tex->bpp == 8) + palette_index = (tcw.PalSelect >> 4) << 8; //VQ table (if VQ tex) if (tcw.VQ_Comp) - indirect_color_ptr=sa; + vq_codebook = sa; //Convert a pvr texture into OpenGL switch (tcw.PixelFmt) @@ -214,7 +214,7 @@ void TextureCacheData::Create(bool isGL) if (tcw.VQ_Comp) { verify(tex->VQ != NULL || tex->VQ32 != NULL); - indirect_color_ptr=sa; + vq_codebook = sa; if (tcw.MipMapped) sa+=MipPoint[tsp.TexU]; texconv = tex->VQ; @@ -271,8 +271,8 @@ void TextureCacheData::Update() palette_hash = pal_hash_256[tcw.PalSelect >> 4]; } - palette_index=indirect_color_ptr; //might be used if pal. tex - vq_codebook=(u8*)&vram[indirect_color_ptr]; //might be used if VQ tex + ::palette_index = this->palette_index; // might be used if pal. tex + ::vq_codebook = &vram[vq_codebook]; // might be used if VQ tex //texture conversion work u32 stride=w; From 4f8e18215b0a29a7ac23b90b15b678c1d685ea60 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 12 Jul 2019 17:20:43 +0200 Subject: [PATCH 142/158] Fixed savestates: restore compatibility with lr and master Add new maple devices from lr Clean up shil.cpp --- core/hw/aica/sgc_if.cpp | 4 +- core/hw/flashrom/flashrom.h | 4 +- core/hw/maple/maple_cfg.cpp | 38 +- core/hw/maple/maple_cfg.h | 2 +- core/hw/maple/maple_devs.cpp | 4 +- core/hw/maple/maple_devs.h | 22 + core/hw/sh4/dyna/shil.cpp | 1000 +------------------------------ core/hw/sh4/sh4_interrupts.cpp | 2 +- core/nullDC.cpp | 15 +- core/serialize.cpp | 1011 +++++++------------------------- 10 files changed, 284 insertions(+), 1818 deletions(-) diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 5dd37a729..5de996378 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -1179,9 +1179,6 @@ void WriteCommonReg8(u32 reg,u32 data) s16 cdda_sector[CDDA_SIZE]={0}; u32 cdda_index=CDDA_SIZE<<1; - -SampleType mxlr[64]; - u32 samples_gen; //no DSP for now in this version @@ -1192,6 +1189,7 @@ void AICA_Sample32() return; } + SampleType mxlr[64]; memset(mxlr,0,sizeof(mxlr)); //Generate 32 samples for each channel, before moving to next channel diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index c47e596d4..078a44069 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -644,15 +644,15 @@ private: virtual bool Serialize(void **data, unsigned int *total_size) override { - REICAST_SA(&this->data[write_protect_size], size - write_protect_size); REICAST_S(state); + REICAST_SA(&this->data[write_protect_size], size - write_protect_size); return true; } virtual bool Unserialize(void **data, unsigned int *total_size) override { - REICAST_USA(&this->data[write_protect_size], size - write_protect_size); REICAST_US(state); + REICAST_USA(&this->data[write_protect_size], size - write_protect_size); return true; } }; diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index b71fd2f5e..bddf40e0b 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -245,7 +245,7 @@ void mcfg_SerializeDevices(void **data, unsigned int *total_size) } } -void mcfg_UnserializeDevices(void **data, unsigned int *total_size) +void mcfg_UnserializeDevices(void **data, unsigned int *total_size, bool old) { mcfg_DestroyDevices(); @@ -256,6 +256,42 @@ void mcfg_UnserializeDevices(void **data, unsigned int *total_size) MapleDeviceType device_type = (MapleDeviceType)**p; *p = *p + 1; *total_size = *total_size + 1; + if (old) + { + switch (device_type) + { + case OldMapleDeviceType::MDT_None: + device_type = MDT_None; + break; + case OldMapleDeviceType::MDT_SegaController: + device_type = MDT_SegaController; + break; + case OldMapleDeviceType::MDT_SegaVMU: + device_type = MDT_SegaVMU; + break; + case OldMapleDeviceType::MDT_PurupuruPack: + device_type = MDT_PurupuruPack; + break; + case OldMapleDeviceType::MDT_Microphone: + device_type = MDT_Microphone; + break; + case OldMapleDeviceType::MDT_Keyboard: + device_type = MDT_Keyboard; + break; + case OldMapleDeviceType::MDT_Mouse: + device_type = MDT_Mouse; + break; + case OldMapleDeviceType::MDT_LightGun: + device_type = MDT_LightGun; + break; + case OldMapleDeviceType::MDT_NaomiJamma: + device_type = MDT_NaomiJamma; + break; + default: + die("Invalid maple device type"); + break; + } + } if (device_type != MDT_None) { mcfg_Create(device_type, i, j); diff --git a/core/hw/maple/maple_cfg.h b/core/hw/maple/maple_cfg.h index 299117bb6..3dce39645 100644 --- a/core/hw/maple/maple_cfg.h +++ b/core/hw/maple/maple_cfg.h @@ -64,6 +64,6 @@ void mcfg_CreateAtomisWaveControllers(); void mcfg_DestroyDevices(); void mcfg_SerializeDevices(void **data, unsigned int *total_size); -void mcfg_UnserializeDevices(void **data, unsigned int *total_size); +void mcfg_UnserializeDevices(void **data, unsigned int *total_size, bool old_type_numbering); bool maple_atomiswave_coin_chute(int slot); diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index b7ecc68f1..a745a748c 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -2657,7 +2657,9 @@ maple_device* maple_Create(MapleDeviceType type) break; default: - return 0; + ERROR_LOG(MAPLE, "Invalid device type %d", type); + die("Invalid maple device type"); + break; } return rv; diff --git a/core/hw/maple/maple_devs.h b/core/hw/maple/maple_devs.h index ec45b4986..ce924ce9e 100755 --- a/core/hw/maple/maple_devs.h +++ b/core/hw/maple/maple_devs.h @@ -1,6 +1,27 @@ #pragma once #include "types.h" +enum MapleDeviceType +{ + MDT_SegaController, + + MDT_SegaVMU, + MDT_Microphone, + MDT_PurupuruPack, + MDT_AsciiStick, + MDT_Keyboard, + MDT_Mouse, + MDT_LightGun, + MDT_TwinStick, + + MDT_NaomiJamma, + + MDT_None, + MDT_Count +}; + +namespace OldMapleDeviceType +{ enum MapleDeviceType { MDT_SegaController, @@ -17,6 +38,7 @@ enum MapleDeviceType MDT_None, MDT_Count }; +} enum NAOMI_KEYS { diff --git a/core/hw/sh4/dyna/shil.cpp b/core/hw/sh4/dyna/shil.cpp index 628a453fc..eb371b1d7 100644 --- a/core/hw/sh4/dyna/shil.cpp +++ b/core/hw/sh4/dyna/shil.cpp @@ -1,876 +1,10 @@ -/* - Some WIP optimisation stuff and maby helper functions for shil -*/ - #include -#include -#include #include "types.h" -#include "shil.h" -#include "decoder.h" #include "hw/sh4/sh4_mem.h" -#include "blockmanager.h" -u32 RegisterWrite[sh4_reg_count]; -u32 RegisterRead[sh4_reg_count]; - -void RegReadInfo(shil_param p,size_t ord) -{ - if (p.is_reg()) - { - for (u32 i=0; i=RegisterRead[p._reg+i] && RegisterWrite[p._reg+i]!=0xFFFFFFFF) //if last read was before last write, and there was a last write - { - DEBUG_LOG(DYNAREC, "DEAD OPCODE %d %zd!\n",RegisterWrite[p._reg+i],ord); - ops[RegisterWrite[p._reg+i]].Flow=1; //the last write was unused - } - RegisterWrite[p._reg+i]=ord; - } - } -} -u32 fallback_blocks; -u32 total_blocks; -u32 REMOVED_OPS; - -bool isdst(shil_opcode* op,Sh4RegType rd) -{ - return (op->rd.is_r32() && op->rd._reg==rd) || (op->rd2.is_r32() && op->rd2._reg==rd); -} - -//really hacky ~ -//Isn't this now obsolete anyway ? (constprop pass should include it ..) -// -> constprop has some small stability issues still, not ready to be used on ip/bios fully yet -void PromoteConstAddress(RuntimeBlockInfo* blk) -{ - bool is_const=false; - u32 value; - - total_blocks++; - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - if (is_const && op->op==shop_readm && op->rs1.is_reg() && op->rs1._reg==reg_r0) - { - u32 val=value; - if (op->rs3.is_imm()) - { - val+=op->rs3._imm; - op->rs3=shil_param(); - } - op->rs1=shil_param(FMT_IMM,val); - } - - if (op->op==shop_mov32 && op->rs1.is_imm() && isdst(op,reg_r0) ) - { - is_const=true; - value=op->rs1._imm; - } - else if (is_const && (isdst(op,reg_r0) || op->op==shop_ifb || op->op==shop_sync_sr) ) - is_const=false; - } -} - -void sq_pref(RuntimeBlockInfo* blk, int i, Sh4RegType rt, bool mark) -{ - u32 data=0; - for (int c=i-1;c>0;c--) - { - if (blk->oplist[c].op==shop_writem && blk->oplist[c].rs1._reg==rt) - { - if (blk->oplist[c].rs2.is_r32i() || blk->oplist[c].rs2.is_r32f() || blk->oplist[c].rs2.is_r64f() || blk->oplist[c].rs2.is_r32fv()) - { - data+=blk->oplist[c].flags; - if (mark) - blk->oplist[c].flags2=0x1337; - } - else - break; - } - - if (blk->oplist[c].op==shop_pref || (blk->oplist[c].rd.is_reg() && blk->oplist[c].rd._reg==rt && blk->oplist[c].op!= shop_sub)) - { - break; - } - - if (data==32) - break; - } - - if (mark) return; - - if (data>=8) - { - blk->oplist[i].flags =0x1337; - sq_pref(blk,i,rt,true); - DEBUG_LOG(DYNAREC, "SQW-WM match %d !",data); - } - else if (data) - { - DEBUG_LOG(DYNAREC, "SQW-WM FAIL %d !",data); - } -} - -void sq_pref(RuntimeBlockInfo* blk) -{ - for (int i=0;ioplist.size();i++) - { - blk->oplist[i].flags2=0; - if (blk->oplist[i].op==shop_pref) - sq_pref(blk,i,blk->oplist[i].rs1._reg,false); - } -} - -//Read Groups -void rdgrp(RuntimeBlockInfo* blk) -{ - int started=-1; - Sh4RegType reg; - Sh4RegType regd; - u32 stride; - bool pend_add; - u32 rdc; - u32 addv; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - op->Flow=0; - - if (started<0) - { - if (op->op==shop_readm && op->rd.type>=FMT_F32 && op->rs1.is_reg() && op->rs3.is_null()) - { - started=i; - stride=op->rd.count(); - reg=op->rs1._reg; - regd=op->rd._reg; - pend_add=true; - rdc=1; - addv=0; - } - } - else - { - if (!pend_add && op->op==shop_readm && op->rd._reg==(regd+stride) && op->rs1.is_reg() && op->rs1._reg==reg && op->rs3.is_null()) - { - regd=(Sh4RegType)(regd+stride); - pend_add=true; - rdc++; - } - else if (pend_add && op->op==shop_add && op->rd._reg==op->rs1._reg && op->rs1.is_reg() && op->rs2.is_imm() && op->rs2._imm==(stride*4)) - { - pend_add=false; - addv+=op->rs2._imm; - } - else - { - u32 byts=rdc*stride*4; - if (rdc!=1 && (byts==8 || byts==12 || byts==16 || byts==32 || byts==64)) - { - verify(addv==byts || (pend_add && (addv+stride*4==byts))); - - blk->oplist[started].rd.type=byts==8?FMT_V2:byts==12?FMT_V3: - byts==16?FMT_V4:byts==32?FMT_V8:FMT_V16; - blk->oplist[started].flags=byts|0x80; - if (stride==8) - blk->oplist[started].flags|=0x100; - blk->oplist[started].Flow=(rdc-1)*2 - (pend_add?1:0); - blk->oplist[started+1].rs2._imm=addv; - - DEBUG_LOG(DYNAREC, "Read Combination %d %d!",rdc,addv); - } - else if (rdc!=1) - { - DEBUG_LOG(DYNAREC, "Read Combination failed %d %d %d",rdc,rdc*stride*4,addv); - } - started=-1; - } - } - } - - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - if (op->Flow) - { - blk->oplist.erase(blk->oplist.begin()+i+2,blk->oplist.begin()+i+2+op->Flow); - } - } -} -//Write Groups -void wtgrp(RuntimeBlockInfo* blk) -{ - int started=-1; - Sh4RegType reg; - Sh4RegType regd; - u32 stride; - bool pend_add; - u32 rdc; - u32 addv; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - op->Flow=0; - - if (started<0) - { - if (op->op==shop_writem && op->rs2.type>=FMT_F32 && op->rs1.is_reg() && op->rs3.is_null()) - { - started=i; - stride=op->rd.count(); - reg=op->rs1._reg; - regd=op->rs2._reg; - pend_add=true; - rdc=1; - addv=0; - } - } - else - { - if (!pend_add && op->op==shop_writem && op->rs2._reg==(regd-stride) && op->rs1.is_reg() && op->rs1._reg==reg && op->rs3.is_null()) - { - regd=(Sh4RegType)(regd-stride); - pend_add=true; - rdc++; - } - else if (pend_add && op->op==shop_sub && op->rd._reg==op->rs1._reg && op->rs1.is_reg() && op->rs1._reg==reg && op->rs2.is_imm() && op->rs2._imm==(stride*4)) - { - pend_add=false; - addv+=op->rs2._imm; - } - else - { - u32 byts=rdc*stride*4; - u32 mask=byts/4; - if (mask==3) mask=4; - mask--; - - if (rdc!=1 /*&& (!(regd&mask))*/ && (byts==8 || byts==12 || byts==16 || byts==32 || byts==64)) - { - verify(addv==byts || (pend_add && (addv+stride*4==byts))); - - blk->oplist[started].rs2.type=byts==8?FMT_V2:byts==12?FMT_V3: - byts==16?FMT_V4:byts==32?FMT_V8:FMT_V16; - blk->oplist[started].rs2._reg=regd; - blk->oplist[started].rs3._imm=-(rdc-1)*stride*4; - blk->oplist[started].rs3.type=FMT_IMM; - blk->oplist[started].flags=byts|0x80; - if (stride==8) - blk->oplist[started].flags|=0x100; - blk->oplist[started].Flow=(rdc-1)*2 - (pend_add?1:0); - blk->oplist[started+1].rs2._imm=addv; - - DEBUG_LOG(DYNAREC, "Write Combination %d %d!",rdc,addv); - } - else if (rdc!=1) - { - DEBUG_LOG(DYNAREC, "Write Combination failed fr%d,%d, %d %d %d",regd,mask,rdc,rdc*stride*4,addv); - } - i=started; - started=-1; - } - } - } - - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - if (op->Flow) - { - blk->oplist.erase(blk->oplist.begin()+i+2,blk->oplist.begin()+i+2+op->Flow); - } - } -} - -bool ReadsPhy(shil_opcode* op, u32 phy) -{ - return true; -} - -bool WritesPhy(shil_opcode* op, u32 phy) -{ - return true; -} - -void rw_related(RuntimeBlockInfo* blk) -{ - u32 reg[sh4_reg_count]={0}; - - u32 total=0; - u32 memtotal=0; - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - op->Flow=0; - - - if (op->op==shop_ifb || op->op==shop_sync_sr) - { - memset(reg,0,sizeof(reg)); - } - if ( (op->op==shop_add || op->op==shop_sub) ) - { - if (reg[op->rd._reg]) - { - if (op->rs1.is_r32i() && op->rs1._reg==op->rd._reg && op->rs2.is_imm_s16()) - { - //nothing ! - } - else - reg[op->rd._reg]=0; - } - } - else - { - - if (op->op==shop_readm || op->op==shop_writem) - if (op->rs1.is_r32i()) - memtotal++; - - if (op->op==shop_readm || op->op==shop_writem) - { - if (op->rs1.is_r32i()) - { - if (op->rs3.is_imm_s16() || op->rs3.is_null()) - { - reg[op->rs1._reg]++; - if (reg[op->rs1._reg]>1) - total++; - } - //else - //reg[op->rs1._reg]=0; - } - } - - if (op->rd.is_reg() && reg[op->rd._reg]) - reg[op->rd._reg]=0; - if (op->rd2.is_reg() && reg[op->rd2._reg]) - reg[op->rd2._reg]=0; - } - - } - - if (memtotal) - { - u32 lookups=memtotal-total; - - //printf("rw_related total: %d/%d -- %.2f:1\n",total,memtotal,memtotal/(float)lookups); - } - else - { - //printf("rw_related total: none\n"); - } - - blk->memops=memtotal; - blk->linkedmemops=total; -} - - -//constprop -void constprop(RuntimeBlockInfo* blk) -{ - u32 rv[16]; - bool isi[16]={0}; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - if (op->rs2.is_r32i() && op->rs2._reg<16 && isi[op->rs2._reg]) - { - /* - not all opcodes can take rs2 as constant - */ - if (op->op!=shop_readm && op->op!=shop_writem - && op->op!=shop_mul_u16 && op->op!=shop_mul_s16 && op->op!=shop_mul_i32 - && op->op!=shop_mul_u64 && op->op!=shop_mul_s64 - && op->op!=shop_adc && op->op!=shop_sbc) - { - op->rs2.type=FMT_IMM; - op->rs2._imm=rv[op->rs2._reg]; - - if (op->op==shop_shld || op->op==shop_shad) - { - //convert em to mov/shl/shr - - DEBUG_LOG(DYNAREC, "sh*d -> s*l !"); - s32 v=op->rs2._imm; - - if (v>=0) - { - //x86e->Emit(sl32,reg.mapg(op->rd),v); - op->op=shop_shl; - op->rs2._imm=0x1f & v; - } - else if (0==(v&0x1f)) - { - if (op->op!=shop_shad) - { - //r[n]=0; - //x86e->Emit(op_mov32,reg.mapg(op->rd),0); - op->op=shop_mov32; - op->rs1.type=FMT_IMM; - op->rs1._imm=0; - op->rs2.type=FMT_NULL; - } - else - { - //r[n]>>=31; - //x86e->Emit(op_sar32,reg.mapg(op->rd),31); - op->op=shop_sar; - op->rs2._imm=31; - } - } - else - { - //x86e->Emit(sr32,reg.mapg(op->rd),-v); - if (op->op!=shop_shad) - op->op=shop_shr; - else - op->op=shop_sar; - - op->rs2._imm=0x1f & (-v); - } - } - } - } - - if (op->rs1.is_r32i() && op->rs1._reg<16 && isi[op->rs1._reg]) - { - if ((op->op==shop_readm /*|| op->op==shop_writem*/) && (op->flags&0x7F)==4) - { - op->rs1.type=FMT_IMM; - op->rs1._imm=rv[op->rs1._reg]; - - if (op->rs3.is_imm()) - { - op->rs1._imm+=op->rs3._imm; - op->rs3.type=FMT_NULL; - } - DEBUG_LOG(DYNAREC, "%s promotion: %08X",shop_readm==op->op?"shop_readm":"shop_writem",op->rs1._imm); - } - else if (op->op==shop_jdyn) - { - if (blk->BlockType==BET_DynamicJump || blk->BlockType==BET_DynamicCall) - { - blk->BranchBlock=rv[op->rs1._reg]; - if (op->rs2.is_imm()) - blk->BranchBlock+=op->rs2._imm;; - - blk->BlockType=blk->BlockType==BET_DynamicJump?BET_StaticJump:BET_StaticCall; - blk->oplist.erase(blk->oplist.begin()+i); - i--; - DEBUG_LOG(DYNAREC, "SBP: %08X -> %08X!",blk->addr,blk->BranchBlock); - continue; - } - else - { - DEBUG_LOG(DYNAREC, "SBP: failed :("); - } - } - else if (op->op==shop_mov32) - { - //handled later on ! - } - else if (op->op==shop_add || op->op==shop_sub) - { - - if (op->rs2.is_imm()) - { - op->rs1.type = FMT_IMM; - op->rs1._imm= op->op==shop_add ? - (rv[op->rs1._reg]+op->rs2._imm): - (rv[op->rs1._reg]-op->rs2._imm); - op->rs2.type = FMT_NULL; - DEBUG_LOG(DYNAREC, "%s -> mov32!",op->op==shop_add?"shop_add":"shop_sub"); - op->op=shop_mov32; - } - - else if (op->op==shop_add && !op->rs2.is_imm()) - { - u32 immy=rv[op->rs1._reg]; - op->rs1=op->rs2; - op->rs2.type = FMT_IMM; - op->rs2._imm=immy; - DEBUG_LOG(DYNAREC, "%s -> imm prm (%08X)!",op->op==shop_add?"shop_add":"shop_sub",immy); - } - } - else - { - op->op=op->op; - } - } - - if (op->rd.is_r32i() && op->rd._reg<16) isi[op->rd._reg]=false; - if (op->rd2.is_r32i() && op->rd2._reg<16) isi[op->rd._reg]=false; - - if (op->op==shop_mov32 && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16) - { - isi[op->rd._reg]=true; - rv[op->rd._reg]=op->rs1._imm; - } - - //NOT WORKING - //WE NEED PROPER PAGELOCKS - if (false && op->op==shop_readm && op->rs1.is_imm() && op->rd.is_r32i() && op->rd._reg<16 && op->flags==0x4 && op->rs3.is_null()) - { - u32 baddr=blk->addr&0x0FFFFFFF; - - if (/*baddr==0xC158400 &&*/ blk->addr/PAGE_SIZE == op->rs1._imm/PAGE_SIZE) - { - isi[op->rd._reg]=true; - rv[op->rd._reg]= ReadMem32(op->rs1._imm); - DEBUG_LOG(DYNAREC, "IMM MOVE: %08X -> %08X",op->rs1._imm,rv[op->rd._reg]); - - op->op=shop_mov32; - op->rs1._imm=rv[op->rd._reg]; - } - } - } - - rw_related(blk); -} - -//read_v4m3z1 -void read_v4m3z1(RuntimeBlockInfo* blk) -{ - - int state=0; - int st_sta=0; - Sh4RegType reg_a; - Sh4RegType reg_fb; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - bool a=false,b=false; - if ((i+6)>blk->oplist.size()) - break; - - if (state==0 && op->op==shop_readm && op->rd.is_r32f() && op->rs1.is_r32i() && op->rs3.is_null()) - { - if (op->rd._reg==reg_fr_0 || op->rd._reg==reg_fr_4 || op->rd._reg==reg_fr_8 || op->rd._reg==reg_fr_12) - { - reg_a=op->rs1._reg; - reg_fb=op->rd._reg; - st_sta=i; - goto _next_st; - } - goto _fail; - } - else if (state < 8 && state & 1 && op->op==shop_add && op->rd._reg==reg_a && op->rs1.is_reg() && op->rs1._reg==reg_a && op->rs2.is_imm() && op->rs2._imm==4) - { - if (state==7) - { - u32 start=st_sta; - - for (int j=0;j<6;j++) - { - blk->oplist.erase(blk->oplist.begin()+start); - } - - i=start+1; - op=&blk->oplist[start+0]; - op->op=shop_readm; - op->flags=0x440; - op->rd=shil_param(reg_fb==reg_fr_0?regv_fv_0: - reg_fb==reg_fr_4?regv_fv_4: - reg_fb==reg_fr_8?regv_fv_8: - reg_fb==reg_fr_12?regv_fv_12:reg_sr_T); - op->rd2=shil_param(); - - op->rs1=shil_param(reg_a); - op->rs2=shil_param(); - op->rs3=shil_param(); - - op=&blk->oplist[start+1]; - op->op=shop_add; - op->flags=0; - op->rd=shil_param(reg_a); - op->rd2=shil_param(); - - op->rs1=shil_param(reg_a); - op->rs2=shil_param(FMT_IMM,16); - op->rs3=shil_param(); - - goto _end; - } - else - goto _next_st; - } - else if (state >1 && - op->op==shop_readm && op->rd.is_r32f() && op->rd._reg==(reg_fb+state/2) && op->rs1.is_r32i() && op->rs1._reg==reg_a && op->rs3.is_null()) - { - goto _next_st; - } - else if ((a=(op->op==shop_mov32 && op->rd._reg==(reg_fb+3) && op->rs1.is_imm() && (op->rs1._imm==0x3f800000 /*|| op->rs1._imm==0*/))) || - (b=(i>7 && op[-7].op==shop_mov32 && op[-7].rd._reg==(reg_fb+3) && op[-7].rs1.is_imm() && (op[-7].rs1._imm==0x3f800000 /*|| op[-7].rs1._imm==0*/))) ) - { - if (state==6) - { - if (b) - st_sta--; - if (a) - DEBUG_LOG(DYNAREC, "NOT B"); - u32 start=st_sta; - - for (int j=0;j<5;j++) - { - blk->oplist.erase(blk->oplist.begin()+start); - } - - i=start+1; - op=&blk->oplist[start+0]; - op->op=shop_readm; - op->flags=0x431; - op->rd=shil_param(reg_fb==reg_fr_0?regv_fv_0: - reg_fb==reg_fr_4?regv_fv_4: - reg_fb==reg_fr_8?regv_fv_8: - reg_fb==reg_fr_12?regv_fv_12:reg_sr_T); - op->rd2=shil_param(); - - op->rs1=shil_param(reg_a); - op->rs2=shil_param(); - op->rs3=shil_param(); - - op=&blk->oplist[start+1]; - op->op=shop_add; - op->flags=0; - op->rd=shil_param(reg_a); - op->rd2=shil_param(); - - op->rs1=shil_param(reg_a); - op->rs2=shil_param(FMT_IMM,12); - op->rs3=shil_param(); - - goto _end; - } - else - goto _fail; - } - else - goto _fail; - - - die("wth"); - -_next_st: - state ++; - continue; - -_fail: - if (state) - i=st_sta; -_end: - state=0; - - } - -} - -//dejcond -void dejcond(RuntimeBlockInfo* blk) -{ - u32 rv[16]; - bool isi[16]={0}; - - if (!blk->has_jcond) return; - - bool found=false; - u32 jcondp=0; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - if (found) - { - if ((op->rd.is_reg() && op->rd._reg==reg_sr_T) || op->op==shop_ifb) - { - found=false; - } - } - - if (op->op==shop_jcond) - { - found=true; - jcondp=i; - } - } - - if (found) - { - blk->has_jcond=false; - blk->oplist.erase(blk->oplist.begin()+jcondp); - } -} - -//detect bswaps and talk about them -void enswap(RuntimeBlockInfo* blk) -{ - Sh4RegType r; - int state=0; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - op->Flow=0; - - if (state==0 && op->op==shop_swaplb) - { - if (op->rd._reg==op->rs1._reg) - { - state=1; - r=op->rd._reg; - op->Flow=1; - continue; - } - else - { - DEBUG_LOG(DYNAREC, "bswap -- wrong regs"); - } - } - - if (state==1 && op->op==shop_ror && op->rs2.is_imm() && op->rs2._imm==16 && - op->rs1._reg==r) - { - if (op->rd._reg==r) - { - state=2; - op->Flow=1; - continue; - } - else - { - DEBUG_LOG(DYNAREC, "bswap -- wrong regs"); - } - } - - if (state==2 && op->op==shop_swaplb && op->rs1._reg==r) - { - if (op->rd._reg!=r) - { - DEBUG_LOG(DYNAREC, "oops?"); - } - else - { - DEBUG_LOG(DYNAREC, "SWAPM!"); - } - op->Flow=1; - state=0; - } - - } -} - -//enjcond -//this is a normally slower -//however, cause of reg alloc stuff in arm, this -//speeds up access to SR_T (pc_dyn is stored in reg, not mem) -//This is temporary til that limitation is fixed on the reg alloc logic -void enjcond(RuntimeBlockInfo* blk) -{ - u32 rv[16]; - bool isi[16]={0}; - - if (!blk->has_jcond && (blk->BlockType==BET_Cond_0||blk->BlockType==BET_Cond_1)) - { - shil_opcode jcnd; - - jcnd.op=shop_jcond; - jcnd.rs1=shil_param(reg_sr_T); - jcnd.rd=shil_param(reg_pc_dyn); - jcnd.flags=0; - blk->oplist.push_back(jcnd); - blk->has_jcond=true; - } -} - - -//"links" consts to each other -void constlink(RuntimeBlockInfo* blk) -{ - Sh4RegType def=NoReg; - s32 val; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - if (op->op!=shop_mov32) - def=NoReg; - else - { - - if (def!=NoReg && op->rs1.is_imm() && op->rs1._imm==val) - { - op->rs1=shil_param(def); - } - else if (def==NoReg && op->rs1.is_imm() && op->rs1._imm==0) - { - //def=op->rd._reg; - val = op->rs1._imm; - } - } - } -} - - -void srt_waw(RuntimeBlockInfo* blk) -{ - bool found=false; - u32 srtw=0; - - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - if (found) - { - if ((op->rs1.is_reg() && op->rs1._reg==reg_sr_T) - || (op->rs2.is_reg() && op->rs2._reg==reg_sr_T) - || (op->rs3.is_reg() && op->rs3._reg==reg_sr_T) - || op->op==shop_ifb) - { - found=false; - } - } - - if (op->rd.is_reg() && op->rd._reg==reg_sr_T && op->rd2.is_null()) - { - if (found) - { - blk->oplist.erase(blk->oplist.begin()+srtw); - i--; - } - - found=true; - srtw=i; - } - } - -} - -#include "hw/sh4/modules/ccn.h" #include "ngen.h" #include "hw/sh4/sh4_core.h" -#include "hw/sh4/sh4_mmr.h" - #define SHIL_MODE 1 #include "shil_canonical.h" @@ -888,143 +22,11 @@ void srt_waw(RuntimeBlockInfo* blk) #include "ssa.h" -//Simplistic Write after Write without read pass to remove (a few) dead opcodes -//Seems to be working void AnalyseBlock(RuntimeBlockInfo* blk) { SSAOptimizer optim(blk); optim.Optimize(); return; - - u32 st[sh4_reg_count]={0}; - /* - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - - if (op->rs1.is_reg() && st[op->rs1._reg]==0) - st[op->rs1._reg]=1; - - if (op->rs2.is_reg() && st[op->rs2._reg]==0) - st[op->rs2._reg]=1; - - if (op->rs3.is_reg() && st[op->rs3._reg]==0) - st[op->rs3._reg]=1; - - if (op->rd.is_reg()) - st[op->rd._reg]|=2; - - if (op->rd2.is_reg()) - st[op->rd2._reg]|=2; - } - - if (st[reg_sr_T]&1) - { - printf("BLOCK: %08X\n",blk->addr); - - puts("rin: "); - - for (int i=0;ihas_jcond && blk->oplist.size() > 0 && - blk->oplist[blk->oplist.size()-1].rd._reg==reg_sr_T; - - srt_waw(blk); - constlink(blk); - //dejcond(blk); - if (last_op_sets_flags) - { - shilop op= blk->oplist[blk->oplist.size()-1].op; - if (op == shop_test || op==shop_seteq || op==shop_setab || op==shop_setae - || op == shop_setge || op==shop_setgt) - ; - else - last_op_sets_flags=false; - } - if (!last_op_sets_flags) - enjcond(blk); - //read_v4m3z1(blk); - //rw_related(blk); - - return; //disbled to be on the safe side .. - memset(RegisterWrite,-1,sizeof(RegisterWrite)); - memset(RegisterRead,-1,sizeof(RegisterRead)); - - total_blocks++; - for (size_t i=0;ioplist.size();i++) - { - shil_opcode* op=&blk->oplist[i]; - op->Flow=0; - if (op->op==shop_ifb) - { - fallback_blocks++; - return; - } - - RegReadInfo(op->rs1,i); - RegReadInfo(op->rs2,i); - RegReadInfo(op->rs3,i); - - RegWriteInfo(&blk->oplist[0],op->rd,i); - RegWriteInfo(&blk->oplist[0],op->rd2,i); - } - - for (size_t i=0;ioplist.size();i++) - { - if (blk->oplist[i].Flow) - { - blk->oplist.erase(blk->oplist.begin()+i); - REMOVED_OPS++; - i--; - } - } - - int affregs=0; - for (int i=0;i<16;i++) - { - if (RegisterWrite[i]!=0) - { - affregs++; - //printf("r%02d:%02d ",i,RegisterWrite[i]); - } - } - //printf("<> %d\n",affregs); - - //printf("%d FB, %d native, %.2f%% || %d removed ops!\n",fallback_blocks,total_blocks-fallback_blocks,fallback_blocks*100.f/total_blocks,REMOVED_OPS); - //printf("\nBlock: %d affecter regs %d c\n",affregs,blk->guest_cycles); } string name_reg(Sh4RegType reg) @@ -1089,7 +91,7 @@ string name_reg(Sh4RegType reg) return ss.str(); } -string dissasm_param(const shil_param& prm, bool comma) +static string dissasm_param(const shil_param& prm, bool comma) { stringstream ss; diff --git a/core/hw/sh4/sh4_interrupts.cpp b/core/hw/sh4/sh4_interrupts.cpp index a05536fb7..fe9ef6afc 100644 --- a/core/hw/sh4/sh4_interrupts.cpp +++ b/core/hw/sh4/sh4_interrupts.cpp @@ -20,7 +20,7 @@ */ //these are fixed -/* TODO const */ u16 IRLPriority=0x0246; +const u16 IRLPriority = 0x0246; #define IRLP9 &IRLPriority,0 #define IRLP11 &IRLPriority,4 #define IRLP13 &IRLPriority,8 diff --git a/core/nullDC.cpp b/core/nullDC.cpp index cb7134a1b..b2e03e160 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -1026,9 +1026,15 @@ void dc_loadstate() return; } - fread(data, 1, total_size, f) ; + size_t read_size = fread(data, 1, total_size, f) ; fclose(f); - + if (read_size != total_size) + { + WARN_LOG(SAVESTATE, "Failed to load state - I/O error"); + gui_display_notification("Failed to load state - I/O error", 2000); + cleanup_serialize(data) ; + return; + } data_ptr = data ; @@ -1040,13 +1046,16 @@ void dc_loadstate() #endif bm_Reset(); - if ( ! dc_unserialize(&data_ptr, &total_size) ) + u32 unserialized_size = 0; + if ( ! dc_unserialize(&data_ptr, &unserialized_size) ) { WARN_LOG(SAVESTATE, "Failed to load state - could not unserialize data") ; gui_display_notification("Invalid save state", 2000); cleanup_serialize(data) ; return; } + if (unserialized_size != total_size) + WARN_LOG(SAVESTATE, "Save state error: read %d bytes but used %d", total_size, unserialized_size); mmu_set_state(); sh4_cpu.ResetCache(); diff --git a/core/serialize.cpp b/core/serialize.cpp index 2a98a00cf..66e843917 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -24,9 +24,7 @@ #include "hw/sh4/dyna/ngen.h" #include "hw/naomi/naomi_cart.h" -/* - * search for "maybe" to find items that were left out that may be needed - */ +#define REICAST_SKIP(size) do { *(u8**)data += size; *total_size += size; } while (false) extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb); @@ -35,7 +33,10 @@ enum serialize_version_enum { V2, V3, V4, - V5_LIBRETRO + V5_LIBRETRO_UNSUPPORTED, + V6_LIBRETRO, + + V5 = 800, } ; //./core/hw/arm7/arm_mem.cpp @@ -45,103 +46,37 @@ extern bool e68k_out; extern u32 e68k_reg_L; extern u32 e68k_reg_M; - - //./core/hw/arm7/arm7.cpp extern DECL_ALIGN(8) reg_pair arm_Reg[RN_ARM_REG_COUNT]; extern bool armIrqEnable; extern bool armFiqEnable; extern int armMode; extern bool Arm7Enabled; -extern u8 cpuBitsSet[256]; -/* - if AREC dynarec enabled: - vector ops; - u8* icPtr; - u8* ICache; - u8 ARM7_TCB[ICacheSize+4096]; - void* EntryPoints[8*1024*1024/4]; - map renamed_regs; - u32 rename_reg_base; - u32 nfb,ffb,bfb,mfb; - static x86_block* x86e; - x86_Label* end_lbl; - u8* ARM::emit_opt=0; - eReg ARM::reg_addr; - eReg ARM::reg_dst; - s32 ARM::imma; -*/ - - - //./core/hw/aica/dsp.o extern DECL_ALIGN(4096) dsp_t dsp; -//recheck dsp.cpp if FEAT_DSPREC == DYNAREC_JIT - - - - -//./core/hw/aica/aica.o -//these are all just pointers into aica_reg -//extern CommonData_struct* CommonData; -//extern DSPData_struct* DSPData; -//extern InterruptInfo* MCIEB; -//extern InterruptInfo* MCIPD; -//extern InterruptInfo* MCIRE; -//extern InterruptInfo* SCIEB; -//extern InterruptInfo* SCIPD; -//extern InterruptInfo* SCIRE; extern AicaTimer timers[3]; - - //./core/hw/aica/aica_if.o extern VLockedMemory aica_ram; extern u32 VREG;//video reg =P extern u32 ARMRST;//arm reset reg extern u32 rtc_EN; -//extern s32 aica_pending_dma ; extern int dma_sched_id; - //./core/hw/aica/aica_mem.o extern u8 aica_reg[0x8000]; - - //./core/hw/aica/sgc_if.o struct ChannelEx; #define AicaChannel ChannelEx -extern s32 volume_lut[16]; -extern s32 tl_lut[256 + 768]; //xx.15 format. >=255 is muted -extern u32 AEG_ATT_SPS[64]; -extern u32 AEG_DSR_SPS[64]; -extern s16 pl; -extern s16 pr; -//this is just a pointer to aica_reg -//extern DSP_OUT_VOL_REG* dsp_out_vol; -//not needed - one-time init -//void(* STREAM_STEP_LUT [5][2][2])(ChannelEx *ch) -//void(* STREAM_INITAL_STEP_LUT [5])(ChannelEx *ch) -//void(* AEG_STEP_LUT [4])(ChannelEx *ch) -//void(* FEG_STEP_LUT [4])(ChannelEx *ch) -//void(* ALFOWS_CALC [4])(ChannelEx *ch) -//void(* PLFOWS_CALC [4])(ChannelEx *ch) //special handling -//extern AicaChannel AicaChannel::Chans[64]; #define Chans AicaChannel::Chans #define CDDA_SIZE (2352/2) extern s16 cdda_sector[CDDA_SIZE]; extern u32 cdda_index; -extern SampleType mxlr[64]; -extern u32 samples_gen; - - - - //./core/hw/holly/sb.o extern Array sb_regs; @@ -149,24 +84,13 @@ extern u32 SB_ISTNRM; extern u32 SB_FFST_rc; extern u32 SB_FFST; - - //./core/hw/holly/sb_mem.o -//unused -//static HollyInterruptID dmatmp1; -//static HollyInterruptID dmatmp2; -//static HollyInterruptID OldDmaId; - extern MemChip *sys_rom; extern MemChip *sys_nvmem; - //./core/hw/gdrom/gdrom_response.o extern u16 reply_11[] ; - - - //./core/hw/gdrom/gdromv3.o extern int gdrom_schid; extern signed int sns_asc; @@ -196,57 +120,20 @@ extern GD_SecNumbT SecNumber; extern GD_StatusT GDStatus; extern ByteCount_t ByteCount ; - - - - //./core/hw/maple/maple_devs.o extern char EEPROM[0x100]; extern bool EEPROM_loaded; //./core/hw/maple/maple_if.o -//one time set extern int maple_schid; -//incremented but never read -//extern u32 dmacount; extern bool maple_ddt_pending_reset; - //./core/hw/modem/modem.cpp extern int modem_sched; - - //./core/hw/pvr/Renderer_if.o -//only written - not read -//extern u32 VertexCount; -extern u32 FrameCount; -//one-time init -//extern Renderer* renderer; -//these are just mutexes used during rendering -//extern cResetEvent rs; -//extern cResetEvent re; -//these max_?? through ovrn are written and not read -//extern int max_idx; -//extern int max_mvo; -//extern int max_op; -//extern int max_pt; -//extern int max_tr; -//extern int max_vtx; -//extern int max_modt; -//extern int ovrn; -//seems safe to omit this - gets refreshed every frame from a pool -//extern TA_context* _pvrrc; -//just a flag indiating the rendering thread is running -//extern int rend_en ; -//the renderer thread - one time set -//extern cThread rthd; extern bool pend_rend; -//maybe -//extern u32 memops_t,memops_l; - - //./core/hw/pvr/pvr_mem.o extern u32 YUV_tempdata[512/4];//512 bytes extern u32 YUV_dest; @@ -256,113 +143,27 @@ extern u32 YUV_y_curr; extern u32 YUV_x_size; extern u32 YUV_y_size; - - - //./core/hw/pvr/pvr_regs.o extern bool fog_needs_update; extern u8 pvr_regs[pvr_RegSize]; - - - //./core/hw/pvr/spg.o extern u32 in_vblank; extern u32 clc_pvr_scanline; -extern u32 pvr_numscanlines; -extern u32 prv_cur_scanline; -extern u32 vblk_cnt; -extern u32 Line_Cycles; -extern u32 Frame_Cycles; extern int render_end_schid; extern int vblank_schid; extern int time_sync; -extern double speed_load_mspdf; -extern int mips_counter; -extern double full_rps; -extern u32 fskip; - - - //./core/hw/pvr/ta.o -extern u32 ta_type_lut[256]; extern u8 ta_fsm[2049]; //[2048] stores the current state extern u32 ta_fsm_cl; - - - -//./core/hw/pvr/ta_ctx.o -//these frameskipping don't need to be saved -//extern int frameskip; -//extern bool FrameSkipping; // global switch to enable/disable frameskip -//maybe need these - but hopefully not -//extern TA_context* ta_ctx; -//extern tad_context ta_tad; -//extern TA_context* vd_ctx; -//extern rend_context vd_rc; -//extern cMutex mtx_rqueue; -//extern TA_context* rqueue; -//extern cResetEvent frame_finished; -//extern cMutex mtx_pool; -//extern vector ctx_pool; -//extern vector ctx_list; -//end maybe - - - //./core/hw/pvr/ta_vtx.o extern bool pal_needs_update; -//extern u32 decoded_colors[3][65536]; -extern u32 tileclip_val; -extern u8 f32_su8_tbl[65536]; -//written but never read -//extern ModTriangle* lmr; -//never changed -//extern PolyParam nullPP; -//maybe -//extern PolyParam* CurrentPP; -//maybe -//extern List* CurrentPPlist; -//TA state vars -extern DECL_ALIGN(4) u8 FaceBaseColor[4]; -extern DECL_ALIGN(4) u8 FaceOffsColor[4]; -extern DECL_ALIGN(4) u8 FaceBaseColor1[4]; -extern DECL_ALIGN(4) u8 FaceOffsColor1[4]; -extern DECL_ALIGN(4) u32 SFaceBaseColor; -extern DECL_ALIGN(4) u32 SFaceOffsColor; -//maybe -//extern TaListFP* TaCmd; -//maybe -//extern u32 CurrentList; -//maybe -//extern TaListFP* VertexDataFP; -//written but never read -//extern bool ListIsFinished[5]; -//maybe ; need special handler -//FifoSplitter<0> TAFifo0; -//counter for frameskipping - doesn't need to be saved -//extern int ta_parse_cnt; - - - //./core/rend/TexCache.o -//maybe -//extern u8* vq_codebook; -//extern u32 palette_index; -//extern bool KillTex; -//extern u32 detwiddle[2][8][1024]; -//maybe -//extern vector VramLocks[/*VRAM_SIZE*/(16*1024*1024)/PAGE_SIZE]; -//maybe - probably not - just a locking mechanism -//extern cMutex vramlist_lock; extern VLockedMemory vram; - - - //./core/hw/sh4/sh4_mmr.o extern Array OnChipRAM; extern Array CCN; //CCN : 14 registers @@ -376,23 +177,10 @@ extern Array TMU; //TMU : 12 registers extern Array SCI; //SCI : 8 registers extern Array SCIF; //SCIF : 10 registers - - - //./core/hw/sh4/sh4_mem.o extern VLockedMemory mem_b; -//one-time init -//extern _vmem_handler area1_32b; -//one-time init -//extern _vmem_handler area5_handler; - - - //./core/hw/sh4/sh4_interrupts.o -extern u16 IRLPriority; -//one-time init -//extern InterptSourceList_Entry InterruptSourceList[28]; extern DECL_ALIGN(64) u16 InterruptEnvId[32]; extern DECL_ALIGN(64) u32 InterruptBit[32]; extern DECL_ALIGN(64) u32 InterruptLevelBit[16]; @@ -400,51 +188,26 @@ extern u32 interrupt_vpend; // Vector of pending interrupts extern u32 interrupt_vmask; // Vector of masked interrupts (-1 inhibits all interrupts) extern u32 decoded_srimask; // Vector of interrupts allowed by SR.IMSK (-1 inhibits all interrupts) - - - //./core/hw/sh4/sh4_core_regs.o extern Sh4RCB* p_sh4rcb; -//just method pointers -//extern sh4_if sh4_cpu; -//one-time set -//extern u8* sh4_dyna_rcb; -extern u32 old_rm; -extern u32 old_dn; - - - //./core/hw/sh4/sh4_sched.o extern u64 sh4_sched_ffb; extern u32 sh4_sched_intr; extern vector sch_list; -//extern int sh4_sched_next_id; - - - //./core/hw/sh4/interpr/sh4_interpreter.o extern int aica_schid; extern int rtc_schid; - - - //./core/hw/sh4/modules/serial.o extern SCIF_SCFSR2_type SCIF_SCFSR2; extern u8 SCIF_SCFRDR2; extern SCIF_SCFDR2_type SCIF_SCFDR2; - - - //./core/hw/sh4/modules/bsc.o extern BSC_PDTRA_type BSC_PDTRA; - - - //./core/hw/sh4/modules/tmu.o extern u32 tmu_shift[3]; extern u32 tmu_mask[3]; @@ -454,15 +217,9 @@ extern int tmu_sched[3]; extern u32 tmu_ch_base[3]; extern u64 tmu_ch_base64[3]; - - - //./core/hw/sh4/modules/ccn.o extern u32 CCN_QACR_TR[2]; - - - //./core/hw/sh4/modules/mmu.o extern TLB_Entry UTLB[64]; extern TLB_Entry ITLB[4]; @@ -472,127 +229,11 @@ extern u32 sq_remap[64]; static u32 ITLB_LRU_USE[64]; #endif - - //./core/imgread/common.o extern u32 NullDriveDiscType; -//maybe - seems to all be one-time inits ; needs special handler -//extern Disc* disc; extern u8 q_subchannel[96]; - - - -//./core/nullDC.o -//extern unsigned FLASH_SIZE; -//extern unsigned BBSRAM_SIZE; -//extern unsigned BIOS_SIZE; -//extern unsigned RAM_SIZE; -//extern unsigned ARAM_SIZE; -//extern unsigned VRAM_SIZE; -//extern unsigned RAM_MASK; -//extern unsigned ARAM_MASK; -//extern unsigned VRAM_MASK; -//settings can be dynamic -//extern settings_t settings; - - - - -//./core/reios/reios.o -//never used -//extern u8* biosrom; -//one time init -//extern u8* flashrom; -//one time init -//extern u32 base_fad ; -//one time init -//extern bool descrambl; -//one time init -//extern bool bootfile_inited; -//all these reios_?? are one-time inits -//extern char reios_bootfile[32]; -//extern char reios_hardware_id[17]; -//extern char reios_maker_id[17]; -//extern char reios_device_info[17]; -//extern char reios_area_symbols[9]; -//extern char reios_peripherals[9]; -//extern char reios_product_number[11]; -//extern char reios_product_version[7]; -//extern char reios_releasedate[17]; -//extern char reios_boot_filename[17]; -//extern char reios_software_company[17]; -//extern char reios_software_name[129]; -//one time init -//extern map hooks; -//one time init -//extern map hooks_rev; - - - - -//./core/reios/gdrom_hle.o -//never used in any meaningful way -//extern u32 SecMode[4]; - - - - -//./core/reios/descrambl.o -//random seeds can be...random -//extern unsigned int seed; - - - -//./core/rend/gles/gles.o -//maybe -//extern GLCache glcache; -//maybe -//extern gl_ctx gl; -//maybe -//extern struct ShaderUniforms_t ShaderUniforms; -//maybe -//extern u32 gcflip; -//maybe -//extern float fb_scale_x; -//extern float fb_scale_y; -//extern float scale_x; -//extern float scale_y; -//extern int screen_width; -//extern int screen_height; -//extern GLuint fogTextureId; -//end maybe - - - -//./core/rend/gles/gldraw.o -//maybe -//extern PipelineShader* CurrentShader; -//written, but never used -//extern Vertex* vtx_sort_base; -//maybe -//extern vector pidx_sort; - - - - -//./core/rend/gles/gltex.o -//maybe ; special handler -//extern map TexCache; -//maybe -//extern FBT fb_rtt; -//not used -//static int TexCacheLookups; -//static int TexCacheHits; -//static float LastTexCacheStats; -//maybe should get reset naturally if needed -//GLuint fbTextureId; - - - - //./core/hw/naomi/naomi.o -extern u32 naomi_updates; extern u32 GSerialBuffer; extern u32 BSerialBuffer; extern int GBufPos; @@ -618,86 +259,6 @@ extern u32 reg_dimm_48; //parameters extern u32 reg_dimm_4c; //status/control reg ? extern bool NaomiDataRead; - - - -//./core/hw/naomi/naomi_cart.o -//all one-time loads -//u8* RomPtr; -//u32 RomSize; -//fd_t* RomCacheMap; -//u32 RomCacheMapCount; - - - - -//./core/rec-x64/rec_x64.o -//maybe need special handler -//extern BlockCompilerx64 *compilerx64_data; - - - - -//./core/rec.o -#if FEAT_SHREC == DYNAREC_CPP -extern int idxnxx; -#endif - - - -//./core/hw/sh4/dyna/decoder.o -//temp storage only -//extern RuntimeBlockInfo* blk; -extern state_t state; -extern Sh4RegType div_som_reg1; -extern Sh4RegType div_som_reg2; -extern Sh4RegType div_som_reg3; - - - - -//./core/hw/sh4/dyna/driver.o -//extern u8 SH4_TCB[CODE_SIZE+4096]; -//one time ptr set -//extern u8* CodeCache; -//extern u32 LastAddr; -//extern u32 LastAddr_min; -//temp storage only -//extern u32* emit_ptr; -extern char block_hash[1024]; - - - - -//./core/hw/sh4/dyna/blockmanager.o -//cleared but never read -//extern bm_List blocks_page[/*BLOCKS_IN_PAGE_LIST_COUNT*/(32*1024*1024)/4096]; -//maybe - the next three seem to be list of precompiled blocks of code - but if not found will populate -//extern bm_List all_blocks; -//extern bm_List del_blocks; -//extern blkmap_t blkmap; -//these two are never referenced -//extern u32 bm_gc_luc; -//extern u32 bm_gcf_luc; -//data is never written to this -//extern u32 PAGE_STATE[(32*1024*1024)/*RAM_SIZE*//32]; -//never read -//extern u32 total_saved; -//counter with no real controlling logic behind it -//extern u32 rebuild_counter; -//just printf output -//extern bool print_stats; - - - - -//./core/hw/sh4/dyna/shil.o -extern u32 RegisterWrite[sh4_reg_count]; -extern u32 RegisterRead[sh4_reg_count]; -extern u32 fallback_blocks; -extern u32 total_blocks; -extern u32 REMOVED_OPS; - bool rc_serialize(void *src, unsigned int src_size, void **dest, unsigned int *total_size) { if ( *dest != NULL ) @@ -728,21 +289,21 @@ bool register_serialize(Array& regs,void **data, unsigned int *t for ( i = 0 ; i < regs.Size ; i++ ) { - REICAST_S(regs.data[i].flags) ; REICAST_S(regs.data[i].data32) ; } return true ; } -bool register_unserialize(Array& regs,void **data, unsigned int *total_size ) +bool register_unserialize(Array& regs,void **data, unsigned int *total_size, serialize_version_enum version) { int i = 0 ; u32 dummy = 0 ; for ( i = 0 ; i < regs.Size ; i++ ) { - REICAST_US(regs.data[i].flags) ; + if (version < V5) + REICAST_US(dummy); // regs.data[i].flags if ( ! (regs.data[i].flags & REG_RF) ) REICAST_US(regs.data[i].data32) ; else @@ -755,7 +316,7 @@ bool dc_serialize(void **data, unsigned int *total_size) { int i = 0; int j = 0; - serialize_version_enum version = V4 ; + serialize_version_enum version = V5; *total_size = 0 ; @@ -775,11 +336,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(armFiqEnable); REICAST_S(armMode); REICAST_S(Arm7Enabled); - REICAST_SA(cpuBitsSet,256); - bool dummy; - REICAST_S(dummy); - REICAST_S(dummy); - REICAST_S(dummy); REICAST_S(dsp); @@ -797,22 +353,10 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_SA(aica_reg,0x8000); - - - REICAST_SA(volume_lut,16); - REICAST_SA(tl_lut,256 + 768); - REICAST_SA(AEG_ATT_SPS,64); - REICAST_SA(AEG_DSR_SPS,64); - REICAST_S(pl); - REICAST_S(pr); - channel_serialize(data, total_size) ; REICAST_SA(cdda_sector,CDDA_SIZE); REICAST_S(cdda_index); - REICAST_SA(mxlr,64); - REICAST_S(samples_gen); - register_serialize(sb_regs, data, total_size) ; REICAST_S(SB_ISTNRM); @@ -822,15 +366,6 @@ bool dc_serialize(void **data, unsigned int *total_size) sys_rom->Serialize(data, total_size); sys_nvmem->Serialize(data, total_size); - /* - REICAST_S(sys_nvmem->size); - REICAST_S(sys_nvmem->mask); -#ifdef FLASH_SIZE - REICAST_S(sys_nvmem->state); -#endif - REICAST_SA(sys_nvmem->data, sys_nvmem->size); - */ - REICAST_SA(reply_11,16) ; @@ -853,6 +388,7 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(data_write_mode); REICAST_S(DriveSel); REICAST_S(Error); + REICAST_S(IntReason); REICAST_S(Features); REICAST_S(SecCount); @@ -869,10 +405,6 @@ bool dc_serialize(void **data, unsigned int *total_size) mcfg_SerializeDevices(data, total_size); - REICAST_S(FrameCount); - REICAST_S(pend_rend); - - REICAST_SA(YUV_tempdata,512/4); REICAST_S(YUV_dest); REICAST_S(YUV_blockcount); @@ -885,29 +417,10 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(in_vblank); REICAST_S(clc_pvr_scanline); - REICAST_S(pvr_numscanlines); - REICAST_S(prv_cur_scanline); - REICAST_S(vblk_cnt); - REICAST_S(Line_Cycles); - REICAST_S(Frame_Cycles); - REICAST_S(speed_load_mspdf); - REICAST_S(mips_counter); - REICAST_S(full_rps); - REICAST_S(fskip); - - - REICAST_SA(ta_type_lut,256); - REICAST_SA(ta_fsm,2049); + REICAST_S(ta_fsm[2048]); REICAST_S(ta_fsm_cl); - REICAST_S(tileclip_val); - REICAST_SA(f32_su8_tbl,65536); - REICAST_SA(FaceBaseColor,4); - REICAST_SA(FaceOffsColor,4); - REICAST_S(SFaceBaseColor); - REICAST_S(SFaceOffsColor); - REICAST_SA(vram.data, vram.size); REICAST_SA(OnChipRAM.data,OnChipRAM_SIZE); @@ -925,9 +438,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_SA(mem_b.data, mem_b.size); - - - REICAST_S(IRLPriority); REICAST_SA(InterruptEnvId,32); REICAST_SA(InterruptBit,32); REICAST_SA(InterruptLevelBit,16); @@ -951,23 +461,11 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_SA((*p_sh4rcb).sq_buffer,64/8); - //store these before unserializing and then restore after - //void *getptr = &((*p_sh4rcb).cntx.sr.GetFull) ; - //void *setptr = &((*p_sh4rcb).cntx.sr.SetFull) ; REICAST_S((*p_sh4rcb).cntx); - REICAST_S(old_rm); - REICAST_S(old_dn); - - - - REICAST_S(sh4_sched_ffb); REICAST_S(sh4_sched_intr); - //extern vector list; - - REICAST_S(sch_list[aica_schid].tag) ; REICAST_S(sch_list[aica_schid].start) ; REICAST_S(sch_list[aica_schid].end) ; @@ -1007,16 +505,16 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(sch_list[time_sync].start) ; REICAST_S(sch_list[time_sync].end) ; - #ifdef ENABLE_MODEM +#ifdef ENABLE_MODEM REICAST_S(sch_list[modem_sched].tag) ; REICAST_S(sch_list[modem_sched].start) ; REICAST_S(sch_list[modem_sched].end) ; - #else +#else int modem_dummy = 0; REICAST_S(modem_dummy); REICAST_S(modem_dummy); REICAST_S(modem_dummy); - #endif +#endif REICAST_S(SCIF_SCFSR2); REICAST_S(SCIF_SCFRDR2); @@ -1044,8 +542,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(NullDriveDiscType); REICAST_SA(q_subchannel,96); - REICAST_S(naomi_updates); - REICAST_S(i); //BoardID REICAST_S(GSerialBuffer); REICAST_S(BSerialBuffer); REICAST_S(GBufPos); @@ -1071,38 +567,6 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(reg_dimm_4c); REICAST_S(NaomiDataRead); -#if FEAT_SHREC == DYNAREC_CPP - REICAST_S(idxnxx); -#else - REICAST_S(i); -#endif - - REICAST_S(state); - REICAST_S(div_som_reg1); - REICAST_S(div_som_reg2); - REICAST_S(div_som_reg3); - - REICAST_S(i); //LastAddr - REICAST_S(i); //LastAddr_min - REICAST_SA(block_hash,1024); - - REICAST_SA(RegisterWrite,sh4_reg_count); - REICAST_SA(RegisterRead,sh4_reg_count); - REICAST_S(fallback_blocks); - REICAST_S(total_blocks); - REICAST_S(REMOVED_OPS); - - REICAST_S(i); //REICAST_SA(kcode,4); - REICAST_S(i); - REICAST_S(i); //REICAST_SA(rt,4); - REICAST_S(i); //REICAST_SA(lt,4); - REICAST_S(i); //REICAST_SA(vks,4); - REICAST_S(i); - REICAST_S(i); - REICAST_S(i); - REICAST_S(i); //REICAST_SA(joyx,4); - REICAST_S(i); //REICAST_SA(joyy,4); - REICAST_S(settings.dreamcast.broadcast); REICAST_S(settings.dreamcast.cable); REICAST_S(settings.dreamcast.region); @@ -1110,6 +574,8 @@ bool dc_serialize(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Serialize(data, total_size); + DEBUG_LOG(SAVESTATE, "Saved %d bytes", *total_size); + return true ; } @@ -1129,11 +595,11 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(armFiqEnable); REICAST_US(armMode); REICAST_US(Arm7Enabled); - REICAST_USA(cpuBitsSet,256); + REICAST_SKIP(256); // cpuBitsSet bool dummy; - REICAST_US(dummy); - REICAST_US(dummy); - REICAST_US(dummy); + REICAST_US(dummy); // intState + REICAST_US(dummy); // stopState + REICAST_US(dummy); // holdState REICAST_US(dsp); @@ -1143,7 +609,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(timers[i].m_step); } - REICAST_USA(aica_ram.data,aica_ram.size) ; REICAST_US(VREG); REICAST_US(ARMRST); @@ -1151,33 +616,27 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(aica_reg,0x8000); + u16 dummyshort; - - REICAST_USA(volume_lut,16); - REICAST_USA(tl_lut,256 + 768); - REICAST_USA(AEG_ATT_SPS,64); - REICAST_USA(AEG_DSR_SPS,64); - REICAST_US(pl); - REICAST_US(pr); + REICAST_SKIP(4 * 16); // volume_lut + REICAST_SKIP(4 * 256 + 768); // tl_lut. Due to a previous bug this is not 4 * (256 + 768) + REICAST_SKIP(4 * 64); // AEG_ATT_SPS + REICAST_SKIP(4 * 64); // AEG_DSR_SPS + REICAST_US(dummyshort); // pl + REICAST_US(dummyshort); // pr channel_unserialize(data, total_size) ; REICAST_USA(cdda_sector,CDDA_SIZE); REICAST_US(cdda_index); - REICAST_USA(mxlr,64); - REICAST_US(samples_gen); + REICAST_SKIP(4 * 64); // mxlr + REICAST_US(i); // samples_gen - - register_unserialize(sb_regs, data, total_size) ; + register_unserialize(sb_regs, data, total_size, V6_LIBRETRO) ; REICAST_US(SB_ISTNRM); REICAST_US(SB_FFST_rc); REICAST_US(SB_FFST); - - - //this is one-time init, no updates - don't need to serialize - //extern RomChip sys_rom; - REICAST_US(i); //LIBRETRO_S(sys_nvmem_sram.size); verify(i == 0); REICAST_US(i); //LIBRETRO_S(sys_nvmem_sram.mask); @@ -1192,10 +651,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) die("Naomi/Atomiswave libretro savestates are not supported"); REICAST_USA(sys_nvmem->data, sys_nvmem->size); - - //this is one-time init, no updates - don't need to serialize - //extern _vmem_handler area0_handler; - REICAST_USA(reply_11,16); REICAST_US(sns_asc); @@ -1222,19 +677,17 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(SecNumber); REICAST_US(GDStatus); REICAST_US(ByteCount); - REICAST_US(i); //LIBRETRO_S(GDROM_TICK); - + REICAST_US(i); // GDROM_TICK REICAST_USA(EEPROM,0x100); REICAST_US(EEPROM_loaded); + bool dumbool; REICAST_US(maple_ddt_pending_reset); - - mcfg_UnserializeDevices(data, total_size); - - REICAST_US(FrameCount); - REICAST_US(pend_rend); - + mcfg_UnserializeDevices(data, total_size, false); + REICAST_US(i); // FrameCount + REICAST_US(dumbool); // pend_rend + pend_rend = false; REICAST_USA(YUV_tempdata,512/4); REICAST_US(YUV_dest); @@ -1244,73 +697,65 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(YUV_x_size); REICAST_US(YUV_y_size); - bool dumbool; - REICAST_US(dumbool); //LIBRETRO_S(fog_needs_update); + REICAST_US(dumbool); // fog_needs_update REICAST_USA(pvr_regs,pvr_RegSize); fog_needs_update = true ; REICAST_US(in_vblank); REICAST_US(clc_pvr_scanline); - REICAST_US(pvr_numscanlines); - REICAST_US(prv_cur_scanline); - REICAST_US(vblk_cnt); - REICAST_US(Line_Cycles); - REICAST_US(Frame_Cycles); - REICAST_US(speed_load_mspdf); - REICAST_US(mips_counter); - REICAST_US(full_rps); + REICAST_US(i); // pvr_numscanlines + REICAST_US(i); // prv_cur_scanline + REICAST_US(i); // vblk_cnt + REICAST_US(i); // Line_Cycles + REICAST_US(i); // Frame_Cycles + REICAST_SKIP(8); // speed_load_mspdf + REICAST_US(i); // mips_counter + REICAST_SKIP(8); // full_rps - REICAST_USA(ta_type_lut,256); + REICAST_SKIP(4 * 256); // ta_type_lut REICAST_USA(ta_fsm,2049); REICAST_US(ta_fsm_cl); - - REICAST_US(dumbool); //LIBRETRO_S(pal_needs_update); - for (int i = 0; i < 4; i++) REICAST_US(j); //LIBRETRO_SA(_pal_rev_256,4); - for (int i = 0; i < 64; i++) REICAST_US(j); //LIBRETRO_SA(_pal_rev_16,64); - for (int i = 0; i < 4; i++) REICAST_US(j); //LIBRETRO_SA(pal_rev_256,4); - for (int i = 0; i < 64; i++) REICAST_US(j); //LIBRETRO_SA(pal_rev_16,64); + REICAST_US(dumbool); // pal_needs_update + for (int i = 0; i < 4; i++) REICAST_US(j); // _pal_rev_256 + for (int i = 0; i < 64; i++) REICAST_US(j); // _pal_rev_16 + for (int i = 0; i < 4; i++) REICAST_US(j); // pal_rev_256 + for (int i = 0; i < 64; i++) REICAST_US(j); // pal_rev_16 for ( i = 0 ; i < 3 ; i++ ) { u32 buf[65536]; //u32 *ptr = decoded_colors[i] ; REICAST_US(buf); //LIBRETRO_SA(ptr,65536); } - REICAST_US(tileclip_val); - REICAST_USA(f32_su8_tbl,65536); - REICAST_USA(FaceBaseColor,4); - REICAST_USA(FaceOffsColor,4); - REICAST_US(SFaceBaseColor); - REICAST_US(SFaceOffsColor); + REICAST_US(i); // tileclip_val + REICAST_SKIP(65536); // f32_su8_tbl + REICAST_SKIP(4); // FaceBaseColor + REICAST_SKIP(4); // FaceOffsColor + REICAST_US(i); // SFaceBaseColor + REICAST_US(i); // SFaceOffsColor pal_needs_update = true; - REICAST_US(i); //LIBRETRO_S(palette_index); - REICAST_US(dumbool); //LIBRETRO_S(KillTex); - for (int i = 0; i < 1024; i++) REICAST_US(j); //LIBRETRO_SA(palette16_ram,1024); - for (int i = 0; i < 1024; i++) REICAST_US(j); //LIBRETRO_SA(palette32_ram,1024); - for (i = 0 ; i < 2 ; i++) - for (j = 0 ; j < 8 ; j++) - { - u32 buf[1024]; //u32 *ptr = detwiddle[i][j] ; - REICAST_US(buf); //LIBRETRO_SA(ptr,1024); - } - REICAST_USA(vram.data, vram.size); + REICAST_US(i); // palette_index + REICAST_US(dumbool); // KillTex + REICAST_SKIP(4 * 1024); // palette16_ram + REICAST_SKIP(4 * 1024); // palette32_ram + REICAST_SKIP(2 * 8 * 4 * 1024); // detwiddle[][] + REICAST_USA(vram.data, vram.size); REICAST_USA(OnChipRAM.data,OnChipRAM_SIZE); - register_unserialize(CCN, data, total_size) ; - register_unserialize(UBC, data, total_size) ; - register_unserialize(BSC, data, total_size) ; - register_unserialize(DMAC, data, total_size) ; - register_unserialize(CPG, data, total_size) ; - register_unserialize(RTC, data, total_size) ; - register_unserialize(INTC, data, total_size) ; - register_unserialize(TMU, data, total_size) ; - register_unserialize(SCI, data, total_size) ; - register_unserialize(SCIF, data, total_size) ; + register_unserialize(CCN, data, total_size, V6_LIBRETRO) ; + register_unserialize(UBC, data, total_size, V6_LIBRETRO) ; + register_unserialize(BSC, data, total_size, V6_LIBRETRO) ; + register_unserialize(DMAC, data, total_size, V6_LIBRETRO) ; + register_unserialize(CPG, data, total_size, V6_LIBRETRO) ; + register_unserialize(RTC, data, total_size, V6_LIBRETRO) ; + register_unserialize(INTC, data, total_size, V6_LIBRETRO) ; + register_unserialize(TMU, data, total_size, V6_LIBRETRO) ; + register_unserialize(SCI, data, total_size, V6_LIBRETRO) ; + register_unserialize(SCIF, data, total_size, V6_LIBRETRO) ; REICAST_USA(mem_b.data, mem_b.size); - - REICAST_US(IRLPriority); + REICAST_US(dummyshort); // IRLPriority REICAST_USA(InterruptEnvId,32); REICAST_USA(InterruptBit,32); REICAST_USA(InterruptLevelBit,16); @@ -1328,25 +773,16 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) else if ( i == 3 ) do_sqw_nommu = &do_sqw_nommu_full ; - - REICAST_USA((*p_sh4rcb).sq_buffer,64/8); - //store these before unserializing and then restore after - //void *getptr = &((*p_sh4rcb).cntx.sr.GetFull) ; - //void *setptr = &((*p_sh4rcb).cntx.sr.SetFull) ; REICAST_US((*p_sh4rcb).cntx); - //(*p_sh4rcb).cntx.sr.GetFull = getptr ; - //(*p_sh4rcb).cntx.sr.SetFull = setptr ; - REICAST_US(old_rm); - REICAST_US(old_dn); + REICAST_US(i); // old_rm + REICAST_US(i); // old_dn REICAST_US(sh4_sched_ffb); REICAST_US(sh4_sched_intr); - //extern vector sch_list; - REICAST_US(sch_list[aica_schid].tag) ; REICAST_US(sch_list[aica_schid].start) ; REICAST_US(sch_list[aica_schid].end) ; @@ -1385,17 +821,16 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(sch_list[time_sync].tag) ; REICAST_US(sch_list[time_sync].start) ; REICAST_US(sch_list[time_sync].end) ; - - #ifdef ENABLE_MODEM +#ifdef ENABLE_MODEM REICAST_US(sch_list[modem_sched].tag) ; REICAST_US(sch_list[modem_sched].start) ; REICAST_US(sch_list[modem_sched].end) ; - #else +#else int modem_dummy; REICAST_US(modem_dummy); REICAST_US(modem_dummy); REICAST_US(modem_dummy); - #endif +#endif REICAST_US(SCIF_SCFSR2); REICAST_US(SCIF_SCFRDR2); @@ -1412,14 +847,15 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_USA(CCN_QACR_TR,2); - REICAST_USA(UTLB,64); - REICAST_USA(ITLB,4); + REICAST_USA(UTLB, 64); + REICAST_USA(ITLB, 4); + #if defined(NO_MMU) REICAST_USA(sq_remap,64); #else REICAST_USA(ITLB_LRU_USE,64); + REICAST_US(i); // mmu_error_TT #endif - REICAST_US(NullDriveDiscType); REICAST_USA(q_subchannel,96); @@ -1435,7 +871,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) - REICAST_US(naomi_updates); + REICAST_US(i); // naomi_updates REICAST_US(i); // BoardID REICAST_US(GSerialBuffer); REICAST_US(BSerialBuffer); @@ -1469,23 +905,23 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(i); #endif - REICAST_US(state); - REICAST_US(div_som_reg1); - REICAST_US(div_som_reg2); - REICAST_US(div_som_reg3); + REICAST_SKIP(sizeof(state_t)); // state + REICAST_US(i); // div_som_reg1 + REICAST_US(i); // div_som_reg2 + REICAST_US(i); // div_som_reg3 - //REICAST_USA(CodeCache,CODE_SIZE) ; - //REICAST_USA(SH4_TCB,CODE_SIZE+4096); - REICAST_US(i); //LastAddr - REICAST_US(i); //LastAddr_min - REICAST_USA(block_hash,1024); + REICAST_US(i); // LastAddr + REICAST_US(i); // LastAddr_min + REICAST_SKIP(1024); // block_hash - - REICAST_USA(RegisterWrite,sh4_reg_count); - REICAST_USA(RegisterRead,sh4_reg_count); - REICAST_US(fallback_blocks); - REICAST_US(total_blocks); - REICAST_US(REMOVED_OPS); + for (int i = 0; i < sh4_reg_count; i++) // RegisterRead, RegisterWrite + { + REICAST_US(j); + REICAST_US(j); + } + REICAST_US(i); // fallback_blocks); + REICAST_US(i); // total_blocks); + REICAST_US(i); // REMOVED_OPS REICAST_US(settings.dreamcast.broadcast); REICAST_US(settings.dreamcast.cable); @@ -1494,6 +930,8 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Unserialize(data, total_size); + DEBUG_LOG(SAVESTATE, "Loaded %d bytes (libretro compat)", *total_size); + return true ; } @@ -1506,9 +944,9 @@ bool dc_unserialize(void **data, unsigned int *total_size) *total_size = 0 ; REICAST_US(version) ; - if (version == V5_LIBRETRO) + if (version == V6_LIBRETRO) return dc_unserialize_libretro(data, total_size); - if (version != V4) + if (version != V4 && version != V5) { WARN_LOG(SAVESTATE, "Save State version not supported: %d", version); return false; @@ -1524,11 +962,8 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(armFiqEnable); REICAST_US(armMode); REICAST_US(Arm7Enabled); - REICAST_USA(cpuBitsSet,256); - bool dummy; - REICAST_US(dummy); - REICAST_US(dummy); - REICAST_US(dummy); + if (version < 5) + REICAST_SKIP(256 + 3); REICAST_US(dsp); @@ -1545,46 +980,40 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(aica_reg,0x8000); - REICAST_USA(volume_lut,16); - REICAST_USA(tl_lut,256 + 768); - REICAST_USA(AEG_ATT_SPS,64); - REICAST_USA(AEG_DSR_SPS,64); - REICAST_US(pl); - REICAST_US(pr); - + if (version < V5) + { + REICAST_SKIP(4 * 16); + REICAST_SKIP(4 * 256 + 768); + REICAST_SKIP(4 * 64); + REICAST_SKIP(4 * 64); + REICAST_SKIP(2); + REICAST_SKIP(2); + } channel_unserialize(data, total_size) ; REICAST_USA(cdda_sector,CDDA_SIZE); REICAST_US(cdda_index); - REICAST_USA(mxlr,64); - REICAST_US(samples_gen); + if (version < V5) + { + REICAST_SKIP(4 * 64); + REICAST_SKIP(4); + } - register_unserialize(sb_regs, data, total_size) ; + register_unserialize(sb_regs, data, total_size, version) ; REICAST_US(SB_ISTNRM); REICAST_US(SB_FFST_rc); REICAST_US(SB_FFST); + if (version < V5) + { + REICAST_SKIP(4); // size + REICAST_SKIP(4); // mask + } sys_rom->Unserialize(data, total_size); sys_nvmem->Unserialize(data, total_size); - /* - REICAST_US(sys_nvmem.size); - REICAST_US(sys_nvmem.mask); -#ifdef FLASH_SIZE - REICAST_US(sys_nvmem.state); -#endif - REICAST_USA(sys_nvmem.data,sys_nvmem.size); - */ - - //this is one-time init, no updates - don't need to serialize - //extern _vmem_handler area0_handler; - - - REICAST_USA(reply_11,16) ; - - REICAST_US(sns_asc); REICAST_US(sns_ascq); REICAST_US(sns_key); @@ -1610,18 +1039,19 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(GDStatus); REICAST_US(ByteCount); - REICAST_USA(EEPROM,0x100); REICAST_US(EEPROM_loaded); - REICAST_US(maple_ddt_pending_reset); - mcfg_UnserializeDevices(data, total_size); - - REICAST_US(FrameCount); - REICAST_US(pend_rend); + mcfg_UnserializeDevices(data, total_size, version < 5); + if (version < V5) + { + REICAST_SKIP(4); + REICAST_SKIP(1); // pend_rend + } + pend_rend = false; REICAST_USA(YUV_tempdata,512/4); REICAST_US(YUV_dest); @@ -1636,47 +1066,54 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(in_vblank); REICAST_US(clc_pvr_scanline); - REICAST_US(pvr_numscanlines); - REICAST_US(prv_cur_scanline); - REICAST_US(vblk_cnt); - REICAST_US(Line_Cycles); - REICAST_US(Frame_Cycles); - REICAST_US(speed_load_mspdf); - REICAST_US(mips_counter); - REICAST_US(full_rps); - REICAST_US(fskip); + if (version < V5) + { + REICAST_US(i); // pvr_numscanlines + REICAST_US(i); // prv_cur_scanline + REICAST_US(i); // vblk_cnt + REICAST_US(i); // Line_Cycles + REICAST_US(i); // Frame_Cycles + REICAST_SKIP(8); // speed_load_mspdf + REICAST_US(i); // mips_counter + REICAST_SKIP(8); // full_rps + REICAST_US(i); // fskip - REICAST_USA(ta_type_lut,256); - REICAST_USA(ta_fsm,2049); + REICAST_SKIP(4 * 256); + REICAST_SKIP(2048); // ta_fsm + } + REICAST_US(ta_fsm[2048]); REICAST_US(ta_fsm_cl); - REICAST_US(tileclip_val); - REICAST_USA(f32_su8_tbl,65536); - REICAST_USA(FaceBaseColor,4); - REICAST_USA(FaceOffsColor,4); - REICAST_US(SFaceBaseColor); - REICAST_US(SFaceOffsColor); - + if (version < V5) + { + REICAST_SKIP(4); + REICAST_SKIP(65536); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + } pal_needs_update = true; REICAST_USA(vram.data, vram.size); REICAST_USA(OnChipRAM.data,OnChipRAM_SIZE); - register_unserialize(CCN, data, total_size) ; - register_unserialize(UBC, data, total_size) ; - register_unserialize(BSC, data, total_size) ; - register_unserialize(DMAC, data, total_size) ; - register_unserialize(CPG, data, total_size) ; - register_unserialize(RTC, data, total_size) ; - register_unserialize(INTC, data, total_size) ; - register_unserialize(TMU, data, total_size) ; - register_unserialize(SCI, data, total_size) ; - register_unserialize(SCIF, data, total_size) ; + register_unserialize(CCN, data, total_size, version) ; + register_unserialize(UBC, data, total_size, version) ; + register_unserialize(BSC, data, total_size, version) ; + register_unserialize(DMAC, data, total_size, version) ; + register_unserialize(CPG, data, total_size, version) ; + register_unserialize(RTC, data, total_size, version) ; + register_unserialize(INTC, data, total_size, version) ; + register_unserialize(TMU, data, total_size, version) ; + register_unserialize(SCI, data, total_size, version) ; + register_unserialize(SCIF, data, total_size, version) ; REICAST_USA(mem_b.data, mem_b.size); - REICAST_US(IRLPriority); + if (version < V5) + REICAST_SKIP(2); REICAST_USA(InterruptEnvId,32); REICAST_USA(InterruptBit,32); REICAST_USA(InterruptLevelBit,16); @@ -1694,28 +1131,18 @@ bool dc_unserialize(void **data, unsigned int *total_size) else if ( i == 3 ) do_sqw_nommu = &do_sqw_nommu_full ; - - REICAST_USA((*p_sh4rcb).sq_buffer,64/8); - //store these before unserializing and then restore after - //void *getptr = &((*p_sh4rcb).cntx.sr.GetFull) ; - //void *setptr = &((*p_sh4rcb).cntx.sr.SetFull) ; REICAST_US((*p_sh4rcb).cntx); - //(*p_sh4rcb).cntx.sr.GetFull = getptr ; - //(*p_sh4rcb).cntx.sr.SetFull = setptr ; - - REICAST_US(old_rm); - REICAST_US(old_dn); - - - + if (version < V5) + { + REICAST_SKIP(4); + REICAST_SKIP(4); + } REICAST_US(sh4_sched_ffb); REICAST_US(sh4_sched_intr); - //extern vector list; - REICAST_US(sch_list[aica_schid].tag) ; REICAST_US(sch_list[aica_schid].start) ; REICAST_US(sch_list[aica_schid].end) ; @@ -1755,27 +1182,23 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(sch_list[time_sync].start) ; REICAST_US(sch_list[time_sync].end) ; - #ifdef ENABLE_MODEM +#ifdef ENABLE_MODEM REICAST_US(sch_list[modem_sched].tag) ; REICAST_US(sch_list[modem_sched].start) ; REICAST_US(sch_list[modem_sched].end) ; - #else +#else int modem_dummy; REICAST_US(modem_dummy); REICAST_US(modem_dummy); REICAST_US(modem_dummy); - #endif +#endif REICAST_US(SCIF_SCFSR2); REICAST_US(SCIF_SCFRDR2); REICAST_US(SCIF_SCFDR2); - REICAST_US(BSC_PDTRA); - - - REICAST_USA(tmu_shift,3); REICAST_USA(tmu_mask,3); REICAST_USA(tmu_mask64,3); @@ -1783,14 +1206,8 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(tmu_ch_base,3); REICAST_USA(tmu_ch_base64,3); - - - REICAST_USA(CCN_QACR_TR,2); - - - REICAST_USA(UTLB,64); REICAST_USA(ITLB,4); #if defined(NO_MMU) @@ -1799,24 +1216,14 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_USA(ITLB_LRU_USE,64); #endif - REICAST_US(NullDriveDiscType); REICAST_USA(q_subchannel,96); -// FIXME -// REICAST_US(i); // FLASH_SIZE -// REICAST_US(i); // BBSRAM_SIZE -// REICAST_US(i); // BIOS_SIZE -// REICAST_US(i); // RAM_SIZE -// REICAST_US(i); // ARAM_SIZE -// REICAST_US(i); // VRAM_SIZE -// REICAST_US(i); // RAM_MASK -// REICAST_US(i); // ARAM_MASK -// REICAST_US(i); // VRAM_MASK - - - REICAST_US(naomi_updates); - REICAST_US(i); // BoardID + if (version < V5) + { + REICAST_SKIP(4); + REICAST_SKIP(4); + } REICAST_US(GSerialBuffer); REICAST_US(BSerialBuffer); REICAST_US(GBufPos); @@ -1842,41 +1249,29 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(reg_dimm_4c); REICAST_US(NaomiDataRead); -#if FEAT_SHREC == DYNAREC_CPP - REICAST_US(idxnxx); -#else - REICAST_US(i); -#endif - - REICAST_US(state); - REICAST_US(div_som_reg1); - REICAST_US(div_som_reg2); - REICAST_US(div_som_reg3); - - //REICAST_USA(CodeCache,CODE_SIZE) ; - //REICAST_USA(SH4_TCB,CODE_SIZE+4096); - REICAST_US(i); //LastAddr - REICAST_US(i); //LastAddr_min); - REICAST_USA(block_hash,1024); - - REICAST_USA(RegisterWrite,sh4_reg_count); - REICAST_USA(RegisterRead,sh4_reg_count); - REICAST_US(fallback_blocks); - REICAST_US(total_blocks); - REICAST_US(REMOVED_OPS); - - REICAST_US(i); //REICAST_USA(kcode,4); - REICAST_US(i); - REICAST_US(i); //REICAST_USA(rt,4); - REICAST_US(i); //REICAST_USA(lt,4); - REICAST_US(i); //REICAST_USA(vks,4); - REICAST_US(i); - REICAST_US(i); - REICAST_US(i); - REICAST_US(i); //REICAST_USA(joyx,4); - REICAST_US(i); //REICAST_USA(joyy,4); + if (version < V5) + { + REICAST_US(i); // idxnxx + REICAST_SKIP(sizeof(state_t)); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(1024); + REICAST_SKIP(8 * sh4_reg_count); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(2 * 4); + REICAST_SKIP(4); + REICAST_SKIP(4); + REICAST_SKIP(4 * 4); + REICAST_SKIP(4); + REICAST_SKIP(4); + } REICAST_US(settings.dreamcast.broadcast); REICAST_US(settings.dreamcast.cable); REICAST_US(settings.dreamcast.region); @@ -1884,6 +1279,8 @@ bool dc_unserialize(void **data, unsigned int *total_size) if (CurrentCartridge != NULL) CurrentCartridge->Unserialize(data, total_size); + DEBUG_LOG(SAVESTATE, "Loaded %d bytes", *total_size); + return true ; } #endif From 14ddd01e39ae23a5e2f82204477cb4d00169eac5 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 12 Jul 2019 17:53:17 +0200 Subject: [PATCH 143/158] compilation warnings --- core/arm_emitter/E_VDataOp.h | 2 +- core/arm_emitter/H_Branches.h | 6 +++--- core/deps/coreio/coreio.cpp | 2 +- core/hw/maple/maple_cfg.cpp | 5 ++++- core/hw/pvr/Renderer_if.h | 1 + core/reios/gdrom_hle.cpp | 4 ++-- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/core/arm_emitter/E_VDataOp.h b/core/arm_emitter/E_VDataOp.h index f33ebc743..81869fff1 100755 --- a/core/arm_emitter/E_VDataOp.h +++ b/core/arm_emitter/E_VDataOp.h @@ -627,7 +627,7 @@ namespace ARM eFSReg SnS=(eFSReg)(Sn*2); eFSReg SmS=(eFSReg)(Sm*2); - verify(Sd<32 && Sn<32 && Sm<32); + verify((int)Sd < 32 && (int)Sn < 32 && (int)Sm < 32); VDIV_VFP(SdS,SnS,SmS); } diff --git a/core/arm_emitter/H_Branches.h b/core/arm_emitter/H_Branches.h index 0193a888f..ff3ca6454 100644 --- a/core/arm_emitter/H_Branches.h +++ b/core/arm_emitter/H_Branches.h @@ -27,13 +27,13 @@ namespace ARM snat lit = Literal(FnAddr); if(0==lit) { - printf("Error, Compiler caught NULL literal, CALL(%08X)\n", FnAddr); + printf("Error, Compiler caught NULL literal, CALL(%08zX)\n", FnAddr); verify(false); return; } if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX { - printf("Warning, CALL(%08X) is out of range for literal(%08X)\n", FnAddr, lit); + printf("Warning, CALL(%08zX) is out of range for literal(%08zX)\n", FnAddr, lit); // verify(false); MOV32(IP, FnAddr, CC); @@ -66,7 +66,7 @@ namespace ARM }*/ if( (lit<-33554432) || (lit>33554428) ) // ..28 for BL ..30 for BLX { - printf("Warning, %X is out of range for imm jump! \n", FnAddr); + printf("Warning, %zX is out of range for imm jump! \n", FnAddr); //verify(false); MOV32(IP, FnAddr, CC); diff --git a/core/deps/coreio/coreio.cpp b/core/deps/coreio/coreio.cpp index f3f37b97a..67e70d801 100644 --- a/core/deps/coreio/coreio.cpp +++ b/core/deps/coreio/coreio.cpp @@ -148,7 +148,7 @@ size_t HTTP_GET(string host, int port,string path, size_t offs, size_t len, void string CL = "Content-Length:"; if (ln.substr(0, CL.size()) == CL) { - sscanf(ln.substr(CL.size(), ln.npos).c_str(),"%d", &content_length); + sscanf(ln.substr(CL.size(), ln.npos).c_str(),"%zd", &content_length); } break; diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index bddf40e0b..02c00dc88 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -204,6 +204,9 @@ void mcfg_CreateDevices() if (settings.input.maple_expansion_devices[bus][0] != MDT_None) mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); break; + default: + WARN_LOG(MAPLE, "Invalid device type %d for port %d", settings.input.maple_devices[bus], bus); + break; } } } @@ -258,7 +261,7 @@ void mcfg_UnserializeDevices(void **data, unsigned int *total_size, bool old) *total_size = *total_size + 1; if (old) { - switch (device_type) + switch ((OldMapleDeviceType::MapleDeviceType)device_type) { case OldMapleDeviceType::MDT_None: device_type = MDT_None; diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index 6784d2db0..b53865f97 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -36,6 +36,7 @@ extern TA_context* _pvrrc; struct Renderer { virtual bool Init()=0; + virtual ~Renderer() {} virtual void Resize(int w, int h)=0; diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index 0bc9fe9ae..bee6342cf 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -192,14 +192,14 @@ void gdrom_hle_op() case GDROM_RESET: INFO_LOG(REIOS, "GDROM:\tHLE GDROM_RESET"); break; case GDROM_CHECK_DRIVE: // - debugf("\nGDROM:\tHLE GDROM_CHECK_DRIVE r4:%X\n",r[4],r[5]); + debugf("\nGDROM:\tHLE GDROM_CHECK_DRIVE r4:%X\n",r[4]); WriteMem32(r[4]+0,0x02); // STANDBY WriteMem32(r[4]+4,libGDR_GetDiscType()); // CDROM | 0x80 for GDROM r[0]=0; // RET SUCCESS break; case GDROM_ABORT_COMMAND: // - INFO_LOG(REIOS, "GDROM:\tHLE GDROM_ABORT_COMMAND r4:%X",r[4],r[5]); + INFO_LOG(REIOS, "GDROM:\tHLE GDROM_ABORT_COMMAND r4:%X",r[4]); r[0]=-1; // RET FAILURE break; From 68acf48d642c1b9a2ae1f0d311ce2df51e3b6347 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 12 Jul 2019 19:18:39 +0200 Subject: [PATCH 144/158] Support for Twin Stick and Ascii FT Stick --- core/hw/maple/maple_cfg.cpp | 13 ++++++ core/hw/maple/maple_devs.cpp | 91 +++++++++++++++++++++++++++++++++++- core/rend/gui.cpp | 14 +++++- 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 02c00dc88..4816ff018 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -204,6 +204,19 @@ void mcfg_CreateDevices() if (settings.input.maple_expansion_devices[bus][0] != MDT_None) mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); break; + + case MDT_TwinStick: + mcfg_Create(MDT_TwinStick, bus, 5); + if (settings.input.maple_expansion_devices[bus][0] != MDT_None) + mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); + break; + + case MDT_AsciiStick: + mcfg_Create(MDT_AsciiStick, bus, 5); + if (settings.input.maple_expansion_devices[bus][0] != MDT_None) + mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); + break; + default: WARN_LOG(MAPLE, "Invalid device type %d for port %d", settings.input.maple_devices[bus], bus); break; diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index a745a748c..213f994f3 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -26,6 +26,8 @@ const char* maple_sega_dreameye_name_2 = "Dreamcast Camera Flash LDevic"; const char* maple_sega_mic_name = "MicDevice for Dreameye"; const char* maple_sega_purupuru_name = "Puru Puru Pack"; const char* maple_sega_lightgun_name = "Dreamcast Gun"; +const char* maple_sega_twinstick_name = "Twin Stick"; +const char* maple_ascii_stick_name = "ASCII STICK"; const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD."; @@ -222,6 +224,16 @@ struct maple_sega_controller: maple_base return MDT_SegaController; } + virtual const char *get_device_name() + { + return maple_sega_controller_name; + } + + virtual const char *get_device_brand() + { + return maple_sega_brand; + } + virtual u32 dma(u32 cmd) { //printf("maple_sega_controller::dma Called 0x%X;Command %d\n", bus_id, cmd); @@ -245,10 +257,10 @@ struct maple_sega_controller: maple_base w8(0); //30 - wstr(maple_sega_controller_name,30); + wstr(get_device_name(), 30); //60 - wstr(maple_sega_brand,60); + wstr(get_device_brand(), 60); //2 w16(0x01AE); // 43 mA @@ -332,6 +344,73 @@ struct maple_atomiswave_controller: maple_sega_controller } }; +/* + Sega Twin Stick Controller +*/ +struct maple_sega_twinstick: maple_sega_controller +{ + virtual u32 get_capabilities() override { + // byte 0: 0 0 0 0 0 0 0 0 + // byte 1: 0 0 a5 a4 a3 a2 a1 a0 + // byte 2: R2 L2 D2 U2 D X Y Z + // byte 3: R L D U St A B C + + return 0xfefe0000; // no analog axes, X Y A B D Start U/D/L/R U2/D2/L2/R2 + } + + virtual u32 transform_kcode(u32 kcode) override { + return kcode | 0x0101; + } + + virtual MapleDeviceType get_device_type() override + { + return MDT_TwinStick; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) override { + return 0x80; + } + + virtual const char *get_device_name() + { + return maple_sega_twinstick_name; + } +}; + + +/* + Ascii Stick (Arcade/FT Stick) +*/ +struct maple_ascii_stick: maple_sega_controller +{ + virtual u32 get_capabilities() override { + // byte 0: 0 0 0 0 0 0 0 0 + // byte 1: 0 0 a5 a4 a3 a2 a1 a0 + // byte 2: R2 L2 D2 U2 D X Y Z + // byte 3: R L D U St A B C + + return 0xff070000; // no analog axes, X Y Z A B C Start U/D/L/R + } + + virtual u32 transform_kcode(u32 kcode) override { + return kcode | 0xF800; + } + + virtual MapleDeviceType get_device_type() + { + return MDT_AsciiStick; + } + + virtual u32 get_analog_axis(int index, const PlainJoystickState &pjs) override { + return 0x80; + } + + virtual const char *get_device_name() + { + return maple_ascii_stick_name; + } +}; + /* Sega Dreamcast Visual Memory Unit This is pretty much done (?) @@ -2656,6 +2735,14 @@ maple_device* maple_Create(MapleDeviceType type) rv = new maple_naomi_jamma(); break; + case MDT_TwinStick: + rv = new maple_sega_twinstick(); + break; + + case MDT_AsciiStick: + rv = new maple_ascii_stick(); + break; + default: ERROR_LOG(MAPLE, "Invalid device type %d", type); die("Invalid maple device type"); diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index e87b3a4fd..58334b202 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -356,7 +356,7 @@ static void gui_display_commands() settings_opening = false; } -const char *maple_device_types[] = { "None", "Sega Controller", "Light Gun", "Keyboard", "Mouse" }; +const char *maple_device_types[] = { "None", "Sega Controller", "Light Gun", "Keyboard", "Mouse", "Twin Stick", "Ascii Stick" }; const char *maple_expansion_device_types[] = { "None", "Sega VMU", "Purupuru", "Microphone" }; static const char *maple_device_name(MapleDeviceType type) @@ -371,6 +371,10 @@ static const char *maple_device_name(MapleDeviceType type) return maple_device_types[3]; case MDT_Mouse: return maple_device_types[4]; + case MDT_TwinStick: + return maple_device_types[5]; + case MDT_AsciiStick: + return maple_device_types[6]; case MDT_None: default: return maple_device_types[0]; @@ -389,6 +393,10 @@ static MapleDeviceType maple_device_type_from_index(int idx) return MDT_Keyboard; case 4: return MDT_Mouse; + case 5: + return MDT_TwinStick; + case 6: + return MDT_AsciiStick; case 0: default: return MDT_None; @@ -829,7 +837,9 @@ static void gui_display_settings() } ImGui::EndCombo(); } - int port_count = settings.input.maple_devices[bus] == MDT_SegaController ? 2 : settings.input.maple_devices[bus] == MDT_LightGun ? 1 : 0; + int port_count = settings.input.maple_devices[bus] == MDT_SegaController ? 2 + : settings.input.maple_devices[bus] == MDT_LightGun || settings.input.maple_devices[bus] == MDT_TwinStick || settings.input.maple_devices[bus] == MDT_AsciiStick ? 1 + : 0; for (int port = 0; port < port_count; port++) { ImGui::SameLine(); From e63d7d717e58503187c1267d5d5b5e82d61296e7 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 13 Jul 2019 10:59:20 +0200 Subject: [PATCH 145/158] Fix Restart crash. Clear texture cache during reset --- core/hw/pvr/drkPvr.cpp | 3 ++- core/rend/gui.cpp | 33 ++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/core/hw/pvr/drkPvr.cpp b/core/hw/pvr/drkPvr.cpp index 60241e89e..2b1eef451 100644 --- a/core/hw/pvr/drkPvr.cpp +++ b/core/hw/pvr/drkPvr.cpp @@ -16,7 +16,7 @@ #include "pvr_regs.h" #include "pvr_mem.h" #include "Renderer_if.h" - +#include "rend/TexCache.h" void libPvr_LockedBlockWrite (vram_block* block,u32 addr) { @@ -26,6 +26,7 @@ void libPvr_LockedBlockWrite (vram_block* block,u32 addr) void libPvr_Reset(bool hard) { + KillTex = true; Regs_Reset(hard); spg_Reset(hard); } diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 58334b202..4ab7b82ec 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -70,6 +70,7 @@ static float scaling = 1; GuiState gui_state = Main; static bool settings_opening; static bool touch_up; +static std::string error_msg; static void display_vmus(); static void reset_vmus(); @@ -292,6 +293,19 @@ void gui_open_settings() } } +static void gui_start_game(const std::string& path) +{ + try { + dc_start_game(path.empty() ? NULL : path.c_str()); + } catch (ReicastException& ex) { + ERROR_LOG(BOOT, "%s", ex.reason.c_str()); + error_msg = ex.reason; + gui_state = Main; + game_started = false; + cfgSetVirtual("config", "image", ""); + } +} + static void gui_display_commands() { dc_stop(); @@ -337,8 +351,8 @@ static void gui_display_commands() ImGui::NextColumn(); if (ImGui::Button("Restart", ImVec2(150 * scaling, 50 * scaling))) { - dc_reset(true); - gui_state = Closed; + gui_state = ClosedNoResume; + gui_start_game(cfgLoadStr("config", "image", "")); } ImGui::NextColumn(); if (ImGui::Button("Exit", ImVec2(150 * scaling, 50 * scaling))) @@ -587,8 +601,6 @@ static void controller_mapping_popup(std::shared_ptr gamepad) ImGui::PopStyleVar(); } -static std::string error_msg; - static void error_popup() { if (!error_msg.empty()) @@ -1413,19 +1425,6 @@ static void gui_display_demo() ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData(), false); } -static void gui_start_game(const std::string& path) -{ - try { - dc_start_game(path.empty() ? NULL : path.c_str()); - } catch (ReicastException& ex) { - ERROR_LOG(BOOT, "%s", ex.reason.c_str()); - error_msg = ex.reason; - gui_state = Main; - game_started = false; - cfgSetVirtual("config", "image", ""); - } -} - static void gui_display_content() { ImGui_Impl_NewFrame(); From a13633560d98ee2340ce1b71113cd1723ce91144 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 13 Jul 2019 11:08:11 +0200 Subject: [PATCH 146/158] remove naomi config from CI files --- appveyor.yml | 4 ---- bitrise.yml | 27 --------------------------- 2 files changed, 31 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cfefcd4a2..c291b1f1e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,14 +23,10 @@ build_script: - cmd: >- if "%CONFIGURATION%"=="fast" (mingw32-make platform=win32) - if "%CONFIGURATION%"=="naomi" (mingw32-make platform=win32 NAOMI=1) - after_build: - cmd: >- if "%CONFIGURATION%"=="fast" (cd ..\.. && set EXE_PATH=shell\linux\nosym-reicast.exe) - if "%CONFIGURATION%"=="naomi" (cd ..\.. && set EXE_PATH=shell\linux\nosym-reicast.exe) - mkdir artifacts move %EXE_PATH% artifacts\flycast-win_%PLATFORM%-%CONFIGURATION%-%APPVEYOR_REPO_COMMIT%.exe diff --git a/bitrise.yml b/bitrise.yml index 33a4c9791..bb692e150 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -8,33 +8,6 @@ trigger_map: - pull_request_source_branch: "*" workflow: deploy workflows: - deploy-naomi: - envs: - - opts: - is_expand: false - BITRISE_SCHEME: reicast-osx-naomi - steps: - - activate-ssh-key@4.0.3: - run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}' - - git-clone@4.0.14: {} - - cache-pull@2.0.1: {} - - certificate-and-profile-installer@1.10.1: {} - - recreate-user-schemes@1.0.2: - inputs: - - project_path: "$BITRISE_PROJECT_PATH" - - xcode-archive-mac@1.6.2: - inputs: - - project_path: "$BITRISE_PROJECT_PATH" - - scheme: "$BITRISE_SCHEME" - - export_method: "$BITRISE_EXPORT_METHOD" - - amazon-s3-uploader@1.0.1: - inputs: - - aws_access_key: AKIAJOZQS4H2PHQWYFCA - - aws_secret_key: "$S3_SECRET_KEY" - - bucket_name: flycast-builds - - path_in_bucket: osx/$GIT_BUILD - - file_path: "$BITRISE_EXPORTED_FILE_PATH" - - cache-push@2.1.1: {} deploy: envs: - opts: From bbc11a30aa846e95b13c9bf4b5c60827d53cf78a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 13 Jul 2019 12:44:10 +0200 Subject: [PATCH 147/158] Naomi rename vars and clean up. Logging changes. --- core/hw/flashrom/flashrom.h | 2 +- core/hw/mem/_vmem.cpp | 14 +-- core/hw/naomi/naomi.cpp | 145 ++++++++------------------------ core/hw/naomi/naomi.h | 22 ++--- core/hw/naomi/naomi_cart.cpp | 74 ++++++++-------- core/hw/sh4/modules/fastmmu.cpp | 2 +- core/hw/sh4/modules/mmu.cpp | 2 + core/hw/sh4/modules/wince.h | 42 ++++----- core/rend/norend/norend.cpp | 2 +- core/serialize.cpp | 40 ++++----- 10 files changed, 127 insertions(+), 218 deletions(-) diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index 807f128e6..561de1d9f 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -283,7 +283,7 @@ struct DCFlashChip : MemChip state = FS_ReadAMDID1; break; default: - EMUERROR("Unknown FlashWrite mode: %x\n", val); + INFO_LOG(FLASHROM, "Unknown FlashWrite mode: %x\n", val); break; } break; diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 1eb8d6bf9..96453c6a5 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -299,31 +299,31 @@ void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet(Address //default read handlers u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss) { - DEBUG_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); + INFO_LOG(MEMORY, "[sh4]Read8 from 0x%X, not mapped [_vmem default handler]", addresss); return (u8)MEM_ERROR_RETURN_VALUE; } u16 DYNACALL _vmem_ReadMem16_not_mapped(u32 addresss) { - DEBUG_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); + INFO_LOG(MEMORY, "[sh4]Read16 from 0x%X, not mapped [_vmem default handler]", addresss); return (u16)MEM_ERROR_RETURN_VALUE; } -u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 addresss) +u32 DYNACALL _vmem_ReadMem32_not_mapped(u32 address) { - DEBUG_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", addresss); + INFO_LOG(MEMORY, "[sh4]Read32 from 0x%X, not mapped [_vmem default handler]", address); return (u32)MEM_ERROR_RETURN_VALUE; } //default write handers void DYNACALL _vmem_WriteMem8_not_mapped(u32 addresss,u8 data) { - DEBUG_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + INFO_LOG(MEMORY, "[sh4]Write8 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } void DYNACALL _vmem_WriteMem16_not_mapped(u32 addresss,u16 data) { - DEBUG_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + INFO_LOG(MEMORY, "[sh4]Write16 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } void DYNACALL _vmem_WriteMem32_not_mapped(u32 addresss,u32 data) { - DEBUG_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); + INFO_LOG(MEMORY, "[sh4]Write32 to 0x%X=0x%X, not mapped [_vmem default handler]", addresss, data); } //code to register handlers //0 is considered error :) diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index 131559ea7..3444771c3 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -8,6 +8,7 @@ #include "hw/holly/holly_intc.h" #include "hw/maple/maple_cfg.h" #include "hw/sh4/sh4_sched.h" +#include "hw/sh4/modules/dmac.h" #include "naomi.h" #include "naomi_cart.h" @@ -340,23 +341,6 @@ u16 NaomiGameIDRead() return (GSerialBuffer&(1<<(31-GBufPos)))?1:0; } - - - -u32 _ReadMem_naomi(u32 Addr, u32 sz) -{ - verify(sz!=1); - - DEBUG_LOG(NAOMI, "naomi?WTF? ReadMem: %X, %d", Addr, sz); - return 1; - -} -void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) -{ - DEBUG_LOG(NAOMI, "naomi?WTF? WriteMem: %X <= %X, %d", Addr, data, sz); -} - - //DIMM board //Uses interrupt ext#3 (holly_EXT_PCI) @@ -382,23 +366,22 @@ void _WriteMem_naomi(u32 Addr, u32 data, u32 sz) //n1 bios writes the value -1, meaning it expects the bit 0 to be set //.// -u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? -u32 reg_dimm_40; //parameters -u32 reg_dimm_44; //parameters -u32 reg_dimm_48; //parameters - -u32 reg_dimm_4c=0x11; //status/control reg ? +u32 reg_dimm_command; // command, written, 0x1E03 some flag ? +u32 reg_dimm_offsetl; +u32 reg_dimm_parameterl; +u32 reg_dimm_parameterh; +u32 reg_dimm_status = 0x11; bool NaomiDataRead = false; static bool aw_ram_test_skipped = false; -void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) +void naomi_process(u32 command, u32 offsetl, u32 parameterl, u32 parameterh) { - DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", r3c, r40, r44, r48); - DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",r3c >> 15,(r3c & 0x7e00) >> 9, r3c & 0x1FF); - DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (r3c & 0xFF00) >> 8,r3c & 0xFF); + DEBUG_LOG(NAOMI, "Naomi process 0x%04X 0x%04X 0x%04X 0x%04X", command, offsetl, parameterl, parameterh); + DEBUG_LOG(NAOMI, "Possible format 0 %d 0x%02X 0x%04X",command >> 15,(command & 0x7e00) >> 9, command & 0x1FF); + DEBUG_LOG(NAOMI, "Possible format 1 0x%02X 0x%02X", (command & 0xFF00) >> 8,command & 0xFF); - u32 param=(r3c&0xFF); + u32 param=(command&0xFF); if (param==0xFF) { DEBUG_LOG(NAOMI, "invalid opcode or smth ?"); @@ -407,8 +390,8 @@ void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48) //else if (param!=3) if (opcd<255) { - reg_dimm_3c=0x8000 | (opcd%12<<9) | (0x0); - DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_3c); + reg_dimm_command=0x8000 | (opcd%12<<9) | (0x0); + DEBUG_LOG(NAOMI, "new reg is 0x%X", reg_dimm_command); asic_RaiseInterrupt(holly_EXP_PCI); DEBUG_LOG(NAOMI, "Interrupt raised"); opcd++; @@ -451,11 +434,12 @@ void Naomi_DmaStart(u32 addr, u32 data) if (SB_GDST==1) { verify(1 == SB_GDDIR ); - - SB_GDSTARD=SB_GDSTAR+SB_GDLEN; + DEBUG_LOG(NAOMI, "NAOMI-DMA start addr %08X len %d", SB_GDSTAR, SB_GDLEN); + + SB_GDSTARD = SB_GDSTAR + SB_GDLEN; - SB_GDLEND=SB_GDLEN; - SB_GDST=0; + SB_GDLEND = SB_GDLEN; + SB_GDST = 0; if (CurrentCartridge != NULL) { u32 len = SB_GDLEN; @@ -464,8 +448,12 @@ void Naomi_DmaStart(u32 addr, u32 data) { u32 block_len = len; void* ptr = CurrentCartridge->GetDmaPtr(block_len); - if (ptr != NULL) - WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); + if (block_len == 0) + { + INFO_LOG(NAOMI, "Aborted DMA transfer. Read past end of cart?"); + break; + } + WriteMemBlock_nommu_ptr(SB_GDSTAR + offset, (u32*)ptr, block_len); CurrentCartridge->AdvancePtr(block_len); len -= block_len; offset += block_len; @@ -573,82 +561,11 @@ void naomi_reg_Reset(bool Manual) GLastCmd = 0; SerStep = 0; SerStep2 = 0; -} - -void Update_naomi() -{ - /* - if (naomi_updates>1) - { - naomi_updates--; - } - else if (naomi_updates==1) - { - naomi_updates=0; - asic_RaiseInterrupt(holly_EXP_PCI); - }*/ -#if 0 - if(!(SB_GDST&1) || !(SB_GDEN &1)) - return; - - //SB_GDST=0; - - //TODO : Fix dmaor - u32 dmaor = DMAC_DMAOR.full; - - u32 src = SB_GDSTARD, - len = SB_GDLEN-SB_GDLEND ; - - //len=min(len,(u32)32); - // do we need to do this for gdrom dma ? - if(0x8201 != (dmaor &DMAOR_MASK)) { - INFO_LOG(NAOMI, "GDROM: DMAOR has invalid settings (%X) !", dmaor); - //return; - } - if(len & 0x1F) { - INFO_LOG(NAOMI, "GDROM: SB_GDLEN has invalid size (%X) !", len); - return; - } - - if(0 == len) - { - INFO_LOG(NAOMI, "GDROM: Len: %X, Abnormal Termination !", len); - } - u32 len_backup=len; - if( 1 == SB_GDDIR ) - { - WriteMemBlock_nommu_ptr(dst,NaomiRom+(DmaOffset&0x7ffffff),size); - - DmaCount=0xffff; - } - else - INFO_LOG(NAOMI, "GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)"); - - //SB_GDLEN = 0x00000000; //13/5/2k7 -> acording to docs these regs are not updated by hardware - //SB_GDSTAR = (src + len_backup); - - SB_GDLEND+= len_backup; - SB_GDSTARD+= len_backup;//(src + len_backup)&0x1FFFFFFF; - - if (SB_GDLEND==SB_GDLEN) - { - //printf("Streamed GDMA end - %d bytes trasnfered\n",SB_GDLEND); - SB_GDST=0;//done - // The DMA end interrupt flag - asic_RaiseInterrupt(holly_GDROM_DMA); - } - //Readed ALL sectors - if (read_params.remaining_sectors==0) - { - u32 buff_size =read_buff.cache_size - read_buff.cache_index; - //And all buffer :p - if (buff_size==0) - { - verify(!SB_GDST&1) - gd_set_state(gds_procpacketdone); - } - } -#endif + reg_dimm_command = 0; + reg_dimm_offsetl = 0; + reg_dimm_parameterl = 0; + reg_dimm_parameterh = 0; + reg_dimm_status = 0x11; } static u8 aw_maple_devs; @@ -659,6 +576,10 @@ u32 libExtDevice_ReadMem_A0_006(u32 addr,u32 size) { //printf("libExtDevice_ReadMem_A0_006 %d@%08x: %x\n", size, addr, mem600[addr]); switch (addr) { +// case 0: +// return 0; +// case 4: +// return 1; case 0x280: // 0x00600280 r 0000dcba // a/b - 1P/2P coin inputs (JAMMA), active low diff --git a/core/hw/naomi/naomi.h b/core/hw/naomi/naomi.h index 8781f034b..88ae8cb58 100644 --- a/core/hw/naomi/naomi.h +++ b/core/hw/naomi/naomi.h @@ -8,8 +8,6 @@ void naomi_reg_Init(); void naomi_reg_Term(); void naomi_reg_Reset(bool Manual); -void Update_naomi(); - u32 ReadMem_naomi(u32 Addr, u32 sz); void WriteMem_naomi(u32 Addr, u32 data, u32 sz); @@ -20,21 +18,11 @@ u16 NaomiGameIDRead(); void NaomiGameIDWrite(const u16 Data); void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48); -typedef u16 (*getNaomiAxisFP)(); - -struct NaomiInputMapping { - getNaomiAxisFP axis[8]; - u8 button_mapping_byte[16]; - u8 button_mapping_mask[16]; -}; - -extern NaomiInputMapping Naomi_Mapping; - -extern u32 reg_dimm_3c; //IO window ! written, 0x1E03 some flag ? -extern u32 reg_dimm_40; //parameters -extern u32 reg_dimm_44; //parameters -extern u32 reg_dimm_48; //parameters -extern u32 reg_dimm_4c; //status/control reg ? +extern u32 reg_dimm_command; // command, written, 0x1E03 some flag ? +extern u32 reg_dimm_offsetl; +extern u32 reg_dimm_parameterl; +extern u32 reg_dimm_parameterh; +extern u32 reg_dimm_status; extern bool NaomiDataRead; extern u32 naomi_updates; diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 209df28cb..cc9a708c2 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -730,23 +730,25 @@ void NaomiCartridge::AdvancePtr(u32 size) { u32 NaomiCartridge::ReadMem(u32 address, u32 size) { verify(size!=1); - //printf("+naomi?WTF? ReadMem: %X, %d\n", address, size); + switch(address & 255) { - case 0x3c: - DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); - return reg_dimm_3c | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios - case 0x40: - DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); - return reg_dimm_40; - case 0x44: - DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); - return reg_dimm_44; - case 0x48: - DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); - return reg_dimm_48; + case 0x3c: // 5f703c: DIMM COMMAND + DEBUG_LOG(NAOMI, "DIMM COMMAND read<%d>", size); + return reg_dimm_command | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios + case 0x40: // 5f7040: DIMM OFFSETL + DEBUG_LOG(NAOMI, "DIMM OFFSETL read<%d>", size); + return reg_dimm_offsetl; + case 0x44: // 5f7044: DIMM PARAMETERL + DEBUG_LOG(NAOMI, "DIMM PARAMETERL read<%d>", size); + return reg_dimm_parameterl; + case 0x48: // 5f7048: DIMM PARAMETERH + DEBUG_LOG(NAOMI, "DIMM PARAMETERH read<%d>", size); + return reg_dimm_parameterh; + case 0x04C: // 5f704c: DIMM STATUS + DEBUG_LOG(NAOMI, "DIMM STATUS read<%d>", size); + return reg_dimm_status; - //These are known to be valid on normal ROMs and DIMM board case NAOMI_ROM_OFFSETH_addr&255: return RomPioOffset>>16 | (RomPioAutoIncrement << 15); @@ -786,7 +788,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) return 1; - //This should be valid case NAOMI_DMA_OFFSETH_addr&255: return DmaOffset>>16; case NAOMI_DMA_OFFSETL_addr&255: @@ -796,10 +797,6 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) DEBUG_LOG(NAOMI, "naomi ReadBoardId: %X, %d", address, size); return 1; - case 0x04C: - DEBUG_LOG(NAOMI, "naomi GD? READ: %X, %d", address, size); - return reg_dimm_4c; - case NAOMI_COMM2_CTRL_addr & 255: DEBUG_LOG(NAOMI, "NAOMI_COMM2_CTRL read"); return comm_ctrl; @@ -840,35 +837,34 @@ u32 NaomiCartridge::ReadMem(u32 address, u32 size) void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) { - // printf("+naomi WriteMem: %X <= %X, %d\n", address, data, size); switch(address & 255) { - case 0x3c: - if (0x1E03==data) + case 0x3c: // 5f703c: DIMM COMMAND + if (0x1E03 == data) { /* - if (!(reg_dimm_4c&0x100)) + if (!(reg_dimm_status & 0x100)) asic_RaiseInterrupt(holly_EXP_PCI); - reg_dimm_4c|=1;*/ + reg_dimm_status |= 1;*/ } - reg_dimm_3c=data; - DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); + reg_dimm_command = data; + DEBUG_LOG(NAOMI, "DIMM COMMAND Write: %X <= %X, %d", address, data, size); return; - case 0x40: - reg_dimm_40=data; - DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); + case 0x40: // 5f7040: DIMM OFFSETL + reg_dimm_offsetl = data; + DEBUG_LOG(NAOMI, "DIMM OFFSETL Write: %X <= %X, %d", address, data, size); return; - case 0x44: - reg_dimm_44=data; - DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); + case 0x44: // 5f7044: DIMM PARAMETERL + reg_dimm_parameterl = data; + DEBUG_LOG(NAOMI, "DIMM PARAMETERL Write: %X <= %X, %d", address, data, size); return; - case 0x48: - reg_dimm_48=data; - DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); + case 0x48: // 5f7048: DIMM PARAMETERH + reg_dimm_parameterh = data; + DEBUG_LOG(NAOMI, "DIMM PARAMETERH Write: %X <= %X, %d", address, data, size); return; - case 0x4C: + case 0x4C: // 5f704c: DIMM STATUS if (data&0x100) { asic_CancelInterrupt(holly_EXP_PCI); @@ -879,10 +875,10 @@ void NaomiCartridge::WriteMem(u32 address, u32 data, u32 size) /*FILE* ramd=fopen("c:\\ndc.ram.bin","wb"); fwrite(mem_b.data,1,RAM_SIZE,ramd); fclose(ramd);*/ - naomi_process(reg_dimm_3c,reg_dimm_40,reg_dimm_44,reg_dimm_48); + naomi_process(reg_dimm_command, reg_dimm_offsetl, reg_dimm_parameterl, reg_dimm_parameterh); } - reg_dimm_4c=data&~0x100; - DEBUG_LOG(NAOMI, "naomi GD? Write: %X <= %X, %d", address, data, size); + reg_dimm_status = data & ~0x100; + DEBUG_LOG(NAOMI, "DIMM STATUS Write: %X <= %X, %d", address, data, size); return; //These are known to be valid on normal ROMs and DIMM board diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index c1d685b4e..e5e681777 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -323,7 +323,7 @@ u32 mmu_data_translation(u32 va, u32& rv) if (va == unresolved_unicode_string) { unresolved_unicode_string = 0; - INFO_LOG(SH4, "RESOLVED %s", get_unicode_string(va).c_str()); + printf("RESOLVED %s\n", get_unicode_string(va).c_str()); } } #endif diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index d3aae1f62..6075249ad 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -81,6 +81,8 @@ u32 mmu_full_lookup(u32 va, u32& idx, u32& rv); #ifdef TRACE_WINCE_SYSCALLS #include "wince.h" +u32 unresolved_ascii_string; +u32 unresolved_unicode_string; #endif #define printf_mmu(...) DEBUG_LOG(SH4, __VA_ARGS__) diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index d967df55b..74bfcc4db 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -31,7 +31,7 @@ static bool read_mem32(u32 addr, u32& data) { u32 pa; const TLB_Entry *entry; - if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem32_nommu(pa); return true; @@ -41,7 +41,7 @@ static bool read_mem16(u32 addr, u16& data) { u32 pa; const TLB_Entry *entry; - if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem16_nommu(pa); return true; @@ -51,7 +51,7 @@ static bool read_mem8(u32 addr, u8& data) { u32 pa; const TLB_Entry *entry; - if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) + if (mmu_full_lookup(addr, &entry, pa) != MMU_ERROR_NONE) return false; data = ReadMem8_nommu(pa); return true; @@ -227,10 +227,10 @@ static const char *wince_methods[][256] = { }, }; -u32 unresolved_ascii_string; -u32 unresolved_unicode_string; +extern u32 unresolved_ascii_string; +extern u32 unresolved_unicode_string; -std::string get_unicode_string(u32 addr) +static inline std::string get_unicode_string(u32 addr) { std::string str; while (true) @@ -248,7 +248,7 @@ std::string get_unicode_string(u32 addr) } return str; } -std::string get_ascii_string(u32 addr) +static inline std::string get_ascii_string(u32 addr) { std::string str; while (true) @@ -312,31 +312,33 @@ static bool print_wince_syscall(u32 address) sprintf(method_buf, "[%d]", meth_id); method = method_buf; } - INFO_LOG(SH4, "WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); + printf("WinCE %08x %04x.%04x %s: %s", address, getCurrentProcessId() & 0xffff, getCurrentThreadId() & 0xffff, api, method); if (address == 0xfffffd51) // SetLastError - INFO_LOG(SH4, " dwErrCode = %x", r[4]); + printf(" dwErrCode = %x\n", r[4]); else if (address == 0xffffd5ef) // CreateFile - INFO_LOG(SH4, " lpFileName = %s", get_unicode_string(r[4]).c_str()); + printf(" lpFileName = %s\n", get_unicode_string(r[4]).c_str()); else if (address == 0xfffffd97) // CreateProc - INFO_LOG(SH4, " imageName = %s, commandLine = %s", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); + printf(" imageName = %s, commandLine = %s\n", get_unicode_string(r[4]).c_str(), get_unicode_string(r[5]).c_str()); else if (!strcmp("DebugNotify", method)) - INFO_LOG(SH4, " %x, %x\n", r[4], r[5]); + printf(" %x, %x\n", r[4], r[5]); else if (address == 0xffffd5d3) // RegOpenKeyExW - INFO_LOG(SH4, " hKey = %x, lpSubKey = %s", r[4], get_unicode_string(r[5]).c_str()); + printf(" hKey = %x, lpSubKey = %s\n", r[4], get_unicode_string(r[5]).c_str()); else if (!strcmp("LoadLibraryW", method)) - INFO_LOG(SH4, " fileName = %s", get_unicode_string(r[4]).c_str()); + printf(" fileName = %s\n", get_unicode_string(r[4]).c_str()); else if (!strcmp("GetProcAddressW", method)) - INFO_LOG(SH4, " hModule = %x, procName = %s", r[4], get_unicode_string(r[5]).c_str()); + printf(" hModule = %x, procName = %s\n", r[4], get_unicode_string(r[5]).c_str()); else if (!strcmp("NKvDbgPrintfW", method)) - INFO_LOG(SH4, " fmt = %s", get_unicode_string(r[4]).c_str()); + printf(" fmt = %s\n", get_unicode_string(r[4]).c_str()); else if (!strcmp("OutputDebugStringW", method)) - INFO_LOG(SH4, " str = %s", get_unicode_string(r[4]).c_str()); + printf(" str = %s\n", get_unicode_string(r[4]).c_str()); else if (!strcmp("RegisterAFSName", method)) - INFO_LOG(SH4, " name = %s", get_unicode_string(r[4]).c_str()); + printf(" name = %s\n", get_unicode_string(r[4]).c_str()); else if (!strcmp("CreateAPISet", method)) - INFO_LOG(SH4, " name = %s", get_ascii_string(r[4]).c_str()); + printf(" name = %s\n", get_ascii_string(r[4]).c_str()); else if (!strcmp("Register", method) && !strcmp("APISET", api)) - INFO_LOG(SH4, " p = %x, id = %x", r[4], r[5]); + printf(" p = %x, id = %x\n", r[4], r[5]); + else + printf("\n"); // might be useful to detect errors? (hidden & dangerous) //if (!strcmp("GetProcName", method)) // os_DebugBreak(); diff --git a/core/rend/norend/norend.cpp b/core/rend/norend/norend.cpp index 01d507df9..83aecb740 100644 --- a/core/rend/norend/norend.cpp +++ b/core/rend/norend/norend.cpp @@ -22,7 +22,7 @@ struct norend : Renderer bool Render() { - return true;//!pvrrc.isRTT; + return !pvrrc.isRTT; } void Present() { } diff --git a/core/serialize.cpp b/core/serialize.cpp index 699757a68..320bb0201 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -622,11 +622,11 @@ extern int SerStep; extern int SerStep2; extern unsigned char BSerial[]; extern unsigned char GSerial[]; -extern u32 reg_dimm_3c; //IO window ! writen, 0x1E03 some flag ? -extern u32 reg_dimm_40; //parameters -extern u32 reg_dimm_44; //parameters -extern u32 reg_dimm_48; //parameters -extern u32 reg_dimm_4c; //status/control reg ? +extern u32 reg_dimm_command; +extern u32 reg_dimm_offsetl; +extern u32 reg_dimm_parameterl; +extern u32 reg_dimm_parameterh; +extern u32 reg_dimm_status; extern bool NaomiDataRead; @@ -1079,11 +1079,11 @@ bool dc_serialize(void **data, unsigned int *total_size) REICAST_S(SerStep2); REICAST_SA(BSerial,69); REICAST_SA(GSerial,69); - REICAST_S(reg_dimm_3c); - REICAST_S(reg_dimm_40); - REICAST_S(reg_dimm_44); - REICAST_S(reg_dimm_48); - REICAST_S(reg_dimm_4c); + REICAST_S(reg_dimm_command); + REICAST_S(reg_dimm_offsetl); + REICAST_S(reg_dimm_parameterl); + REICAST_S(reg_dimm_parameterh); + REICAST_S(reg_dimm_status); REICAST_S(NaomiDataRead); #if FEAT_SHREC == DYNAREC_CPP @@ -1471,11 +1471,11 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size) REICAST_US(SerStep2); REICAST_USA(BSerial,69); REICAST_USA(GSerial,69); - REICAST_US(reg_dimm_3c); - REICAST_US(reg_dimm_40); - REICAST_US(reg_dimm_44); - REICAST_US(reg_dimm_48); - REICAST_US(reg_dimm_4c); + REICAST_US(reg_dimm_command); + REICAST_US(reg_dimm_offsetl); + REICAST_US(reg_dimm_parameterl); + REICAST_US(reg_dimm_parameterh); + REICAST_US(reg_dimm_status); REICAST_US(NaomiDataRead); REICAST_US(i); //LIBRETRO_S(cycle_counter); @@ -1850,11 +1850,11 @@ bool dc_unserialize(void **data, unsigned int *total_size) REICAST_US(SerStep2); REICAST_USA(BSerial,69); REICAST_USA(GSerial,69); - REICAST_US(reg_dimm_3c); - REICAST_US(reg_dimm_40); - REICAST_US(reg_dimm_44); - REICAST_US(reg_dimm_48); - REICAST_US(reg_dimm_4c); + REICAST_US(reg_dimm_command); + REICAST_US(reg_dimm_offsetl); + REICAST_US(reg_dimm_parameterl); + REICAST_US(reg_dimm_parameterh); + REICAST_US(reg_dimm_status); REICAST_US(NaomiDataRead); #if FEAT_SHREC == DYNAREC_CPP From 137553653470e075cb938fc12f9aaafa16fad6cc Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sat, 13 Jul 2019 15:30:10 +0200 Subject: [PATCH 148/158] fix android intent-filter. fix spurious maple warning --- core/hw/maple/maple_cfg.cpp | 3 + core/hw/maple/maple_devs.cpp | 6 +- .../reicast/src/dreamcast/AndroidManifest.xml | 51 ++++++++++++++ .../reicast/src/naomi/AndroidManifest.xml | 69 ------------------- .../src/naomi/res/values/donottranslate.xml | 14 ---- 5 files changed, 57 insertions(+), 86 deletions(-) delete mode 100644 shell/android-studio/reicast/src/naomi/AndroidManifest.xml delete mode 100644 shell/android-studio/reicast/src/naomi/res/values/donottranslate.xml diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 4816ff018..210b0b8a1 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -217,6 +217,9 @@ void mcfg_CreateDevices() mcfg_Create((MapleDeviceType)settings.input.maple_expansion_devices[bus][0], bus, 0); break; + case MDT_None: + break; + default: WARN_LOG(MAPLE, "Invalid device type %d for port %d", settings.input.maple_devices[bus], bus); break; diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 213f994f3..5d8128f9b 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -371,7 +371,7 @@ struct maple_sega_twinstick: maple_sega_controller return 0x80; } - virtual const char *get_device_name() + virtual const char *get_device_name() override { return maple_sega_twinstick_name; } @@ -396,7 +396,7 @@ struct maple_ascii_stick: maple_sega_controller return kcode | 0xF800; } - virtual MapleDeviceType get_device_type() + virtual MapleDeviceType get_device_type() override { return MDT_AsciiStick; } @@ -405,7 +405,7 @@ struct maple_ascii_stick: maple_sega_controller return 0x80; } - virtual const char *get_device_name() + virtual const char *get_device_name() override { return maple_ascii_stick_name; } diff --git a/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml b/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml index d0a0cfb3b..017147011 100644 --- a/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml +++ b/shell/android-studio/reicast/src/dreamcast/AndroidManifest.xml @@ -53,6 +53,57 @@ android:mimeType="*/*" android:pathPattern=".*\\.cue" android:scheme="file" /> + + + + + + + + + + + diff --git a/shell/android-studio/reicast/src/naomi/AndroidManifest.xml b/shell/android-studio/reicast/src/naomi/AndroidManifest.xml deleted file mode 100644 index a1a4c24b2..000000000 --- a/shell/android-studio/reicast/src/naomi/AndroidManifest.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/shell/android-studio/reicast/src/naomi/res/values/donottranslate.xml b/shell/android-studio/reicast/src/naomi/res/values/donottranslate.xml deleted file mode 100644 index 5baf4c3f8..000000000 --- a/shell/android-studio/reicast/src/naomi/res/values/donottranslate.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - Flycast Naomi - naomi - - - bin - dat - lst - zip - 7z - - - \ No newline at end of file From 9932d9bf438068b65f66f47178f283a6fb86be1b Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 24 Jul 2019 18:24:58 +0200 Subject: [PATCH 149/158] OSX: fix bios files path (now in /data/) --- core/hw/arm7/arm7.cpp | 2 +- core/hw/naomi/naomi_cart.cpp | 6 +----- core/hw/sh4/sh4_mem.cpp | 2 +- core/linux/common.cpp | 2 +- core/nullDC.cpp | 10 ++-------- core/rend/gles/CustomTexture.cpp | 4 ++-- core/rend/gles/gles.cpp | 2 +- core/rend/gui.cpp | 2 +- core/stdclass.cpp | 2 +- core/stdclass.h | 6 ++++++ 10 files changed, 17 insertions(+), 21 deletions(-) diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 322d23e05..26870e9ec 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -2183,7 +2183,7 @@ void armt_init() mem_region_set_exec(ICache, ICacheSize); -#if TARGET_IPHONE +#ifdef TARGET_IPHONE memset((u8*)mmap(ICache, ICacheSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0),0xFF,ICacheSize); #else memset(ICache,0xFF,ICacheSize); diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 373936c23..99add2927 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -72,11 +72,7 @@ static bool naomi_LoadBios(const char *filename, Archive *child_archive, Archive struct BIOS_t *bios = &BIOS[biosid]; -#if HOST_OS != OS_DARWIN - std::string basepath = get_readonly_data_path("/data/"); -#else - std::string basepath = get_readonly_data_path("/"); -#endif + std::string basepath = get_readonly_data_path(DATA_PATH); std::unique_ptr bios_archive(OpenArchive((basepath + filename).c_str())); bool found_region = false; diff --git a/core/hw/sh4/sh4_mem.cpp b/core/hw/sh4/sh4_mem.cpp index 40bcd3a2b..ddbfbf343 100644 --- a/core/hw/sh4/sh4_mem.cpp +++ b/core/hw/sh4/sh4_mem.cpp @@ -215,7 +215,7 @@ void mem_Term() sh4_area0_Term(); // done by emulator thread - //SaveRomFiles(get_writable_data_path("/data/")); + //SaveRomFiles(get_writable_data_path(DATA_PATH)); //mem_b.Term(); // handled by vmem diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 11f523768..ce717d853 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -144,7 +144,7 @@ double os_GetSeconds() return a.tv_sec-tvs_base+a.tv_usec/1000000.0; } -#if TARGET_IPHONE +#ifdef TARGET_IPHONE void os_DebugBreak() { __asm__("trap"); } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index b2e03e160..1ed27c403 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -355,12 +355,6 @@ int reicast_init(int argc, char* argv[]) return 0; } -#if HOST_OS != OS_DARWIN -#define DATA_PATH "/data/" -#else -#define DATA_PATH "/" -#endif - void set_platform(int platform) { switch (platform) @@ -542,7 +536,7 @@ void* dc_run(void*) sh4_cpu.Run(); - SaveRomFiles(get_writable_data_path("/data/")); + SaveRomFiles(get_writable_data_path(DATA_PATH)); if (reset_requested) { dc_reset(false); @@ -935,7 +929,7 @@ static string get_savestate_file_path() if (lastindex != -1) state_file = state_file.substr(0, lastindex); state_file = state_file + ".state"; - return get_writable_data_path("/data/") + state_file; + return get_writable_data_path(DATA_PATH) + state_file; } void dc_savestate() diff --git a/core/rend/gles/CustomTexture.cpp b/core/rend/gles/CustomTexture.cpp index 59cc12827..270cef23b 100644 --- a/core/rend/gles/CustomTexture.cpp +++ b/core/rend/gles/CustomTexture.cpp @@ -101,7 +101,7 @@ bool CustomTexture::Init() std::string game_id = GetGameId(); if (game_id.length() > 0) { - textures_path = get_readonly_data_path("/data/") + "textures/" + game_id + "/"; + textures_path = get_readonly_data_path(DATA_PATH) + "textures/" + game_id + "/"; DIR *dir = opendir(textures_path.c_str()); if (dir != NULL) @@ -160,7 +160,7 @@ void CustomTexture::LoadCustomTextureAsync(TextureCacheData *texture_data) void CustomTexture::DumpTexture(u32 hash, int w, int h, GLuint textype, void *temp_tex_buffer) { - std::string base_dump_dir = get_writable_data_path("/data/texdump/"); + std::string base_dump_dir = get_writable_data_path(DATA_PATH "texdump/"); if (!file_exists(base_dump_dir)) make_directory(base_dump_dir); std::string game_id = GetGameId(); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 4f871dd23..e5e9798bf 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1229,7 +1229,7 @@ void gl_load_osd_resources() #ifdef _ANDROID int w, h; if (osd_tex == 0) - osd_tex = loadPNG(get_readonly_data_path("/data/buttons.png"), w, h); + osd_tex = loadPNG(get_readonly_data_path(DATA_PATH "buttons.png"), w, h); #endif } diff --git a/core/rend/gui.cpp b/core/rend/gui.cpp index 4ab7b82ec..8cdbe09c6 100644 --- a/core/rend/gui.cpp +++ b/core/rend/gui.cpp @@ -1296,7 +1296,7 @@ static void gui_display_settings() #elif HOST_OS == OS_LINUX "Linux" #elif HOST_OS == OS_DARWIN -#if TARGET_IPHONE +#ifdef TARGET_IPHONE "iOS" #else "OSX" diff --git a/core/stdclass.cpp b/core/stdclass.cpp index 76921d170..0f97e4ac8 100644 --- a/core/stdclass.cpp +++ b/core/stdclass.cpp @@ -120,7 +120,7 @@ string get_game_save_prefix() #endif if (lastindex != -1) save_file = save_file.substr(lastindex + 1); - return get_writable_data_path("/data/") + save_file; + return get_writable_data_path(DATA_PATH) + save_file; } string get_game_basename() diff --git a/core/stdclass.h b/core/stdclass.h index 3b1347349..9e4673208 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -261,6 +261,12 @@ public : } }; +#if !defined(TARGET_IPHONE) +#define DATA_PATH "/data/" +#else +#define DATA_PATH "/" +#endif + //Set the path ! void set_user_config_dir(const string& dir); void set_user_data_dir(const string& dir); From 32055c3bf94e0081a2c86802715cceb871df542a Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 24 Jul 2019 18:53:09 +0200 Subject: [PATCH 150/158] Better error messages when BIOS files missing --- core/hw/naomi/naomi_cart.cpp | 2 +- core/nullDC.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 99add2927..127c91b98 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -216,7 +216,7 @@ static void naomi_cart_LoadZip(const char *filename) { // If a specific BIOS is needed for this game, fail. if (game->bios != NULL || !bios_loaded) - throw NaomiCartException(std::string("Error: cannot load BIOS ") + (game->bios != NULL ? game->bios : "naomi.zip")); + throw NaomiCartException(std::string("Error: cannot load BIOS ") + (game->bios != NULL ? game->bios : "naomi.zip") + " in " + get_readonly_data_path(DATA_PATH)); // otherwise use the default BIOS } diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 1ed27c403..ccf093489 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -458,7 +458,9 @@ void dc_start_game(const char *path) InitSettings(); dc_reset(true); LoadSettings(false); - if (!LoadRomFiles(get_readonly_data_path(DATA_PATH))) + + std::string data_path = get_readonly_data_path(DATA_PATH); + if (!LoadRomFiles(data_path)) { if (settings.platform.system == DC_PLATFORM_DREAMCAST) { @@ -473,7 +475,7 @@ void dc_start_game(const char *path) else #endif { - throw ReicastException("Cannot find BIOS files"); + throw ReicastException("Cannot find BIOS files in " + data_path); } } } From 2529b5048e9cdf628b216971e4211dbde4d0ad03 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Wed, 24 Jul 2019 19:09:54 +0200 Subject: [PATCH 151/158] get rid of useless macro --- core/hw/aica/aica.h | 204 ++++++++++++++++++++++---------------------- 1 file changed, 101 insertions(+), 103 deletions(-) diff --git a/core/hw/aica/aica.h b/core/hw/aica/aica.h index 12edca626..64bfcf11b 100644 --- a/core/hw/aica/aica.h +++ b/core/hw/aica/aica.h @@ -16,50 +16,50 @@ #define TIMER_C (0x2890+8) #define REG_L (0x2D00) #define REG_M (0x2D04) -#define entry(name,sz) u32 name:sz; + struct CommonData_struct { //+0 - entry(MVOL,4); - entry(VER,4); - entry(DAC18B,1); - entry(MEM8MB,1); - entry(pad0_0,5); - entry(Mono,1); + u32 MVOL:4; + u32 VER:4; + u32 DAC18B:1; + u32 MEM8MB:1; + u32 pad0_0:5; + u32 Mono:1; u32 :16; //+4 - entry(RBP,12); - entry(pad1_0,1); - entry(RBL,2); - entry(TESTB0,1); + u32 RBP:12; + u32 pad1_0:1; + u32 RBL:2; + u32 TESTB0:1; u32 :16; //+8 - entry(MIBUF,8); - entry(MIEMP,1); - entry(MIFUL ,1); - entry(MIOVF ,1); - entry(MOEMP ,1); - entry(MOFUL ,1); - entry(pad3_0,3); + u32 MIBUF:8; + u32 MIEMP:1; + u32 MIFUL :1; + u32 MIOVF :1; + u32 MOEMP :1; + u32 MOFUL :1; + u32 pad3_0:3; u32 :16; //+C - entry(MOBUF,8); - entry(MSLC,6); - entry(AFSET,1); - entry(padC_0,1); + u32 MOBUF:8; + u32 MSLC:6; + u32 AFSET:1; + u32 padC_0:1; u32 :16; //+10 - entry(EG,13); - entry(SGC,2); - entry(LP,1); + u32 EG:13; + u32 SGC:2; + u32 LP:1; u32 :16; //+14 - entry(CA,16); + u32 CA:16; u32 :16; @@ -67,101 +67,101 @@ struct CommonData_struct u8 pad_med_0[0x6C-4]; //+80 - entry(MRWINH,4); - entry($T,1); - entry($TSCD,3); - entry(pad80_0,1); - entry(DMEA_hi,7); + u32 MRWINH:4; + u32 $T:1; + u32 $TSCD:3; + u32 pad80_0:1; + u32 DMEA_hi:7; u32 :16; //+84 - entry(pad84_0,2); - entry(DMEA_lo,14); + u32 pad84_0:2; + u32 DMEA_lo:14; u32 :16; //+88 - entry(pad88_0,2); - entry(DRGA,13); - entry(DGATE,1); + u32 pad88_0:2; + u32 DRGA:13; + u32 DGATE:1; u32 :16; //+8C - entry(DEXE,1); - entry(pad8C_0,1); - entry(DLG,13); - entry(DDIR,1); + u32 DEXE:1; + u32 pad8C_0:1; + u32 DLG:13; + u32 DDIR:1; u32 :16; //+90 - entry(TIMA,8); - entry(TACTL,3); - entry(pad90_0,5); + u32 TIMA:8; + u32 TACTL:3; + u32 pad90_0:5; u32 :16; //+94 - entry(TIMB,8); - entry(TBCTL,3); - entry(pad94_0,5); + u32 TIMB:8; + u32 TBCTL:3; + u32 pad94_0:5; u32 :16; //+98 - entry(TIMC,8); - entry(TCCTL,3); - entry(pad98_0,5); + u32 TIMC:8; + u32 TCCTL:3; + u32 pad98_0:5; u32 :16; //+9C - entry(SCIEB,11); - entry(pad9C_0,5); + u32 SCIEB:11; + u32 pad9C_0:5; u32 :16; //+A0 - entry(SCIPD,11); - entry(padA0_0,5); + u32 SCIPD:11; + u32 padA0_0:5; u32 :16; //+A4 - entry(SCIRE,11); - entry(padA4_0,5); + u32 SCIRE:11; + u32 padA4_0:5; u32 :16; //+A8 - entry(SCILV0,8); - entry(padA8_0,8); + u32 SCILV0:8; + u32 padA8_0:8; u32 :16; //+AC - entry(SCILV1,8); - entry(padAC_0,8); + u32 SCILV1:8; + u32 padAC_0:8; u32 :16; //+B0 - entry(SCILV2,8); - entry(padB0_0,8); + u32 SCILV2:8; + u32 padB0_0:8; u32 :16; //+B4 - entry(MCIEB,11); - entry(padB4_0,5) + u32 MCIEB:11; + u32 padB4_0:5; u32 :16; //+B8 - entry(MCIPD,11); - entry(padB8_0,5) + u32 MCIPD:11; + u32 padB8_0:5; u32 :16; //+BC - entry(MCIRE,11); - entry(padBC_0,5) + u32 MCIRE:11; + u32 padBC_0:5; u32 :16; @@ -169,10 +169,10 @@ struct CommonData_struct u8 pad_lot_0[0x344-4]; //+400 , hopefully :p - entry(AR,1); - entry(pad400_0,7); - entry(VREG,2); - entry(pad400_1,6); + u32 AR:1; + u32 pad400_0:7; + u32 VREG:2; + u32 pad400_1:6; u32 :16; @@ -180,32 +180,32 @@ struct CommonData_struct u8 pad_lot_1[0x100-4]; //+500 , hopefully :p - entry(L0_r,1); - entry(L1_r,1); - entry(L2_r,1); - entry(L3_r,1); - entry(L4_r,1); - entry(L5_r,1); - entry(L6_r,1); - entry(L7_r,1); + u32 L0_r:1; + u32 L1_r:1; + u32 L2_r:1; + u32 L3_r:1; + u32 L4_r:1; + u32 L5_r:1; + u32 L6_r:1; + u32 L7_r:1; - entry(pad500_0,8); + u32 pad500_0:8; u32 :16; //+504 - entry(M0_r,1); - entry(M1_r,1); - entry(M2_r,1); - entry(M3_r,1); - entry(M4_r,1); - entry(M5_r,1); - entry(M6_r,1); - entry(M7_r,1); - entry(RP,1); + u32 M0_r:1; + u32 M1_r:1; + u32 M2_r:1; + u32 M3_r:1; + u32 M4_r:1; + u32 M5_r:1; + u32 M6_r:1; + u32 M7_r:1; + u32 RP:1; - entry(pad504_0,7); + u32 pad504_0:7; u32 :16; }; @@ -263,30 +263,30 @@ union InterruptInfo struct { //Bit 0 (R): Requests interrupt to external interrupt input pin "INTON". (SCSI) - entry(INTON,1); + u32 INTON:1; //Bit 1 (R): Reserved. - entry(res_1,1); + u32 res_1:1; //Bit 2 (R): Reserved. - entry(res_3,1); + u32 res_3:1; //Bit 3 (R): MIDI input interrupt. //(Interrupt request generated when input FIFO has fetched valid data. Hence, if the CPU reads FIFO data, it must read the lot once and leave the FIFO empty. When the FIFO has changed to empty status, the interrupt request is canceled automatically.) - entry(MIDI_IN,1); + u32 MIDI_IN:1; //Bit 4 (R): DMA end interrupt - entry(DMA_END,1); + u32 DMA_END:1; //Bit 5 (R/W): SCPU interrupt caused by data being written to the CPU, so only "1" can be written. (Writing "0" has no effect.) This flag can be set from either the MCPU or the SCPU. - entry(SCPU,1); + u32 SCPU:1; //Bit 6 (R): Timer A interrupt - entry(TimerA,1); + u32 TimerA:1; //Bit 7 (R): Timer B interrupt - entry(TimerB,1); + u32 TimerB:1; //Bit 8 (R): Timer C interrupt - entry(TimerC,1); + u32 TimerC:1; //Bit 9 (R): MIDI output interrupt. //(If the output FIFO changes to empty status, an interrupt request is generated.) //(If the status is no longer empty because data is written to the output FIFO, the interrupt request is canceled automatically.) - entry(MIDI_OUT,1); + u32 MIDI_OUT:1; //Bit 10 (R): Interrupt of one sample interval - entry(SAMPLE_DONE,1); + u32 SAMPLE_DONE:1; }; u32 full; }; @@ -297,8 +297,6 @@ extern InterruptInfo* SCIEB; extern InterruptInfo* SCIPD; extern InterruptInfo* SCIRE; -#undef entry - extern CommonData_struct* CommonData; extern DSPData_struct* DSPData; From 4dfa83079ab644fe69a8ec6615f78fedcf219d0c Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 25 Jul 2019 21:34:43 +0200 Subject: [PATCH 152/158] aica and arm7 clean up --- core/hw/aica/aica_mem.h | 3 - core/hw/aica/dsp.cpp | 4 +- core/hw/aica/sgc_if.cpp | 4 +- core/hw/arm7/arm7.cpp | 120 +++++------------- core/hw/arm7/arm_mem.h | 5 - core/hw/arm7/virt_arm.cpp | 113 ----------------- .../reicast-osx.xcodeproj/project.pbxproj | 2 - 7 files changed, 33 insertions(+), 218 deletions(-) diff --git a/core/hw/aica/aica_mem.h b/core/hw/aica/aica_mem.h index 3b46367b3..dae697979 100644 --- a/core/hw/aica/aica_mem.h +++ b/core/hw/aica/aica_mem.h @@ -8,7 +8,4 @@ void init_mem(); void term_mem(); extern u8 aica_reg[0x8000]; -#define aica_reg_16 ((u16*)aica_reg) -#define AICA_RAM_SIZE (ARAM_SIZE) -#define AICA_RAM_MASK (ARAM_MASK) \ No newline at end of file diff --git a/core/hw/aica/dsp.cpp b/core/hw/aica/dsp.cpp index 676c03978..81cc25aaa 100644 --- a/core/hw/aica/dsp.cpp +++ b/core/hw/aica/dsp.cpp @@ -246,8 +246,8 @@ void dsp_rec_DRAM_CI(x86_block& x86e,_INST& prev_op,u32 step,x86_gpr_reg MEM_RD_ if (!(step&1)) { //Get and mask ram address :) - x86e.Emit(op_mov32,EAX,&dsp.regs.MEM_ADDR); - x86e.Emit(op_and32,EAX,AICA_RAM_MASK); + x86e.Emit(op_mov32, EAX, &dsp.regs.MEM_ADDR); + x86e.Emit(op_and32, EAX, ARAM_MASK); x86e.Emit(op_add32,EAX,(unat)aica_ram.data); diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 5de996378..b5dfec6ae 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -1169,8 +1169,8 @@ void WriteCommonReg8(u32 reg,u32 data) WriteMemArr(aica_reg,reg,data,1); if (reg==0x2804 || reg==0x2805) { - dsp.RBL=(8192<RBL)-1; - dsp.RBP=( CommonData->RBP*2048&AICA_RAM_MASK); + dsp.RBL = (8192 << CommonData->RBL) - 1; + dsp.RBP = (CommonData->RBP * 2048) & ARAM_MASK; dsp.dyndirty=true; } } diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 26870e9ec..54f9c70c5 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -4,12 +4,8 @@ #include - -#define C_CORE - #define arm_printf(...) DEBUG_LOG(AICA_ARM, __VA_ARGS__) -//#define CPUReadHalfWordQuick(addr) arm_ReadMem16(addr & 0x7FFFFF) #define CPUReadMemoryQuick(addr) (*(u32*)&aica_ram[addr&ARAM_MASK]) #define CPUReadByte arm_ReadMem8 #define CPUReadMemory arm_ReadMem32 @@ -45,12 +41,6 @@ void CPUSwap(u32 *a, u32 *b) *a = c; } -/* -bool N_FLAG; -bool Z_FLAG; -bool C_FLAG; -bool V_FLAG; -*/ #define N_FLAG (reg[RN_PSR_FLAGS].FLG.N) #define Z_FLAG (reg[RN_PSR_FLAGS].FLG.Z) #define C_FLAG (reg[RN_PSR_FLAGS].FLG.C) @@ -58,10 +48,9 @@ bool V_FLAG; bool armIrqEnable; bool armFiqEnable; -//bool armState; int armMode; -bool Arm7Enabled=false; +bool Arm7Enabled = false; u8 cpuBitsSet[256]; @@ -73,14 +62,18 @@ void CPUSoftwareInterrupt(int comment); void CPUUndefinedException(); #if FEAT_AREC == DYNAREC_NONE +void libAICA_TimeStep(); +// +// ARM7 interpreter +// void arm_Run_(u32 CycleCount) { if (!Arm7Enabled) return; - u32 clockTicks=0; - while (clockTicks @@ -744,9 +682,9 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data) arm_WriteMem32(addr,data); } - #if HOST_CPU==CPU_X86 - virt_arm_reg(0)=rv; - #endif +#if HOST_CPU==CPU_X86 + virt_arm_reg(0)=rv; +#endif return rv; } @@ -1303,7 +1241,7 @@ void *armGetEmitPtr() return NULL; } -#if HOST_CPU == CPU_X86 && FEAT_AREC != DYNAREC_NONE +#if HOST_CPU == CPU_X86 /* X86 backend * Uses a mix of @@ -2175,11 +2113,11 @@ void armt_init() //align to next page .. ICache = (u8*)(((unat)ARM7_TCB+4095)& ~4095); - #if HOST_OS==OS_DARWIN - //Can't just mprotect on iOS - munmap(ICache, ICacheSize); - ICache = (u8*)mmap(ICache, ICacheSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); - #endif +#ifdef TARGET_IPHONE + //Can't just mprotect on iOS + munmap(ICache, ICacheSize); + ICache = (u8*)mmap(ICache, ICacheSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANON, 0, 0); +#endif mem_region_set_exec(ICache, ICacheSize); @@ -2193,4 +2131,4 @@ void armt_init() } -#endif +#endif // FEAT_AREC != DYNAREC_NONE diff --git a/core/hw/arm7/arm_mem.h b/core/hw/arm7/arm_mem.h index 20697062b..3f7bc4747 100644 --- a/core/hw/arm7/arm_mem.h +++ b/core/hw/arm7/arm_mem.h @@ -54,11 +54,6 @@ static inline void DYNACALL WriteMemArm(u32 addr,T data) u32 sh4_ReadMem_reg(u32 addr,u32 size); void sh4_WriteMem_reg(u32 addr,u32 data,u32 size); -#define aica_reg_16 ((u16*)aica_reg) - -#define AICA_RAM_SIZE (ARAM_SIZE) -#define AICA_RAM_MASK (ARAM_MASK) - extern bool aica_interr; extern u32 aica_reg_L; extern bool e68k_out; diff --git a/core/hw/arm7/virt_arm.cpp b/core/hw/arm7/virt_arm.cpp index ffd6a114b..5b7f363aa 100644 --- a/core/hw/arm7/virt_arm.cpp +++ b/core/hw/arm7/virt_arm.cpp @@ -2,12 +2,8 @@ #if HOST_CPU==CPU_X86 && FEAT_AREC != DYNAREC_NONE -#define C_CORE - namespace VARM { - //#define CPUReadHalfWordQuick(addr) arm_ReadMem16(addr & 0x7FFFFF) -//#define CPUReadMemoryQuick(addr) (*(u32*)(addr)) #define CPUReadByte(addr) (*(u8*)(addr)) #define CPUReadMemory(addr) (*(u32*)(addr)) #define CPUReadHalfWord(addr) (*(u16*)(addr)) @@ -99,115 +95,6 @@ namespace VARM void CPUSwitchMode(int mode, bool saveState, bool breakLoop) { verify(mode==0x10); - /* - CPUUpdateCPSR(); - - switch(armMode) { - case 0x10: - case 0x1F: - reg[R13_USR].I = reg[13].I; - reg[R14_USR].I = reg[14].I; - reg[17].I = reg[16].I; - break; - case 0x11: - CPUSwap(®[R8_FIQ].I, ®[8].I); - CPUSwap(®[R9_FIQ].I, ®[9].I); - CPUSwap(®[R10_FIQ].I, ®[10].I); - CPUSwap(®[R11_FIQ].I, ®[11].I); - CPUSwap(®[R12_FIQ].I, ®[12].I); - reg[R13_FIQ].I = reg[13].I; - reg[R14_FIQ].I = reg[14].I; - reg[SPSR_FIQ].I = reg[17].I; - break; - case 0x12: - reg[R13_IRQ].I = reg[13].I; - reg[R14_IRQ].I = reg[14].I; - reg[SPSR_IRQ].I = reg[17].I; - break; - case 0x13: - reg[R13_SVC].I = reg[13].I; - reg[R14_SVC].I = reg[14].I; - reg[SPSR_SVC].I = reg[17].I; - break; - case 0x17: - reg[R13_ABT].I = reg[13].I; - reg[R14_ABT].I = reg[14].I; - reg[SPSR_ABT].I = reg[17].I; - break; - case 0x1b: - reg[R13_UND].I = reg[13].I; - reg[R14_UND].I = reg[14].I; - reg[SPSR_UND].I = reg[17].I; - break; - } - - u32 CPSR = reg[16].I; - u32 SPSR = reg[17].I; - - switch(mode) { - case 0x10: - case 0x1F: - reg[13].I = reg[R13_USR].I; - reg[14].I = reg[R14_USR].I; - reg[16].I = SPSR; - break; - case 0x11: - CPUSwap(®[8].I, ®[R8_FIQ].I); - CPUSwap(®[9].I, ®[R9_FIQ].I); - CPUSwap(®[10].I, ®[R10_FIQ].I); - CPUSwap(®[11].I, ®[R11_FIQ].I); - CPUSwap(®[12].I, ®[R12_FIQ].I); - reg[13].I = reg[R13_FIQ].I; - reg[14].I = reg[R14_FIQ].I; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_FIQ].I; - break; - case 0x12: - reg[13].I = reg[R13_IRQ].I; - reg[14].I = reg[R14_IRQ].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_IRQ].I; - break; - case 0x13: - reg[13].I = reg[R13_SVC].I; - reg[14].I = reg[R14_SVC].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_SVC].I; - break; - case 0x17: - reg[13].I = reg[R13_ABT].I; - reg[14].I = reg[R14_ABT].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_ABT].I; - break; - case 0x1b: - reg[13].I = reg[R13_UND].I; - reg[14].I = reg[R14_UND].I; - reg[16].I = SPSR; - if(saveState) - reg[17].I = CPSR; - else - reg[17].I = reg[SPSR_UND].I; - break; - default: - printf("Unsupported ARM mode %02x\n", mode); - die("Arm error.."); - break; - } - armMode = mode; - CPUUpdateFlags(); - CPUUpdateCPSR();*/ } void CPUUpdateCPSR() diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index 700df50f0..3cf74b978 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -475,7 +475,6 @@ 84B7BDD51B72720100F9733F /* arm7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm7.h; sourceTree = ""; }; 84B7BDD61B72720100F9733F /* arm_mem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = arm_mem.cpp; sourceTree = ""; }; 84B7BDD71B72720100F9733F /* arm_mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arm_mem.h; sourceTree = ""; }; - 84B7BDD81B72720100F9733F /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = ""; }; 84B7BDD91B72720100F9733F /* vbaARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vbaARM.cpp; sourceTree = ""; }; 84B7BDDA1B72720100F9733F /* virt_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = virt_arm.cpp; sourceTree = ""; }; 84B7BDDB1B72720100F9733F /* virt_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = virt_arm.h; sourceTree = ""; }; @@ -1324,7 +1323,6 @@ 84B7BDD51B72720100F9733F /* arm7.h */, 84B7BDD61B72720100F9733F /* arm_mem.cpp */, 84B7BDD71B72720100F9733F /* arm_mem.h */, - 84B7BDD81B72720100F9733F /* resource.h */, 84B7BDD91B72720100F9733F /* vbaARM.cpp */, 84B7BDDA1B72720100F9733F /* virt_arm.cpp */, 84B7BDDB1B72720100F9733F /* virt_arm.h */, From d27ab0361cc626881e4bab605e8c6e377dbbb996 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 25 Jul 2019 21:51:48 +0200 Subject: [PATCH 153/158] arm build fix --- core/hw/arm7/arm7.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 54f9c70c5..8122f7c31 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -60,9 +60,9 @@ void CPUUpdateCPSR(); void CPUUpdateFlags(); void CPUSoftwareInterrupt(int comment); void CPUUndefinedException(); +void libAICA_TimeStep(); #if FEAT_AREC == DYNAREC_NONE -void libAICA_TimeStep(); // // ARM7 interpreter From a9dbbccf93d9dd97aa29b63231e94d8e8203276d Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 28 Jul 2019 17:06:12 +0200 Subject: [PATCH 154/158] Unprotect VRAM before switching system. Fix texture cache clean --- core/hw/pvr/Renderer_if.cpp | 3 --- core/nullDC.cpp | 1 + core/rend/TexCache.cpp | 16 +++++----------- core/rend/gl4/gles.cpp | 5 +---- core/rend/gles/gles.cpp | 5 +---- core/rend/gles/gltex.cpp | 1 + 6 files changed, 9 insertions(+), 22 deletions(-) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index 20c2d1309..8a8a8e808 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -98,8 +98,6 @@ bool fb_dirty; TA_context* _pvrrc; void SetREP(TA_context* cntx); -void killtex(); -bool render_output_framebuffer(); static void rend_create_renderer(); void dump_frame(const char* file, TA_context* ctx, u8* vram, u8* vram_ref = NULL) { @@ -394,7 +392,6 @@ void rend_init_renderer() void rend_term_renderer() { - killtex(); gui_term(); renderer->Term(); delete renderer; diff --git a/core/nullDC.cpp b/core/nullDC.cpp index ccf093489..dd34f4a48 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -357,6 +357,7 @@ int reicast_init(int argc, char* argv[]) void set_platform(int platform) { + _vmem_unprotect_vram(0, VRAM_SIZE); switch (platform) { case DC_PLATFORM_DREAMCAST: diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index fba0ce9b4..41fe8dfff 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -274,17 +274,11 @@ void libCore_vramlock_Unlock_block(vram_block* block) void libCore_vramlock_Unlock_block_wb(vram_block* block) { - //VRAM_SIZE/PAGE_SIZE; - if (block->end>VRAM_SIZE) - WARN_LOG(PVR, "Error : block end is after vram , skipping unlock"); - else - { - if (mmu_enabled()) - vmem32_unprotect_vram(block->start, block->len); - vramlock_list_remove(block); - //more work needed - free(block); - } + if (mmu_enabled()) + vmem32_unprotect_vram(block->start, block->len); + vramlock_list_remove(block); + //more work needed + free(block); } // diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index e1f140a76..5d040cebd 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -971,8 +971,6 @@ static bool RenderFrame() eglCheck(); - KillTex=false; - if (is_rtt) ReadRTTBuffer(); else if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) @@ -1015,8 +1013,7 @@ struct gl4rend : Renderer glcache.DeleteTextures(1, &depthSaveTexId); depthSaveTexId = 0; } - if (KillTex) - killtex(); + killtex(); CollectCleanup(); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index e5e9798bf..0582f1007 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -2040,8 +2040,6 @@ bool RenderFrame() eglCheck(); - KillTex=false; - if (is_rtt) ReadRTTBuffer(); else if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved) @@ -2062,8 +2060,7 @@ struct glesrend : Renderer void Resize(int w, int h) { screen_width=w; screen_height=h; } void Term() { - if (KillTex) - killtex(); + killtex(); gles_term(); } diff --git a/core/rend/gles/gltex.cpp b/core/rend/gles/gltex.cpp index 8f6507830..22d6f1451 100644 --- a/core/rend/gles/gltex.cpp +++ b/core/rend/gles/gltex.cpp @@ -848,6 +848,7 @@ void killtex() } TexCache.clear(); + KillTex = false; INFO_LOG(RENDERER, "Texture cache cleared"); } From 1333d6f776d4d6cb326ea2caeb422eb92e098e78 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 28 Jul 2019 17:37:04 +0200 Subject: [PATCH 155/158] Remove TARGET_BOUNDED_EXECUTION. Build warnings and clean up --- core/deps/imgui/imgui.h | 2 +- core/emitter/x86_op_encoder.h | 3 + core/hw/naomi/naomi_cart.cpp | 2 +- core/hw/sh4/dyna/driver.cpp | 4 +- core/hw/sh4/interpr/sh4_interpreter.cpp | 12 +- core/linux/common.cpp | 2 +- core/linux/posix_vmem.cpp | 2 +- core/rec-cpp/rec_cpp.cpp | 7 +- shell/emscripten/Makefile | 68 - shell/linux-deps/include/X11/DECkeysym.h | 65 - shell/linux-deps/include/X11/HPkeysym.h | 164 - shell/linux-deps/include/X11/ImUtil.h | 30 - shell/linux-deps/include/X11/Sunkeysym.h | 106 - shell/linux-deps/include/X11/X.h | 717 --- shell/linux-deps/include/X11/XF86keysym.h | 233 - shell/linux-deps/include/X11/XKBlib.h | 1149 ----- shell/linux-deps/include/X11/XWDFile.h | 113 - shell/linux-deps/include/X11/Xalloca.h | 121 - shell/linux-deps/include/X11/Xarch.h | 94 - shell/linux-deps/include/X11/Xatom.h | 79 - shell/linux-deps/include/X11/Xauth.h | 141 - shell/linux-deps/include/X11/Xcms.h | 803 ---- shell/linux-deps/include/X11/Xdefs.h | 108 - shell/linux-deps/include/X11/Xdmcp.h | 181 - shell/linux-deps/include/X11/Xfuncproto.h | 172 - shell/linux-deps/include/X11/Xfuncs.h | 69 - shell/linux-deps/include/X11/Xlib.h | 4024 ----------------- shell/linux-deps/include/X11/XlibConf.h | 38 - shell/linux-deps/include/X11/Xlibint.h | 1369 ------ shell/linux-deps/include/X11/Xlocale.h | 59 - shell/linux-deps/include/X11/Xmd.h | 185 - shell/linux-deps/include/X11/Xos.h | 148 - shell/linux-deps/include/X11/Xos_r.h | 1095 ----- shell/linux-deps/include/X11/Xosdefs.h | 116 - shell/linux-deps/include/X11/Xpoll.h | 218 - shell/linux-deps/include/X11/Xproto.h | 2157 --------- shell/linux-deps/include/X11/Xprotostr.h | 77 - shell/linux-deps/include/X11/Xregion.h | 189 - shell/linux-deps/include/X11/Xresource.h | 358 -- shell/linux-deps/include/X11/Xthreads.h | 313 -- shell/linux-deps/include/X11/Xtrans/Xtrans.c | 1380 ------ shell/linux-deps/include/X11/Xtrans/Xtrans.h | 478 -- .../linux-deps/include/X11/Xtrans/Xtransint.h | 414 -- .../linux-deps/include/X11/Xtrans/Xtranslcl.c | 2562 ----------- .../include/X11/Xtrans/Xtranssock.c | 2501 ---------- .../linux-deps/include/X11/Xtrans/Xtranstli.c | 1418 ------ .../include/X11/Xtrans/Xtransutil.c | 649 --- .../linux-deps/include/X11/Xtrans/transport.c | 73 - shell/linux-deps/include/X11/Xutil.h | 826 ---- shell/linux-deps/include/X11/Xw32defs.h | 79 - shell/linux-deps/include/X11/Xwindows.h | 91 - shell/linux-deps/include/X11/Xwinsock.h | 65 - shell/linux-deps/include/X11/ap_keysym.h | 51 - shell/linux-deps/include/X11/bitmaps/1x1 | 6 - shell/linux-deps/include/X11/bitmaps/2x2 | 6 - shell/linux-deps/include/X11/bitmaps/Dashes | 4 - shell/linux-deps/include/X11/bitmaps/Down | 13 - shell/linux-deps/include/X11/bitmaps/Excl | 17 - .../linux-deps/include/X11/bitmaps/FlipHoriz | 13 - shell/linux-deps/include/X11/bitmaps/FlipVert | 13 - shell/linux-deps/include/X11/bitmaps/Fold | 13 - shell/linux-deps/include/X11/bitmaps/Left | 13 - shell/linux-deps/include/X11/bitmaps/Right | 13 - .../linux-deps/include/X11/bitmaps/RotateLeft | 13 - .../include/X11/bitmaps/RotateRight | 13 - shell/linux-deps/include/X11/bitmaps/Term | 14 - shell/linux-deps/include/X11/bitmaps/Up | 13 - shell/linux-deps/include/X11/bitmaps/black | 6 - shell/linux-deps/include/X11/bitmaps/black6 | 4 - shell/linux-deps/include/X11/bitmaps/box6 | 4 - shell/linux-deps/include/X11/bitmaps/boxes | 6 - .../linux-deps/include/X11/bitmaps/calculator | 19 - shell/linux-deps/include/X11/bitmaps/cntr_ptr | 8 - .../include/X11/bitmaps/cntr_ptrmsk | 6 - .../include/X11/bitmaps/cross_weave | 6 - shell/linux-deps/include/X11/bitmaps/dimple1 | 6 - shell/linux-deps/include/X11/bitmaps/dimple3 | 6 - shell/linux-deps/include/X11/bitmaps/dot | 6 - shell/linux-deps/include/X11/bitmaps/dropbar7 | 4 - shell/linux-deps/include/X11/bitmaps/dropbar8 | 4 - .../linux-deps/include/X11/bitmaps/escherknot | 473 -- shell/linux-deps/include/X11/bitmaps/flagdown | 27 - shell/linux-deps/include/X11/bitmaps/flagup | 27 - .../include/X11/bitmaps/flipped_gray | 4 - shell/linux-deps/include/X11/bitmaps/gray | 4 - shell/linux-deps/include/X11/bitmaps/gray1 | 4 - shell/linux-deps/include/X11/bitmaps/gray3 | 4 - shell/linux-deps/include/X11/bitmaps/grid16 | 6 - shell/linux-deps/include/X11/bitmaps/grid2 | 4 - shell/linux-deps/include/X11/bitmaps/grid4 | 4 - shell/linux-deps/include/X11/bitmaps/grid8 | 4 - shell/linux-deps/include/X11/bitmaps/hlines2 | 4 - shell/linux-deps/include/X11/bitmaps/hlines3 | 4 - shell/linux-deps/include/X11/bitmaps/icon | 6 - .../linux-deps/include/X11/bitmaps/keyboard16 | 6 - .../linux-deps/include/X11/bitmaps/ldblarrow | 5 - shell/linux-deps/include/X11/bitmaps/left_ptr | 8 - .../include/X11/bitmaps/left_ptrmsk | 6 - shell/linux-deps/include/X11/bitmaps/letters | 27 - .../linux-deps/include/X11/bitmaps/light_gray | 4 - .../linux-deps/include/X11/bitmaps/mailempty | 27 - .../include/X11/bitmaps/mailemptymsk | 27 - shell/linux-deps/include/X11/bitmaps/mailfull | 27 - .../include/X11/bitmaps/mailfullmsk | 27 - .../include/X11/bitmaps/mensetmanus | 258 -- shell/linux-deps/include/X11/bitmaps/menu10 | 5 - shell/linux-deps/include/X11/bitmaps/menu12 | 5 - shell/linux-deps/include/X11/bitmaps/menu16 | 6 - shell/linux-deps/include/X11/bitmaps/menu6 | 4 - shell/linux-deps/include/X11/bitmaps/menu8 | 4 - .../linux-deps/include/X11/bitmaps/noletters | 27 - shell/linux-deps/include/X11/bitmaps/opendot | 8 - .../include/X11/bitmaps/opendotMask | 8 - shell/linux-deps/include/X11/bitmaps/plaid | 11 - .../linux-deps/include/X11/bitmaps/rdblarrow | 5 - .../linux-deps/include/X11/bitmaps/right_ptr | 8 - .../include/X11/bitmaps/right_ptrmsk | 6 - .../linux-deps/include/X11/bitmaps/root_weave | 4 - shell/linux-deps/include/X11/bitmaps/scales | 6 - shell/linux-deps/include/X11/bitmaps/sipb | 16 - shell/linux-deps/include/X11/bitmaps/star | 8 - shell/linux-deps/include/X11/bitmaps/starMask | 8 - shell/linux-deps/include/X11/bitmaps/stipple | 4 - shell/linux-deps/include/X11/bitmaps/target | 6 - shell/linux-deps/include/X11/bitmaps/terminal | 52 - .../include/X11/bitmaps/tie_fighter | 6 - shell/linux-deps/include/X11/bitmaps/vlines2 | 4 - shell/linux-deps/include/X11/bitmaps/vlines3 | 4 - .../linux-deps/include/X11/bitmaps/weird_size | 5 - .../linux-deps/include/X11/bitmaps/wide_weave | 6 - shell/linux-deps/include/X11/bitmaps/wingdogs | 14 - shell/linux-deps/include/X11/bitmaps/woman | 66 - shell/linux-deps/include/X11/bitmaps/xfd_icon | 27 - shell/linux-deps/include/X11/bitmaps/xlogo11 | 6 - shell/linux-deps/include/X11/bitmaps/xlogo16 | 6 - shell/linux-deps/include/X11/bitmaps/xlogo32 | 14 - shell/linux-deps/include/X11/bitmaps/xlogo64 | 46 - shell/linux-deps/include/X11/bitmaps/xsnow | 1112 ----- shell/linux-deps/include/X11/cursorfont.h | 111 - shell/linux-deps/include/X11/extensions/XI.h | 308 -- shell/linux-deps/include/X11/extensions/XI2.h | 236 - .../include/X11/extensions/XI2proto.h | 1044 ----- .../include/X11/extensions/XIproto.h | 1756 ------- shell/linux-deps/include/X11/extensions/XKB.h | 788 ---- .../include/X11/extensions/XKBgeom.h | 659 --- .../include/X11/extensions/XKBproto.h | 1282 ------ .../include/X11/extensions/XKBsrv.h | 1187 ----- .../include/X11/extensions/XKBstr.h | 614 --- shell/linux-deps/include/X11/keysym.h | 74 - shell/linux-deps/include/X11/keysymdef.h | 2477 ---------- shell/linux-deps/include/alsa/alisp.h | 55 - shell/linux-deps/include/alsa/asoundef.h | 310 -- shell/linux-deps/include/alsa/asoundlib.h | 60 - shell/linux-deps/include/alsa/conf.h | 207 - shell/linux-deps/include/alsa/control.h | 590 --- .../include/alsa/control_external.h | 265 -- shell/linux-deps/include/alsa/error.h | 78 - shell/linux-deps/include/alsa/global.h | 159 - shell/linux-deps/include/alsa/hwdep.h | 160 - shell/linux-deps/include/alsa/iatomic.h | 1198 ----- shell/linux-deps/include/alsa/input.h | 83 - shell/linux-deps/include/alsa/mixer.h | 317 -- shell/linux-deps/include/alsa/mixer_abst.h | 112 - shell/linux-deps/include/alsa/output.h | 86 - shell/linux-deps/include/alsa/pcm.h | 1160 ----- shell/linux-deps/include/alsa/pcm_external.h | 70 - shell/linux-deps/include/alsa/pcm_extplug.h | 189 - shell/linux-deps/include/alsa/pcm_ioplug.h | 217 - shell/linux-deps/include/alsa/pcm_old.h | 230 - shell/linux-deps/include/alsa/pcm_plugin.h | 202 - shell/linux-deps/include/alsa/pcm_rate.h | 153 - shell/linux-deps/include/alsa/rawmidi.h | 159 - shell/linux-deps/include/alsa/seq.h | 737 --- shell/linux-deps/include/alsa/seq_event.h | 319 -- .../linux-deps/include/alsa/seq_midi_event.h | 65 - shell/linux-deps/include/alsa/seqmid.h | 490 -- .../linux-deps/include/alsa/sound/asound_fm.h | 134 - shell/linux-deps/include/alsa/sound/emu10k1.h | 349 -- shell/linux-deps/include/alsa/sound/hdsp.h | 113 - shell/linux-deps/include/alsa/sound/hdspm.h | 229 - .../linux-deps/include/alsa/sound/sb16_csp.h | 115 - .../include/alsa/sound/sscape_ioctl.h | 21 - .../include/alsa/sound/type_compat.h | 40 - shell/linux-deps/include/alsa/timer.h | 259 -- shell/linux-deps/include/alsa/use-case.h | 381 -- shell/linux-deps/include/alsa/version.h | 15 - shell/linux-deps/lib/alibX11.so | Bin 909984 -> 0 bytes shell/linux-deps/lib/libEGL.so | Bin 5418 -> 0 bytes shell/linux-deps/lib/libGLESv2.so | Bin 18402 -> 0 bytes shell/linux-deps/lib/libX11.so | Bin 1124632 -> 0 bytes shell/linux-deps/lib/libXau.so | Bin 9636 -> 0 bytes shell/linux-deps/lib/libXdmcp.so | Bin 13680 -> 0 bytes shell/linux-deps/lib/libasound.so | Bin 583980 -> 0 bytes shell/linux-deps/lib/libxcb.so | Bin 63052 -> 0 bytes shell/linux/Makefile | 2 +- shell/mac86/Makefile | 102 - 196 files changed, 13 insertions(+), 48097 deletions(-) delete mode 100644 shell/emscripten/Makefile delete mode 100644 shell/linux-deps/include/X11/DECkeysym.h delete mode 100644 shell/linux-deps/include/X11/HPkeysym.h delete mode 100644 shell/linux-deps/include/X11/ImUtil.h delete mode 100644 shell/linux-deps/include/X11/Sunkeysym.h delete mode 100644 shell/linux-deps/include/X11/X.h delete mode 100644 shell/linux-deps/include/X11/XF86keysym.h delete mode 100644 shell/linux-deps/include/X11/XKBlib.h delete mode 100644 shell/linux-deps/include/X11/XWDFile.h delete mode 100644 shell/linux-deps/include/X11/Xalloca.h delete mode 100644 shell/linux-deps/include/X11/Xarch.h delete mode 100644 shell/linux-deps/include/X11/Xatom.h delete mode 100644 shell/linux-deps/include/X11/Xauth.h delete mode 100644 shell/linux-deps/include/X11/Xcms.h delete mode 100644 shell/linux-deps/include/X11/Xdefs.h delete mode 100644 shell/linux-deps/include/X11/Xdmcp.h delete mode 100644 shell/linux-deps/include/X11/Xfuncproto.h delete mode 100644 shell/linux-deps/include/X11/Xfuncs.h delete mode 100644 shell/linux-deps/include/X11/Xlib.h delete mode 100644 shell/linux-deps/include/X11/XlibConf.h delete mode 100644 shell/linux-deps/include/X11/Xlibint.h delete mode 100644 shell/linux-deps/include/X11/Xlocale.h delete mode 100644 shell/linux-deps/include/X11/Xmd.h delete mode 100644 shell/linux-deps/include/X11/Xos.h delete mode 100644 shell/linux-deps/include/X11/Xos_r.h delete mode 100644 shell/linux-deps/include/X11/Xosdefs.h delete mode 100644 shell/linux-deps/include/X11/Xpoll.h delete mode 100644 shell/linux-deps/include/X11/Xproto.h delete mode 100644 shell/linux-deps/include/X11/Xprotostr.h delete mode 100644 shell/linux-deps/include/X11/Xregion.h delete mode 100644 shell/linux-deps/include/X11/Xresource.h delete mode 100644 shell/linux-deps/include/X11/Xthreads.h delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtrans.c delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtrans.h delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtransint.h delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtranslcl.c delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtranssock.c delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtranstli.c delete mode 100644 shell/linux-deps/include/X11/Xtrans/Xtransutil.c delete mode 100644 shell/linux-deps/include/X11/Xtrans/transport.c delete mode 100644 shell/linux-deps/include/X11/Xutil.h delete mode 100644 shell/linux-deps/include/X11/Xw32defs.h delete mode 100644 shell/linux-deps/include/X11/Xwindows.h delete mode 100644 shell/linux-deps/include/X11/Xwinsock.h delete mode 100644 shell/linux-deps/include/X11/ap_keysym.h delete mode 100644 shell/linux-deps/include/X11/bitmaps/1x1 delete mode 100644 shell/linux-deps/include/X11/bitmaps/2x2 delete mode 100644 shell/linux-deps/include/X11/bitmaps/Dashes delete mode 100644 shell/linux-deps/include/X11/bitmaps/Down delete mode 100644 shell/linux-deps/include/X11/bitmaps/Excl delete mode 100644 shell/linux-deps/include/X11/bitmaps/FlipHoriz delete mode 100644 shell/linux-deps/include/X11/bitmaps/FlipVert delete mode 100644 shell/linux-deps/include/X11/bitmaps/Fold delete mode 100644 shell/linux-deps/include/X11/bitmaps/Left delete mode 100644 shell/linux-deps/include/X11/bitmaps/Right delete mode 100644 shell/linux-deps/include/X11/bitmaps/RotateLeft delete mode 100644 shell/linux-deps/include/X11/bitmaps/RotateRight delete mode 100644 shell/linux-deps/include/X11/bitmaps/Term delete mode 100644 shell/linux-deps/include/X11/bitmaps/Up delete mode 100644 shell/linux-deps/include/X11/bitmaps/black delete mode 100644 shell/linux-deps/include/X11/bitmaps/black6 delete mode 100644 shell/linux-deps/include/X11/bitmaps/box6 delete mode 100644 shell/linux-deps/include/X11/bitmaps/boxes delete mode 100644 shell/linux-deps/include/X11/bitmaps/calculator delete mode 100644 shell/linux-deps/include/X11/bitmaps/cntr_ptr delete mode 100644 shell/linux-deps/include/X11/bitmaps/cntr_ptrmsk delete mode 100644 shell/linux-deps/include/X11/bitmaps/cross_weave delete mode 100644 shell/linux-deps/include/X11/bitmaps/dimple1 delete mode 100644 shell/linux-deps/include/X11/bitmaps/dimple3 delete mode 100644 shell/linux-deps/include/X11/bitmaps/dot delete mode 100644 shell/linux-deps/include/X11/bitmaps/dropbar7 delete mode 100644 shell/linux-deps/include/X11/bitmaps/dropbar8 delete mode 100644 shell/linux-deps/include/X11/bitmaps/escherknot delete mode 100644 shell/linux-deps/include/X11/bitmaps/flagdown delete mode 100644 shell/linux-deps/include/X11/bitmaps/flagup delete mode 100644 shell/linux-deps/include/X11/bitmaps/flipped_gray delete mode 100644 shell/linux-deps/include/X11/bitmaps/gray delete mode 100644 shell/linux-deps/include/X11/bitmaps/gray1 delete mode 100644 shell/linux-deps/include/X11/bitmaps/gray3 delete mode 100644 shell/linux-deps/include/X11/bitmaps/grid16 delete mode 100644 shell/linux-deps/include/X11/bitmaps/grid2 delete mode 100644 shell/linux-deps/include/X11/bitmaps/grid4 delete mode 100644 shell/linux-deps/include/X11/bitmaps/grid8 delete mode 100644 shell/linux-deps/include/X11/bitmaps/hlines2 delete mode 100644 shell/linux-deps/include/X11/bitmaps/hlines3 delete mode 100644 shell/linux-deps/include/X11/bitmaps/icon delete mode 100644 shell/linux-deps/include/X11/bitmaps/keyboard16 delete mode 100644 shell/linux-deps/include/X11/bitmaps/ldblarrow delete mode 100644 shell/linux-deps/include/X11/bitmaps/left_ptr delete mode 100644 shell/linux-deps/include/X11/bitmaps/left_ptrmsk delete mode 100644 shell/linux-deps/include/X11/bitmaps/letters delete mode 100644 shell/linux-deps/include/X11/bitmaps/light_gray delete mode 100644 shell/linux-deps/include/X11/bitmaps/mailempty delete mode 100644 shell/linux-deps/include/X11/bitmaps/mailemptymsk delete mode 100644 shell/linux-deps/include/X11/bitmaps/mailfull delete mode 100644 shell/linux-deps/include/X11/bitmaps/mailfullmsk delete mode 100644 shell/linux-deps/include/X11/bitmaps/mensetmanus delete mode 100644 shell/linux-deps/include/X11/bitmaps/menu10 delete mode 100644 shell/linux-deps/include/X11/bitmaps/menu12 delete mode 100644 shell/linux-deps/include/X11/bitmaps/menu16 delete mode 100644 shell/linux-deps/include/X11/bitmaps/menu6 delete mode 100644 shell/linux-deps/include/X11/bitmaps/menu8 delete mode 100644 shell/linux-deps/include/X11/bitmaps/noletters delete mode 100644 shell/linux-deps/include/X11/bitmaps/opendot delete mode 100644 shell/linux-deps/include/X11/bitmaps/opendotMask delete mode 100644 shell/linux-deps/include/X11/bitmaps/plaid delete mode 100644 shell/linux-deps/include/X11/bitmaps/rdblarrow delete mode 100644 shell/linux-deps/include/X11/bitmaps/right_ptr delete mode 100644 shell/linux-deps/include/X11/bitmaps/right_ptrmsk delete mode 100644 shell/linux-deps/include/X11/bitmaps/root_weave delete mode 100644 shell/linux-deps/include/X11/bitmaps/scales delete mode 100644 shell/linux-deps/include/X11/bitmaps/sipb delete mode 100644 shell/linux-deps/include/X11/bitmaps/star delete mode 100644 shell/linux-deps/include/X11/bitmaps/starMask delete mode 100644 shell/linux-deps/include/X11/bitmaps/stipple delete mode 100644 shell/linux-deps/include/X11/bitmaps/target delete mode 100644 shell/linux-deps/include/X11/bitmaps/terminal delete mode 100644 shell/linux-deps/include/X11/bitmaps/tie_fighter delete mode 100644 shell/linux-deps/include/X11/bitmaps/vlines2 delete mode 100644 shell/linux-deps/include/X11/bitmaps/vlines3 delete mode 100644 shell/linux-deps/include/X11/bitmaps/weird_size delete mode 100644 shell/linux-deps/include/X11/bitmaps/wide_weave delete mode 100644 shell/linux-deps/include/X11/bitmaps/wingdogs delete mode 100644 shell/linux-deps/include/X11/bitmaps/woman delete mode 100644 shell/linux-deps/include/X11/bitmaps/xfd_icon delete mode 100644 shell/linux-deps/include/X11/bitmaps/xlogo11 delete mode 100644 shell/linux-deps/include/X11/bitmaps/xlogo16 delete mode 100644 shell/linux-deps/include/X11/bitmaps/xlogo32 delete mode 100644 shell/linux-deps/include/X11/bitmaps/xlogo64 delete mode 100644 shell/linux-deps/include/X11/bitmaps/xsnow delete mode 100644 shell/linux-deps/include/X11/cursorfont.h delete mode 100644 shell/linux-deps/include/X11/extensions/XI.h delete mode 100644 shell/linux-deps/include/X11/extensions/XI2.h delete mode 100644 shell/linux-deps/include/X11/extensions/XI2proto.h delete mode 100644 shell/linux-deps/include/X11/extensions/XIproto.h delete mode 100644 shell/linux-deps/include/X11/extensions/XKB.h delete mode 100644 shell/linux-deps/include/X11/extensions/XKBgeom.h delete mode 100644 shell/linux-deps/include/X11/extensions/XKBproto.h delete mode 100644 shell/linux-deps/include/X11/extensions/XKBsrv.h delete mode 100644 shell/linux-deps/include/X11/extensions/XKBstr.h delete mode 100644 shell/linux-deps/include/X11/keysym.h delete mode 100644 shell/linux-deps/include/X11/keysymdef.h delete mode 100644 shell/linux-deps/include/alsa/alisp.h delete mode 100644 shell/linux-deps/include/alsa/asoundef.h delete mode 100644 shell/linux-deps/include/alsa/asoundlib.h delete mode 100644 shell/linux-deps/include/alsa/conf.h delete mode 100644 shell/linux-deps/include/alsa/control.h delete mode 100644 shell/linux-deps/include/alsa/control_external.h delete mode 100644 shell/linux-deps/include/alsa/error.h delete mode 100644 shell/linux-deps/include/alsa/global.h delete mode 100644 shell/linux-deps/include/alsa/hwdep.h delete mode 100644 shell/linux-deps/include/alsa/iatomic.h delete mode 100644 shell/linux-deps/include/alsa/input.h delete mode 100644 shell/linux-deps/include/alsa/mixer.h delete mode 100644 shell/linux-deps/include/alsa/mixer_abst.h delete mode 100644 shell/linux-deps/include/alsa/output.h delete mode 100644 shell/linux-deps/include/alsa/pcm.h delete mode 100644 shell/linux-deps/include/alsa/pcm_external.h delete mode 100644 shell/linux-deps/include/alsa/pcm_extplug.h delete mode 100644 shell/linux-deps/include/alsa/pcm_ioplug.h delete mode 100644 shell/linux-deps/include/alsa/pcm_old.h delete mode 100644 shell/linux-deps/include/alsa/pcm_plugin.h delete mode 100644 shell/linux-deps/include/alsa/pcm_rate.h delete mode 100644 shell/linux-deps/include/alsa/rawmidi.h delete mode 100644 shell/linux-deps/include/alsa/seq.h delete mode 100644 shell/linux-deps/include/alsa/seq_event.h delete mode 100644 shell/linux-deps/include/alsa/seq_midi_event.h delete mode 100644 shell/linux-deps/include/alsa/seqmid.h delete mode 100644 shell/linux-deps/include/alsa/sound/asound_fm.h delete mode 100644 shell/linux-deps/include/alsa/sound/emu10k1.h delete mode 100644 shell/linux-deps/include/alsa/sound/hdsp.h delete mode 100644 shell/linux-deps/include/alsa/sound/hdspm.h delete mode 100644 shell/linux-deps/include/alsa/sound/sb16_csp.h delete mode 100644 shell/linux-deps/include/alsa/sound/sscape_ioctl.h delete mode 100644 shell/linux-deps/include/alsa/sound/type_compat.h delete mode 100644 shell/linux-deps/include/alsa/timer.h delete mode 100644 shell/linux-deps/include/alsa/use-case.h delete mode 100644 shell/linux-deps/include/alsa/version.h delete mode 100644 shell/linux-deps/lib/alibX11.so delete mode 100644 shell/linux-deps/lib/libEGL.so delete mode 100644 shell/linux-deps/lib/libGLESv2.so delete mode 100644 shell/linux-deps/lib/libX11.so delete mode 100644 shell/linux-deps/lib/libXau.so delete mode 100644 shell/linux-deps/lib/libXdmcp.so delete mode 100644 shell/linux-deps/lib/libasound.so delete mode 100644 shell/linux-deps/lib/libxcb.so delete mode 100644 shell/mac86/Makefile diff --git a/core/deps/imgui/imgui.h b/core/deps/imgui/imgui.h index a5c485974..ae923668a 100644 --- a/core/deps/imgui/imgui.h +++ b/core/deps/imgui/imgui.h @@ -63,7 +63,7 @@ Index of this file: #include #define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h #endif -#if defined(__clang__) || defined(__GNUC__) +#if (defined(__clang__) || defined(__GNUC__)) && !defined(_ANDROID) #define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // Apply printf-style warnings to user functions. #define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) #else diff --git a/core/emitter/x86_op_encoder.h b/core/emitter/x86_op_encoder.h index 0f3e9db9c..f2228c40c 100644 --- a/core/emitter/x86_op_encoder.h +++ b/core/emitter/x86_op_encoder.h @@ -381,6 +381,9 @@ void x86_encode_opcode_tmpl(x86_block* block, const x86_opcode* op, encoded_type case enc_imm_32 : block->write32(p3); break; + + case enc_imm_none: + break; } } diff --git a/core/hw/naomi/naomi_cart.cpp b/core/hw/naomi/naomi_cart.cpp index 127c91b98..e3ad4e451 100644 --- a/core/hw/naomi/naomi_cart.cpp +++ b/core/hw/naomi/naomi_cart.cpp @@ -470,7 +470,7 @@ void naomi_cart_LoadRom(const char* file) raw_bin_file = true; } - INFO_LOG(NAOMI, "+%ld romfiles, %.2f MB set size, %.2f MB set address space", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f); + INFO_LOG(NAOMI, "+%zd romfiles, %.2f MB set size, %.2f MB set address space", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f); if (RomCacheMap) { diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index d75980f02..d2ff9bfca 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -106,9 +106,7 @@ void recSh4_Run() verify(rcb_noffs(&next_pc)==-184); ngen_mainloop(sh4_dyna_rcb); -#if !defined(TARGET_BOUNDED_EXECUTION) - sh4_int_bCpuRun=false; -#endif + sh4_int_bCpuRun = false; } void emit_Write32(u32 data) diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index 2b6a9e8dc..62d8e001a 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -47,11 +47,7 @@ void Sh4_int_Run() l = SH4_TIMESLICE; -#if !defined(TARGET_BOUNDED_EXECUTION) do -#else - for (int i=0; i<10000; i++) -#endif { #if !defined(NO_MMU) try { @@ -73,13 +69,9 @@ void Sh4_int_Run() l -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles } #endif -#if !defined(TARGET_BOUNDED_EXECUTION) - } while(sh4_int_bCpuRun); + } while (sh4_int_bCpuRun); - sh4_int_bCpuRun=false; -#else - } -#endif + sh4_int_bCpuRun = false; } void Sh4_int_Stop() diff --git a/core/linux/common.cpp b/core/linux/common.cpp index ce717d853..bb14b4666 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -107,7 +107,7 @@ void fault_handler (int sn, siginfo_t * si, void *segfault_ctx) #endif else { - ERROR_LOG(COMMON, "SIGSEGV @ %lx -> %p was not in vram, dynacode:%d", ctx.pc, si->si_addr, dyna_cde); + ERROR_LOG(COMMON, "SIGSEGV @ %zx -> %p was not in vram, dynacode:%d", ctx.pc, si->si_addr, dyna_cde); die("segfault"); signal(SIGSEGV, SIG_DFL); } diff --git a/core/linux/posix_vmem.cpp b/core/linux/posix_vmem.cpp index 921dfd16c..6e8d0fd28 100644 --- a/core/linux/posix_vmem.cpp +++ b/core/linux/posix_vmem.cpp @@ -191,7 +191,7 @@ VMemType vmem_platform_init(void **vmem_base_addr, void **sh4rcb_addr) { // Just tries to wipe as much as possible in the relevant area. void vmem_platform_destroy() { if (vmem_4gb_space) - mem_region_release(virt_ram_base, 0x100000000); + mem_region_release(virt_ram_base, (size_t)0x100000000); else mem_region_release(virt_ram_base, 0x20000000); } diff --git a/core/rec-cpp/rec_cpp.cpp b/core/rec-cpp/rec_cpp.cpp index a260e9f09..e27d75126 100644 --- a/core/rec-cpp/rec_cpp.cpp +++ b/core/rec-cpp/rec_cpp.cpp @@ -42,11 +42,8 @@ void ngen_mainloop(void* v_cntx) cycle_counter = 0; -#if !defined(TARGET_BOUNDED_EXECUTION) - while (sh4_int_bCpuRun) { -#else - for (int i=0; i<10000; i++) { -#endif + while (sh4_int_bCpuRun) + { cycle_counter = SH4_TIMESLICE; do { DynarecCodeEntryPtr rcb = bm_GetCodeByVAddr(ctx->cntx.pc); diff --git a/shell/emscripten/Makefile b/shell/emscripten/Makefile deleted file mode 100644 index 237e10d01..000000000 --- a/shell/emscripten/Makefile +++ /dev/null @@ -1,68 +0,0 @@ - -LOCAL_PATH := $(call my-dir) -FOR_LINUX :=1 -NOT_ARM := 1 -#NO_REC := 1 -#NO_REND := 1 -CPP_REC := 1 -NO_NIXPROF := 1 -RZDCY_SRC_DIR = ../../core - -include $(RZDCY_SRC_DIR)/core.mk - -CC_PREFIX ?= - -CXX=${CC_PREFIX}em++ -CC=${CC_PREFIX}emcc -#AS=${CC_PREFIX}as -STRIP=${CC_PREFIX}emstrip - -LD=${CC} - -MFLAGS := -ASFLAGS := - -LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common - - -CXXONLYFLAGS := -std=c++11 -CXXFLAGS := -O3 -D GLES -D RELEASE -c -D TARGET_EMSCRIPTEN -D TARGET_NO_REC -D TARGET_NO_EXCEPTIONS -D TARGET_NO_THREADS -D TARGET_BOUNDED_EXECUTION -D TARGET_NO_COREIO_HTTP -CXXFLAGS += -fno-strict-aliasing -CXXFLAGS += -ffast-math - -CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti - - -INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I../linux-deps/include - -LIBS := #emscripten has all the basic libs, and egl, and sdl, built in - -OBJECTS=$(RZDCY_FILES:.cpp=.build.obj) -OBJECTS:=$(OBJECTS:.c=.build.obj) -OBJECTS:=$(OBJECTS:.S=.build.obj) -OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS)) - - -EXECUTABLE=reicast.html - -all: $(CPPFILES) $(EXECUTABLE) - -$(EXECUTABLE): $(OBJECTS) - echo $(RZDCY_FILES) - $(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ --preload-file data/dc_boot.bin --preload-file data/dc_flash.bin -s TOTAL_MEMORY=96000000 -s NO_EXIT_RUNTIME=1 -O3 - -obj/%.build.obj : $(RZDCY_SRC_DIR)/%.cpp - mkdir -p $(dir $@) - $(CXX) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $(CXXONLYFLAGS) $< -o $@ - -obj/%.build.obj : $(RZDCY_SRC_DIR)/%.c - mkdir -p $(dir $@) - $(CC) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ - -obj/%.build.obj : $(RZDCY_SRC_DIR)/%.S - mkdir -p $(dir $@) - $(AS) $(ASFLAGS) $(INCS) $< -o $@ - - -clean: - rm $(OBJECTS) $(EXECUTABLE) -f diff --git a/shell/linux-deps/include/X11/DECkeysym.h b/shell/linux-deps/include/X11/DECkeysym.h deleted file mode 100644 index 07307169d..000000000 --- a/shell/linux-deps/include/X11/DECkeysym.h +++ /dev/null @@ -1,65 +0,0 @@ -/*********************************************************** - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* - * DEC private keysyms - * (29th bit set) - */ - -/* two-key compose sequence initiators, chosen to map to Latin1 characters */ - -#define DXK_ring_accent 0x1000FEB0 -#define DXK_circumflex_accent 0x1000FE5E -#define DXK_cedilla_accent 0x1000FE2C -#define DXK_acute_accent 0x1000FE27 -#define DXK_grave_accent 0x1000FE60 -#define DXK_tilde 0x1000FE7E -#define DXK_diaeresis 0x1000FE22 - -/* special keysym for LK2** "Remove" key on editing keypad */ - -#define DXK_Remove 0x1000FF00 /* Remove */ diff --git a/shell/linux-deps/include/X11/HPkeysym.h b/shell/linux-deps/include/X11/HPkeysym.h deleted file mode 100644 index ed000b167..000000000 --- a/shell/linux-deps/include/X11/HPkeysym.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Hewlett Packard -or Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD -TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. Hewlett-Packard shall not be liable for errors -contained herein or direct, indirect, special, incidental or -consequential damages in connection with the furnishing, -performance, or use of this material. - -*/ - -#ifndef _HPKEYSYM_H - -#define _HPKEYSYM - -#define hpXK_ClearLine 0x1000FF6F -#define hpXK_InsertLine 0x1000FF70 -#define hpXK_DeleteLine 0x1000FF71 -#define hpXK_InsertChar 0x1000FF72 -#define hpXK_DeleteChar 0x1000FF73 -#define hpXK_BackTab 0x1000FF74 -#define hpXK_KP_BackTab 0x1000FF75 -#define hpXK_Modelock1 0x1000FF48 -#define hpXK_Modelock2 0x1000FF49 -#define hpXK_Reset 0x1000FF6C -#define hpXK_System 0x1000FF6D -#define hpXK_User 0x1000FF6E -#define hpXK_mute_acute 0x100000A8 -#define hpXK_mute_grave 0x100000A9 -#define hpXK_mute_asciicircum 0x100000AA -#define hpXK_mute_diaeresis 0x100000AB -#define hpXK_mute_asciitilde 0x100000AC -#define hpXK_lira 0x100000AF -#define hpXK_guilder 0x100000BE -#define hpXK_Ydiaeresis 0x100000EE -#define hpXK_IO 0x100000EE -#define hpXK_longminus 0x100000F6 -#define hpXK_block 0x100000FC - - -#ifndef _OSF_Keysyms -#define _OSF_Keysyms - -#define osfXK_Copy 0x1004FF02 -#define osfXK_Cut 0x1004FF03 -#define osfXK_Paste 0x1004FF04 -#define osfXK_BackTab 0x1004FF07 -#define osfXK_BackSpace 0x1004FF08 -#define osfXK_Clear 0x1004FF0B -#define osfXK_Escape 0x1004FF1B -#define osfXK_AddMode 0x1004FF31 -#define osfXK_PrimaryPaste 0x1004FF32 -#define osfXK_QuickPaste 0x1004FF33 -#define osfXK_PageLeft 0x1004FF40 -#define osfXK_PageUp 0x1004FF41 -#define osfXK_PageDown 0x1004FF42 -#define osfXK_PageRight 0x1004FF43 -#define osfXK_Activate 0x1004FF44 -#define osfXK_MenuBar 0x1004FF45 -#define osfXK_Left 0x1004FF51 -#define osfXK_Up 0x1004FF52 -#define osfXK_Right 0x1004FF53 -#define osfXK_Down 0x1004FF54 -#define osfXK_EndLine 0x1004FF57 -#define osfXK_BeginLine 0x1004FF58 -#define osfXK_EndData 0x1004FF59 -#define osfXK_BeginData 0x1004FF5A -#define osfXK_PrevMenu 0x1004FF5B -#define osfXK_NextMenu 0x1004FF5C -#define osfXK_PrevField 0x1004FF5D -#define osfXK_NextField 0x1004FF5E -#define osfXK_Select 0x1004FF60 -#define osfXK_Insert 0x1004FF63 -#define osfXK_Undo 0x1004FF65 -#define osfXK_Menu 0x1004FF67 -#define osfXK_Cancel 0x1004FF69 -#define osfXK_Help 0x1004FF6A -#define osfXK_SelectAll 0x1004FF71 -#define osfXK_DeselectAll 0x1004FF72 -#define osfXK_Reselect 0x1004FF73 -#define osfXK_Extend 0x1004FF74 -#define osfXK_Restore 0x1004FF78 -#define osfXK_Delete 0x1004FFFF - -#endif /* _OSF_Keysyms */ - - -/************************************************************** - * The use of the following macros is deprecated. - * They are listed below only for backwards compatibility. - */ -#define XK_Reset 0x1000FF6C -#define XK_System 0x1000FF6D -#define XK_User 0x1000FF6E -#define XK_ClearLine 0x1000FF6F -#define XK_InsertLine 0x1000FF70 -#define XK_DeleteLine 0x1000FF71 -#define XK_InsertChar 0x1000FF72 -#define XK_DeleteChar 0x1000FF73 -#define XK_BackTab 0x1000FF74 -#define XK_KP_BackTab 0x1000FF75 -#define XK_Ext16bit_L 0x1000FF76 -#define XK_Ext16bit_R 0x1000FF77 -#define XK_mute_acute 0x100000a8 -#define XK_mute_grave 0x100000a9 -#define XK_mute_asciicircum 0x100000aa -#define XK_mute_diaeresis 0x100000ab -#define XK_mute_asciitilde 0x100000ac -#define XK_lira 0x100000af -#define XK_guilder 0x100000be -#ifndef XK_Ydiaeresis -#define XK_Ydiaeresis 0x100000ee -#endif -#define XK_IO 0x100000ee -#define XK_longminus 0x100000f6 -#define XK_block 0x100000fc - -#endif /* _HPKEYSYM_H */ diff --git a/shell/linux-deps/include/X11/ImUtil.h b/shell/linux-deps/include/X11/ImUtil.h deleted file mode 100644 index ffdba1a93..000000000 --- a/shell/linux-deps/include/X11/ImUtil.h +++ /dev/null @@ -1,30 +0,0 @@ - -#ifndef _X11_IMUTIL_H_ -#define _X11_IMUTIL_H_ - -extern int -_XGetScanlinePad( - Display *dpy, - int depth); - -extern int -_XGetBitsPerPixel( - Display *dpy, - int depth); - -extern int -_XSetImage( - XImage *srcimg, - register XImage *dstimg, - register int x, - register int y); - -extern int -_XReverse_Bytes( - register unsigned char *bpt, - register int nb); -extern void -_XInitImageFuncPtrs( - register XImage *image); - -#endif /* _X11_IMUTIL_H_ */ diff --git a/shell/linux-deps/include/X11/Sunkeysym.h b/shell/linux-deps/include/X11/Sunkeysym.h deleted file mode 100644 index 78d1286bb..000000000 --- a/shell/linux-deps/include/X11/Sunkeysym.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -/************************************************************ - -Copyright 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -***********************************************************/ - -/* - * Floating Accent - */ - -#define SunXK_FA_Grave 0x1005FF00 -#define SunXK_FA_Circum 0x1005FF01 -#define SunXK_FA_Tilde 0x1005FF02 -#define SunXK_FA_Acute 0x1005FF03 -#define SunXK_FA_Diaeresis 0x1005FF04 -#define SunXK_FA_Cedilla 0x1005FF05 - -/* - * Miscellaneous Functions - */ - -#define SunXK_F36 0x1005FF10 /* Labeled F11 */ -#define SunXK_F37 0x1005FF11 /* Labeled F12 */ - -#define SunXK_Sys_Req 0x1005FF60 -#define SunXK_Print_Screen 0x0000FF61 /* Same as XK_Print */ - -/* - * International & Multi-Key Character Composition - */ - -#define SunXK_Compose 0x0000FF20 /* Same as XK_Multi_key */ -#define SunXK_AltGraph 0x0000FF7E /* Same as XK_Mode_switch */ - -/* - * Cursor Control - */ - -#define SunXK_PageUp 0x0000FF55 /* Same as XK_Prior */ -#define SunXK_PageDown 0x0000FF56 /* Same as XK_Next */ - -/* - * Open Look Functions - */ - -#define SunXK_Undo 0x0000FF65 /* Same as XK_Undo */ -#define SunXK_Again 0x0000FF66 /* Same as XK_Redo */ -#define SunXK_Find 0x0000FF68 /* Same as XK_Find */ -#define SunXK_Stop 0x0000FF69 /* Same as XK_Cancel */ -#define SunXK_Props 0x1005FF70 -#define SunXK_Front 0x1005FF71 -#define SunXK_Copy 0x1005FF72 -#define SunXK_Open 0x1005FF73 -#define SunXK_Paste 0x1005FF74 -#define SunXK_Cut 0x1005FF75 - -#define SunXK_PowerSwitch 0x1005FF76 -#define SunXK_AudioLowerVolume 0x1005FF77 -#define SunXK_AudioMute 0x1005FF78 -#define SunXK_AudioRaiseVolume 0x1005FF79 -#define SunXK_VideoDegauss 0x1005FF7A -#define SunXK_VideoLowerBrightness 0x1005FF7B -#define SunXK_VideoRaiseBrightness 0x1005FF7C -#define SunXK_PowerSwitchShift 0x1005FF7D diff --git a/shell/linux-deps/include/X11/X.h b/shell/linux-deps/include/X11/X.h deleted file mode 100644 index 5cf695d7b..000000000 --- a/shell/linux-deps/include/X11/X.h +++ /dev/null @@ -1,717 +0,0 @@ -/* Definitions for the X window system likely to be used by applications */ - -#ifndef X_H -#define X_H - -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#define X_PROTOCOL 11 /* current protocol version */ -#define X_PROTOCOL_REVISION 0 /* current minor version */ - -/* Resources */ - -/* - * _XSERVER64 must ONLY be defined when compiling X server sources on - * systems where unsigned long is not 32 bits, must NOT be used in - * client or library code. - */ -#ifndef _XSERVER64 -# ifndef _XTYPEDEF_XID -# define _XTYPEDEF_XID -typedef unsigned long XID; -# endif -# ifndef _XTYPEDEF_MASK -# define _XTYPEDEF_MASK -typedef unsigned long Mask; -# endif -# ifndef _XTYPEDEF_ATOM -# define _XTYPEDEF_ATOM -typedef unsigned long Atom; /* Also in Xdefs.h */ -# endif -typedef unsigned long VisualID; -typedef unsigned long Time; -#else -# include -# ifndef _XTYPEDEF_XID -# define _XTYPEDEF_XID -typedef CARD32 XID; -# endif -# ifndef _XTYPEDEF_MASK -# define _XTYPEDEF_MASK -typedef CARD32 Mask; -# endif -# ifndef _XTYPEDEF_ATOM -# define _XTYPEDEF_ATOM -typedef CARD32 Atom; -# endif -typedef CARD32 VisualID; -typedef CARD32 Time; -#endif - -typedef XID Window; -typedef XID Drawable; -#ifndef _XTYPEDEF_FONT -# define _XTYPEDEF_FONT -typedef XID Font; -#endif -typedef XID Pixmap; -typedef XID Cursor; -typedef XID Colormap; -typedef XID GContext; -typedef XID KeySym; - -typedef unsigned char KeyCode; - -/***************************************************************** - * RESERVED RESOURCE AND CONSTANT DEFINITIONS - *****************************************************************/ - -#ifndef None -#define None 0L /* universal null resource or null atom */ -#endif - -#define ParentRelative 1L /* background pixmap in CreateWindow - and ChangeWindowAttributes */ - -#define CopyFromParent 0L /* border pixmap in CreateWindow - and ChangeWindowAttributes - special VisualID and special window - class passed to CreateWindow */ - -#define PointerWindow 0L /* destination window in SendEvent */ -#define InputFocus 1L /* destination window in SendEvent */ - -#define PointerRoot 1L /* focus window in SetInputFocus */ - -#define AnyPropertyType 0L /* special Atom, passed to GetProperty */ - -#define AnyKey 0L /* special Key Code, passed to GrabKey */ - -#define AnyButton 0L /* special Button Code, passed to GrabButton */ - -#define AllTemporary 0L /* special Resource ID passed to KillClient */ - -#define CurrentTime 0L /* special Time */ - -#define NoSymbol 0L /* special KeySym */ - -/***************************************************************** - * EVENT DEFINITIONS - *****************************************************************/ - -/* Input Event Masks. Used as event-mask window attribute and as arguments - to Grab requests. Not to be confused with event names. */ - -#define NoEventMask 0L -#define KeyPressMask (1L<<0) -#define KeyReleaseMask (1L<<1) -#define ButtonPressMask (1L<<2) -#define ButtonReleaseMask (1L<<3) -#define EnterWindowMask (1L<<4) -#define LeaveWindowMask (1L<<5) -#define PointerMotionMask (1L<<6) -#define PointerMotionHintMask (1L<<7) -#define Button1MotionMask (1L<<8) -#define Button2MotionMask (1L<<9) -#define Button3MotionMask (1L<<10) -#define Button4MotionMask (1L<<11) -#define Button5MotionMask (1L<<12) -#define ButtonMotionMask (1L<<13) -#define KeymapStateMask (1L<<14) -#define ExposureMask (1L<<15) -#define VisibilityChangeMask (1L<<16) -#define StructureNotifyMask (1L<<17) -#define ResizeRedirectMask (1L<<18) -#define SubstructureNotifyMask (1L<<19) -#define SubstructureRedirectMask (1L<<20) -#define FocusChangeMask (1L<<21) -#define PropertyChangeMask (1L<<22) -#define ColormapChangeMask (1L<<23) -#define OwnerGrabButtonMask (1L<<24) - -/* Event names. Used in "type" field in XEvent structures. Not to be -confused with event masks above. They start from 2 because 0 and 1 -are reserved in the protocol for errors and replies. */ - -#define KeyPress 2 -#define KeyRelease 3 -#define ButtonPress 4 -#define ButtonRelease 5 -#define MotionNotify 6 -#define EnterNotify 7 -#define LeaveNotify 8 -#define FocusIn 9 -#define FocusOut 10 -#define KeymapNotify 11 -#define Expose 12 -#define GraphicsExpose 13 -#define NoExpose 14 -#define VisibilityNotify 15 -#define CreateNotify 16 -#define DestroyNotify 17 -#define UnmapNotify 18 -#define MapNotify 19 -#define MapRequest 20 -#define ReparentNotify 21 -#define ConfigureNotify 22 -#define ConfigureRequest 23 -#define GravityNotify 24 -#define ResizeRequest 25 -#define CirculateNotify 26 -#define CirculateRequest 27 -#define PropertyNotify 28 -#define SelectionClear 29 -#define SelectionRequest 30 -#define SelectionNotify 31 -#define ColormapNotify 32 -#define ClientMessage 33 -#define MappingNotify 34 -#define GenericEvent 35 -#define LASTEvent 36 /* must be bigger than any event # */ - - -/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, - state in various key-, mouse-, and button-related events. */ - -#define ShiftMask (1<<0) -#define LockMask (1<<1) -#define ControlMask (1<<2) -#define Mod1Mask (1<<3) -#define Mod2Mask (1<<4) -#define Mod3Mask (1<<5) -#define Mod4Mask (1<<6) -#define Mod5Mask (1<<7) - -/* modifier names. Used to build a SetModifierMapping request or - to read a GetModifierMapping request. These correspond to the - masks defined above. */ -#define ShiftMapIndex 0 -#define LockMapIndex 1 -#define ControlMapIndex 2 -#define Mod1MapIndex 3 -#define Mod2MapIndex 4 -#define Mod3MapIndex 5 -#define Mod4MapIndex 6 -#define Mod5MapIndex 7 - - -/* button masks. Used in same manner as Key masks above. Not to be confused - with button names below. */ - -#define Button1Mask (1<<8) -#define Button2Mask (1<<9) -#define Button3Mask (1<<10) -#define Button4Mask (1<<11) -#define Button5Mask (1<<12) - -#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */ - - -/* button names. Used as arguments to GrabButton and as detail in ButtonPress - and ButtonRelease events. Not to be confused with button masks above. - Note that 0 is already defined above as "AnyButton". */ - -#define Button1 1 -#define Button2 2 -#define Button3 3 -#define Button4 4 -#define Button5 5 - -/* Notify modes */ - -#define NotifyNormal 0 -#define NotifyGrab 1 -#define NotifyUngrab 2 -#define NotifyWhileGrabbed 3 - -#define NotifyHint 1 /* for MotionNotify events */ - -/* Notify detail */ - -#define NotifyAncestor 0 -#define NotifyVirtual 1 -#define NotifyInferior 2 -#define NotifyNonlinear 3 -#define NotifyNonlinearVirtual 4 -#define NotifyPointer 5 -#define NotifyPointerRoot 6 -#define NotifyDetailNone 7 - -/* Visibility notify */ - -#define VisibilityUnobscured 0 -#define VisibilityPartiallyObscured 1 -#define VisibilityFullyObscured 2 - -/* Circulation request */ - -#define PlaceOnTop 0 -#define PlaceOnBottom 1 - -/* protocol families */ - -#define FamilyInternet 0 /* IPv4 */ -#define FamilyDECnet 1 -#define FamilyChaos 2 -#define FamilyInternet6 6 /* IPv6 */ - -/* authentication families not tied to a specific protocol */ -#define FamilyServerInterpreted 5 - -/* Property notification */ - -#define PropertyNewValue 0 -#define PropertyDelete 1 - -/* Color Map notification */ - -#define ColormapUninstalled 0 -#define ColormapInstalled 1 - -/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */ - -#define GrabModeSync 0 -#define GrabModeAsync 1 - -/* GrabPointer, GrabKeyboard reply status */ - -#define GrabSuccess 0 -#define AlreadyGrabbed 1 -#define GrabInvalidTime 2 -#define GrabNotViewable 3 -#define GrabFrozen 4 - -/* AllowEvents modes */ - -#define AsyncPointer 0 -#define SyncPointer 1 -#define ReplayPointer 2 -#define AsyncKeyboard 3 -#define SyncKeyboard 4 -#define ReplayKeyboard 5 -#define AsyncBoth 6 -#define SyncBoth 7 - -/* Used in SetInputFocus, GetInputFocus */ - -#define RevertToNone (int)None -#define RevertToPointerRoot (int)PointerRoot -#define RevertToParent 2 - -/***************************************************************** - * ERROR CODES - *****************************************************************/ - -#define Success 0 /* everything's okay */ -#define BadRequest 1 /* bad request code */ -#define BadValue 2 /* int parameter out of range */ -#define BadWindow 3 /* parameter not a Window */ -#define BadPixmap 4 /* parameter not a Pixmap */ -#define BadAtom 5 /* parameter not an Atom */ -#define BadCursor 6 /* parameter not a Cursor */ -#define BadFont 7 /* parameter not a Font */ -#define BadMatch 8 /* parameter mismatch */ -#define BadDrawable 9 /* parameter not a Pixmap or Window */ -#define BadAccess 10 /* depending on context: - - key/button already grabbed - - attempt to free an illegal - cmap entry - - attempt to store into a read-only - color map entry. - - attempt to modify the access control - list from other than the local host. - */ -#define BadAlloc 11 /* insufficient resources */ -#define BadColor 12 /* no such colormap */ -#define BadGC 13 /* parameter not a GC */ -#define BadIDChoice 14 /* choice not in range or already used */ -#define BadName 15 /* font or color name doesn't exist */ -#define BadLength 16 /* Request length incorrect */ -#define BadImplementation 17 /* server is defective */ - -#define FirstExtensionError 128 -#define LastExtensionError 255 - -/***************************************************************** - * WINDOW DEFINITIONS - *****************************************************************/ - -/* Window classes used by CreateWindow */ -/* Note that CopyFromParent is already defined as 0 above */ - -#define InputOutput 1 -#define InputOnly 2 - -/* Window attributes for CreateWindow and ChangeWindowAttributes */ - -#define CWBackPixmap (1L<<0) -#define CWBackPixel (1L<<1) -#define CWBorderPixmap (1L<<2) -#define CWBorderPixel (1L<<3) -#define CWBitGravity (1L<<4) -#define CWWinGravity (1L<<5) -#define CWBackingStore (1L<<6) -#define CWBackingPlanes (1L<<7) -#define CWBackingPixel (1L<<8) -#define CWOverrideRedirect (1L<<9) -#define CWSaveUnder (1L<<10) -#define CWEventMask (1L<<11) -#define CWDontPropagate (1L<<12) -#define CWColormap (1L<<13) -#define CWCursor (1L<<14) - -/* ConfigureWindow structure */ - -#define CWX (1<<0) -#define CWY (1<<1) -#define CWWidth (1<<2) -#define CWHeight (1<<3) -#define CWBorderWidth (1<<4) -#define CWSibling (1<<5) -#define CWStackMode (1<<6) - - -/* Bit Gravity */ - -#define ForgetGravity 0 -#define NorthWestGravity 1 -#define NorthGravity 2 -#define NorthEastGravity 3 -#define WestGravity 4 -#define CenterGravity 5 -#define EastGravity 6 -#define SouthWestGravity 7 -#define SouthGravity 8 -#define SouthEastGravity 9 -#define StaticGravity 10 - -/* Window gravity + bit gravity above */ - -#define UnmapGravity 0 - -/* Used in CreateWindow for backing-store hint */ - -#define NotUseful 0 -#define WhenMapped 1 -#define Always 2 - -/* Used in GetWindowAttributes reply */ - -#define IsUnmapped 0 -#define IsUnviewable 1 -#define IsViewable 2 - -/* Used in ChangeSaveSet */ - -#define SetModeInsert 0 -#define SetModeDelete 1 - -/* Used in ChangeCloseDownMode */ - -#define DestroyAll 0 -#define RetainPermanent 1 -#define RetainTemporary 2 - -/* Window stacking method (in configureWindow) */ - -#define Above 0 -#define Below 1 -#define TopIf 2 -#define BottomIf 3 -#define Opposite 4 - -/* Circulation direction */ - -#define RaiseLowest 0 -#define LowerHighest 1 - -/* Property modes */ - -#define PropModeReplace 0 -#define PropModePrepend 1 -#define PropModeAppend 2 - -/***************************************************************** - * GRAPHICS DEFINITIONS - *****************************************************************/ - -/* graphics functions, as in GC.alu */ - -#define GXclear 0x0 /* 0 */ -#define GXand 0x1 /* src AND dst */ -#define GXandReverse 0x2 /* src AND NOT dst */ -#define GXcopy 0x3 /* src */ -#define GXandInverted 0x4 /* NOT src AND dst */ -#define GXnoop 0x5 /* dst */ -#define GXxor 0x6 /* src XOR dst */ -#define GXor 0x7 /* src OR dst */ -#define GXnor 0x8 /* NOT src AND NOT dst */ -#define GXequiv 0x9 /* NOT src XOR dst */ -#define GXinvert 0xa /* NOT dst */ -#define GXorReverse 0xb /* src OR NOT dst */ -#define GXcopyInverted 0xc /* NOT src */ -#define GXorInverted 0xd /* NOT src OR dst */ -#define GXnand 0xe /* NOT src OR NOT dst */ -#define GXset 0xf /* 1 */ - -/* LineStyle */ - -#define LineSolid 0 -#define LineOnOffDash 1 -#define LineDoubleDash 2 - -/* capStyle */ - -#define CapNotLast 0 -#define CapButt 1 -#define CapRound 2 -#define CapProjecting 3 - -/* joinStyle */ - -#define JoinMiter 0 -#define JoinRound 1 -#define JoinBevel 2 - -/* fillStyle */ - -#define FillSolid 0 -#define FillTiled 1 -#define FillStippled 2 -#define FillOpaqueStippled 3 - -/* fillRule */ - -#define EvenOddRule 0 -#define WindingRule 1 - -/* subwindow mode */ - -#define ClipByChildren 0 -#define IncludeInferiors 1 - -/* SetClipRectangles ordering */ - -#define Unsorted 0 -#define YSorted 1 -#define YXSorted 2 -#define YXBanded 3 - -/* CoordinateMode for drawing routines */ - -#define CoordModeOrigin 0 /* relative to the origin */ -#define CoordModePrevious 1 /* relative to previous point */ - -/* Polygon shapes */ - -#define Complex 0 /* paths may intersect */ -#define Nonconvex 1 /* no paths intersect, but not convex */ -#define Convex 2 /* wholly convex */ - -/* Arc modes for PolyFillArc */ - -#define ArcChord 0 /* join endpoints of arc */ -#define ArcPieSlice 1 /* join endpoints to center of arc */ - -/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into - GC.stateChanges */ - -#define GCFunction (1L<<0) -#define GCPlaneMask (1L<<1) -#define GCForeground (1L<<2) -#define GCBackground (1L<<3) -#define GCLineWidth (1L<<4) -#define GCLineStyle (1L<<5) -#define GCCapStyle (1L<<6) -#define GCJoinStyle (1L<<7) -#define GCFillStyle (1L<<8) -#define GCFillRule (1L<<9) -#define GCTile (1L<<10) -#define GCStipple (1L<<11) -#define GCTileStipXOrigin (1L<<12) -#define GCTileStipYOrigin (1L<<13) -#define GCFont (1L<<14) -#define GCSubwindowMode (1L<<15) -#define GCGraphicsExposures (1L<<16) -#define GCClipXOrigin (1L<<17) -#define GCClipYOrigin (1L<<18) -#define GCClipMask (1L<<19) -#define GCDashOffset (1L<<20) -#define GCDashList (1L<<21) -#define GCArcMode (1L<<22) - -#define GCLastBit 22 -/***************************************************************** - * FONTS - *****************************************************************/ - -/* used in QueryFont -- draw direction */ - -#define FontLeftToRight 0 -#define FontRightToLeft 1 - -#define FontChange 255 - -/***************************************************************** - * IMAGING - *****************************************************************/ - -/* ImageFormat -- PutImage, GetImage */ - -#define XYBitmap 0 /* depth 1, XYFormat */ -#define XYPixmap 1 /* depth == drawable depth */ -#define ZPixmap 2 /* depth == drawable depth */ - -/***************************************************************** - * COLOR MAP STUFF - *****************************************************************/ - -/* For CreateColormap */ - -#define AllocNone 0 /* create map with no entries */ -#define AllocAll 1 /* allocate entire map writeable */ - - -/* Flags used in StoreNamedColor, StoreColors */ - -#define DoRed (1<<0) -#define DoGreen (1<<1) -#define DoBlue (1<<2) - -/***************************************************************** - * CURSOR STUFF - *****************************************************************/ - -/* QueryBestSize Class */ - -#define CursorShape 0 /* largest size that can be displayed */ -#define TileShape 1 /* size tiled fastest */ -#define StippleShape 2 /* size stippled fastest */ - -/***************************************************************** - * KEYBOARD/POINTER STUFF - *****************************************************************/ - -#define AutoRepeatModeOff 0 -#define AutoRepeatModeOn 1 -#define AutoRepeatModeDefault 2 - -#define LedModeOff 0 -#define LedModeOn 1 - -/* masks for ChangeKeyboardControl */ - -#define KBKeyClickPercent (1L<<0) -#define KBBellPercent (1L<<1) -#define KBBellPitch (1L<<2) -#define KBBellDuration (1L<<3) -#define KBLed (1L<<4) -#define KBLedMode (1L<<5) -#define KBKey (1L<<6) -#define KBAutoRepeatMode (1L<<7) - -#define MappingSuccess 0 -#define MappingBusy 1 -#define MappingFailed 2 - -#define MappingModifier 0 -#define MappingKeyboard 1 -#define MappingPointer 2 - -/***************************************************************** - * SCREEN SAVER STUFF - *****************************************************************/ - -#define DontPreferBlanking 0 -#define PreferBlanking 1 -#define DefaultBlanking 2 - -#define DisableScreenSaver 0 -#define DisableScreenInterval 0 - -#define DontAllowExposures 0 -#define AllowExposures 1 -#define DefaultExposures 2 - -/* for ForceScreenSaver */ - -#define ScreenSaverReset 0 -#define ScreenSaverActive 1 - -/***************************************************************** - * HOSTS AND CONNECTIONS - *****************************************************************/ - -/* for ChangeHosts */ - -#define HostInsert 0 -#define HostDelete 1 - -/* for ChangeAccessControl */ - -#define EnableAccess 1 -#define DisableAccess 0 - -/* Display classes used in opening the connection - * Note that the statically allocated ones are even numbered and the - * dynamically changeable ones are odd numbered */ - -#define StaticGray 0 -#define GrayScale 1 -#define StaticColor 2 -#define PseudoColor 3 -#define TrueColor 4 -#define DirectColor 5 - - -/* Byte order used in imageByteOrder and bitmapBitOrder */ - -#define LSBFirst 0 -#define MSBFirst 1 - -#endif /* X_H */ diff --git a/shell/linux-deps/include/X11/XF86keysym.h b/shell/linux-deps/include/X11/XF86keysym.h deleted file mode 100644 index df5e9cc7f..000000000 --- a/shell/linux-deps/include/X11/XF86keysym.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * XFree86 vendor specific keysyms. - * - * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. - * - * When adding new entries, the xc/lib/XKeysymDB file should also be - * updated to make the new entries visible to Xlib. - */ - -/* - * ModeLock - * - * This one is old, and not really used any more since XKB offers this - * functionality. - */ - -#define XF86XK_ModeLock 0x1008FF01 /* Mode Switch Lock */ - -/* - * Note, 0x1008FF07 - 0x1008FF0F are free and should be used for misc new - * keysyms that don't fit into any of the groups below. - * - * 0x1008FF64, 0x1008FF6F, 0x1008FF71, 0x1008FF83 are no longer used, - * and should be used first for new keysyms. - * - * Check in keysymdef.h for generic symbols before adding new XFree86-specific - * symbols here. - * - * X.Org will not be adding to the XF86 set of keysyms, though they have - * been adopted and are considered a "standard" part of X keysym definitions. - * XFree86 never properly commented these keysyms, so we have done our - * best to explain the semantic meaning of these keys. - * - * XFree86 has removed their mail archives of the period, that might have - * shed more light on some of these definitions. Until/unless we resurrect - * these archives, these are from memory and usage. - */ - - -/* Backlight controls. */ -#define XF86XK_MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */ -#define XF86XK_MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */ -#define XF86XK_KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */ -#define XF86XK_KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */ -#define XF86XK_KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */ - -/* - * Keys found on some "Internet" keyboards. - */ -#define XF86XK_Standby 0x1008FF10 /* System into standby mode */ -#define XF86XK_AudioLowerVolume 0x1008FF11 /* Volume control down */ -#define XF86XK_AudioMute 0x1008FF12 /* Mute sound from the system */ -#define XF86XK_AudioRaiseVolume 0x1008FF13 /* Volume control up */ -#define XF86XK_AudioPlay 0x1008FF14 /* Start playing of audio > */ -#define XF86XK_AudioStop 0x1008FF15 /* Stop playing audio */ -#define XF86XK_AudioPrev 0x1008FF16 /* Previous track */ -#define XF86XK_AudioNext 0x1008FF17 /* Next track */ -#define XF86XK_HomePage 0x1008FF18 /* Display user's home page */ -#define XF86XK_Mail 0x1008FF19 /* Invoke user's mail program */ -#define XF86XK_Start 0x1008FF1A /* Start application */ -#define XF86XK_Search 0x1008FF1B /* Search */ -#define XF86XK_AudioRecord 0x1008FF1C /* Record audio application */ - -/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */ -#define XF86XK_Calculator 0x1008FF1D /* Invoke calculator program */ -#define XF86XK_Memo 0x1008FF1E /* Invoke Memo taking program */ -#define XF86XK_ToDoList 0x1008FF1F /* Invoke To Do List program */ -#define XF86XK_Calendar 0x1008FF20 /* Invoke Calendar program */ -#define XF86XK_PowerDown 0x1008FF21 /* Deep sleep the system */ -#define XF86XK_ContrastAdjust 0x1008FF22 /* Adjust screen contrast */ -#define XF86XK_RockerUp 0x1008FF23 /* Rocker switches exist up */ -#define XF86XK_RockerDown 0x1008FF24 /* and down */ -#define XF86XK_RockerEnter 0x1008FF25 /* and let you press them */ - -/* Some more "Internet" keyboard symbols */ -#define XF86XK_Back 0x1008FF26 /* Like back on a browser */ -#define XF86XK_Forward 0x1008FF27 /* Like forward on a browser */ -#define XF86XK_Stop 0x1008FF28 /* Stop current operation */ -#define XF86XK_Refresh 0x1008FF29 /* Refresh the page */ -#define XF86XK_PowerOff 0x1008FF2A /* Power off system entirely */ -#define XF86XK_WakeUp 0x1008FF2B /* Wake up system from sleep */ -#define XF86XK_Eject 0x1008FF2C /* Eject device (e.g. DVD) */ -#define XF86XK_ScreenSaver 0x1008FF2D /* Invoke screensaver */ -#define XF86XK_WWW 0x1008FF2E /* Invoke web browser */ -#define XF86XK_Sleep 0x1008FF2F /* Put system to sleep */ -#define XF86XK_Favorites 0x1008FF30 /* Show favorite locations */ -#define XF86XK_AudioPause 0x1008FF31 /* Pause audio playing */ -#define XF86XK_AudioMedia 0x1008FF32 /* Launch media collection app */ -#define XF86XK_MyComputer 0x1008FF33 /* Display "My Computer" window */ -#define XF86XK_VendorHome 0x1008FF34 /* Display vendor home web site */ -#define XF86XK_LightBulb 0x1008FF35 /* Light bulb keys exist */ -#define XF86XK_Shop 0x1008FF36 /* Display shopping web site */ -#define XF86XK_History 0x1008FF37 /* Show history of web surfing */ -#define XF86XK_OpenURL 0x1008FF38 /* Open selected URL */ -#define XF86XK_AddFavorite 0x1008FF39 /* Add URL to favorites list */ -#define XF86XK_HotLinks 0x1008FF3A /* Show "hot" links */ -#define XF86XK_BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */ -#define XF86XK_Finance 0x1008FF3C /* Display financial site */ -#define XF86XK_Community 0x1008FF3D /* Display user's community */ -#define XF86XK_AudioRewind 0x1008FF3E /* "rewind" audio track */ -#define XF86XK_BackForward 0x1008FF3F /* ??? */ -#define XF86XK_Launch0 0x1008FF40 /* Launch Application */ -#define XF86XK_Launch1 0x1008FF41 /* Launch Application */ -#define XF86XK_Launch2 0x1008FF42 /* Launch Application */ -#define XF86XK_Launch3 0x1008FF43 /* Launch Application */ -#define XF86XK_Launch4 0x1008FF44 /* Launch Application */ -#define XF86XK_Launch5 0x1008FF45 /* Launch Application */ -#define XF86XK_Launch6 0x1008FF46 /* Launch Application */ -#define XF86XK_Launch7 0x1008FF47 /* Launch Application */ -#define XF86XK_Launch8 0x1008FF48 /* Launch Application */ -#define XF86XK_Launch9 0x1008FF49 /* Launch Application */ -#define XF86XK_LaunchA 0x1008FF4A /* Launch Application */ -#define XF86XK_LaunchB 0x1008FF4B /* Launch Application */ -#define XF86XK_LaunchC 0x1008FF4C /* Launch Application */ -#define XF86XK_LaunchD 0x1008FF4D /* Launch Application */ -#define XF86XK_LaunchE 0x1008FF4E /* Launch Application */ -#define XF86XK_LaunchF 0x1008FF4F /* Launch Application */ - -#define XF86XK_ApplicationLeft 0x1008FF50 /* switch to application, left */ -#define XF86XK_ApplicationRight 0x1008FF51 /* switch to application, right*/ -#define XF86XK_Book 0x1008FF52 /* Launch bookreader */ -#define XF86XK_CD 0x1008FF53 /* Launch CD/DVD player */ -#define XF86XK_Calculater 0x1008FF54 /* Launch Calculater */ -#define XF86XK_Clear 0x1008FF55 /* Clear window, screen */ -#define XF86XK_Close 0x1008FF56 /* Close window */ -#define XF86XK_Copy 0x1008FF57 /* Copy selection */ -#define XF86XK_Cut 0x1008FF58 /* Cut selection */ -#define XF86XK_Display 0x1008FF59 /* Output switch key */ -#define XF86XK_DOS 0x1008FF5A /* Launch DOS (emulation) */ -#define XF86XK_Documents 0x1008FF5B /* Open documents window */ -#define XF86XK_Excel 0x1008FF5C /* Launch spread sheet */ -#define XF86XK_Explorer 0x1008FF5D /* Launch file explorer */ -#define XF86XK_Game 0x1008FF5E /* Launch game */ -#define XF86XK_Go 0x1008FF5F /* Go to URL */ -#define XF86XK_iTouch 0x1008FF60 /* Logitch iTouch- don't use */ -#define XF86XK_LogOff 0x1008FF61 /* Log off system */ -#define XF86XK_Market 0x1008FF62 /* ?? */ -#define XF86XK_Meeting 0x1008FF63 /* enter meeting in calendar */ -#define XF86XK_MenuKB 0x1008FF65 /* distingush keyboard from PB */ -#define XF86XK_MenuPB 0x1008FF66 /* distinuish PB from keyboard */ -#define XF86XK_MySites 0x1008FF67 /* Favourites */ -#define XF86XK_New 0x1008FF68 /* New (folder, document... */ -#define XF86XK_News 0x1008FF69 /* News */ -#define XF86XK_OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/ -#define XF86XK_Open 0x1008FF6B /* Open */ -#define XF86XK_Option 0x1008FF6C /* ?? */ -#define XF86XK_Paste 0x1008FF6D /* Paste */ -#define XF86XK_Phone 0x1008FF6E /* Launch phone; dial number */ -#define XF86XK_Q 0x1008FF70 /* Compaq's Q - don't use */ -#define XF86XK_Reply 0x1008FF72 /* Reply e.g., mail */ -#define XF86XK_Reload 0x1008FF73 /* Reload web page, file, etc. */ -#define XF86XK_RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */ -#define XF86XK_RotationPB 0x1008FF75 /* don't use */ -#define XF86XK_RotationKB 0x1008FF76 /* don't use */ -#define XF86XK_Save 0x1008FF77 /* Save (file, document, state */ -#define XF86XK_ScrollUp 0x1008FF78 /* Scroll window/contents up */ -#define XF86XK_ScrollDown 0x1008FF79 /* Scrool window/contentd down */ -#define XF86XK_ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */ -#define XF86XK_Send 0x1008FF7B /* Send mail, file, object */ -#define XF86XK_Spell 0x1008FF7C /* Spell checker */ -#define XF86XK_SplitScreen 0x1008FF7D /* Split window or screen */ -#define XF86XK_Support 0x1008FF7E /* Get support (??) */ -#define XF86XK_TaskPane 0x1008FF7F /* Show tasks */ -#define XF86XK_Terminal 0x1008FF80 /* Launch terminal emulator */ -#define XF86XK_Tools 0x1008FF81 /* toolbox of desktop/app. */ -#define XF86XK_Travel 0x1008FF82 /* ?? */ -#define XF86XK_UserPB 0x1008FF84 /* ?? */ -#define XF86XK_User1KB 0x1008FF85 /* ?? */ -#define XF86XK_User2KB 0x1008FF86 /* ?? */ -#define XF86XK_Video 0x1008FF87 /* Launch video player */ -#define XF86XK_WheelButton 0x1008FF88 /* button from a mouse wheel */ -#define XF86XK_Word 0x1008FF89 /* Launch word processor */ -#define XF86XK_Xfer 0x1008FF8A -#define XF86XK_ZoomIn 0x1008FF8B /* zoom in view, map, etc. */ -#define XF86XK_ZoomOut 0x1008FF8C /* zoom out view, map, etc. */ - -#define XF86XK_Away 0x1008FF8D /* mark yourself as away */ -#define XF86XK_Messenger 0x1008FF8E /* as in instant messaging */ -#define XF86XK_WebCam 0x1008FF8F /* Launch web camera app. */ -#define XF86XK_MailForward 0x1008FF90 /* Forward in mail */ -#define XF86XK_Pictures 0x1008FF91 /* Show pictures */ -#define XF86XK_Music 0x1008FF92 /* Launch music application */ - -#define XF86XK_Battery 0x1008FF93 /* Display battery information */ -#define XF86XK_Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */ -#define XF86XK_WLAN 0x1008FF95 /* Enable/disable WLAN */ -#define XF86XK_UWB 0x1008FF96 /* Enable/disable UWB */ - -#define XF86XK_AudioForward 0x1008FF97 /* fast-forward audio track */ -#define XF86XK_AudioRepeat 0x1008FF98 /* toggle repeat mode */ -#define XF86XK_AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */ -#define XF86XK_Subtitle 0x1008FF9A /* cycle through subtitle */ -#define XF86XK_AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */ -#define XF86XK_CycleAngle 0x1008FF9C /* cycle through angles */ -#define XF86XK_FrameBack 0x1008FF9D /* video: go one frame back */ -#define XF86XK_FrameForward 0x1008FF9E /* video: go one frame forward */ -#define XF86XK_Time 0x1008FF9F /* display, or shows an entry for time seeking */ -#define XF86XK_Select 0x1008FFA0 /* Select button on joypads and remotes */ -#define XF86XK_View 0x1008FFA1 /* Show a view options/properties */ -#define XF86XK_TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */ - -#define XF86XK_Red 0x1008FFA3 /* Red button */ -#define XF86XK_Green 0x1008FFA4 /* Green button */ -#define XF86XK_Yellow 0x1008FFA5 /* Yellow button */ -#define XF86XK_Blue 0x1008FFA6 /* Blue button */ - -#define XF86XK_Suspend 0x1008FFA7 /* Sleep to RAM */ -#define XF86XK_Hibernate 0x1008FFA8 /* Sleep to disk */ -#define XF86XK_TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */ -#define XF86XK_TouchpadOn 0x1008FFB0 /* The touchpad got switched on */ -#define XF86XK_TouchpadOff 0x1008FFB1 /* The touchpad got switched off */ - -/* Keys for special action keys (hot keys) */ -/* Virtual terminals on some operating systems */ -#define XF86XK_Switch_VT_1 0x1008FE01 -#define XF86XK_Switch_VT_2 0x1008FE02 -#define XF86XK_Switch_VT_3 0x1008FE03 -#define XF86XK_Switch_VT_4 0x1008FE04 -#define XF86XK_Switch_VT_5 0x1008FE05 -#define XF86XK_Switch_VT_6 0x1008FE06 -#define XF86XK_Switch_VT_7 0x1008FE07 -#define XF86XK_Switch_VT_8 0x1008FE08 -#define XF86XK_Switch_VT_9 0x1008FE09 -#define XF86XK_Switch_VT_10 0x1008FE0A -#define XF86XK_Switch_VT_11 0x1008FE0B -#define XF86XK_Switch_VT_12 0x1008FE0C - -#define XF86XK_Ungrab 0x1008FE20 /* force ungrab */ -#define XF86XK_ClearGrab 0x1008FE21 /* kill application with grab */ -#define XF86XK_Next_VMode 0x1008FE22 /* next video mode available */ -#define XF86XK_Prev_VMode 0x1008FE23 /* prev. video mode available */ -#define XF86XK_LogWindowTree 0x1008FE24 /* print window tree to log */ -#define XF86XK_LogGrabInfo 0x1008FE25 /* print all active grabs to log */ diff --git a/shell/linux-deps/include/X11/XKBlib.h b/shell/linux-deps/include/X11/XKBlib.h deleted file mode 100644 index 8f6c72c12..000000000 --- a/shell/linux-deps/include/X11/XKBlib.h +++ /dev/null @@ -1,1149 +0,0 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ - -#ifndef _X11_XKBLIB_H_ -#define _X11_XKBLIB_H_ - -#include -#include - -typedef struct _XkbAnyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* # of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XKB event minor code */ - unsigned int device; /* device ID */ -} XkbAnyEvent; - -typedef struct _XkbNewKeyboardNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbNewKeyboardNotify */ - int device; /* device ID */ - int old_device; /* device ID of previous keyboard */ - int min_key_code; /* minimum key code */ - int max_key_code; /* maximum key code */ - int old_min_key_code;/* min key code of previous kbd */ - int old_max_key_code;/* max key code of previous kbd */ - unsigned int changed; /* changed aspects of the keyboard */ - char req_major; /* major and minor opcode of req */ - char req_minor; /* that caused change, if applicable */ -} XkbNewKeyboardNotifyEvent; - -typedef struct _XkbMapNotifyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbMapNotify */ - int device; /* device ID */ - unsigned int changed; /* fields which have been changed */ - unsigned int flags; /* reserved */ - int first_type; /* first changed key type */ - int num_types; /* number of changed key types */ - KeyCode min_key_code; - KeyCode max_key_code; - KeyCode first_key_sym; - KeyCode first_key_act; - KeyCode first_key_behavior; - KeyCode first_key_explicit; - KeyCode first_modmap_key; - KeyCode first_vmodmap_key; - int num_key_syms; - int num_key_acts; - int num_key_behaviors; - int num_key_explicit; - int num_modmap_keys; - int num_vmodmap_keys; - unsigned int vmods; /* mask of changed virtual mods */ -} XkbMapNotifyEvent; - -typedef struct _XkbStateNotifyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* # of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbStateNotify */ - int device; /* device ID */ - unsigned int changed; /* mask of changed state components */ - int group; /* keyboard group */ - int base_group; /* base keyboard group */ - int latched_group; /* latched keyboard group */ - int locked_group; /* locked keyboard group */ - unsigned int mods; /* modifier state */ - unsigned int base_mods; /* base modifier state */ - unsigned int latched_mods; /* latched modifiers */ - unsigned int locked_mods; /* locked modifiers */ - int compat_state; /* compatibility state */ - unsigned char grab_mods; /* mods used for grabs */ - unsigned char compat_grab_mods;/* grab mods for non-XKB clients */ - unsigned char lookup_mods; /* mods sent to clients */ - unsigned char compat_lookup_mods; /* mods sent to non-XKB clients */ - int ptr_buttons; /* pointer button state */ - KeyCode keycode; /* keycode that caused the change */ - char event_type; /* KeyPress or KeyRelease */ - char req_major; /* Major opcode of request */ - char req_minor; /* Minor opcode of request */ -} XkbStateNotifyEvent; - -typedef struct _XkbControlsNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbControlsNotify */ - int device; /* device ID */ - unsigned int changed_ctrls; /* controls with changed sub-values */ - unsigned int enabled_ctrls; /* controls currently enabled */ - unsigned int enabled_ctrl_changes;/* controls just {en,dis}abled */ - int num_groups; /* total groups on keyboard */ - KeyCode keycode; /* key that caused change or 0 */ - char event_type; /* type of event that caused change */ - char req_major; /* if keycode==0, major and minor */ - char req_minor; /* opcode of req that caused change */ -} XkbControlsNotifyEvent; - -typedef struct _XkbIndicatorNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbIndicatorNotify */ - int device; /* device ID */ - unsigned int changed; /* indicators with new state or map */ - unsigned int state; /* current state of all indicators */ -} XkbIndicatorNotifyEvent; - -typedef struct _XkbNamesNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbNamesNotify */ - int device; /* device ID */ - unsigned int changed; /* names that have changed */ - int first_type; /* first key type with new name */ - int num_types; /* number of key types with new names */ - int first_lvl; /* first key type new new level names */ - int num_lvls; /* # of key types w/new level names */ - int num_aliases; /* total number of key aliases*/ - int num_radio_groups;/* total number of radio groups */ - unsigned int changed_vmods; /* virtual modifiers with new names */ - unsigned int changed_groups; /* groups with new names */ - unsigned int changed_indicators;/* indicators with new names */ - int first_key; /* first key with new name */ - int num_keys; /* number of keys with new names */ -} XkbNamesNotifyEvent; - -typedef struct _XkbCompatMapNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbCompatMapNotify */ - int device; /* device ID */ - unsigned int changed_groups; /* groups with new compat maps */ - int first_si; /* first new symbol interp */ - int num_si; /* number of new symbol interps */ - int num_total_si; /* total # of symbol interps */ -} XkbCompatMapNotifyEvent; - -typedef struct _XkbBellNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbBellNotify */ - int device; /* device ID */ - int percent; /* requested volume as a % of maximum */ - int pitch; /* requested pitch in Hz */ - int duration; /* requested duration in useconds */ - int bell_class; /* (input extension) feedback class */ - int bell_id; /* (input extension) ID of feedback */ - Atom name; /* "name" of requested bell */ - Window window; /* window associated with event */ - Bool event_only; /* "event only" requested */ -} XkbBellNotifyEvent; - -typedef struct _XkbActionMessage { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbActionMessage */ - int device; /* device ID */ - KeyCode keycode; /* key that generated the event */ - Bool press; /* true if act caused by key press */ - Bool key_event_follows;/* true if key event also generated */ - int group; /* effective group */ - unsigned int mods; /* effective mods */ - char message[XkbActionMessageLength+1]; - /* message -- leave space for NUL */ -} XkbActionMessageEvent; - -typedef struct _XkbAccessXNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbAccessXNotify */ - int device; /* device ID */ - int detail; /* XkbAXN_* */ - int keycode; /* key of event */ - int sk_delay; /* current slow keys delay */ - int debounce_delay; /* current debounce delay */ -} XkbAccessXNotifyEvent; - -typedef struct _XkbExtensionDeviceNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbExtensionDeviceNotify */ - int device; /* device ID */ - unsigned int reason; /* reason for the event */ - unsigned int supported; /* mask of supported features */ - unsigned int unsupported; /* mask of unsupported features */ - /* that some app tried to use */ - int first_btn; /* first button that changed */ - int num_btns; /* range of buttons changed */ - unsigned int leds_defined; /* indicators with names or maps */ - unsigned int led_state; /* current state of the indicators */ - int led_class; /* feedback class for led changes */ - int led_id; /* feedback id for led changes */ -} XkbExtensionDeviceNotifyEvent; - -typedef union _XkbEvent { - int type; - XkbAnyEvent any; - XkbNewKeyboardNotifyEvent new_kbd; - XkbMapNotifyEvent map; - XkbStateNotifyEvent state; - XkbControlsNotifyEvent ctrls; - XkbIndicatorNotifyEvent indicators; - XkbNamesNotifyEvent names; - XkbCompatMapNotifyEvent compat; - XkbBellNotifyEvent bell; - XkbActionMessageEvent message; - XkbAccessXNotifyEvent accessx; - XkbExtensionDeviceNotifyEvent device; - XEvent core; -} XkbEvent; - -typedef struct _XkbKbdDpyState XkbKbdDpyStateRec,*XkbKbdDpyStatePtr; - - /* XkbOpenDisplay error codes */ -#define XkbOD_Success 0 -#define XkbOD_BadLibraryVersion 1 -#define XkbOD_ConnectionRefused 2 -#define XkbOD_NonXkbServer 3 -#define XkbOD_BadServerVersion 4 - - /* Values for XlibFlags */ -#define XkbLC_ForceLatin1Lookup (1<<0) -#define XkbLC_ConsumeLookupMods (1<<1) -#define XkbLC_AlwaysConsumeShiftAndLock (1<<2) -#define XkbLC_IgnoreNewKeyboards (1<<3) -#define XkbLC_ControlFallback (1<<4) -#define XkbLC_ConsumeKeysOnComposeFail (1<<29) -#define XkbLC_ComposeLED (1<<30) -#define XkbLC_BeepOnComposeFail (1<<31) - -#define XkbLC_AllComposeControls (0xc0000000) -#define XkbLC_AllControls (0xc000001f) - -_XFUNCPROTOBEGIN - -extern Bool XkbIgnoreExtension( - Bool /* ignore */ -); - -extern Display *XkbOpenDisplay( - char * /* name */, - int * /* ev_rtrn */, - int * /* err_rtrn */, - int * /* major_rtrn */, - int * /* minor_rtrn */, - int * /* reason */ -); - -extern Bool XkbQueryExtension( - Display * /* dpy */, - int * /* opcodeReturn */, - int * /* eventBaseReturn */, - int * /* errorBaseReturn */, - int * /* majorRtrn */, - int * /* minorRtrn */ -); - -extern Bool XkbUseExtension( - Display * /* dpy */, - int * /* major_rtrn */, - int * /* minor_rtrn */ -); - -extern Bool XkbLibraryVersion( - int * /* libMajorRtrn */, - int * /* libMinorRtrn */ -); - -extern unsigned int XkbSetXlibControls( - Display* /* dpy */, - unsigned int /* affect */, - unsigned int /* values */ -); - -extern unsigned int XkbGetXlibControls( - Display* /* dpy */ -); - -extern unsigned int XkbXlibControlsImplemented(void); - -typedef Atom (*XkbInternAtomFunc)( - Display * /* dpy */, - _Xconst char * /* name */, - Bool /* only_if_exists */ -); - -typedef char * (*XkbGetAtomNameFunc)( - Display * /* dpy */, - Atom /* atom */ -); - -extern void XkbSetAtomFuncs( - XkbInternAtomFunc /* getAtom */, - XkbGetAtomNameFunc /* getName */ -); - -extern KeySym XkbKeycodeToKeysym( - Display * /* dpy */, -#if NeedWidePrototypes - unsigned int /* kc */, -#else - KeyCode /* kc */, -#endif - int /* group */, - int /* level */ -); - -extern unsigned int XkbKeysymToModifiers( - Display * /* dpy */, - KeySym /* ks */ -); - -extern Bool XkbLookupKeySym( - Display * /* dpy */, - KeyCode /* keycode */, - unsigned int /* modifiers */, - unsigned int * /* modifiers_return */, - KeySym * /* keysym_return */ -); - -extern int XkbLookupKeyBinding( - Display * /* dpy */, - KeySym /* sym_rtrn */, - unsigned int /* mods */, - char * /* buffer */, - int /* nbytes */, - int * /* extra_rtrn */ -); - -extern Bool XkbTranslateKeyCode( - XkbDescPtr /* xkb */, - KeyCode /* keycode */, - unsigned int /* modifiers */, - unsigned int * /* modifiers_return */, - KeySym * /* keysym_return */ -); - -extern int XkbTranslateKeySym( - Display * /* dpy */, - register KeySym * /* sym_return */, - unsigned int /* modifiers */, - char * /* buffer */, - int /* nbytes */, - int * /* extra_rtrn */ -); - -extern Bool XkbSetAutoRepeatRate( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* delay */, - unsigned int /* interval */ -); - -extern Bool XkbGetAutoRepeatRate( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int * /* delayRtrn */, - unsigned int * /* intervalRtrn */ -); - -extern Bool XkbChangeEnabledControls( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ -); - -extern Bool XkbDeviceBell( - Display * /* dpy */, - Window /* win */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */, - Atom /* name */ -); - -extern Bool XkbForceDeviceBell( - Display * /* dpy */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */ -); - -extern Bool XkbDeviceBellEvent( - Display * /* dpy */, - Window /* win */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */, - Atom /* name */ -); - -extern Bool XkbBell( - Display * /* dpy */, - Window /* win */, - int /* percent */, - Atom /* name */ -); - -extern Bool XkbForceBell( - Display * /* dpy */, - int /* percent */ -); - -extern Bool XkbBellEvent( - Display * /* dpy */, - Window /* win */, - int /* percent */, - Atom /* name */ -); - -extern Bool XkbSelectEvents( - Display * /* dpy */, - unsigned int /* deviceID */, - unsigned int /* affect */, - unsigned int /* values */ -); - -extern Bool XkbSelectEventDetails( - Display * /* dpy */, - unsigned int /* deviceID */, - unsigned int /* eventType */, - unsigned long /* affect */, - unsigned long /* details */ -); - -extern void XkbNoteMapChanges( - XkbMapChangesPtr /* old */, - XkbMapNotifyEvent * /* new */, - unsigned int /* wanted */ -); - -extern void XkbNoteNameChanges( - XkbNameChangesPtr /* old */, - XkbNamesNotifyEvent * /* new */, - unsigned int /* wanted */ -); - -extern Status XkbGetIndicatorState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int * /* pStateRtrn */ -); - -extern Status XkbGetDeviceIndicatorState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - unsigned int * /* pStateRtrn */ -); - -extern Status XkbGetIndicatorMap( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ -); - -extern Bool XkbSetIndicatorMap( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ -); - -#define XkbNoteIndicatorMapChanges(o,n,w) \ - ((o)->map_changes|=((n)->map_changes&(w))) -#define XkbNoteIndicatorStateChanges(o,n,w)\ - ((o)->state_changes|=((n)->state_changes&(w))) -#define XkbGetIndicatorMapChanges(d,x,c) \ - (XkbGetIndicatorMap((d),(c)->map_changes,x)) -#define XkbChangeIndicatorMaps(d,x,c) \ - (XkbSetIndicatorMap((d),(c)->map_changes,x)) - -extern Bool XkbGetNamedIndicator( - Display * /* dpy */, - Atom /* name */, - int * /* pNdxRtrn */, - Bool * /* pStateRtrn */, - XkbIndicatorMapPtr /* pMapRtrn */, - Bool * /* pRealRtrn */ -); - -extern Bool XkbGetNamedDeviceIndicator( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - Atom /* name */, - int * /* pNdxRtrn */, - Bool * /* pStateRtrn */, - XkbIndicatorMapPtr /* pMapRtrn */, - Bool * /* pRealRtrn */ -); - -extern Bool XkbSetNamedIndicator( - Display * /* dpy */, - Atom /* name */, - Bool /* changeState */, - Bool /* state */, - Bool /* createNewMap */, - XkbIndicatorMapPtr /* pMap */ -); - -extern Bool XkbSetNamedDeviceIndicator( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - Atom /* name */, - Bool /* changeState */, - Bool /* state */, - Bool /* createNewMap */, - XkbIndicatorMapPtr /* pMap */ -); - -extern Bool XkbLockModifiers( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ -); - -extern Bool XkbLatchModifiers( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ -); - -extern Bool XkbLockGroup( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* group */ -); - -extern Bool XkbLatchGroup( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* group */ -); - -extern Bool XkbSetServerInternalMods( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affectReal */, - unsigned int /* realValues */, - unsigned int /* affectVirtual */, - unsigned int /* virtualValues */ -); - -extern Bool XkbSetIgnoreLockMods( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affectReal */, - unsigned int /* realValues */, - unsigned int /* affectVirtual */, - unsigned int /* virtualValues */ -); - - -extern Bool XkbVirtualModsToReal( - XkbDescPtr /* xkb */, - unsigned int /* virtual_mask */, - unsigned int * /* mask_rtrn */ -); - -extern Bool XkbComputeEffectiveMap( - XkbDescPtr /* xkb */, - XkbKeyTypePtr /* type */, - unsigned char * /* map_rtrn */ -); - -extern Status XkbInitCanonicalKeyTypes( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* keypadVMod */ -); - -extern XkbDescPtr XkbAllocKeyboard( - void -); - -extern void XkbFreeKeyboard( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeDesc */ -); - -extern Status XkbAllocClientMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nTypes */ -); - -extern Status XkbAllocServerMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nActions */ -); - -extern void XkbFreeClientMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern void XkbFreeServerMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern XkbKeyTypePtr XkbAddKeyType( - XkbDescPtr /* xkb */, - Atom /* name */, - int /* map_count */, - Bool /* want_preserve */, - int /* num_lvls */ -); - -extern Status XkbAllocIndicatorMaps( - XkbDescPtr /* xkb */ -); - -extern void XkbFreeIndicatorMaps( - XkbDescPtr /* xkb */ -); - -extern XkbDescPtr XkbGetMap( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */ -); - -extern Status XkbGetUpdatedMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ -); - -extern Status XkbGetMapChanges( - Display * /* dpy */, - XkbDescPtr /* xkb */, - XkbMapChangesPtr /* changes */ -); - - -extern Status XkbRefreshKeyboardMapping( - XkbMapNotifyEvent * /* event */ -); - -extern Status XkbGetKeyTypes( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ -); - -extern Status XkbGetKeySyms( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ -); - -extern Status XkbGetKeyActions( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ -); - -extern Status XkbGetKeyBehaviors( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ -); - -extern Status XkbGetVirtualMods( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ -); - -extern Status XkbGetKeyExplicitComponents( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ -); - -extern Status XkbGetKeyModifierMap( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ -); - -extern Status XkbGetKeyVirtualModMap( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ -); - -extern Status XkbAllocControls( - XkbDescPtr /* xkb */, - unsigned int /* which*/ -); - -extern void XkbFreeControls( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern Status XkbGetControls( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ -); - -extern Bool XkbSetControls( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ -); - -extern void XkbNoteControlsChanges( - XkbControlsChangesPtr /* old */, - XkbControlsNotifyEvent * /* new */, - unsigned int /* wanted */ -); - -#define XkbGetControlsChanges(d,x,c) XkbGetControls(d,(c)->changed_ctrls,x) -#define XkbChangeControls(d,x,c) XkbSetControls(d,(c)->changed_ctrls,x) - -extern Status XkbAllocCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nInterpret */ -); - -extern void XkbFreeCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern Status XkbGetCompatMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* xkb */ -); - -extern Bool XkbSetCompatMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* xkb */, - Bool /* updateActions */ -); - -extern XkbSymInterpretPtr XkbAddSymInterpret( - XkbDescPtr /* xkb */, - XkbSymInterpretPtr /* si */, - Bool /* updateMap */, - XkbChangesPtr /* changes */ -); - -extern Status XkbAllocNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* nTotalRG */, - int /* nTotalAliases */ -); - -extern Status XkbGetNames( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ -); - -extern Bool XkbSetNames( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* firstType */, - unsigned int /* nTypes */, - XkbDescPtr /* desc */ -); - -extern Bool XkbChangeNames( - Display * /* dpy */, - XkbDescPtr /* xkb */, - XkbNameChangesPtr /* changes */ -); - -extern void XkbFreeNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - - -extern Status XkbGetState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbStatePtr /* rtrnState */ -); - -extern Bool XkbSetMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ -); - -extern Bool XkbChangeMap( - Display* /* dpy */, - XkbDescPtr /* desc */, - XkbMapChangesPtr /* changes */ -); - -extern Bool XkbSetDetectableAutoRepeat( - Display * /* dpy */, - Bool /* detectable */, - Bool * /* supported */ -); - -extern Bool XkbGetDetectableAutoRepeat( - Display * /* dpy */, - Bool * /* supported */ -); - -extern Bool XkbSetAutoResetControls( - Display * /* dpy */, - unsigned int /* changes */, - unsigned int * /* auto_ctrls */, - unsigned int * /* auto_values */ -); - -extern Bool XkbGetAutoResetControls( - Display * /* dpy */, - unsigned int * /* auto_ctrls */, - unsigned int * /* auto_ctrl_values */ -); - -extern Bool XkbSetPerClientControls( - Display * /* dpy */, - unsigned int /* change */, - unsigned int * /* values */ -); - -extern Bool XkbGetPerClientControls( - Display * /* dpy */, - unsigned int * /* ctrls */ -); - -extern Status XkbCopyKeyType( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */ -); - -extern Status XkbCopyKeyTypes( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */, - int /* num_types */ -); - -extern Status XkbResizeKeyType( - XkbDescPtr /* xkb */, - int /* type_ndx */, - int /* map_count */, - Bool /* want_preserve */, - int /* new_num_lvls */ -); - -extern KeySym *XkbResizeKeySyms( - XkbDescPtr /* desc */, - int /* forKey */, - int /* symsNeeded */ -); - -extern XkbAction *XkbResizeKeyActions( - XkbDescPtr /* desc */, - int /* forKey */, - int /* actsNeeded */ -); - -extern Status XkbChangeTypesOfKey( - XkbDescPtr /* xkb */, - int /* key */, - int /* num_groups */, - unsigned int /* groups */, - int * /* newTypes */, - XkbMapChangesPtr /* pChanges */ -); - -extern Status XkbChangeKeycodeRange( - XkbDescPtr /* xkb */, - int /* minKC */, - int /* maxKC */, - XkbChangesPtr /* changes */ -); - -/***====================================================================***/ - -extern XkbComponentListPtr XkbListComponents( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbComponentNamesPtr /* ptrns */, - int * /* max_inout */ -); - -extern void XkbFreeComponentList( - XkbComponentListPtr /* list */ -); - -extern XkbDescPtr XkbGetKeyboard( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */ -); - -extern XkbDescPtr XkbGetKeyboardByName( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbComponentNamesPtr /* names */, - unsigned int /* want */, - unsigned int /* need */, - Bool /* load */ -); - -/***====================================================================***/ - -extern int XkbKeyTypesForCoreSymbols( /* returns # of groups */ - XkbDescPtr /* xkb */, /* keyboard device */ - int /* map_width */, /* width of core KeySym array */ - KeySym * /* core_syms */, /* always mapWidth symbols */ - unsigned int /* protected */, /* explicit key types */ - int * /* types_inout */, /* always four type indices */ - KeySym * /* xkb_syms_rtrn */ /* must have enough space */ -); - -extern Bool XkbApplyCompatMapToKey( /* False only on error */ - XkbDescPtr /* xkb */, /* keymap to be edited */ - KeyCode /* key */, /* key to be updated */ - XkbChangesPtr /* changes */ /* resulting changes to map */ -); - -extern Bool XkbUpdateMapFromCore( /* False only on error */ - XkbDescPtr /* xkb */, /* XKB keyboard to be edited */ - KeyCode /* first_key */, /* first changed key */ - int /* num_keys */, /* number of changed keys */ - int /* map_width */, /* width of core keymap */ - KeySym * /* core_keysyms */, /* symbols from core keymap */ - XkbChangesPtr /* changes */ /* resulting changes */ -); - -/***====================================================================***/ - -extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass */, - unsigned int /* ledId */ -); - -extern Status XkbResizeDeviceButtonActions( - XkbDeviceInfoPtr /* devi */, - unsigned int /* newTotal */ -); - -extern XkbDeviceInfoPtr XkbAllocDeviceInfo( - unsigned int /* deviceSpec */, - unsigned int /* nButtons */, - unsigned int /* szLeds */ -); - -extern void XkbFreeDeviceInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* which */, - Bool /* freeDevI */ -); - -extern void XkbNoteDeviceChanges( - XkbDeviceChangesPtr /* old */, - XkbExtensionDeviceNotifyEvent * /* new */, - unsigned int /* wanted */ -); - -extern XkbDeviceInfoPtr XkbGetDeviceInfo( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */ -); - -extern Status XkbGetDeviceInfoChanges( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - XkbDeviceChangesPtr /* changes */ -); - -extern Status XkbGetDeviceButtonActions( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - Bool /* all */, - unsigned int /* first */, - unsigned int /* nBtns */ -); - -extern Status XkbGetDeviceLedInfo( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass (class, XIDflt, XIAll) */, - unsigned int /* ledId (id, XIDflt, XIAll) */, - unsigned int /* which (XkbXI_Indicator{Names,Map}Mask */ -); - -extern Bool XkbSetDeviceInfo( - Display * /* dpy */, - unsigned int /* which */, - XkbDeviceInfoPtr /* devi */ -); - -extern Bool XkbChangeDeviceInfo( - Display* /* dpy */, - XkbDeviceInfoPtr /* desc */, - XkbDeviceChangesPtr /* changes */ -); - -extern Bool XkbSetDeviceLedInfo( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - unsigned int /* which */ -); - -extern Bool XkbSetDeviceButtonActions( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* first */, - unsigned int /* nBtns */ -); - -/***====================================================================***/ - -extern char XkbToControl( - char /* c */ -); - -/***====================================================================***/ - -extern Bool XkbSetDebuggingFlags( - Display * /* dpy */, - unsigned int /* mask */, - unsigned int /* flags */, - char * /* msg */, - unsigned int /* ctrls_mask */, - unsigned int /* ctrls */, - unsigned int * /* rtrn_flags */, - unsigned int * /* rtrn_ctrls */ -); - -extern Bool XkbApplyVirtualModChanges( - XkbDescPtr /* xkb */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ -); - -extern Bool XkbUpdateActionVirtualMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* changed */ -); - -extern void XkbUpdateKeyTypeVirtualMods( - XkbDescPtr /* xkb */, - XkbKeyTypePtr /* type */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ -); - -_XFUNCPROTOEND - -#endif /* _X11_XKBLIB_H_ */ diff --git a/shell/linux-deps/include/X11/XWDFile.h b/shell/linux-deps/include/X11/XWDFile.h deleted file mode 100644 index 50e17df3d..000000000 --- a/shell/linux-deps/include/X11/XWDFile.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - -Copyright 1985, 1986, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ - -/* - * XWDFile.h MIT Project Athena, X Window system window raster - * image dumper, dump file format header file. - * - * Author: Tony Della Fera, DEC - * 27-Jun-85 - * - * Modifier: William F. Wyatt, SAO - * 18-Nov-86 - version 6 for saving/restoring color maps - */ - -#ifndef XWDFILE_H -#define XWDFILE_H - -#include - -#define XWD_FILE_VERSION 7 -#define sz_XWDheader 100 -#define sz_XWDColor 12 - -typedef CARD32 xwdval; /* for old broken programs */ - -/* Values in the file are most significant byte first. */ - -typedef struct _xwd_file_header { - /* header_size = SIZEOF(XWDheader) + length of null-terminated - * window name. */ - CARD32 header_size B32; - - CARD32 file_version B32; /* = XWD_FILE_VERSION above */ - CARD32 pixmap_format B32; /* ZPixmap or XYPixmap */ - CARD32 pixmap_depth B32; /* Pixmap depth */ - CARD32 pixmap_width B32; /* Pixmap width */ - CARD32 pixmap_height B32; /* Pixmap height */ - CARD32 xoffset B32; /* Bitmap x offset, normally 0 */ - CARD32 byte_order B32; /* of image data: MSBFirst, LSBFirst */ - - /* bitmap_unit applies to bitmaps (depth 1 format XY) only. - * It is the number of bits that each scanline is padded to. */ - CARD32 bitmap_unit B32; - - CARD32 bitmap_bit_order B32; /* bitmaps only: MSBFirst, LSBFirst */ - - /* bitmap_pad applies to pixmaps (non-bitmaps) only. - * It is the number of bits that each scanline is padded to. */ - CARD32 bitmap_pad B32; - - CARD32 bits_per_pixel B32; /* Bits per pixel */ - - /* bytes_per_line is pixmap_width padded to bitmap_unit (bitmaps) - * or bitmap_pad (pixmaps). It is the delta (in bytes) to get - * to the same x position on an adjacent row. */ - CARD32 bytes_per_line B32; - CARD32 visual_class B32; /* Class of colormap */ - CARD32 red_mask B32; /* Z red mask */ - CARD32 green_mask B32; /* Z green mask */ - CARD32 blue_mask B32; /* Z blue mask */ - CARD32 bits_per_rgb B32; /* Log2 of distinct color values */ - CARD32 colormap_entries B32; /* Number of entries in colormap; not used? */ - CARD32 ncolors B32; /* Number of XWDColor structures */ - CARD32 window_width B32; /* Window width */ - CARD32 window_height B32; /* Window height */ - CARD32 window_x B32; /* Window upper left X coordinate */ - CARD32 window_y B32; /* Window upper left Y coordinate */ - CARD32 window_bdrwidth B32; /* Window border width */ -} XWDFileHeader; - -/* Null-terminated window name follows the above structure. */ - -/* Next comes XWDColor structures, at offset XWDFileHeader.header_size in - * the file. XWDFileHeader.ncolors tells how many XWDColor structures - * there are. - */ - -typedef struct { - CARD32 pixel B32; - CARD16 red B16; - CARD16 green B16; - CARD16 blue B16; - CARD8 flags; - CARD8 pad; -} XWDColor; - -/* Last comes the image data in the format described by XWDFileHeader. */ - -#endif /* XWDFILE_H */ - diff --git a/shell/linux-deps/include/X11/Xalloca.h b/shell/linux-deps/include/X11/Xalloca.h deleted file mode 100644 index 1919884bb..000000000 --- a/shell/linux-deps/include/X11/Xalloca.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - -Copyright 1995, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ -/* - * The purpose of this header is to define the macros ALLOCATE_LOCAL and - * DEALLOCATE_LOCAL appropriately for the platform being compiled on. - * These macros are used to make fast, function-local memory allocations. - * Their characteristics are as follows: - * - * void *ALLOCATE_LOCAL(int size) - * Returns a pointer to size bytes of memory, or NULL if the allocation - * failed. The memory must be freed with DEALLOCATE_LOCAL before the - * function that made the allocation returns. You should not ask for - * large blocks of memory with this function, since on many platforms - * the memory comes from the stack, which may have limited size. - * - * void DEALLOCATE_LOCAL(void *) - * Frees the memory allocated by ALLOCATE_LOCAL. Omission of this - * step may be harmless on some platforms, but will result in - * memory leaks or worse on others. - * - * Before including this file, you should define two macros, - * ALLOCATE_LOCAL_FALLBACK and DEALLOCATE_LOCAL_FALLBACK, that have the - * same characteristics as ALLOCATE_LOCAL and DEALLOCATE_LOCAL. The - * header uses the fallbacks if it doesn't know a "better" way to define - * ALLOCATE_LOCAL and DEALLOCATE_LOCAL. Typical usage would be: - * - * #define ALLOCATE_LOCAL_FALLBACK(_size) malloc(_size) - * #define DEALLOCATE_LOCAL_FALLBACK(_ptr) free(_ptr) - * #include "Xalloca.h" - */ - -#ifndef XALLOCA_H -#define XALLOCA_H 1 - -#ifndef INCLUDE_ALLOCA_H -/* Need to add more here to match Imake *.cf's */ -# if defined(HAVE_ALLOCA_H) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define INCLUDE_ALLOCA_H -# endif -#endif - -#ifdef INCLUDE_ALLOCA_H -# include -#endif - -#ifndef NO_ALLOCA -/* - * os-dependent definition of local allocation and deallocation - * If you want something other than (DE)ALLOCATE_LOCAL_FALLBACK - * for ALLOCATE/DEALLOCATE_LOCAL then you add that in here. - */ - - -# ifdef __GNUC__ -# ifndef alloca -# define alloca __builtin_alloca -# endif /* !alloca */ -# define ALLOCATE_LOCAL(size) alloca((int)(size)) -# else /* ! __GNUC__ */ - -/* - * warning: old mips alloca (pre 2.10) is unusable, new one is built in - * Test is easy, the new one is named __builtin_alloca and comes - * from alloca.h which #defines alloca. - */ -# if defined(__sun) || defined(alloca) -/* - * Some System V boxes extract alloca.o from /lib/libPW.a; if you - * decide that you don't want to use alloca, you might want to fix it here. - */ -/* alloca might be a macro taking one arg (hi, Sun!), so give it one. */ -# if !defined(__cplusplus) -# define __Xnullarg /* as nothing */ - extern void *alloca(__Xnullarg); -# endif -# define ALLOCATE_LOCAL(size) alloca((int)(size)) -# endif /* who does alloca */ -# endif /* __GNUC__ */ - -#endif /* NO_ALLOCA */ - -#if !defined(ALLOCATE_LOCAL) -# if defined(ALLOCATE_LOCAL_FALLBACK) && defined(DEALLOCATE_LOCAL_FALLBACK) -# define ALLOCATE_LOCAL(_size) ALLOCATE_LOCAL_FALLBACK(_size) -# define DEALLOCATE_LOCAL(_ptr) DEALLOCATE_LOCAL_FALLBACK(_ptr) -# else /* no fallbacks supplied; error */ -# define ALLOCATE_LOCAL(_size) ALLOCATE_LOCAL_FALLBACK undefined! -# define DEALLOCATE_LOCAL(_ptr) DEALLOCATE_LOCAL_FALLBACK undefined! -# endif /* defined(ALLOCATE_LOCAL_FALLBACK && DEALLOCATE_LOCAL_FALLBACK) */ -#else -# if !defined(DEALLOCATE_LOCAL) -# define DEALLOCATE_LOCAL(_ptr) do {} while(0) -# endif -#endif /* defined(ALLOCATE_LOCAL) */ - -#endif /* XALLOCA_H */ diff --git a/shell/linux-deps/include/X11/Xarch.h b/shell/linux-deps/include/X11/Xarch.h deleted file mode 100644 index f80c58099..000000000 --- a/shell/linux-deps/include/X11/Xarch.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _XARCH_H_ -# define _XARCH_H_ - -/* - * Copyright 1997 Metro Link Incorporated - * - * All Rights Reserved - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the names of the above listed copyright holder(s) - * not be used in advertising or publicity pertaining to distribution of - * the software without specific, written prior permission. The above listed - * copyright holder(s) make(s) no representations about the suitability of - * this software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE - * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -/* - * Determine the machine's byte order. - */ - -/* See if it is set in the imake config first */ -# ifdef X_BYTE_ORDER - -# define X_BIG_ENDIAN 4321 -# define X_LITTLE_ENDIAN 1234 - -# else - -# if defined(SVR4) || defined(__SVR4) -# include -# include -# elif defined(CSRG_BASED) -# if defined(__NetBSD__) || defined(__OpenBSD__) -# include -# endif -# include -# elif defined(linux) -# if defined __STRICT_ANSI__ -# undef __STRICT_ANSI__ -# include -# define __STRICT_ANSI__ -# else -# include -# endif -/* 'endian.h' might have been included before 'Xarch.h' */ -# if !defined(LITTLE_ENDIAN) && defined(__LITTLE_ENDIAN) -# define LITTLE_ENDIAN __LITTLE_ENDIAN -# endif -# if !defined(BIG_ENDIAN) && defined(__BIG_ENDIAN) -# define BIG_ENDIAN __BIG_ENDIAN -# endif -# if !defined(PDP_ENDIAN) && defined(__PDP_ENDIAN) -# define PDP_ENDIAN __PDP_ENDIAN -# endif -# if !defined(BYTE_ORDER) && defined(__BYTE_ORDER) -# define BYTE_ORDER __BYTE_ORDER -# endif -# endif - -# ifndef BYTE_ORDER -# define LITTLE_ENDIAN 1234 -# define BIG_ENDIAN 4321 - -# if defined(__sun) && defined(__SVR4) -# include -# ifdef _LITTLE_ENDIAN -# define BYTE_ORDER LITTLE_ENDIAN -# endif -# ifdef _BIG_ENDIAN -# define BYTE_ORDER BIG_ENDIAN -# endif -# endif /* sun */ -# endif /* BYTE_ORDER */ - -# define X_BYTE_ORDER BYTE_ORDER -# define X_BIG_ENDIAN BIG_ENDIAN -# define X_LITTLE_ENDIAN LITTLE_ENDIAN - -# endif /* not in imake config */ - -#endif /* _XARCH_H_ */ diff --git a/shell/linux-deps/include/X11/Xatom.h b/shell/linux-deps/include/X11/Xatom.h deleted file mode 100644 index 485a4236d..000000000 --- a/shell/linux-deps/include/X11/Xatom.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef XATOM_H -#define XATOM_H 1 - -/* THIS IS A GENERATED FILE - * - * Do not change! Changing this file implies a protocol change! - */ - -#define XA_PRIMARY ((Atom) 1) -#define XA_SECONDARY ((Atom) 2) -#define XA_ARC ((Atom) 3) -#define XA_ATOM ((Atom) 4) -#define XA_BITMAP ((Atom) 5) -#define XA_CARDINAL ((Atom) 6) -#define XA_COLORMAP ((Atom) 7) -#define XA_CURSOR ((Atom) 8) -#define XA_CUT_BUFFER0 ((Atom) 9) -#define XA_CUT_BUFFER1 ((Atom) 10) -#define XA_CUT_BUFFER2 ((Atom) 11) -#define XA_CUT_BUFFER3 ((Atom) 12) -#define XA_CUT_BUFFER4 ((Atom) 13) -#define XA_CUT_BUFFER5 ((Atom) 14) -#define XA_CUT_BUFFER6 ((Atom) 15) -#define XA_CUT_BUFFER7 ((Atom) 16) -#define XA_DRAWABLE ((Atom) 17) -#define XA_FONT ((Atom) 18) -#define XA_INTEGER ((Atom) 19) -#define XA_PIXMAP ((Atom) 20) -#define XA_POINT ((Atom) 21) -#define XA_RECTANGLE ((Atom) 22) -#define XA_RESOURCE_MANAGER ((Atom) 23) -#define XA_RGB_COLOR_MAP ((Atom) 24) -#define XA_RGB_BEST_MAP ((Atom) 25) -#define XA_RGB_BLUE_MAP ((Atom) 26) -#define XA_RGB_DEFAULT_MAP ((Atom) 27) -#define XA_RGB_GRAY_MAP ((Atom) 28) -#define XA_RGB_GREEN_MAP ((Atom) 29) -#define XA_RGB_RED_MAP ((Atom) 30) -#define XA_STRING ((Atom) 31) -#define XA_VISUALID ((Atom) 32) -#define XA_WINDOW ((Atom) 33) -#define XA_WM_COMMAND ((Atom) 34) -#define XA_WM_HINTS ((Atom) 35) -#define XA_WM_CLIENT_MACHINE ((Atom) 36) -#define XA_WM_ICON_NAME ((Atom) 37) -#define XA_WM_ICON_SIZE ((Atom) 38) -#define XA_WM_NAME ((Atom) 39) -#define XA_WM_NORMAL_HINTS ((Atom) 40) -#define XA_WM_SIZE_HINTS ((Atom) 41) -#define XA_WM_ZOOM_HINTS ((Atom) 42) -#define XA_MIN_SPACE ((Atom) 43) -#define XA_NORM_SPACE ((Atom) 44) -#define XA_MAX_SPACE ((Atom) 45) -#define XA_END_SPACE ((Atom) 46) -#define XA_SUPERSCRIPT_X ((Atom) 47) -#define XA_SUPERSCRIPT_Y ((Atom) 48) -#define XA_SUBSCRIPT_X ((Atom) 49) -#define XA_SUBSCRIPT_Y ((Atom) 50) -#define XA_UNDERLINE_POSITION ((Atom) 51) -#define XA_UNDERLINE_THICKNESS ((Atom) 52) -#define XA_STRIKEOUT_ASCENT ((Atom) 53) -#define XA_STRIKEOUT_DESCENT ((Atom) 54) -#define XA_ITALIC_ANGLE ((Atom) 55) -#define XA_X_HEIGHT ((Atom) 56) -#define XA_QUAD_WIDTH ((Atom) 57) -#define XA_WEIGHT ((Atom) 58) -#define XA_POINT_SIZE ((Atom) 59) -#define XA_RESOLUTION ((Atom) 60) -#define XA_COPYRIGHT ((Atom) 61) -#define XA_NOTICE ((Atom) 62) -#define XA_FONT_NAME ((Atom) 63) -#define XA_FAMILY_NAME ((Atom) 64) -#define XA_FULL_NAME ((Atom) 65) -#define XA_CAP_HEIGHT ((Atom) 66) -#define XA_WM_CLASS ((Atom) 67) -#define XA_WM_TRANSIENT_FOR ((Atom) 68) - -#define XA_LAST_PREDEFINED ((Atom) 68) -#endif /* XATOM_H */ diff --git a/shell/linux-deps/include/X11/Xauth.h b/shell/linux-deps/include/X11/Xauth.h deleted file mode 100644 index ace975d84..000000000 --- a/shell/linux-deps/include/X11/Xauth.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $Xorg: Xauth.h,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */ - -/* - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ - -/* $XFree86: xc/lib/Xau/Xauth.h,v 1.5 2001/12/14 19:54:36 dawes Exp $ */ - -#ifndef _Xauth_h -#define _Xauth_h - -typedef struct xauth { - unsigned short family; - unsigned short address_length; - char *address; - unsigned short number_length; - char *number; - unsigned short name_length; - char *name; - unsigned short data_length; - char *data; -} Xauth; - -#ifndef _XAUTH_STRUCT_ONLY - -# include -# include - -# include - -# define FamilyLocal (256) /* not part of X standard (i.e. X.h) */ -# define FamilyWild (65535) -# define FamilyNetname (254) /* not part of X standard */ -# define FamilyKrb5Principal (253) /* Kerberos 5 principal name */ -# define FamilyLocalHost (252) /* for local non-net authentication */ - - -_XFUNCPROTOBEGIN - -char *XauFileName(void); - -Xauth *XauReadAuth( -FILE* /* auth_file */ -); - -int XauLockAuth( -_Xconst char* /* file_name */, -int /* retries */, -int /* timeout */, -long /* dead */ -); - -int XauUnlockAuth( -_Xconst char* /* file_name */ -); - -int XauWriteAuth( -FILE* /* auth_file */, -Xauth* /* auth */ -); - -Xauth *XauGetAuthByAddr( -#if NeedWidePrototypes -unsigned int /* family */, -unsigned int /* address_length */, -#else -unsigned short /* family */, -unsigned short /* address_length */, -#endif -_Xconst char* /* address */, -#if NeedWidePrototypes -unsigned int /* number_length */, -#else -unsigned short /* number_length */, -#endif -_Xconst char* /* number */, -#if NeedWidePrototypes -unsigned int /* name_length */, -#else -unsigned short /* name_length */, -#endif -_Xconst char* /* name */ -); - -Xauth *XauGetBestAuthByAddr( -#if NeedWidePrototypes -unsigned int /* family */, -unsigned int /* address_length */, -#else -unsigned short /* family */, -unsigned short /* address_length */, -#endif -_Xconst char* /* address */, -#if NeedWidePrototypes -unsigned int /* number_length */, -#else -unsigned short /* number_length */, -#endif -_Xconst char* /* number */, -int /* types_length */, -char** /* type_names */, -_Xconst int* /* type_lengths */ -); - -void XauDisposeAuth( -Xauth* /* auth */ -); - -_XFUNCPROTOEND - -/* Return values from XauLockAuth */ - -# define LOCK_SUCCESS 0 /* lock succeeded */ -# define LOCK_ERROR 1 /* lock unexpectely failed, check errno */ -# define LOCK_TIMEOUT 2 /* lock failed, timeouts expired */ - -#endif /* _XAUTH_STRUCT_ONLY */ - -#endif /* _Xauth_h */ diff --git a/shell/linux-deps/include/X11/Xcms.h b/shell/linux-deps/include/X11/Xcms.h deleted file mode 100644 index 8151fd1f3..000000000 --- a/shell/linux-deps/include/X11/Xcms.h +++ /dev/null @@ -1,803 +0,0 @@ - -/* - * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. - * All Rights Reserved - * - * This file is a component of an X Window System-specific implementation - * of Xcms based on the TekColor Color Management System. Permission is - * hereby granted to use, copy, modify, sell, and otherwise distribute this - * software and its documentation for any purpose and without fee, provided - * that this copyright, permission, and disclaimer notice is reproduced in - * all copies of this software and in supporting documentation. TekColor - * is a trademark of Tektronix, Inc. - * - * Tektronix makes no representation about the suitability of this software - * for any purpose. It is provided "as is" and with all faults. - * - * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, - * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF - * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. - * - * - * DESCRIPTION - * Public include file for X Color Management System - */ -#ifndef _X11_XCMS_H_ -#define _X11_XCMS_H_ - -#include - - /* - * XCMS Status Values - */ -#define XcmsFailure 0 -#define XcmsSuccess 1 -#define XcmsSuccessWithCompression 2 - - /* - * Color Space Format ID's - * Color Space ID's are of XcmsColorFormat type. - * - * bit 31 - * 0 == Device-Independent - * 1 == Device-Dependent - * - * bit 30: - * 0 == Registered with X Consortium - * 1 == Unregistered - */ -#define XcmsUndefinedFormat (XcmsColorFormat)0x00000000 -#define XcmsCIEXYZFormat (XcmsColorFormat)0x00000001 -#define XcmsCIEuvYFormat (XcmsColorFormat)0x00000002 -#define XcmsCIExyYFormat (XcmsColorFormat)0x00000003 -#define XcmsCIELabFormat (XcmsColorFormat)0x00000004 -#define XcmsCIELuvFormat (XcmsColorFormat)0x00000005 -#define XcmsTekHVCFormat (XcmsColorFormat)0x00000006 -#define XcmsRGBFormat (XcmsColorFormat)0x80000000 -#define XcmsRGBiFormat (XcmsColorFormat)0x80000001 - - /* - * State of XcmsPerScrnInfo - */ -#define XcmsInitNone 0x00 /* no initialization attempted */ -#define XcmsInitSuccess 0x01 /* initialization successful */ -#define XcmsInitFailure 0xff /* failure, use defaults */ - -#define DisplayOfCCC(ccc) ((ccc)->dpy) -#define ScreenNumberOfCCC(ccc) ((ccc)->screenNumber) -#define VisualOfCCC(ccc) ((ccc)->visual) -#define ClientWhitePointOfCCC(ccc) (&(ccc)->clientWhitePt) -#define ScreenWhitePointOfCCC(ccc) (&(ccc)->pPerScrnInfo->screenWhitePt) -#define FunctionSetOfCCC(ccc) ((ccc)->pPerScrnInfo->functionSet) - -typedef unsigned long XcmsColorFormat; /* Color Space Format ID */ - -typedef double XcmsFloat; - - /* - * Device RGB - */ -typedef struct { - unsigned short red; /* scaled from 0x0000 to 0xffff */ - unsigned short green; /* scaled from 0x0000 to 0xffff */ - unsigned short blue; /* scaled from 0x0000 to 0xffff */ -} XcmsRGB; - - /* - * RGB Intensity - */ -typedef struct { - XcmsFloat red; /* 0.0 - 1.0 */ - XcmsFloat green; /* 0.0 - 1.0 */ - XcmsFloat blue; /* 0.0 - 1.0 */ -} XcmsRGBi; - - /* - * CIE XYZ - */ -typedef struct { - XcmsFloat X; - XcmsFloat Y; - XcmsFloat Z; -} XcmsCIEXYZ; - - /* - * CIE u'v'Y - */ -typedef struct { - XcmsFloat u_prime; /* 0.0 - 1.0 */ - XcmsFloat v_prime; /* 0.0 - 1.0 */ - XcmsFloat Y; /* 0.0 - 1.0 */ -} XcmsCIEuvY; - - /* - * CIE xyY - */ -typedef struct { - XcmsFloat x; /* 0.0 - 1.0 */ - XcmsFloat y; /* 0.0 - 1.0 */ - XcmsFloat Y; /* 0.0 - 1.0 */ -} XcmsCIExyY; - - /* - * CIE L*a*b* - */ -typedef struct { - XcmsFloat L_star; /* 0.0 - 100.0 */ - XcmsFloat a_star; - XcmsFloat b_star; -} XcmsCIELab; - - /* - * CIE L*u*v* - */ -typedef struct { - XcmsFloat L_star; /* 0.0 - 100.0 */ - XcmsFloat u_star; - XcmsFloat v_star; -} XcmsCIELuv; - - /* - * TekHVC - */ -typedef struct { - XcmsFloat H; /* 0.0 - 360.0 */ - XcmsFloat V; /* 0.0 - 100.0 */ - XcmsFloat C; /* 0.0 - 100.0 */ -} XcmsTekHVC; - - /* - * PAD - */ -typedef struct { - XcmsFloat pad0; - XcmsFloat pad1; - XcmsFloat pad2; - XcmsFloat pad3; -} XcmsPad; - - - /* - * XCMS Color Structure - */ -typedef struct { - union { - XcmsRGB RGB; - XcmsRGBi RGBi; - XcmsCIEXYZ CIEXYZ; - XcmsCIEuvY CIEuvY; - XcmsCIExyY CIExyY; - XcmsCIELab CIELab; - XcmsCIELuv CIELuv; - XcmsTekHVC TekHVC; - XcmsPad Pad; - } spec; /* the color specification */ - unsigned long pixel; /* pixel value (as needed) */ - XcmsColorFormat format; /* the specification format */ -} XcmsColor; - - - /* - * XCMS Per Screen related data - */ - -typedef struct _XcmsPerScrnInfo { - XcmsColor screenWhitePt; /* Screen White point */ - XPointer functionSet; /* pointer to Screen Color Characterization */ - /* Function Set structure */ - XPointer screenData; /* pointer to corresponding Screen Color*/ - /* Characterization Data */ - unsigned char state; /* XcmsInitNone, XcmsInitSuccess, XcmsInitFailure */ - char pad[3]; -} XcmsPerScrnInfo; - -typedef struct _XcmsCCC *XcmsCCC; - -typedef Status (*XcmsCompressionProc)( /* Gamut Compression Proc */ - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -typedef Status (*XcmsWhiteAdjustProc)( /* White Point Adjust Proc */ - XcmsCCC /* ccc */, - XcmsColor* /* initial_white_point*/, - XcmsColor* /* target_white_point*/, - XcmsColorFormat /* target_format */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - - /* - * XCMS Color Conversion Context - */ -typedef struct _XcmsCCC { - Display *dpy; /* X Display */ - int screenNumber; /* X screen number */ - Visual *visual; /* X Visual */ - XcmsColor clientWhitePt; /* Client White Point */ - XcmsCompressionProc gamutCompProc; /* Gamut Compression Function */ - XPointer gamutCompClientData; /* Gamut Comp Func Client Data */ - XcmsWhiteAdjustProc whitePtAdjProc; /* White Point Adjustment Function */ - XPointer whitePtAdjClientData; /* White Pt Adj Func Client Data */ - XcmsPerScrnInfo *pPerScrnInfo; /* pointer to per screen information */ - /* associated with the above display */ - /* screenNumber */ -} XcmsCCCRec; - -typedef Status (*XcmsScreenInitProc)( /* Screen Initialization Proc */ - Display* /* dpy */, - int /* screen_number */, - XcmsPerScrnInfo* /* screen_info */ -); - -typedef void (*XcmsScreenFreeProc)( - XPointer /* screenData */ -); - - /* - * Function List Pointer -- pointer to an array of function pointers. - * The end of list is indicated by a NULL pointer. - */ -/* - * XXX: The use of the XcmsConversionProc type is broken. The - * device-independent colour conversion code uses it as: - -typedef Status (*XcmsConversionProc)(XcmsCCC, XcmsColor *, XcmsColor *, - unsigned int); - - * while the device-dependent code uses it as: - -typedef Status (*XcmsConversionProc)(XcmsCCC, XcmsColor *, unsigned int, - Bool *); - - * Until this is reworked, it's probably best to leave it unprotoized. - * The code works regardless. - */ -typedef Status (*XcmsDDConversionProc)( /* using device-dependent version */ - XcmsCCC /* ccc */, - XcmsColor* /* pcolors_in_out */, - unsigned int /* ncolors */, - Bool* /* pCompressed */ - ); - -typedef Status (*XcmsDIConversionProc)( /* using device-independent version */ - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* pcolors_in_out */, - unsigned int /* ncolors */ - ); - -typedef XcmsDIConversionProc XcmsConversionProc; -typedef XcmsConversionProc *XcmsFuncListPtr; - -typedef int (*XcmsParseStringProc)( /* Color String Parsing Proc */ - char* /* color_string */, - XcmsColor* /* color_return */ -); - - /* - * Color Space -- per Color Space related data (Device-Independent - * or Device-Dependent) - */ -typedef struct _XcmsColorSpace { - const char *prefix; /* Prefix of string format. */ - XcmsColorFormat id; /* Format ID number. */ - XcmsParseStringProc parseString; - /* String format parsing function */ - XcmsFuncListPtr to_CIEXYZ; /* Pointer to an array of function */ - /* pointers such that when the */ - /* functions are executed in sequence */ - /* will convert a XcmsColor structure */ - /* from this color space to CIEXYZ */ - /* space. */ - XcmsFuncListPtr from_CIEXYZ;/* Pointer to an array of function */ - /* pointers such that when the */ - /* functions are executed in sequence */ - /* will convert a XcmsColor structure */ - /* from CIEXYZ space to this color */ - /* space. */ - int inverse_flag; /* If 1, indicates that for 0 <= i < n */ - /* where n is the number of function */ - /* pointers in the lists to_CIEXYZ */ - /* and from_CIEXYZ; for each function */ - /* to_CIEXYZ[i] its inverse function */ - /* is from_CIEXYZ[n - i]. */ - -} XcmsColorSpace; - - /* - * Screen Color Characterization Function Set -- per device class - * color space conversion functions. - */ -typedef struct _XcmsFunctionSet { - XcmsColorSpace **DDColorSpaces; - /* Pointer to an array of pointers to */ - /* Device-DEPENDENT color spaces */ - /* understood by this SCCFuncSet. */ - XcmsScreenInitProc screenInitProc; - /* Screen initialization function that */ - /* reads Screen Color Characterization*/ - /* Data off properties on the screen's*/ - /* root window. */ - XcmsScreenFreeProc screenFreeProc; - /* Function that frees the SCCData */ - /* structures. */ -} XcmsFunctionSet; - -_XFUNCPROTOBEGIN - -extern Status XcmsAddColorSpace ( - XcmsColorSpace* /* pColorSpace */ -); - -extern Status XcmsAddFunctionSet ( - XcmsFunctionSet* /* functionSet */ -); - -extern Status XcmsAllocColor ( - Display* /* dpy */, - Colormap /* colormap */, - XcmsColor* /* color_in_out */, - XcmsColorFormat /* result_format */ -); - -extern Status XcmsAllocNamedColor ( - Display* /* dpy */, - Colormap /* colormap */, - _Xconst char* /* color_string */, - XcmsColor* /* color_scrn_return */, - XcmsColor* /* color_exact_return */, - XcmsColorFormat /* result_format */ -); - -extern XcmsCCC XcmsCCCOfColormap ( - Display* /* dpy */, - Colormap /* colormap */ -); - -extern Status XcmsCIELabClipab( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELabClipL( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELabClipLab( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELabQueryMaxC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* L_star */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELabQueryMaxL ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELabQueryMaxLC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELabQueryMinL ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELabToCIEXYZ ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIELabWhiteShiftColors( - XcmsCCC /* ccc */, - XcmsColor* /* initial_white_point*/, - XcmsColor* /* target_white_point*/, - XcmsColorFormat /* target_format */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELuvClipL( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELuvClipLuv( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELuvClipuv( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIELuvQueryMaxC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* L_star */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELuvQueryMaxL ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELuvQueryMaxLC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELuvQueryMinL ( - XcmsCCC /* ccc */, - XcmsFloat /* hue_angle */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsCIELuvToCIEuvY ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIELuvWhiteShiftColors( - XcmsCCC /* ccc */, - XcmsColor* /* initial_white_point*/, - XcmsColor* /* target_white_point*/, - XcmsColorFormat /* target_format */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIEXYZToCIELab ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIEXYZToCIEuvY ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIEXYZToCIExyY ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIEXYZToRGBi ( - XcmsCCC /* ccc */, - XcmsColor* /* colors */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsCIEuvYToCIELuv ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIEuvYToCIEXYZ ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIEuvYToTekHVC ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsCIExyYToCIEXYZ ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern XcmsColor *XcmsClientWhitePointOfCCC ( - XcmsCCC /* ccc */ -); - -extern Status XcmsConvertColors ( - XcmsCCC /* ccc */, - XcmsColor* /* colorArry_in_out */, - unsigned int /* nColors */, - XcmsColorFormat /* targetFormat */, - Bool* /* compArry_return */ -); - -extern XcmsCCC XcmsCreateCCC ( - Display* /* dpy */, - int /* screenNumber */, - Visual* /* visual */, - XcmsColor* /* clientWhitePt */, - XcmsCompressionProc /* gamutCompProc */, - XPointer /* gamutCompClientData */, - XcmsWhiteAdjustProc /* whitePtAdjProc */, - XPointer /* whitePtAdjClientData */ -); - -extern XcmsCCC XcmsDefaultCCC ( - Display* /* dpy */, - int /* screenNumber */ -); - -extern Display *XcmsDisplayOfCCC ( - XcmsCCC /* ccc */ -); - -extern XcmsColorFormat XcmsFormatOfPrefix ( - char* /* prefix */ -); - -extern void XcmsFreeCCC ( - XcmsCCC /* ccc */ -); - -extern Status XcmsLookupColor ( - Display* /* dpy */, - Colormap /* colormap */, - _Xconst char* /* color_string */, - XcmsColor* /* pColor_exact_in_out */, - XcmsColor* /* pColor_scrn_in_out */, - XcmsColorFormat /* result_format */ -); - -extern char *XcmsPrefixOfFormat ( - XcmsColorFormat /* id */ -); - -extern Status XcmsQueryBlack ( - XcmsCCC /* ccc */, - XcmsColorFormat /* target_format */, - XcmsColor* /* color_return */ -); - -extern Status XcmsQueryBlue ( - XcmsCCC /* ccc */, - XcmsColorFormat /* target_format */, - XcmsColor* /* color_return */ -); - -extern Status XcmsQueryColor ( - Display* /* dpy */, - Colormap /* colormap */, - XcmsColor* /* pColor_in_out */, - XcmsColorFormat /* result_format */ -); - -extern Status XcmsQueryColors ( - Display* /* dpy */, - Colormap /* colormap */, - XcmsColor* /* colorArry_in_out */, - unsigned int /* nColors */, - XcmsColorFormat /* result_format */ -); - -extern Status XcmsQueryGreen ( - XcmsCCC /* ccc */, - XcmsColorFormat /* target_format */, - XcmsColor* /* color_return */ -); - -extern Status XcmsQueryRed ( - XcmsCCC /* ccc */, - XcmsColorFormat /* target_format */, - XcmsColor* /* color_return */ -); - -extern Status XcmsQueryWhite ( - XcmsCCC /* ccc */, - XcmsColorFormat /* target_format */, - XcmsColor* /* color_return */ -); - -extern Status XcmsRGBiToCIEXYZ ( - XcmsCCC /* ccc */, - XcmsColor* /* colors */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsRGBiToRGB ( - XcmsCCC /* ccc */, - XcmsColor* /* colors */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsRGBToRGBi ( - XcmsCCC /* ccc */, - XcmsColor* /* colors */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern int XcmsScreenNumberOfCCC ( - XcmsCCC /* ccc */ -); - -extern XcmsColor *XcmsScreenWhitePointOfCCC ( - XcmsCCC /* ccc */ -); - -extern XcmsCCC XcmsSetCCCOfColormap( - Display* /* dpy */, - Colormap /* colormap */, - XcmsCCC /* ccc */ -); - -extern XcmsCompressionProc XcmsSetCompressionProc ( - XcmsCCC /* ccc */, - XcmsCompressionProc /* compression_proc */, - XPointer /* client_data */ -); - -extern XcmsWhiteAdjustProc XcmsSetWhiteAdjustProc ( - XcmsCCC /* ccc */, - XcmsWhiteAdjustProc /* white_adjust_proc */, - XPointer /* client_data */ -); - -extern Status XcmsSetWhitePoint ( - XcmsCCC /* ccc */, - XcmsColor* /* color */ -); - -extern Status XcmsStoreColor ( - Display* /* dpy */, - Colormap /* colormap */, - XcmsColor* /* pColor_in */ -); - -extern Status XcmsStoreColors ( - Display* /* dpy */, - Colormap /* colormap */, - XcmsColor* /* colorArry_in */, - unsigned int /* nColors */, - Bool* /* compArry_return */ -); - -extern Status XcmsTekHVCClipC( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsTekHVCClipV( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsTekHVCClipVC( - XcmsCCC /* ccc */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - unsigned int /* index */, - Bool* /* compression_flags_return */ -); - -extern Status XcmsTekHVCQueryMaxC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue */, - XcmsFloat /* value */, - XcmsColor* /* color_return */ -); - -extern Status XcmsTekHVCQueryMaxV ( - XcmsCCC /* ccc */, - XcmsFloat /* hue */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsTekHVCQueryMaxVC ( - XcmsCCC /* ccc */, - XcmsFloat /* hue */, - XcmsColor* /* color_return */ -); - -extern Status XcmsTekHVCQueryMaxVSamples ( - XcmsCCC /* ccc */, - XcmsFloat /* hue */, - XcmsColor* /* colors_return */, - unsigned int /* nsamples */ -); - -extern Status XcmsTekHVCQueryMinV ( - XcmsCCC /* ccc */, - XcmsFloat /* hue */, - XcmsFloat /* chroma */, - XcmsColor* /* color_return */ -); - -extern Status XcmsTekHVCToCIEuvY ( - XcmsCCC /* ccc */, - XcmsColor* /* white_point */, - XcmsColor* /* colors */, - unsigned int /* ncolors */ -); - -extern Status XcmsTekHVCWhiteShiftColors( - XcmsCCC /* ccc */, - XcmsColor* /* initial_white_point*/, - XcmsColor* /* target_white_point*/, - XcmsColorFormat /* target_format */, - XcmsColor* /* colors_in_out */, - unsigned int /* ncolors */, - Bool* /* compression_flags_return */ -); - -extern Visual *XcmsVisualOfCCC ( - XcmsCCC /* ccc */ -); - -_XFUNCPROTOEND - -#endif /* _X11_XCMS_H_ */ diff --git a/shell/linux-deps/include/X11/Xdefs.h b/shell/linux-deps/include/X11/Xdefs.h deleted file mode 100644 index 46ffdad88..000000000 --- a/shell/linux-deps/include/X11/Xdefs.h +++ /dev/null @@ -1,108 +0,0 @@ -/*********************************************************** - -Copyright (c) 1999 The XFree86 Project Inc. - -All Rights Reserved. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The XFree86 Project -Inc. shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization from The XFree86 Project Inc.. - -*/ - -/** - ** Types definitions shared between server and clients - **/ - -#ifndef _XDEFS_H -#define _XDEFS_H - -#ifdef _XSERVER64 -#include -#endif - -#ifndef _XTYPEDEF_ATOM -# define _XTYPEDEF_ATOM -# ifndef _XSERVER64 -typedef unsigned long Atom; -# else -typedef CARD32 Atom; -# endif -#endif - -#ifndef Bool -# ifndef _XTYPEDEF_BOOL -# define _XTYPEDEF_BOOL -typedef int Bool; -# endif -#endif - -#ifndef _XTYPEDEF_POINTER -# define _XTYPEDEF_POINTER -typedef void *pointer; -#endif - -#ifndef _XTYPEDEF_CLIENTPTR -typedef struct _Client *ClientPtr; -# define _XTYPEDEF_CLIENTPTR -#endif - -#ifndef _XTYPEDEF_XID -# define _XTYPEDEF_XID -# ifndef _XSERVER64 -typedef unsigned long XID; -# else -typedef CARD32 XID; -# endif -#endif - -#ifndef _XTYPEDEF_MASK -# define _XTYPEDEF_MASK -# ifndef _XSERVER64 -typedef unsigned long Mask; -# else -typedef CARD32 Mask; -# endif -#endif - -#ifndef _XTYPEDEF_FONTPTR -# define _XTYPEDEF_FONTPTR -typedef struct _Font *FontPtr; /* also in fonts/include/font.h */ -#endif - -#ifndef _XTYPEDEF_FONT -# define _XTYPEDEF_FONT -typedef XID Font; -#endif - -#ifndef _XTYPEDEF_FSID -# ifndef _XSERVER64 -typedef unsigned long FSID; -# else -typedef CARD32 FSID; -# endif -#endif - -typedef FSID AccContext; - -/* OS independent time value - XXX Should probably go in Xos.h */ -typedef struct timeval **OSTimePtr; - - -typedef void (* BlockHandlerProcPtr)(pointer /* blockData */, - OSTimePtr /* pTimeout */, - pointer /* pReadmask */); - -#endif diff --git a/shell/linux-deps/include/X11/Xdmcp.h b/shell/linux-deps/include/X11/Xdmcp.h deleted file mode 100644 index 74ae4b3a0..000000000 --- a/shell/linux-deps/include/X11/Xdmcp.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 1989 Network Computing Devices, Inc., Mountain View, California. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of N.C.D. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. N.C.D. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - */ - -#ifndef _XDMCP_H_ -#define _XDMCP_H_ - -#include - -#include - -_XFUNCPROTOBEGIN - -#define XDM_PROTOCOL_VERSION 1 -#define XDM_UDP_PORT 177 - -/* IANA has assigned FF0X:0:0:0:0:0:0:12B as the permanently assigned - * multicast addresses for XDMCP, where X in the prefix may be replaced - * by any valid scope identifier, such as 1 for Node-Local, 2 for Link-Local, - * 5 for Site-Local, and so on. We set the default here to the Link-Local - * version to most closely match the old IPv4 subnet broadcast behavior. - * Both xdm and X -query allow specifying a different address if a different - * scope is defined. - */ -#define XDM_DEFAULT_MCAST_ADDR6 "ff02:0:0:0:0:0:0:12b" - -#define XDM_MAX_MSGLEN 8192 -#define XDM_MIN_RTX 2 -#define XDM_MAX_RTX 32 -#define XDM_RTX_LIMIT 7 -#define XDM_KA_RTX_LIMIT 4 -#define XDM_DEF_DORMANCY (3 * 60) /* 3 minutes */ -#define XDM_MAX_DORMANCY (24 * 60 * 60) /* 24 hours */ - -typedef enum { - BROADCAST_QUERY = 1, QUERY, INDIRECT_QUERY, FORWARD_QUERY, - WILLING, UNWILLING, REQUEST, ACCEPT, DECLINE, MANAGE, REFUSE, - FAILED, KEEPALIVE, ALIVE -} xdmOpCode; - -typedef enum { - XDM_QUERY, XDM_BROADCAST, XDM_INDIRECT, XDM_COLLECT_QUERY, - XDM_COLLECT_BROADCAST_QUERY, XDM_COLLECT_INDIRECT_QUERY, - XDM_START_CONNECTION, XDM_AWAIT_REQUEST_RESPONSE, - XDM_AWAIT_MANAGE_RESPONSE, XDM_MANAGE, XDM_RUN_SESSION, XDM_OFF, - XDM_AWAIT_USER_INPUT, XDM_KEEPALIVE, XDM_AWAIT_ALIVE_RESPONSE, -#if defined(IPv6) && defined(AF_INET6) - XDM_MULTICAST, XDM_COLLECT_MULTICAST_QUERY, -#endif - XDM_KEEP_ME_LAST -} xdmcp_states; - -#ifdef NOTDEF -/* table of hosts */ - -#define XDM_MAX_STR_LEN 21 -#define XDM_MAX_HOSTS 20 -struct xdm_host_table { - struct sockaddr_in sockaddr; - char name[XDM_MAX_STR_LEN]; - char status[XDM_MAX_STR_LEN]; -}; -#endif /* NOTDEF */ - -typedef CARD8 *CARD8Ptr; -typedef CARD16 *CARD16Ptr; -typedef CARD32 *CARD32Ptr; - -typedef struct _ARRAY8 { - CARD16 length; - CARD8Ptr data; -} ARRAY8, *ARRAY8Ptr; - -typedef struct _ARRAY16 { - CARD8 length; - CARD16Ptr data; -} ARRAY16, *ARRAY16Ptr; - -typedef struct _ARRAY32 { - CARD8 length; - CARD32Ptr data; -} ARRAY32, *ARRAY32Ptr; - -typedef struct _ARRAYofARRAY8 { - CARD8 length; - ARRAY8Ptr data; -} ARRAYofARRAY8, *ARRAYofARRAY8Ptr; - -typedef struct _XdmcpHeader { - CARD16 version, opcode, length; -} XdmcpHeader, *XdmcpHeaderPtr; - -typedef struct _XdmcpBuffer { - BYTE *data; - int size; /* size of buffer pointed by to data */ - int pointer; /* current index into data */ - int count; /* bytes read from network into data */ -} XdmcpBuffer, *XdmcpBufferPtr; - -typedef struct _XdmAuthKey { - BYTE data[8]; -} XdmAuthKeyRec, *XdmAuthKeyPtr; - - -/* implementation-independent network address structure. - Equiv to sockaddr* for sockets and netbuf* for STREAMS. */ - -typedef char *XdmcpNetaddr; - -extern int XdmcpWriteARRAY16(XdmcpBufferPtr buffer, const ARRAY16Ptr array); -extern int XdmcpWriteARRAY32(XdmcpBufferPtr buffer, const ARRAY32Ptr array); -extern int XdmcpWriteARRAY8(XdmcpBufferPtr buffer, const ARRAY8Ptr array); -extern int XdmcpWriteARRAYofARRAY8(XdmcpBufferPtr buffer, const ARRAYofARRAY8Ptr array); -extern int XdmcpWriteCARD16(XdmcpBufferPtr buffer, unsigned value); -extern int XdmcpWriteCARD32(XdmcpBufferPtr buffer, unsigned value); -extern int XdmcpWriteCARD8(XdmcpBufferPtr buffer, unsigned value); -extern int XdmcpWriteHeader(XdmcpBufferPtr buffer, const XdmcpHeaderPtr header); - -extern int XdmcpFlush(int fd, XdmcpBufferPtr buffer, XdmcpNetaddr to, int tolen); - -extern int XdmcpReadARRAY16(XdmcpBufferPtr buffer, ARRAY16Ptr array); -extern int XdmcpReadARRAY32(XdmcpBufferPtr buffer, ARRAY32Ptr array); -extern int XdmcpReadARRAY8(XdmcpBufferPtr buffer, ARRAY8Ptr array); -extern int XdmcpReadARRAYofARRAY8(XdmcpBufferPtr buffer, ARRAYofARRAY8Ptr array); -extern int XdmcpReadCARD16(XdmcpBufferPtr buffer, CARD16Ptr valuep); -extern int XdmcpReadCARD32(XdmcpBufferPtr buffer, CARD32Ptr valuep); -extern int XdmcpReadCARD8(XdmcpBufferPtr buffer, CARD8Ptr valuep); -extern int XdmcpReadHeader(XdmcpBufferPtr buffer, XdmcpHeaderPtr header); - -extern int XdmcpFill(int fd, XdmcpBufferPtr buffer, XdmcpNetaddr from, int *fromlen); - -extern int XdmcpReadRemaining(const XdmcpBufferPtr buffer); - -extern void XdmcpDisposeARRAY8(ARRAY8Ptr array); -extern void XdmcpDisposeARRAY16(ARRAY16Ptr array); -extern void XdmcpDisposeARRAY32(ARRAY32Ptr array); -extern void XdmcpDisposeARRAYofARRAY8(ARRAYofARRAY8Ptr array); - -extern int XdmcpCopyARRAY8(const ARRAY8Ptr src, ARRAY8Ptr dst); - -extern int XdmcpARRAY8Equal(const ARRAY8Ptr array1, const ARRAY8Ptr array2); - -extern void XdmcpGenerateKey (XdmAuthKeyPtr key); -extern void XdmcpIncrementKey (XdmAuthKeyPtr key); -extern void XdmcpDecrementKey (XdmAuthKeyPtr key); -#ifdef HASXDMAUTH -extern void XdmcpWrap(unsigned char *input, unsigned char *wrapper, unsigned char *output, int bytes); -extern void XdmcpUnwrap(unsigned char *input, unsigned char *wrapper, unsigned char *output, int bytes); -#endif - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -extern int XdmcpCompareKeys (const XdmAuthKeyPtr a, const XdmAuthKeyPtr b); - -extern int XdmcpAllocARRAY16 (ARRAY16Ptr array, int length); -extern int XdmcpAllocARRAY32 (ARRAY32Ptr array, int length); -extern int XdmcpAllocARRAY8 (ARRAY8Ptr array, int length); -extern int XdmcpAllocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int length); - -extern int XdmcpReallocARRAY16 (ARRAY16Ptr array, int length); -extern int XdmcpReallocARRAY32 (ARRAY32Ptr array, int length); -extern int XdmcpReallocARRAY8 (ARRAY8Ptr array, int length); -extern int XdmcpReallocARRAYofARRAY8 (ARRAYofARRAY8Ptr array, int length); - -_XFUNCPROTOEND - -#endif /* _XDMCP_H_ */ diff --git a/shell/linux-deps/include/X11/Xfuncproto.h b/shell/linux-deps/include/X11/Xfuncproto.h deleted file mode 100644 index a61c79351..000000000 --- a/shell/linux-deps/include/X11/Xfuncproto.h +++ /dev/null @@ -1,172 +0,0 @@ -/* Xfuncproto.h. Generated from Xfuncproto.h.in by configure. */ -/* - * -Copyright 1989, 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * - */ - -/* Definitions to make function prototypes manageable */ - -#ifndef _XFUNCPROTO_H_ -#define _XFUNCPROTO_H_ - -#ifndef NeedFunctionPrototypes -#define NeedFunctionPrototypes 1 -#endif /* NeedFunctionPrototypes */ - -#ifndef NeedVarargsPrototypes -#define NeedVarargsPrototypes 1 -#endif /* NeedVarargsPrototypes */ - -#if NeedFunctionPrototypes - -#ifndef NeedNestedPrototypes -#define NeedNestedPrototypes 1 -#endif /* NeedNestedPrototypes */ - -#ifndef _Xconst -#define _Xconst const -#endif /* _Xconst */ - -/* Function prototype configuration (see configure for more info) */ -#ifndef NARROWPROTO -#define NARROWPROTO /**/ -#endif -#ifndef FUNCPROTO -#define FUNCPROTO 15 -#endif - -#ifndef NeedWidePrototypes -#ifdef NARROWPROTO -#define NeedWidePrototypes 0 -#else -#define NeedWidePrototypes 1 /* default to make interropt. easier */ -#endif -#endif /* NeedWidePrototypes */ - -#endif /* NeedFunctionPrototypes */ - -#ifndef _XFUNCPROTOBEGIN -#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */ -#define _XFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ -#define _XFUNCPROTOEND } -#else -#define _XFUNCPROTOBEGIN -#define _XFUNCPROTOEND -#endif -#endif /* _XFUNCPROTOBEGIN */ - -/* Added in X11R6.9, so available in any version of modular xproto */ -#if defined(__GNUC__) && (__GNUC__ >= 4) -# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x))) -#else -# define _X_SENTINEL(x) -#endif /* GNUC >= 4 */ - -/* Added in X11R6.9, so available in any version of modular xproto */ -#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) -# define _X_EXPORT __attribute__((visibility("default"))) -# define _X_HIDDEN __attribute__((visibility("hidden"))) -# define _X_INTERNAL __attribute__((visibility("internal"))) -#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -# define _X_EXPORT __global -# define _X_HIDDEN __hidden -# define _X_INTERNAL __hidden -#else /* not gcc >= 4 and not Sun Studio >= 8 */ -# define _X_EXPORT -# define _X_HIDDEN -# define _X_INTERNAL -#endif /* GNUC >= 4 */ - -/* requires xproto >= 7.0.9 */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) -# define _X_LIKELY(x) __builtin_expect(!!(x), 1) -# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else /* not gcc >= 3.3 */ -# define _X_LIKELY(x) (x) -# define _X_UNLIKELY(x) (x) -#endif - -/* Added in X11R6.9, so available in any version of modular xproto */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301) -# define _X_DEPRECATED __attribute__((deprecated)) -#else /* not gcc >= 3.1 */ -# define _X_DEPRECATED -#endif - -/* requires xproto >= 7.0.17 */ -#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ - || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) -# define _X_NORETURN __attribute((noreturn)) -#else -# define _X_NORETURN -#endif /* GNUC */ - -/* Added in X11R6.9, so available in any version of modular xproto */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) -# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) -#else /* not gcc >= 2.3 */ -# define _X_ATTRIBUTE_PRINTF(x,y) -#endif - -/* requires xproto >= 7.0.22 */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) -#define _X_NONNULL(args...) __attribute__((nonnull(args))) -#else -#define _X_NONNULL(...) /* */ -#endif - -/* requires xproto >= 7.0.22 */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205) -#define _X_UNUSED __attribute__((__unused__)) -#else -#define _X_UNUSED /* */ -#endif - -/* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */ -/* requires xproto >= 7.0.9 - (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */ -#if defined(inline) /* assume autoconf set it correctly */ || \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \ - (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)) -# define _X_INLINE inline -#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ -# define _X_INLINE __inline__ -#else -# define _X_INLINE -#endif - -/* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */ -/* requires xproto >= 7.0.21 */ -#ifndef _X_RESTRICT_KYWD -# if defined(restrict) /* assume autoconf set it correctly */ || \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ -# define _X_RESTRICT_KYWD restrict -# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ -# define _X_RESTRICT_KYWD __restrict__ -# else -# define _X_RESTRICT_KYWD -# endif -#endif - -#endif /* _XFUNCPROTO_H_ */ diff --git a/shell/linux-deps/include/X11/Xfuncs.h b/shell/linux-deps/include/X11/Xfuncs.h deleted file mode 100644 index 354b66326..000000000 --- a/shell/linux-deps/include/X11/Xfuncs.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * -Copyright 1990, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * - */ - -#ifndef _XFUNCS_H_ -# define _XFUNCS_H_ - -# include - -/* the old Xfuncs.h, for pre-R6 */ -# if !(defined(XFree86LOADER) && defined(IN_MODULE)) - -# ifdef X_USEBFUNCS -void bcopy(); -void bzero(); -int bcmp(); -# else -# if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) -# include -void bcopy(); -# define bzero(b,len) memset(b, 0, len) -# define bcmp(b1,b2,len) memcmp(b1, b2, len) -# else -# include -# if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) -# include -# endif -# define _XFUNCS_H_INCLUDED_STRING_H -# endif -# endif /* X_USEBFUNCS */ - -/* the new Xfuncs.h */ - -/* the ANSI C way */ -# ifndef _XFUNCS_H_INCLUDED_STRING_H -# include -# endif -# undef bzero -# define bzero(b,len) memset(b,0,len) - -# if defined WIN32 && defined __MINGW32__ -# define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) -# endif - -# endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */ - -#endif /* _XFUNCS_H_ */ diff --git a/shell/linux-deps/include/X11/Xlib.h b/shell/linux-deps/include/X11/Xlib.h deleted file mode 100644 index dd4c7c443..000000000 --- a/shell/linux-deps/include/X11/Xlib.h +++ /dev/null @@ -1,4024 +0,0 @@ -/* - -Copyright 1985, 1986, 1987, 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -*/ - - -/* - * Xlib.h - Header definition and support file for the C subroutine - * interface library (Xlib) to the X Window System Protocol (V11). - * Structures and symbols starting with "_" are private to the library. - */ -#ifndef _X11_XLIB_H_ -#define _X11_XLIB_H_ - -#define XlibSpecificationRelease 6 - -#include - -#if defined(__SCO__) || defined(__UNIXWARE__) -#include -#endif - -#include - -/* applications should not depend on these two headers being included! */ -#include -#include - -#ifndef X_WCHAR -#include -#else -#ifdef __UNIXOS2__ -#include -#else -/* replace this with #include or typedef appropriate for your system */ -typedef unsigned long wchar_t; -#endif -#endif - -#if defined(ISC) && defined(USE_XMBTOWC) -#define wctomb(a,b) _Xwctomb(a,b) -#define mblen(a,b) _Xmblen(a,b) -#ifndef USE_XWCHAR_STRING -#define mbtowc(a,b,c) _Xmbtowc(a,b,c) -#endif -#endif - -extern int -_Xmblen( -#ifdef ISC - char const *str, - size_t len -#else - char *str, - int len -#endif - ); - -/* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in - November 2000. Its presence is indicated through the following macro. */ -#define X_HAVE_UTF8_STRING 1 - -typedef char *XPointer; - -#define Bool int -#define Status int -#define True 1 -#define False 0 - -#define QueuedAlready 0 -#define QueuedAfterReading 1 -#define QueuedAfterFlush 2 - -#define ConnectionNumber(dpy) (((_XPrivDisplay)dpy)->fd) -#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root) -#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen) -#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy,DefaultScreen(dpy))->root) -#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual) -#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy,scr)->default_gc) -#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel) -#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel) -#define AllPlanes ((unsigned long)~0L) -#define QLength(dpy) (((_XPrivDisplay)dpy)->qlen) -#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy,scr)->width) -#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height) -#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth) -#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight) -#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) -#define DisplayCells(dpy, scr) (DefaultVisual(dpy,scr)->map_entries) -#define ScreenCount(dpy) (((_XPrivDisplay)dpy)->nscreens) -#define ServerVendor(dpy) (((_XPrivDisplay)dpy)->vendor) -#define ProtocolVersion(dpy) (((_XPrivDisplay)dpy)->proto_major_version) -#define ProtocolRevision(dpy) (((_XPrivDisplay)dpy)->proto_minor_version) -#define VendorRelease(dpy) (((_XPrivDisplay)dpy)->release) -#define DisplayString(dpy) (((_XPrivDisplay)dpy)->display_name) -#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) -#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap) -#define BitmapUnit(dpy) (((_XPrivDisplay)dpy)->bitmap_unit) -#define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order) -#define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad) -#define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order) -#ifdef CRAY /* unable to get WORD64 without pulling in other symbols */ -#define NextRequest(dpy) XNextRequest(dpy) -#else -#define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1) -#endif -#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read) - -/* macros for screen oriented applications (toolkit) */ -#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr]) -#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy)) -#define DisplayOfScreen(s) ((s)->display) -#define RootWindowOfScreen(s) ((s)->root) -#define BlackPixelOfScreen(s) ((s)->black_pixel) -#define WhitePixelOfScreen(s) ((s)->white_pixel) -#define DefaultColormapOfScreen(s)((s)->cmap) -#define DefaultDepthOfScreen(s) ((s)->root_depth) -#define DefaultGCOfScreen(s) ((s)->default_gc) -#define DefaultVisualOfScreen(s)((s)->root_visual) -#define WidthOfScreen(s) ((s)->width) -#define HeightOfScreen(s) ((s)->height) -#define WidthMMOfScreen(s) ((s)->mwidth) -#define HeightMMOfScreen(s) ((s)->mheight) -#define PlanesOfScreen(s) ((s)->root_depth) -#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries) -#define MinCmapsOfScreen(s) ((s)->min_maps) -#define MaxCmapsOfScreen(s) ((s)->max_maps) -#define DoesSaveUnders(s) ((s)->save_unders) -#define DoesBackingStore(s) ((s)->backing_store) -#define EventMaskOfScreen(s) ((s)->root_input_mask) - -/* - * Extensions need a way to hang private data on some structures. - */ -typedef struct _XExtData { - int number; /* number returned by XRegisterExtension */ - struct _XExtData *next; /* next item on list of data for structure */ - int (*free_private)( /* called to free private storage */ - struct _XExtData *extension - ); - XPointer private_data; /* data private to this extension. */ -} XExtData; - -/* - * This file contains structures used by the extension mechanism. - */ -typedef struct { /* public to extension, cannot be changed */ - int extension; /* extension number */ - int major_opcode; /* major op-code assigned by server */ - int first_event; /* first event number for the extension */ - int first_error; /* first error number for the extension */ -} XExtCodes; - -/* - * Data structure for retrieving info about pixmap formats. - */ - -typedef struct { - int depth; - int bits_per_pixel; - int scanline_pad; -} XPixmapFormatValues; - - -/* - * Data structure for setting graphics context. - */ -typedef struct { - int function; /* logical operation */ - unsigned long plane_mask;/* plane mask */ - unsigned long foreground;/* foreground pixel */ - unsigned long background;/* background pixel */ - int line_width; /* line width */ - int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ - int cap_style; /* CapNotLast, CapButt, - CapRound, CapProjecting */ - int join_style; /* JoinMiter, JoinRound, JoinBevel */ - int fill_style; /* FillSolid, FillTiled, - FillStippled, FillOpaeueStippled */ - int fill_rule; /* EvenOddRule, WindingRule */ - int arc_mode; /* ArcChord, ArcPieSlice */ - Pixmap tile; /* tile pixmap for tiling operations */ - Pixmap stipple; /* stipple 1 plane pixmap for stipping */ - int ts_x_origin; /* offset for tile or stipple operations */ - int ts_y_origin; - Font font; /* default text font for text operations */ - int subwindow_mode; /* ClipByChildren, IncludeInferiors */ - Bool graphics_exposures;/* boolean, should exposures be generated */ - int clip_x_origin; /* origin for clipping */ - int clip_y_origin; - Pixmap clip_mask; /* bitmap clipping; other calls for rects */ - int dash_offset; /* patterned/dashed line information */ - char dashes; -} XGCValues; - -/* - * Graphics context. The contents of this structure are implementation - * dependent. A GC should be treated as opaque by application code. - */ - -typedef struct _XGC -#ifdef XLIB_ILLEGAL_ACCESS -{ - XExtData *ext_data; /* hook for extension to hang data */ - GContext gid; /* protocol ID for graphics context */ - /* there is more to this structure, but it is private to Xlib */ -} -#endif -*GC; - -/* - * Visual structure; contains information about colormapping possible. - */ -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - VisualID visualid; /* visual id of this visual */ -#if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ class of screen (monochrome, etc.) */ -#else - int class; /* class of screen (monochrome, etc.) */ -#endif - unsigned long red_mask, green_mask, blue_mask; /* mask values */ - int bits_per_rgb; /* log base 2 of distinct color values */ - int map_entries; /* color map entries */ -} Visual; - -/* - * Depth structure; contains information for each possible depth. - */ -typedef struct { - int depth; /* this depth (Z) of the depth */ - int nvisuals; /* number of Visual types at this depth */ - Visual *visuals; /* list of visuals possible at this depth */ -} Depth; - -/* - * Information about the screen. The contents of this structure are - * implementation dependent. A Screen should be treated as opaque - * by application code. - */ - -struct _XDisplay; /* Forward declare before use for C++ */ - -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - struct _XDisplay *display;/* back pointer to display structure */ - Window root; /* Root window id. */ - int width, height; /* width and height of screen */ - int mwidth, mheight; /* width and height of in millimeters */ - int ndepths; /* number of depths possible */ - Depth *depths; /* list of allowable depths on the screen */ - int root_depth; /* bits per pixel */ - Visual *root_visual; /* root visual */ - GC default_gc; /* GC for the root root visual */ - Colormap cmap; /* default color map */ - unsigned long white_pixel; - unsigned long black_pixel; /* White and Black pixel values */ - int max_maps, min_maps; /* max and min color maps */ - int backing_store; /* Never, WhenMapped, Always */ - Bool save_unders; - long root_input_mask; /* initial root input mask */ -} Screen; - -/* - * Format structure; describes ZFormat data the screen will understand. - */ -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - int depth; /* depth of this image format */ - int bits_per_pixel; /* bits/pixel at this depth */ - int scanline_pad; /* scanline must padded to this multiple */ -} ScreenFormat; - -/* - * Data structure for setting window attributes. - */ -typedef struct { - Pixmap background_pixmap; /* background or None or ParentRelative */ - unsigned long background_pixel; /* background pixel */ - Pixmap border_pixmap; /* border of the window */ - unsigned long border_pixel; /* border pixel value */ - int bit_gravity; /* one of bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes;/* planes to be preseved if possible */ - unsigned long backing_pixel;/* value to use in restoring planes */ - Bool save_under; /* should bits under be saved? (popups) */ - long event_mask; /* set of events that should be saved */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override-redirect */ - Colormap colormap; /* color map to be associated with window */ - Cursor cursor; /* cursor to be displayed (or None) */ -} XSetWindowAttributes; - -typedef struct { - int x, y; /* location of window */ - int width, height; /* width and height of window */ - int border_width; /* border width of window */ - int depth; /* depth of window */ - Visual *visual; /* the associated visual structure */ - Window root; /* root of screen containing window */ -#if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ InputOutput, InputOnly*/ -#else - int class; /* InputOutput, InputOnly*/ -#endif - int bit_gravity; /* one of bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes;/* planes to be preserved if possible */ - unsigned long backing_pixel;/* value to be used when restoring planes */ - Bool save_under; /* boolean, should bits under be saved? */ - Colormap colormap; /* color map to be associated with window */ - Bool map_installed; /* boolean, is color map currently installed*/ - int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ - long all_event_masks; /* set of events all people have interest in*/ - long your_event_mask; /* my event mask */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override-redirect */ - Screen *screen; /* back pointer to correct screen */ -} XWindowAttributes; - -/* - * Data structure for host setting; getting routines. - * - */ - -typedef struct { - int family; /* for example FamilyInternet */ - int length; /* length of address, in bytes */ - char *address; /* pointer to where to find the bytes */ -} XHostAddress; - -/* - * Data structure for ServerFamilyInterpreted addresses in host routines - */ -typedef struct { - int typelength; /* length of type string, in bytes */ - int valuelength; /* length of value string, in bytes */ - char *type; /* pointer to where to find the type string */ - char *value; /* pointer to where to find the address */ -} XServerInterpretedAddress; - -/* - * Data structure for "image" data, used by image manipulation routines. - */ -typedef struct _XImage { - int width, height; /* size of image */ - int xoffset; /* number of pixels offset in X direction */ - int format; /* XYBitmap, XYPixmap, ZPixmap */ - char *data; /* pointer to image data */ - int byte_order; /* data byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* quant. of scanline 8, 16, 32 */ - int bitmap_bit_order; /* LSBFirst, MSBFirst */ - int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ - int depth; /* depth of image */ - int bytes_per_line; /* accelarator to next line */ - int bits_per_pixel; /* bits per pixel (ZPixmap) */ - unsigned long red_mask; /* bits in z arrangment */ - unsigned long green_mask; - unsigned long blue_mask; - XPointer obdata; /* hook for the object routines to hang on */ - struct funcs { /* image manipulation routines */ - struct _XImage *(*create_image)( - struct _XDisplay* /* display */, - Visual* /* visual */, - unsigned int /* depth */, - int /* format */, - int /* offset */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - int /* bitmap_pad */, - int /* bytes_per_line */); - int (*destroy_image) (struct _XImage *); - unsigned long (*get_pixel) (struct _XImage *, int, int); - int (*put_pixel) (struct _XImage *, int, int, unsigned long); - struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); - int (*add_pixel) (struct _XImage *, long); - } f; -} XImage; - -/* - * Data structure for XReconfigureWindow - */ -typedef struct { - int x, y; - int width, height; - int border_width; - Window sibling; - int stack_mode; -} XWindowChanges; - -/* - * Data structure used by color operations - */ -typedef struct { - unsigned long pixel; - unsigned short red, green, blue; - char flags; /* do_red, do_green, do_blue */ - char pad; -} XColor; - -/* - * Data structures for graphics operations. On most machines, these are - * congruent with the wire protocol structures, so reformatting the data - * can be avoided on these architectures. - */ -typedef struct { - short x1, y1, x2, y2; -} XSegment; - -typedef struct { - short x, y; -} XPoint; - -typedef struct { - short x, y; - unsigned short width, height; -} XRectangle; - -typedef struct { - short x, y; - unsigned short width, height; - short angle1, angle2; -} XArc; - - -/* Data structure for XChangeKeyboardControl */ - -typedef struct { - int key_click_percent; - int bell_percent; - int bell_pitch; - int bell_duration; - int led; - int led_mode; - int key; - int auto_repeat_mode; /* On, Off, Default */ -} XKeyboardControl; - -/* Data structure for XGetKeyboardControl */ - -typedef struct { - int key_click_percent; - int bell_percent; - unsigned int bell_pitch, bell_duration; - unsigned long led_mask; - int global_auto_repeat; - char auto_repeats[32]; -} XKeyboardState; - -/* Data structure for XGetMotionEvents. */ - -typedef struct { - Time time; - short x, y; -} XTimeCoord; - -/* Data structure for X{Set,Get}ModifierMapping */ - -typedef struct { - int max_keypermod; /* The server's max # of keys per modifier */ - KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */ -} XModifierKeymap; - - -/* - * Display datatype maintaining display specific data. - * The contents of this structure are implementation dependent. - * A Display should be treated as opaque by application code. - */ -#ifndef XLIB_ILLEGAL_ACCESS -typedef struct _XDisplay Display; -#endif - -struct _XPrivate; /* Forward declare before use for C++ */ -struct _XrmHashBucketRec; - -typedef struct -#ifdef XLIB_ILLEGAL_ACCESS -_XDisplay -#endif -{ - XExtData *ext_data; /* hook for extension to hang data */ - struct _XPrivate *private1; - int fd; /* Network socket. */ - int private2; - int proto_major_version;/* major version of server's X protocol */ - int proto_minor_version;/* minor version of servers X protocol */ - char *vendor; /* vendor of the server hardware */ - XID private3; - XID private4; - XID private5; - int private6; - XID (*resource_alloc)( /* allocator function */ - struct _XDisplay* - ); - int byte_order; /* screen byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* padding and data requirements */ - int bitmap_pad; /* padding requirements on bitmaps */ - int bitmap_bit_order; /* LeastSignificant or MostSignificant */ - int nformats; /* number of pixmap formats in list */ - ScreenFormat *pixmap_format; /* pixmap format list */ - int private8; - int release; /* release of the server */ - struct _XPrivate *private9, *private10; - int qlen; /* Length of input event queue */ - unsigned long last_request_read; /* seq number of last event read */ - unsigned long request; /* sequence number of last request. */ - XPointer private11; - XPointer private12; - XPointer private13; - XPointer private14; - unsigned max_request_size; /* maximum number 32 bit words in request*/ - struct _XrmHashBucketRec *db; - int (*private15)( - struct _XDisplay* - ); - char *display_name; /* "host:display" string used on this connect*/ - int default_screen; /* default screen for operations */ - int nscreens; /* number of screens on this server*/ - Screen *screens; /* pointer to list of screens */ - unsigned long motion_buffer; /* size of motion buffer */ - unsigned long private16; - int min_keycode; /* minimum defined keycode */ - int max_keycode; /* maximum defined keycode */ - XPointer private17; - XPointer private18; - int private19; - char *xdefaults; /* contents of defaults from server */ - /* there is more to this structure, but it is private to Xlib */ -} -#ifdef XLIB_ILLEGAL_ACCESS -Display, -#endif -*_XPrivDisplay; - -#undef _XEVENT_ -#ifndef _XEVENT_ -/* - * Definitions of specific events. - */ -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window it is reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - unsigned int keycode; /* detail */ - Bool same_screen; /* same screen flag */ -} XKeyEvent; -typedef XKeyEvent XKeyPressedEvent; -typedef XKeyEvent XKeyReleasedEvent; - -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window it is reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - unsigned int button; /* detail */ - Bool same_screen; /* same screen flag */ -} XButtonEvent; -typedef XButtonEvent XButtonPressedEvent; -typedef XButtonEvent XButtonReleasedEvent; - -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - char is_hint; /* detail */ - Bool same_screen; /* same screen flag */ -} XMotionEvent; -typedef XMotionEvent XPointerMovedEvent; - -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ - int detail; - /* - * NotifyAncestor, NotifyVirtual, NotifyInferior, - * NotifyNonlinear,NotifyNonlinearVirtual - */ - Bool same_screen; /* same screen flag */ - Bool focus; /* boolean focus */ - unsigned int state; /* key or button mask */ -} XCrossingEvent; -typedef XCrossingEvent XEnterWindowEvent; -typedef XCrossingEvent XLeaveWindowEvent; - -typedef struct { - int type; /* FocusIn or FocusOut */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* window of event */ - int mode; /* NotifyNormal, NotifyWhileGrabbed, - NotifyGrab, NotifyUngrab */ - int detail; - /* - * NotifyAncestor, NotifyVirtual, NotifyInferior, - * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, - * NotifyPointerRoot, NotifyDetailNone - */ -} XFocusChangeEvent; -typedef XFocusChangeEvent XFocusInEvent; -typedef XFocusChangeEvent XFocusOutEvent; - -/* generated on EnterWindow and FocusIn when KeyMapState selected */ -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - char key_vector[32]; -} XKeymapEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - int x, y; - int width, height; - int count; /* if non-zero, at least this many more */ -} XExposeEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Drawable drawable; - int x, y; - int width, height; - int count; /* if non-zero, at least this many more */ - int major_code; /* core is CopyArea or CopyPlane */ - int minor_code; /* not defined in the core */ -} XGraphicsExposeEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Drawable drawable; - int major_code; /* core is CopyArea or CopyPlane */ - int minor_code; /* not defined in the core */ -} XNoExposeEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - int state; /* Visibility state */ -} XVisibilityEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window parent; /* parent of the window */ - Window window; /* window id of window created */ - int x, y; /* window location */ - int width, height; /* size of window */ - int border_width; /* border width */ - Bool override_redirect; /* creation should be overridden */ -} XCreateWindowEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; -} XDestroyWindowEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - Bool from_configure; -} XUnmapEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - Bool override_redirect; /* boolean, is override set... */ -} XMapEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window parent; - Window window; -} XMapRequestEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - Window parent; - int x, y; - Bool override_redirect; -} XReparentEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - int x, y; - int width, height; - int border_width; - Window above; - Bool override_redirect; -} XConfigureEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - int x, y; -} XGravityEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - int width, height; -} XResizeRequestEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window parent; - Window window; - int x, y; - int width, height; - int border_width; - Window above; - int detail; /* Above, Below, TopIf, BottomIf, Opposite */ - unsigned long value_mask; -} XConfigureRequestEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window event; - Window window; - int place; /* PlaceOnTop, PlaceOnBottom */ -} XCirculateEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window parent; - Window window; - int place; /* PlaceOnTop, PlaceOnBottom */ -} XCirculateRequestEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - Atom atom; - Time time; - int state; /* NewValue, Deleted */ -} XPropertyEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - Atom selection; - Time time; -} XSelectionClearEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window owner; - Window requestor; - Atom selection; - Atom target; - Atom property; - Time time; -} XSelectionRequestEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window requestor; - Atom selection; - Atom target; - Atom property; /* ATOM or None */ - Time time; -} XSelectionEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - Colormap colormap; /* COLORMAP or None */ -#if defined(__cplusplus) || defined(c_plusplus) - Bool c_new; /* C++ */ -#else - Bool new; -#endif - int state; /* ColormapInstalled, ColormapUninstalled */ -} XColormapEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; - Atom message_type; - int format; - union { - char b[20]; - short s[10]; - long l[5]; - } data; -} XClientMessageEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* unused */ - int request; /* one of MappingModifier, MappingKeyboard, - MappingPointer */ - int first_keycode; /* first keycode */ - int count; /* defines range of change w. first_keycode*/ -} XMappingEvent; - -typedef struct { - int type; - Display *display; /* Display the event was read from */ - XID resourceid; /* resource id */ - unsigned long serial; /* serial number of failed request */ - unsigned char error_code; /* error code of failed request */ - unsigned char request_code; /* Major op-code of failed request */ - unsigned char minor_code; /* Minor op-code of failed request */ -} XErrorEvent; - -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display;/* Display the event was read from */ - Window window; /* window on which event was requested in event mask */ -} XAnyEvent; - - -/*************************************************************** - * - * GenericEvent. This event is the standard event for all newer extensions. - */ - -typedef struct - { - int type; /* of event. Always GenericEvent */ - unsigned long serial; /* # of last request processed */ - Bool send_event; /* true if from SendEvent request */ - Display *display; /* Display the event was read from */ - int extension; /* major opcode of extension that caused the event */ - int evtype; /* actual event type. */ - } XGenericEvent; - -typedef struct { - int type; /* of event. Always GenericEvent */ - unsigned long serial; /* # of last request processed */ - Bool send_event; /* true if from SendEvent request */ - Display *display; /* Display the event was read from */ - int extension; /* major opcode of extension that caused the event */ - int evtype; /* actual event type. */ - unsigned int cookie; - void *data; -} XGenericEventCookie; - -/* - * this union is defined so Xlib can always use the same sized - * event structure internally, to avoid memory fragmentation. - */ -typedef union _XEvent { - int type; /* must not be changed; first element */ - XAnyEvent xany; - XKeyEvent xkey; - XButtonEvent xbutton; - XMotionEvent xmotion; - XCrossingEvent xcrossing; - XFocusChangeEvent xfocus; - XExposeEvent xexpose; - XGraphicsExposeEvent xgraphicsexpose; - XNoExposeEvent xnoexpose; - XVisibilityEvent xvisibility; - XCreateWindowEvent xcreatewindow; - XDestroyWindowEvent xdestroywindow; - XUnmapEvent xunmap; - XMapEvent xmap; - XMapRequestEvent xmaprequest; - XReparentEvent xreparent; - XConfigureEvent xconfigure; - XGravityEvent xgravity; - XResizeRequestEvent xresizerequest; - XConfigureRequestEvent xconfigurerequest; - XCirculateEvent xcirculate; - XCirculateRequestEvent xcirculaterequest; - XPropertyEvent xproperty; - XSelectionClearEvent xselectionclear; - XSelectionRequestEvent xselectionrequest; - XSelectionEvent xselection; - XColormapEvent xcolormap; - XClientMessageEvent xclient; - XMappingEvent xmapping; - XErrorEvent xerror; - XKeymapEvent xkeymap; - XGenericEvent xgeneric; - XGenericEventCookie xcookie; - long pad[24]; -} XEvent; -#endif - -#define XAllocID(dpy) ((*((_XPrivDisplay)dpy)->resource_alloc)((dpy))) - -/* - * per character font metric information. - */ -typedef struct { - short lbearing; /* origin to left edge of raster */ - short rbearing; /* origin to right edge of raster */ - short width; /* advance to next char's origin */ - short ascent; /* baseline to top edge of raster */ - short descent; /* baseline to bottom edge of raster */ - unsigned short attributes; /* per char flags (not predefined) */ -} XCharStruct; - -/* - * To allow arbitrary information with fonts, there are additional properties - * returned. - */ -typedef struct { - Atom name; - unsigned long card32; -} XFontProp; - -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - Font fid; /* Font id for this font */ - unsigned direction; /* hint about direction the font is painted */ - unsigned min_char_or_byte2;/* first character */ - unsigned max_char_or_byte2;/* last character */ - unsigned min_byte1; /* first row that exists */ - unsigned max_byte1; /* last row that exists */ - Bool all_chars_exist;/* flag if all characters have non-zero size*/ - unsigned default_char; /* char to print for undefined character */ - int n_properties; /* how many properties there are */ - XFontProp *properties; /* pointer to array of additional properties*/ - XCharStruct min_bounds; /* minimum bounds over all existing char*/ - XCharStruct max_bounds; /* maximum bounds over all existing char*/ - XCharStruct *per_char; /* first_char to last_char information */ - int ascent; /* log. extent above baseline for spacing */ - int descent; /* log. descent below baseline for spacing */ -} XFontStruct; - -/* - * PolyText routines take these as arguments. - */ -typedef struct { - char *chars; /* pointer to string */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* font to print it in, None don't change */ -} XTextItem; - -typedef struct { /* normal 16 bit characters are two bytes */ - unsigned char byte1; - unsigned char byte2; -} XChar2b; - -typedef struct { - XChar2b *chars; /* two byte characters */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* font to print it in, None don't change */ -} XTextItem16; - - -typedef union { Display *display; - GC gc; - Visual *visual; - Screen *screen; - ScreenFormat *pixmap_format; - XFontStruct *font; } XEDataObject; - -typedef struct { - XRectangle max_ink_extent; - XRectangle max_logical_extent; -} XFontSetExtents; - -/* unused: -typedef void (*XOMProc)(); - */ - -typedef struct _XOM *XOM; -typedef struct _XOC *XOC, *XFontSet; - -typedef struct { - char *chars; - int nchars; - int delta; - XFontSet font_set; -} XmbTextItem; - -typedef struct { - wchar_t *chars; - int nchars; - int delta; - XFontSet font_set; -} XwcTextItem; - -#define XNRequiredCharSet "requiredCharSet" -#define XNQueryOrientation "queryOrientation" -#define XNBaseFontName "baseFontName" -#define XNOMAutomatic "omAutomatic" -#define XNMissingCharSet "missingCharSet" -#define XNDefaultString "defaultString" -#define XNOrientation "orientation" -#define XNDirectionalDependentDrawing "directionalDependentDrawing" -#define XNContextualDrawing "contextualDrawing" -#define XNFontInfo "fontInfo" - -typedef struct { - int charset_count; - char **charset_list; -} XOMCharSetList; - -typedef enum { - XOMOrientation_LTR_TTB, - XOMOrientation_RTL_TTB, - XOMOrientation_TTB_LTR, - XOMOrientation_TTB_RTL, - XOMOrientation_Context -} XOrientation; - -typedef struct { - int num_orientation; - XOrientation *orientation; /* Input Text description */ -} XOMOrientation; - -typedef struct { - int num_font; - XFontStruct **font_struct_list; - char **font_name_list; -} XOMFontInfo; - -typedef struct _XIM *XIM; -typedef struct _XIC *XIC; - -typedef void (*XIMProc)( - XIM, - XPointer, - XPointer -); - -typedef Bool (*XICProc)( - XIC, - XPointer, - XPointer -); - -typedef void (*XIDProc)( - Display*, - XPointer, - XPointer -); - -typedef unsigned long XIMStyle; - -typedef struct { - unsigned short count_styles; - XIMStyle *supported_styles; -} XIMStyles; - -#define XIMPreeditArea 0x0001L -#define XIMPreeditCallbacks 0x0002L -#define XIMPreeditPosition 0x0004L -#define XIMPreeditNothing 0x0008L -#define XIMPreeditNone 0x0010L -#define XIMStatusArea 0x0100L -#define XIMStatusCallbacks 0x0200L -#define XIMStatusNothing 0x0400L -#define XIMStatusNone 0x0800L - -#define XNVaNestedList "XNVaNestedList" -#define XNQueryInputStyle "queryInputStyle" -#define XNClientWindow "clientWindow" -#define XNInputStyle "inputStyle" -#define XNFocusWindow "focusWindow" -#define XNResourceName "resourceName" -#define XNResourceClass "resourceClass" -#define XNGeometryCallback "geometryCallback" -#define XNDestroyCallback "destroyCallback" -#define XNFilterEvents "filterEvents" -#define XNPreeditStartCallback "preeditStartCallback" -#define XNPreeditDoneCallback "preeditDoneCallback" -#define XNPreeditDrawCallback "preeditDrawCallback" -#define XNPreeditCaretCallback "preeditCaretCallback" -#define XNPreeditStateNotifyCallback "preeditStateNotifyCallback" -#define XNPreeditAttributes "preeditAttributes" -#define XNStatusStartCallback "statusStartCallback" -#define XNStatusDoneCallback "statusDoneCallback" -#define XNStatusDrawCallback "statusDrawCallback" -#define XNStatusAttributes "statusAttributes" -#define XNArea "area" -#define XNAreaNeeded "areaNeeded" -#define XNSpotLocation "spotLocation" -#define XNColormap "colorMap" -#define XNStdColormap "stdColorMap" -#define XNForeground "foreground" -#define XNBackground "background" -#define XNBackgroundPixmap "backgroundPixmap" -#define XNFontSet "fontSet" -#define XNLineSpace "lineSpace" -#define XNCursor "cursor" - -#define XNQueryIMValuesList "queryIMValuesList" -#define XNQueryICValuesList "queryICValuesList" -#define XNVisiblePosition "visiblePosition" -#define XNR6PreeditCallback "r6PreeditCallback" -#define XNStringConversionCallback "stringConversionCallback" -#define XNStringConversion "stringConversion" -#define XNResetState "resetState" -#define XNHotKey "hotKey" -#define XNHotKeyState "hotKeyState" -#define XNPreeditState "preeditState" -#define XNSeparatorofNestedList "separatorofNestedList" - -#define XBufferOverflow -1 -#define XLookupNone 1 -#define XLookupChars 2 -#define XLookupKeySym 3 -#define XLookupBoth 4 - -typedef void *XVaNestedList; - -typedef struct { - XPointer client_data; - XIMProc callback; -} XIMCallback; - -typedef struct { - XPointer client_data; - XICProc callback; -} XICCallback; - -typedef unsigned long XIMFeedback; - -#define XIMReverse 1L -#define XIMUnderline (1L<<1) -#define XIMHighlight (1L<<2) -#define XIMPrimary (1L<<5) -#define XIMSecondary (1L<<6) -#define XIMTertiary (1L<<7) -#define XIMVisibleToForward (1L<<8) -#define XIMVisibleToBackword (1L<<9) -#define XIMVisibleToCenter (1L<<10) - -typedef struct _XIMText { - unsigned short length; - XIMFeedback *feedback; - Bool encoding_is_wchar; - union { - char *multi_byte; - wchar_t *wide_char; - } string; -} XIMText; - -typedef unsigned long XIMPreeditState; - -#define XIMPreeditUnKnown 0L -#define XIMPreeditEnable 1L -#define XIMPreeditDisable (1L<<1) - -typedef struct _XIMPreeditStateNotifyCallbackStruct { - XIMPreeditState state; -} XIMPreeditStateNotifyCallbackStruct; - -typedef unsigned long XIMResetState; - -#define XIMInitialState 1L -#define XIMPreserveState (1L<<1) - -typedef unsigned long XIMStringConversionFeedback; - -#define XIMStringConversionLeftEdge (0x00000001) -#define XIMStringConversionRightEdge (0x00000002) -#define XIMStringConversionTopEdge (0x00000004) -#define XIMStringConversionBottomEdge (0x00000008) -#define XIMStringConversionConcealed (0x00000010) -#define XIMStringConversionWrapped (0x00000020) - -typedef struct _XIMStringConversionText { - unsigned short length; - XIMStringConversionFeedback *feedback; - Bool encoding_is_wchar; - union { - char *mbs; - wchar_t *wcs; - } string; -} XIMStringConversionText; - -typedef unsigned short XIMStringConversionPosition; - -typedef unsigned short XIMStringConversionType; - -#define XIMStringConversionBuffer (0x0001) -#define XIMStringConversionLine (0x0002) -#define XIMStringConversionWord (0x0003) -#define XIMStringConversionChar (0x0004) - -typedef unsigned short XIMStringConversionOperation; - -#define XIMStringConversionSubstitution (0x0001) -#define XIMStringConversionRetrieval (0x0002) - -typedef enum { - XIMForwardChar, XIMBackwardChar, - XIMForwardWord, XIMBackwardWord, - XIMCaretUp, XIMCaretDown, - XIMNextLine, XIMPreviousLine, - XIMLineStart, XIMLineEnd, - XIMAbsolutePosition, - XIMDontChange -} XIMCaretDirection; - -typedef struct _XIMStringConversionCallbackStruct { - XIMStringConversionPosition position; - XIMCaretDirection direction; - XIMStringConversionOperation operation; - unsigned short factor; - XIMStringConversionText *text; -} XIMStringConversionCallbackStruct; - -typedef struct _XIMPreeditDrawCallbackStruct { - int caret; /* Cursor offset within pre-edit string */ - int chg_first; /* Starting change position */ - int chg_length; /* Length of the change in character count */ - XIMText *text; -} XIMPreeditDrawCallbackStruct; - -typedef enum { - XIMIsInvisible, /* Disable caret feedback */ - XIMIsPrimary, /* UI defined caret feedback */ - XIMIsSecondary /* UI defined caret feedback */ -} XIMCaretStyle; - -typedef struct _XIMPreeditCaretCallbackStruct { - int position; /* Caret offset within pre-edit string */ - XIMCaretDirection direction; /* Caret moves direction */ - XIMCaretStyle style; /* Feedback of the caret */ -} XIMPreeditCaretCallbackStruct; - -typedef enum { - XIMTextType, - XIMBitmapType -} XIMStatusDataType; - -typedef struct _XIMStatusDrawCallbackStruct { - XIMStatusDataType type; - union { - XIMText *text; - Pixmap bitmap; - } data; -} XIMStatusDrawCallbackStruct; - -typedef struct _XIMHotKeyTrigger { - KeySym keysym; - int modifier; - int modifier_mask; -} XIMHotKeyTrigger; - -typedef struct _XIMHotKeyTriggers { - int num_hot_key; - XIMHotKeyTrigger *key; -} XIMHotKeyTriggers; - -typedef unsigned long XIMHotKeyState; - -#define XIMHotKeyStateON (0x0001L) -#define XIMHotKeyStateOFF (0x0002L) - -typedef struct { - unsigned short count_values; - char **supported_values; -} XIMValuesList; - -_XFUNCPROTOBEGIN - -#if defined(WIN32) && !defined(_XLIBINT_) -#define _Xdebug (*_Xdebug_p) -#endif - -extern int _Xdebug; - -extern XFontStruct *XLoadQueryFont( - Display* /* display */, - _Xconst char* /* name */ -); - -extern XFontStruct *XQueryFont( - Display* /* display */, - XID /* font_ID */ -); - - -extern XTimeCoord *XGetMotionEvents( - Display* /* display */, - Window /* w */, - Time /* start */, - Time /* stop */, - int* /* nevents_return */ -); - -extern XModifierKeymap *XDeleteModifiermapEntry( - XModifierKeymap* /* modmap */, -#if NeedWidePrototypes - unsigned int /* keycode_entry */, -#else - KeyCode /* keycode_entry */, -#endif - int /* modifier */ -); - -extern XModifierKeymap *XGetModifierMapping( - Display* /* display */ -); - -extern XModifierKeymap *XInsertModifiermapEntry( - XModifierKeymap* /* modmap */, -#if NeedWidePrototypes - unsigned int /* keycode_entry */, -#else - KeyCode /* keycode_entry */, -#endif - int /* modifier */ -); - -extern XModifierKeymap *XNewModifiermap( - int /* max_keys_per_mod */ -); - -extern XImage *XCreateImage( - Display* /* display */, - Visual* /* visual */, - unsigned int /* depth */, - int /* format */, - int /* offset */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - int /* bitmap_pad */, - int /* bytes_per_line */ -); -extern Status XInitImage( - XImage* /* image */ -); -extern XImage *XGetImage( - Display* /* display */, - Drawable /* d */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* plane_mask */, - int /* format */ -); -extern XImage *XGetSubImage( - Display* /* display */, - Drawable /* d */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* plane_mask */, - int /* format */, - XImage* /* dest_image */, - int /* dest_x */, - int /* dest_y */ -); - -/* - * X function declarations. - */ -extern Display *XOpenDisplay( - _Xconst char* /* display_name */ -); - -extern void XrmInitialize( - void -); - -extern char *XFetchBytes( - Display* /* display */, - int* /* nbytes_return */ -); -extern char *XFetchBuffer( - Display* /* display */, - int* /* nbytes_return */, - int /* buffer */ -); -extern char *XGetAtomName( - Display* /* display */, - Atom /* atom */ -); -extern Status XGetAtomNames( - Display* /* dpy */, - Atom* /* atoms */, - int /* count */, - char** /* names_return */ -); -extern char *XGetDefault( - Display* /* display */, - _Xconst char* /* program */, - _Xconst char* /* option */ -); -extern char *XDisplayName( - _Xconst char* /* string */ -); -extern char *XKeysymToString( - KeySym /* keysym */ -); - -extern int (*XSynchronize( - Display* /* display */, - Bool /* onoff */ -))( - Display* /* display */ -); -extern int (*XSetAfterFunction( - Display* /* display */, - int (*) ( - Display* /* display */ - ) /* procedure */ -))( - Display* /* display */ -); -extern Atom XInternAtom( - Display* /* display */, - _Xconst char* /* atom_name */, - Bool /* only_if_exists */ -); -extern Status XInternAtoms( - Display* /* dpy */, - char** /* names */, - int /* count */, - Bool /* onlyIfExists */, - Atom* /* atoms_return */ -); -extern Colormap XCopyColormapAndFree( - Display* /* display */, - Colormap /* colormap */ -); -extern Colormap XCreateColormap( - Display* /* display */, - Window /* w */, - Visual* /* visual */, - int /* alloc */ -); -extern Cursor XCreatePixmapCursor( - Display* /* display */, - Pixmap /* source */, - Pixmap /* mask */, - XColor* /* foreground_color */, - XColor* /* background_color */, - unsigned int /* x */, - unsigned int /* y */ -); -extern Cursor XCreateGlyphCursor( - Display* /* display */, - Font /* source_font */, - Font /* mask_font */, - unsigned int /* source_char */, - unsigned int /* mask_char */, - XColor _Xconst * /* foreground_color */, - XColor _Xconst * /* background_color */ -); -extern Cursor XCreateFontCursor( - Display* /* display */, - unsigned int /* shape */ -); -extern Font XLoadFont( - Display* /* display */, - _Xconst char* /* name */ -); -extern GC XCreateGC( - Display* /* display */, - Drawable /* d */, - unsigned long /* valuemask */, - XGCValues* /* values */ -); -extern GContext XGContextFromGC( - GC /* gc */ -); -extern void XFlushGC( - Display* /* display */, - GC /* gc */ -); -extern Pixmap XCreatePixmap( - Display* /* display */, - Drawable /* d */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* depth */ -); -extern Pixmap XCreateBitmapFromData( - Display* /* display */, - Drawable /* d */, - _Xconst char* /* data */, - unsigned int /* width */, - unsigned int /* height */ -); -extern Pixmap XCreatePixmapFromBitmapData( - Display* /* display */, - Drawable /* d */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* fg */, - unsigned long /* bg */, - unsigned int /* depth */ -); -extern Window XCreateSimpleWindow( - Display* /* display */, - Window /* parent */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* border_width */, - unsigned long /* border */, - unsigned long /* background */ -); -extern Window XGetSelectionOwner( - Display* /* display */, - Atom /* selection */ -); -extern Window XCreateWindow( - Display* /* display */, - Window /* parent */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* border_width */, - int /* depth */, - unsigned int /* class */, - Visual* /* visual */, - unsigned long /* valuemask */, - XSetWindowAttributes* /* attributes */ -); -extern Colormap *XListInstalledColormaps( - Display* /* display */, - Window /* w */, - int* /* num_return */ -); -extern char **XListFonts( - Display* /* display */, - _Xconst char* /* pattern */, - int /* maxnames */, - int* /* actual_count_return */ -); -extern char **XListFontsWithInfo( - Display* /* display */, - _Xconst char* /* pattern */, - int /* maxnames */, - int* /* count_return */, - XFontStruct** /* info_return */ -); -extern char **XGetFontPath( - Display* /* display */, - int* /* npaths_return */ -); -extern char **XListExtensions( - Display* /* display */, - int* /* nextensions_return */ -); -extern Atom *XListProperties( - Display* /* display */, - Window /* w */, - int* /* num_prop_return */ -); -extern XHostAddress *XListHosts( - Display* /* display */, - int* /* nhosts_return */, - Bool* /* state_return */ -); -_X_DEPRECATED -extern KeySym XKeycodeToKeysym( - Display* /* display */, -#if NeedWidePrototypes - unsigned int /* keycode */, -#else - KeyCode /* keycode */, -#endif - int /* index */ -); -extern KeySym XLookupKeysym( - XKeyEvent* /* key_event */, - int /* index */ -); -extern KeySym *XGetKeyboardMapping( - Display* /* display */, -#if NeedWidePrototypes - unsigned int /* first_keycode */, -#else - KeyCode /* first_keycode */, -#endif - int /* keycode_count */, - int* /* keysyms_per_keycode_return */ -); -extern KeySym XStringToKeysym( - _Xconst char* /* string */ -); -extern long XMaxRequestSize( - Display* /* display */ -); -extern long XExtendedMaxRequestSize( - Display* /* display */ -); -extern char *XResourceManagerString( - Display* /* display */ -); -extern char *XScreenResourceString( - Screen* /* screen */ -); -extern unsigned long XDisplayMotionBufferSize( - Display* /* display */ -); -extern VisualID XVisualIDFromVisual( - Visual* /* visual */ -); - -/* multithread routines */ - -extern Status XInitThreads( - void -); - -extern void XLockDisplay( - Display* /* display */ -); - -extern void XUnlockDisplay( - Display* /* display */ -); - -/* routines for dealing with extensions */ - -extern XExtCodes *XInitExtension( - Display* /* display */, - _Xconst char* /* name */ -); - -extern XExtCodes *XAddExtension( - Display* /* display */ -); -extern XExtData *XFindOnExtensionList( - XExtData** /* structure */, - int /* number */ -); -extern XExtData **XEHeadOfExtensionList( - XEDataObject /* object */ -); - -/* these are routines for which there are also macros */ -extern Window XRootWindow( - Display* /* display */, - int /* screen_number */ -); -extern Window XDefaultRootWindow( - Display* /* display */ -); -extern Window XRootWindowOfScreen( - Screen* /* screen */ -); -extern Visual *XDefaultVisual( - Display* /* display */, - int /* screen_number */ -); -extern Visual *XDefaultVisualOfScreen( - Screen* /* screen */ -); -extern GC XDefaultGC( - Display* /* display */, - int /* screen_number */ -); -extern GC XDefaultGCOfScreen( - Screen* /* screen */ -); -extern unsigned long XBlackPixel( - Display* /* display */, - int /* screen_number */ -); -extern unsigned long XWhitePixel( - Display* /* display */, - int /* screen_number */ -); -extern unsigned long XAllPlanes( - void -); -extern unsigned long XBlackPixelOfScreen( - Screen* /* screen */ -); -extern unsigned long XWhitePixelOfScreen( - Screen* /* screen */ -); -extern unsigned long XNextRequest( - Display* /* display */ -); -extern unsigned long XLastKnownRequestProcessed( - Display* /* display */ -); -extern char *XServerVendor( - Display* /* display */ -); -extern char *XDisplayString( - Display* /* display */ -); -extern Colormap XDefaultColormap( - Display* /* display */, - int /* screen_number */ -); -extern Colormap XDefaultColormapOfScreen( - Screen* /* screen */ -); -extern Display *XDisplayOfScreen( - Screen* /* screen */ -); -extern Screen *XScreenOfDisplay( - Display* /* display */, - int /* screen_number */ -); -extern Screen *XDefaultScreenOfDisplay( - Display* /* display */ -); -extern long XEventMaskOfScreen( - Screen* /* screen */ -); - -extern int XScreenNumberOfScreen( - Screen* /* screen */ -); - -typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */ - Display* /* display */, - XErrorEvent* /* error_event */ -); - -extern XErrorHandler XSetErrorHandler ( - XErrorHandler /* handler */ -); - - -typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */ - Display* /* display */ -); - -extern XIOErrorHandler XSetIOErrorHandler ( - XIOErrorHandler /* handler */ -); - - -extern XPixmapFormatValues *XListPixmapFormats( - Display* /* display */, - int* /* count_return */ -); -extern int *XListDepths( - Display* /* display */, - int /* screen_number */, - int* /* count_return */ -); - -/* ICCCM routines for things that don't require special include files; */ -/* other declarations are given in Xutil.h */ -extern Status XReconfigureWMWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */, - unsigned int /* mask */, - XWindowChanges* /* changes */ -); - -extern Status XGetWMProtocols( - Display* /* display */, - Window /* w */, - Atom** /* protocols_return */, - int* /* count_return */ -); -extern Status XSetWMProtocols( - Display* /* display */, - Window /* w */, - Atom* /* protocols */, - int /* count */ -); -extern Status XIconifyWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */ -); -extern Status XWithdrawWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */ -); -extern Status XGetCommand( - Display* /* display */, - Window /* w */, - char*** /* argv_return */, - int* /* argc_return */ -); -extern Status XGetWMColormapWindows( - Display* /* display */, - Window /* w */, - Window** /* windows_return */, - int* /* count_return */ -); -extern Status XSetWMColormapWindows( - Display* /* display */, - Window /* w */, - Window* /* colormap_windows */, - int /* count */ -); -extern void XFreeStringList( - char** /* list */ -); -extern int XSetTransientForHint( - Display* /* display */, - Window /* w */, - Window /* prop_window */ -); - -/* The following are given in alphabetical order */ - -extern int XActivateScreenSaver( - Display* /* display */ -); - -extern int XAddHost( - Display* /* display */, - XHostAddress* /* host */ -); - -extern int XAddHosts( - Display* /* display */, - XHostAddress* /* hosts */, - int /* num_hosts */ -); - -extern int XAddToExtensionList( - struct _XExtData** /* structure */, - XExtData* /* ext_data */ -); - -extern int XAddToSaveSet( - Display* /* display */, - Window /* w */ -); - -extern Status XAllocColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* screen_in_out */ -); - -extern Status XAllocColorCells( - Display* /* display */, - Colormap /* colormap */, - Bool /* contig */, - unsigned long* /* plane_masks_return */, - unsigned int /* nplanes */, - unsigned long* /* pixels_return */, - unsigned int /* npixels */ -); - -extern Status XAllocColorPlanes( - Display* /* display */, - Colormap /* colormap */, - Bool /* contig */, - unsigned long* /* pixels_return */, - int /* ncolors */, - int /* nreds */, - int /* ngreens */, - int /* nblues */, - unsigned long* /* rmask_return */, - unsigned long* /* gmask_return */, - unsigned long* /* bmask_return */ -); - -extern Status XAllocNamedColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color_name */, - XColor* /* screen_def_return */, - XColor* /* exact_def_return */ -); - -extern int XAllowEvents( - Display* /* display */, - int /* event_mode */, - Time /* time */ -); - -extern int XAutoRepeatOff( - Display* /* display */ -); - -extern int XAutoRepeatOn( - Display* /* display */ -); - -extern int XBell( - Display* /* display */, - int /* percent */ -); - -extern int XBitmapBitOrder( - Display* /* display */ -); - -extern int XBitmapPad( - Display* /* display */ -); - -extern int XBitmapUnit( - Display* /* display */ -); - -extern int XCellsOfScreen( - Screen* /* screen */ -); - -extern int XChangeActivePointerGrab( - Display* /* display */, - unsigned int /* event_mask */, - Cursor /* cursor */, - Time /* time */ -); - -extern int XChangeGC( - Display* /* display */, - GC /* gc */, - unsigned long /* valuemask */, - XGCValues* /* values */ -); - -extern int XChangeKeyboardControl( - Display* /* display */, - unsigned long /* value_mask */, - XKeyboardControl* /* values */ -); - -extern int XChangeKeyboardMapping( - Display* /* display */, - int /* first_keycode */, - int /* keysyms_per_keycode */, - KeySym* /* keysyms */, - int /* num_codes */ -); - -extern int XChangePointerControl( - Display* /* display */, - Bool /* do_accel */, - Bool /* do_threshold */, - int /* accel_numerator */, - int /* accel_denominator */, - int /* threshold */ -); - -extern int XChangeProperty( - Display* /* display */, - Window /* w */, - Atom /* property */, - Atom /* type */, - int /* format */, - int /* mode */, - _Xconst unsigned char* /* data */, - int /* nelements */ -); - -extern int XChangeSaveSet( - Display* /* display */, - Window /* w */, - int /* change_mode */ -); - -extern int XChangeWindowAttributes( - Display* /* display */, - Window /* w */, - unsigned long /* valuemask */, - XSetWindowAttributes* /* attributes */ -); - -extern Bool XCheckIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ -); - -extern Bool XCheckMaskEvent( - Display* /* display */, - long /* event_mask */, - XEvent* /* event_return */ -); - -extern Bool XCheckTypedEvent( - Display* /* display */, - int /* event_type */, - XEvent* /* event_return */ -); - -extern Bool XCheckTypedWindowEvent( - Display* /* display */, - Window /* w */, - int /* event_type */, - XEvent* /* event_return */ -); - -extern Bool XCheckWindowEvent( - Display* /* display */, - Window /* w */, - long /* event_mask */, - XEvent* /* event_return */ -); - -extern int XCirculateSubwindows( - Display* /* display */, - Window /* w */, - int /* direction */ -); - -extern int XCirculateSubwindowsDown( - Display* /* display */, - Window /* w */ -); - -extern int XCirculateSubwindowsUp( - Display* /* display */, - Window /* w */ -); - -extern int XClearArea( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - Bool /* exposures */ -); - -extern int XClearWindow( - Display* /* display */, - Window /* w */ -); - -extern int XCloseDisplay( - Display* /* display */ -); - -extern int XConfigureWindow( - Display* /* display */, - Window /* w */, - unsigned int /* value_mask */, - XWindowChanges* /* values */ -); - -extern int XConnectionNumber( - Display* /* display */ -); - -extern int XConvertSelection( - Display* /* display */, - Atom /* selection */, - Atom /* target */, - Atom /* property */, - Window /* requestor */, - Time /* time */ -); - -extern int XCopyArea( - Display* /* display */, - Drawable /* src */, - Drawable /* dest */, - GC /* gc */, - int /* src_x */, - int /* src_y */, - unsigned int /* width */, - unsigned int /* height */, - int /* dest_x */, - int /* dest_y */ -); - -extern int XCopyGC( - Display* /* display */, - GC /* src */, - unsigned long /* valuemask */, - GC /* dest */ -); - -extern int XCopyPlane( - Display* /* display */, - Drawable /* src */, - Drawable /* dest */, - GC /* gc */, - int /* src_x */, - int /* src_y */, - unsigned int /* width */, - unsigned int /* height */, - int /* dest_x */, - int /* dest_y */, - unsigned long /* plane */ -); - -extern int XDefaultDepth( - Display* /* display */, - int /* screen_number */ -); - -extern int XDefaultDepthOfScreen( - Screen* /* screen */ -); - -extern int XDefaultScreen( - Display* /* display */ -); - -extern int XDefineCursor( - Display* /* display */, - Window /* w */, - Cursor /* cursor */ -); - -extern int XDeleteProperty( - Display* /* display */, - Window /* w */, - Atom /* property */ -); - -extern int XDestroyWindow( - Display* /* display */, - Window /* w */ -); - -extern int XDestroySubwindows( - Display* /* display */, - Window /* w */ -); - -extern int XDoesBackingStore( - Screen* /* screen */ -); - -extern Bool XDoesSaveUnders( - Screen* /* screen */ -); - -extern int XDisableAccessControl( - Display* /* display */ -); - - -extern int XDisplayCells( - Display* /* display */, - int /* screen_number */ -); - -extern int XDisplayHeight( - Display* /* display */, - int /* screen_number */ -); - -extern int XDisplayHeightMM( - Display* /* display */, - int /* screen_number */ -); - -extern int XDisplayKeycodes( - Display* /* display */, - int* /* min_keycodes_return */, - int* /* max_keycodes_return */ -); - -extern int XDisplayPlanes( - Display* /* display */, - int /* screen_number */ -); - -extern int XDisplayWidth( - Display* /* display */, - int /* screen_number */ -); - -extern int XDisplayWidthMM( - Display* /* display */, - int /* screen_number */ -); - -extern int XDrawArc( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - int /* angle1 */, - int /* angle2 */ -); - -extern int XDrawArcs( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XArc* /* arcs */, - int /* narcs */ -); - -extern int XDrawImageString( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* string */, - int /* length */ -); - -extern int XDrawImageString16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst XChar2b* /* string */, - int /* length */ -); - -extern int XDrawLine( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x1 */, - int /* y1 */, - int /* x2 */, - int /* y2 */ -); - -extern int XDrawLines( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* mode */ -); - -extern int XDrawPoint( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */ -); - -extern int XDrawPoints( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* mode */ -); - -extern int XDrawRectangle( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XDrawRectangles( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XRectangle* /* rectangles */, - int /* nrectangles */ -); - -extern int XDrawSegments( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XSegment* /* segments */, - int /* nsegments */ -); - -extern int XDrawString( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* string */, - int /* length */ -); - -extern int XDrawString16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst XChar2b* /* string */, - int /* length */ -); - -extern int XDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XTextItem* /* items */, - int /* nitems */ -); - -extern int XDrawText16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XTextItem16* /* items */, - int /* nitems */ -); - -extern int XEnableAccessControl( - Display* /* display */ -); - -extern int XEventsQueued( - Display* /* display */, - int /* mode */ -); - -extern Status XFetchName( - Display* /* display */, - Window /* w */, - char** /* window_name_return */ -); - -extern int XFillArc( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - int /* angle1 */, - int /* angle2 */ -); - -extern int XFillArcs( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XArc* /* arcs */, - int /* narcs */ -); - -extern int XFillPolygon( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* shape */, - int /* mode */ -); - -extern int XFillRectangle( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XFillRectangles( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XRectangle* /* rectangles */, - int /* nrectangles */ -); - -extern int XFlush( - Display* /* display */ -); - -extern int XForceScreenSaver( - Display* /* display */, - int /* mode */ -); - -extern int XFree( - void* /* data */ -); - -extern int XFreeColormap( - Display* /* display */, - Colormap /* colormap */ -); - -extern int XFreeColors( - Display* /* display */, - Colormap /* colormap */, - unsigned long* /* pixels */, - int /* npixels */, - unsigned long /* planes */ -); - -extern int XFreeCursor( - Display* /* display */, - Cursor /* cursor */ -); - -extern int XFreeExtensionList( - char** /* list */ -); - -extern int XFreeFont( - Display* /* display */, - XFontStruct* /* font_struct */ -); - -extern int XFreeFontInfo( - char** /* names */, - XFontStruct* /* free_info */, - int /* actual_count */ -); - -extern int XFreeFontNames( - char** /* list */ -); - -extern int XFreeFontPath( - char** /* list */ -); - -extern int XFreeGC( - Display* /* display */, - GC /* gc */ -); - -extern int XFreeModifiermap( - XModifierKeymap* /* modmap */ -); - -extern int XFreePixmap( - Display* /* display */, - Pixmap /* pixmap */ -); - -extern int XGeometry( - Display* /* display */, - int /* screen */, - _Xconst char* /* position */, - _Xconst char* /* default_position */, - unsigned int /* bwidth */, - unsigned int /* fwidth */, - unsigned int /* fheight */, - int /* xadder */, - int /* yadder */, - int* /* x_return */, - int* /* y_return */, - int* /* width_return */, - int* /* height_return */ -); - -extern int XGetErrorDatabaseText( - Display* /* display */, - _Xconst char* /* name */, - _Xconst char* /* message */, - _Xconst char* /* default_string */, - char* /* buffer_return */, - int /* length */ -); - -extern int XGetErrorText( - Display* /* display */, - int /* code */, - char* /* buffer_return */, - int /* length */ -); - -extern Bool XGetFontProperty( - XFontStruct* /* font_struct */, - Atom /* atom */, - unsigned long* /* value_return */ -); - -extern Status XGetGCValues( - Display* /* display */, - GC /* gc */, - unsigned long /* valuemask */, - XGCValues* /* values_return */ -); - -extern Status XGetGeometry( - Display* /* display */, - Drawable /* d */, - Window* /* root_return */, - int* /* x_return */, - int* /* y_return */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - unsigned int* /* border_width_return */, - unsigned int* /* depth_return */ -); - -extern Status XGetIconName( - Display* /* display */, - Window /* w */, - char** /* icon_name_return */ -); - -extern int XGetInputFocus( - Display* /* display */, - Window* /* focus_return */, - int* /* revert_to_return */ -); - -extern int XGetKeyboardControl( - Display* /* display */, - XKeyboardState* /* values_return */ -); - -extern int XGetPointerControl( - Display* /* display */, - int* /* accel_numerator_return */, - int* /* accel_denominator_return */, - int* /* threshold_return */ -); - -extern int XGetPointerMapping( - Display* /* display */, - unsigned char* /* map_return */, - int /* nmap */ -); - -extern int XGetScreenSaver( - Display* /* display */, - int* /* timeout_return */, - int* /* interval_return */, - int* /* prefer_blanking_return */, - int* /* allow_exposures_return */ -); - -extern Status XGetTransientForHint( - Display* /* display */, - Window /* w */, - Window* /* prop_window_return */ -); - -extern int XGetWindowProperty( - Display* /* display */, - Window /* w */, - Atom /* property */, - long /* long_offset */, - long /* long_length */, - Bool /* delete */, - Atom /* req_type */, - Atom* /* actual_type_return */, - int* /* actual_format_return */, - unsigned long* /* nitems_return */, - unsigned long* /* bytes_after_return */, - unsigned char** /* prop_return */ -); - -extern Status XGetWindowAttributes( - Display* /* display */, - Window /* w */, - XWindowAttributes* /* window_attributes_return */ -); - -extern int XGrabButton( - Display* /* display */, - unsigned int /* button */, - unsigned int /* modifiers */, - Window /* grab_window */, - Bool /* owner_events */, - unsigned int /* event_mask */, - int /* pointer_mode */, - int /* keyboard_mode */, - Window /* confine_to */, - Cursor /* cursor */ -); - -extern int XGrabKey( - Display* /* display */, - int /* keycode */, - unsigned int /* modifiers */, - Window /* grab_window */, - Bool /* owner_events */, - int /* pointer_mode */, - int /* keyboard_mode */ -); - -extern int XGrabKeyboard( - Display* /* display */, - Window /* grab_window */, - Bool /* owner_events */, - int /* pointer_mode */, - int /* keyboard_mode */, - Time /* time */ -); - -extern int XGrabPointer( - Display* /* display */, - Window /* grab_window */, - Bool /* owner_events */, - unsigned int /* event_mask */, - int /* pointer_mode */, - int /* keyboard_mode */, - Window /* confine_to */, - Cursor /* cursor */, - Time /* time */ -); - -extern int XGrabServer( - Display* /* display */ -); - -extern int XHeightMMOfScreen( - Screen* /* screen */ -); - -extern int XHeightOfScreen( - Screen* /* screen */ -); - -extern int XIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ -); - -extern int XImageByteOrder( - Display* /* display */ -); - -extern int XInstallColormap( - Display* /* display */, - Colormap /* colormap */ -); - -extern KeyCode XKeysymToKeycode( - Display* /* display */, - KeySym /* keysym */ -); - -extern int XKillClient( - Display* /* display */, - XID /* resource */ -); - -extern Status XLookupColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color_name */, - XColor* /* exact_def_return */, - XColor* /* screen_def_return */ -); - -extern int XLowerWindow( - Display* /* display */, - Window /* w */ -); - -extern int XMapRaised( - Display* /* display */, - Window /* w */ -); - -extern int XMapSubwindows( - Display* /* display */, - Window /* w */ -); - -extern int XMapWindow( - Display* /* display */, - Window /* w */ -); - -extern int XMaskEvent( - Display* /* display */, - long /* event_mask */, - XEvent* /* event_return */ -); - -extern int XMaxCmapsOfScreen( - Screen* /* screen */ -); - -extern int XMinCmapsOfScreen( - Screen* /* screen */ -); - -extern int XMoveResizeWindow( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XMoveWindow( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */ -); - -extern int XNextEvent( - Display* /* display */, - XEvent* /* event_return */ -); - -extern int XNoOp( - Display* /* display */ -); - -extern Status XParseColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* spec */, - XColor* /* exact_def_return */ -); - -extern int XParseGeometry( - _Xconst char* /* parsestring */, - int* /* x_return */, - int* /* y_return */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ -); - -extern int XPeekEvent( - Display* /* display */, - XEvent* /* event_return */ -); - -extern int XPeekIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ -); - -extern int XPending( - Display* /* display */ -); - -extern int XPlanesOfScreen( - Screen* /* screen */ -); - -extern int XProtocolRevision( - Display* /* display */ -); - -extern int XProtocolVersion( - Display* /* display */ -); - - -extern int XPutBackEvent( - Display* /* display */, - XEvent* /* event */ -); - -extern int XPutImage( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XImage* /* image */, - int /* src_x */, - int /* src_y */, - int /* dest_x */, - int /* dest_y */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XQLength( - Display* /* display */ -); - -extern Status XQueryBestCursor( - Display* /* display */, - Drawable /* d */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ -); - -extern Status XQueryBestSize( - Display* /* display */, - int /* class */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ -); - -extern Status XQueryBestStipple( - Display* /* display */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ -); - -extern Status XQueryBestTile( - Display* /* display */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ -); - -extern int XQueryColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* def_in_out */ -); - -extern int XQueryColors( - Display* /* display */, - Colormap /* colormap */, - XColor* /* defs_in_out */, - int /* ncolors */ -); - -extern Bool XQueryExtension( - Display* /* display */, - _Xconst char* /* name */, - int* /* major_opcode_return */, - int* /* first_event_return */, - int* /* first_error_return */ -); - -extern int XQueryKeymap( - Display* /* display */, - char [32] /* keys_return */ -); - -extern Bool XQueryPointer( - Display* /* display */, - Window /* w */, - Window* /* root_return */, - Window* /* child_return */, - int* /* root_x_return */, - int* /* root_y_return */, - int* /* win_x_return */, - int* /* win_y_return */, - unsigned int* /* mask_return */ -); - -extern int XQueryTextExtents( - Display* /* display */, - XID /* font_ID */, - _Xconst char* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ -); - -extern int XQueryTextExtents16( - Display* /* display */, - XID /* font_ID */, - _Xconst XChar2b* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ -); - -extern Status XQueryTree( - Display* /* display */, - Window /* w */, - Window* /* root_return */, - Window* /* parent_return */, - Window** /* children_return */, - unsigned int* /* nchildren_return */ -); - -extern int XRaiseWindow( - Display* /* display */, - Window /* w */ -); - -extern int XReadBitmapFile( - Display* /* display */, - Drawable /* d */, - _Xconst char* /* filename */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - Pixmap* /* bitmap_return */, - int* /* x_hot_return */, - int* /* y_hot_return */ -); - -extern int XReadBitmapFileData( - _Xconst char* /* filename */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - unsigned char** /* data_return */, - int* /* x_hot_return */, - int* /* y_hot_return */ -); - -extern int XRebindKeysym( - Display* /* display */, - KeySym /* keysym */, - KeySym* /* list */, - int /* mod_count */, - _Xconst unsigned char* /* string */, - int /* bytes_string */ -); - -extern int XRecolorCursor( - Display* /* display */, - Cursor /* cursor */, - XColor* /* foreground_color */, - XColor* /* background_color */ -); - -extern int XRefreshKeyboardMapping( - XMappingEvent* /* event_map */ -); - -extern int XRemoveFromSaveSet( - Display* /* display */, - Window /* w */ -); - -extern int XRemoveHost( - Display* /* display */, - XHostAddress* /* host */ -); - -extern int XRemoveHosts( - Display* /* display */, - XHostAddress* /* hosts */, - int /* num_hosts */ -); - -extern int XReparentWindow( - Display* /* display */, - Window /* w */, - Window /* parent */, - int /* x */, - int /* y */ -); - -extern int XResetScreenSaver( - Display* /* display */ -); - -extern int XResizeWindow( - Display* /* display */, - Window /* w */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XRestackWindows( - Display* /* display */, - Window* /* windows */, - int /* nwindows */ -); - -extern int XRotateBuffers( - Display* /* display */, - int /* rotate */ -); - -extern int XRotateWindowProperties( - Display* /* display */, - Window /* w */, - Atom* /* properties */, - int /* num_prop */, - int /* npositions */ -); - -extern int XScreenCount( - Display* /* display */ -); - -extern int XSelectInput( - Display* /* display */, - Window /* w */, - long /* event_mask */ -); - -extern Status XSendEvent( - Display* /* display */, - Window /* w */, - Bool /* propagate */, - long /* event_mask */, - XEvent* /* event_send */ -); - -extern int XSetAccessControl( - Display* /* display */, - int /* mode */ -); - -extern int XSetArcMode( - Display* /* display */, - GC /* gc */, - int /* arc_mode */ -); - -extern int XSetBackground( - Display* /* display */, - GC /* gc */, - unsigned long /* background */ -); - -extern int XSetClipMask( - Display* /* display */, - GC /* gc */, - Pixmap /* pixmap */ -); - -extern int XSetClipOrigin( - Display* /* display */, - GC /* gc */, - int /* clip_x_origin */, - int /* clip_y_origin */ -); - -extern int XSetClipRectangles( - Display* /* display */, - GC /* gc */, - int /* clip_x_origin */, - int /* clip_y_origin */, - XRectangle* /* rectangles */, - int /* n */, - int /* ordering */ -); - -extern int XSetCloseDownMode( - Display* /* display */, - int /* close_mode */ -); - -extern int XSetCommand( - Display* /* display */, - Window /* w */, - char** /* argv */, - int /* argc */ -); - -extern int XSetDashes( - Display* /* display */, - GC /* gc */, - int /* dash_offset */, - _Xconst char* /* dash_list */, - int /* n */ -); - -extern int XSetFillRule( - Display* /* display */, - GC /* gc */, - int /* fill_rule */ -); - -extern int XSetFillStyle( - Display* /* display */, - GC /* gc */, - int /* fill_style */ -); - -extern int XSetFont( - Display* /* display */, - GC /* gc */, - Font /* font */ -); - -extern int XSetFontPath( - Display* /* display */, - char** /* directories */, - int /* ndirs */ -); - -extern int XSetForeground( - Display* /* display */, - GC /* gc */, - unsigned long /* foreground */ -); - -extern int XSetFunction( - Display* /* display */, - GC /* gc */, - int /* function */ -); - -extern int XSetGraphicsExposures( - Display* /* display */, - GC /* gc */, - Bool /* graphics_exposures */ -); - -extern int XSetIconName( - Display* /* display */, - Window /* w */, - _Xconst char* /* icon_name */ -); - -extern int XSetInputFocus( - Display* /* display */, - Window /* focus */, - int /* revert_to */, - Time /* time */ -); - -extern int XSetLineAttributes( - Display* /* display */, - GC /* gc */, - unsigned int /* line_width */, - int /* line_style */, - int /* cap_style */, - int /* join_style */ -); - -extern int XSetModifierMapping( - Display* /* display */, - XModifierKeymap* /* modmap */ -); - -extern int XSetPlaneMask( - Display* /* display */, - GC /* gc */, - unsigned long /* plane_mask */ -); - -extern int XSetPointerMapping( - Display* /* display */, - _Xconst unsigned char* /* map */, - int /* nmap */ -); - -extern int XSetScreenSaver( - Display* /* display */, - int /* timeout */, - int /* interval */, - int /* prefer_blanking */, - int /* allow_exposures */ -); - -extern int XSetSelectionOwner( - Display* /* display */, - Atom /* selection */, - Window /* owner */, - Time /* time */ -); - -extern int XSetState( - Display* /* display */, - GC /* gc */, - unsigned long /* foreground */, - unsigned long /* background */, - int /* function */, - unsigned long /* plane_mask */ -); - -extern int XSetStipple( - Display* /* display */, - GC /* gc */, - Pixmap /* stipple */ -); - -extern int XSetSubwindowMode( - Display* /* display */, - GC /* gc */, - int /* subwindow_mode */ -); - -extern int XSetTSOrigin( - Display* /* display */, - GC /* gc */, - int /* ts_x_origin */, - int /* ts_y_origin */ -); - -extern int XSetTile( - Display* /* display */, - GC /* gc */, - Pixmap /* tile */ -); - -extern int XSetWindowBackground( - Display* /* display */, - Window /* w */, - unsigned long /* background_pixel */ -); - -extern int XSetWindowBackgroundPixmap( - Display* /* display */, - Window /* w */, - Pixmap /* background_pixmap */ -); - -extern int XSetWindowBorder( - Display* /* display */, - Window /* w */, - unsigned long /* border_pixel */ -); - -extern int XSetWindowBorderPixmap( - Display* /* display */, - Window /* w */, - Pixmap /* border_pixmap */ -); - -extern int XSetWindowBorderWidth( - Display* /* display */, - Window /* w */, - unsigned int /* width */ -); - -extern int XSetWindowColormap( - Display* /* display */, - Window /* w */, - Colormap /* colormap */ -); - -extern int XStoreBuffer( - Display* /* display */, - _Xconst char* /* bytes */, - int /* nbytes */, - int /* buffer */ -); - -extern int XStoreBytes( - Display* /* display */, - _Xconst char* /* bytes */, - int /* nbytes */ -); - -extern int XStoreColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* color */ -); - -extern int XStoreColors( - Display* /* display */, - Colormap /* colormap */, - XColor* /* color */, - int /* ncolors */ -); - -extern int XStoreName( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */ -); - -extern int XStoreNamedColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color */, - unsigned long /* pixel */, - int /* flags */ -); - -extern int XSync( - Display* /* display */, - Bool /* discard */ -); - -extern int XTextExtents( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ -); - -extern int XTextExtents16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ -); - -extern int XTextWidth( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* count */ -); - -extern int XTextWidth16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* count */ -); - -extern Bool XTranslateCoordinates( - Display* /* display */, - Window /* src_w */, - Window /* dest_w */, - int /* src_x */, - int /* src_y */, - int* /* dest_x_return */, - int* /* dest_y_return */, - Window* /* child_return */ -); - -extern int XUndefineCursor( - Display* /* display */, - Window /* w */ -); - -extern int XUngrabButton( - Display* /* display */, - unsigned int /* button */, - unsigned int /* modifiers */, - Window /* grab_window */ -); - -extern int XUngrabKey( - Display* /* display */, - int /* keycode */, - unsigned int /* modifiers */, - Window /* grab_window */ -); - -extern int XUngrabKeyboard( - Display* /* display */, - Time /* time */ -); - -extern int XUngrabPointer( - Display* /* display */, - Time /* time */ -); - -extern int XUngrabServer( - Display* /* display */ -); - -extern int XUninstallColormap( - Display* /* display */, - Colormap /* colormap */ -); - -extern int XUnloadFont( - Display* /* display */, - Font /* font */ -); - -extern int XUnmapSubwindows( - Display* /* display */, - Window /* w */ -); - -extern int XUnmapWindow( - Display* /* display */, - Window /* w */ -); - -extern int XVendorRelease( - Display* /* display */ -); - -extern int XWarpPointer( - Display* /* display */, - Window /* src_w */, - Window /* dest_w */, - int /* src_x */, - int /* src_y */, - unsigned int /* src_width */, - unsigned int /* src_height */, - int /* dest_x */, - int /* dest_y */ -); - -extern int XWidthMMOfScreen( - Screen* /* screen */ -); - -extern int XWidthOfScreen( - Screen* /* screen */ -); - -extern int XWindowEvent( - Display* /* display */, - Window /* w */, - long /* event_mask */, - XEvent* /* event_return */ -); - -extern int XWriteBitmapFile( - Display* /* display */, - _Xconst char* /* filename */, - Pixmap /* bitmap */, - unsigned int /* width */, - unsigned int /* height */, - int /* x_hot */, - int /* y_hot */ -); - -extern Bool XSupportsLocale (void); - -extern char *XSetLocaleModifiers( - const char* /* modifier_list */ -); - -extern XOM XOpenOM( - Display* /* display */, - struct _XrmHashBucketRec* /* rdb */, - _Xconst char* /* res_name */, - _Xconst char* /* res_class */ -); - -extern Status XCloseOM( - XOM /* om */ -); - -extern char *XSetOMValues( - XOM /* om */, - ... -) _X_SENTINEL(0); - -extern char *XGetOMValues( - XOM /* om */, - ... -) _X_SENTINEL(0); - -extern Display *XDisplayOfOM( - XOM /* om */ -); - -extern char *XLocaleOfOM( - XOM /* om */ -); - -extern XOC XCreateOC( - XOM /* om */, - ... -) _X_SENTINEL(0); - -extern void XDestroyOC( - XOC /* oc */ -); - -extern XOM XOMOfOC( - XOC /* oc */ -); - -extern char *XSetOCValues( - XOC /* oc */, - ... -) _X_SENTINEL(0); - -extern char *XGetOCValues( - XOC /* oc */, - ... -) _X_SENTINEL(0); - -extern XFontSet XCreateFontSet( - Display* /* display */, - _Xconst char* /* base_font_name_list */, - char*** /* missing_charset_list */, - int* /* missing_charset_count */, - char** /* def_string */ -); - -extern void XFreeFontSet( - Display* /* display */, - XFontSet /* font_set */ -); - -extern int XFontsOfFontSet( - XFontSet /* font_set */, - XFontStruct*** /* font_struct_list */, - char*** /* font_name_list */ -); - -extern char *XBaseFontNameListOfFontSet( - XFontSet /* font_set */ -); - -extern char *XLocaleOfFontSet( - XFontSet /* font_set */ -); - -extern Bool XContextDependentDrawing( - XFontSet /* font_set */ -); - -extern Bool XDirectionalDependentDrawing( - XFontSet /* font_set */ -); - -extern Bool XContextualDrawing( - XFontSet /* font_set */ -); - -extern XFontSetExtents *XExtentsOfFontSet( - XFontSet /* font_set */ -); - -extern int XmbTextEscapement( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern int XwcTextEscapement( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ -); - -extern int Xutf8TextEscapement( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern int XmbTextExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern int XwcTextExtents( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern int Xutf8TextExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern Status XmbTextPerCharExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern Status XwcTextPerCharExtents( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern Status Xutf8TextPerCharExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ -); - -extern void XmbDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XmbTextItem* /* text_items */, - int /* nitems */ -); - -extern void XwcDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XwcTextItem* /* text_items */, - int /* nitems */ -); - -extern void Xutf8DrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XmbTextItem* /* text_items */, - int /* nitems */ -); - -extern void XmbDrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern void XwcDrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ -); - -extern void Xutf8DrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern void XmbDrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern void XwcDrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ -); - -extern void Xutf8DrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ -); - -extern XIM XOpenIM( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */ -); - -extern Status XCloseIM( - XIM /* im */ -); - -extern char *XGetIMValues( - XIM /* im */, ... -) _X_SENTINEL(0); - -extern char *XSetIMValues( - XIM /* im */, ... -) _X_SENTINEL(0); - -extern Display *XDisplayOfIM( - XIM /* im */ -); - -extern char *XLocaleOfIM( - XIM /* im*/ -); - -extern XIC XCreateIC( - XIM /* im */, ... -) _X_SENTINEL(0); - -extern void XDestroyIC( - XIC /* ic */ -); - -extern void XSetICFocus( - XIC /* ic */ -); - -extern void XUnsetICFocus( - XIC /* ic */ -); - -extern wchar_t *XwcResetIC( - XIC /* ic */ -); - -extern char *XmbResetIC( - XIC /* ic */ -); - -extern char *Xutf8ResetIC( - XIC /* ic */ -); - -extern char *XSetICValues( - XIC /* ic */, ... -) _X_SENTINEL(0); - -extern char *XGetICValues( - XIC /* ic */, ... -) _X_SENTINEL(0); - -extern XIM XIMOfIC( - XIC /* ic */ -); - -extern Bool XFilterEvent( - XEvent* /* event */, - Window /* window */ -); - -extern int XmbLookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ -); - -extern int XwcLookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - wchar_t* /* buffer_return */, - int /* wchars_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ -); - -extern int Xutf8LookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ -); - -extern XVaNestedList XVaCreateNestedList( - int /*unused*/, ... -) _X_SENTINEL(0); - -/* internal connections for IMs */ - -extern Bool XRegisterIMInstantiateCallback( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */, - XIDProc /* callback */, - XPointer /* client_data */ -); - -extern Bool XUnregisterIMInstantiateCallback( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */, - XIDProc /* callback */, - XPointer /* client_data */ -); - -typedef void (*XConnectionWatchProc)( - Display* /* dpy */, - XPointer /* client_data */, - int /* fd */, - Bool /* opening */, /* open or close flag */ - XPointer* /* watch_data */ /* open sets, close uses */ -); - - -extern Status XInternalConnectionNumbers( - Display* /* dpy */, - int** /* fd_return */, - int* /* count_return */ -); - -extern void XProcessInternalConnection( - Display* /* dpy */, - int /* fd */ -); - -extern Status XAddConnectionWatch( - Display* /* dpy */, - XConnectionWatchProc /* callback */, - XPointer /* client_data */ -); - -extern void XRemoveConnectionWatch( - Display* /* dpy */, - XConnectionWatchProc /* callback */, - XPointer /* client_data */ -); - -extern void XSetAuthorization( - char * /* name */, - int /* namelen */, - char * /* data */, - int /* datalen */ -); - -extern int _Xmbtowc( - wchar_t * /* wstr */, -#ifdef ISC - char const * /* str */, - size_t /* len */ -#else - char * /* str */, - int /* len */ -#endif -); - -extern int _Xwctomb( - char * /* str */, - wchar_t /* wc */ -); - -extern Bool XGetEventData( - Display* /* dpy */, - XGenericEventCookie* /* cookie*/ -); - -extern void XFreeEventData( - Display* /* dpy */, - XGenericEventCookie* /* cookie*/ -); - -_XFUNCPROTOEND - -#endif /* _X11_XLIB_H_ */ diff --git a/shell/linux-deps/include/X11/XlibConf.h b/shell/linux-deps/include/X11/XlibConf.h deleted file mode 100644 index 9f9b94031..000000000 --- a/shell/linux-deps/include/X11/XlibConf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* include/X11/XlibConf.h. Generated from XlibConf.h.in by configure. */ -/* - * Copyright © 2005 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _XLIBCONF_H_ -#define _XLIBCONF_H_ -/* - * This header file exports defines necessary to correctly - * use Xlibint.h both inside Xlib and by external libraries - * such as extensions. - */ - -/* Threading support? */ -#define XTHREADS 1 - -/* Use multi-threaded libc functions? */ -#define XUSE_MTSAFE_API 1 - -#endif /* _XLIBCONF_H_ */ diff --git a/shell/linux-deps/include/X11/Xlibint.h b/shell/linux-deps/include/X11/Xlibint.h deleted file mode 100644 index 80edeec9a..000000000 --- a/shell/linux-deps/include/X11/Xlibint.h +++ /dev/null @@ -1,1369 +0,0 @@ - -/* - -Copyright 1984, 1985, 1987, 1989, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -#ifndef _X11_XLIBINT_H_ -#define _X11_XLIBINT_H_ 1 - -/* - * Xlibint.h - Header definition and support file for the internal - * support routines used by the C subroutine interface - * library (Xlib) to the X Window System. - * - * Warning, there be dragons here.... - */ - -#include -#include /* to declare xEvent */ -#include /* for configured options like XTHREADS */ - -#ifdef WIN32 -#define _XFlush _XFlushIt -#endif - -/* - * If your BytesReadable correctly detects broken connections, then - * you should NOT define XCONN_CHECK_FREQ. - */ -#ifndef XCONN_CHECK_FREQ -#define XCONN_CHECK_FREQ 256 -#endif - -struct _XGC -{ - XExtData *ext_data; /* hook for extension to hang data */ - GContext gid; /* protocol ID for graphics context */ - Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ - Bool dashes; /* boolean: TRUE if dash-list is really a list */ - unsigned long dirty;/* cache dirty bits */ - XGCValues values; /* shadow structure of values */ -}; - -struct _XDisplay -{ - XExtData *ext_data; /* hook for extension to hang data */ - struct _XFreeFuncs *free_funcs; /* internal free functions */ - int fd; /* Network socket. */ - int conn_checker; /* ugly thing used by _XEventsQueued */ - int proto_major_version;/* maj. version of server's X protocol */ - int proto_minor_version;/* minor version of server's X protocol */ - char *vendor; /* vendor of the server hardware */ - XID resource_base; /* resource ID base */ - XID resource_mask; /* resource ID mask bits */ - XID resource_id; /* allocator current ID */ - int resource_shift; /* allocator shift to correct bits */ - XID (*resource_alloc)( /* allocator function */ - struct _XDisplay* - ); - int byte_order; /* screen byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* padding and data requirements */ - int bitmap_pad; /* padding requirements on bitmaps */ - int bitmap_bit_order; /* LeastSignificant or MostSignificant */ - int nformats; /* number of pixmap formats in list */ - ScreenFormat *pixmap_format; /* pixmap format list */ - int vnumber; /* Xlib's X protocol version number. */ - int release; /* release of the server */ - struct _XSQEvent *head, *tail; /* Input event queue. */ - int qlen; /* Length of input event queue */ - unsigned long last_request_read; /* seq number of last event read */ - unsigned long request; /* sequence number of last request. */ - char *last_req; /* beginning of last request, or dummy */ - char *buffer; /* Output buffer starting address. */ - char *bufptr; /* Output buffer index pointer. */ - char *bufmax; /* Output buffer maximum+1 address. */ - unsigned max_request_size; /* maximum number 32 bit words in request*/ - struct _XrmHashBucketRec *db; - int (*synchandler)( /* Synchronization handler */ - struct _XDisplay* - ); - char *display_name; /* "host:display" string used on this connect*/ - int default_screen; /* default screen for operations */ - int nscreens; /* number of screens on this server*/ - Screen *screens; /* pointer to list of screens */ - unsigned long motion_buffer; /* size of motion buffer */ - volatile unsigned long flags; /* internal connection flags */ - int min_keycode; /* minimum defined keycode */ - int max_keycode; /* maximum defined keycode */ - KeySym *keysyms; /* This server's keysyms */ - XModifierKeymap *modifiermap; /* This server's modifier keymap */ - int keysyms_per_keycode;/* number of rows */ - char *xdefaults; /* contents of defaults from server */ - char *scratch_buffer; /* place to hang scratch buffer */ - unsigned long scratch_length; /* length of scratch buffer */ - int ext_number; /* extension number on this display */ - struct _XExten *ext_procs; /* extensions initialized on this display */ - /* - * the following can be fixed size, as the protocol defines how - * much address space is available. - * While this could be done using the extension vector, there - * may be MANY events processed, so a search through the extension - * list to find the right procedure for each event might be - * expensive if many extensions are being used. - */ - Bool (*event_vec[128])( /* vector for wire to event */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - Status (*wire_vec[128])( /* vector for event to wire */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - KeySym lock_meaning; /* for XLookupString */ - struct _XLockInfo *lock; /* multi-thread state, display lock */ - struct _XInternalAsync *async_handlers; /* for internal async */ - unsigned long bigreq_size; /* max size of big requests */ - struct _XLockPtrs *lock_fns; /* pointers to threads functions */ - void (*idlist_alloc)( /* XID list allocator function */ - Display * /* dpy */, - XID * /* ids */, - int /* count */ - ); - /* things above this line should not move, for binary compatibility */ - struct _XKeytrans *key_bindings; /* for XLookupString */ - Font cursor_font; /* for XCreateFontCursor */ - struct _XDisplayAtoms *atoms; /* for XInternAtom */ - unsigned int mode_switch; /* keyboard group modifiers */ - unsigned int num_lock; /* keyboard numlock modifiers */ - struct _XContextDB *context_db; /* context database */ - Bool (**error_vec)( /* vector for wire to error */ - Display * /* display */, - XErrorEvent * /* he */, - xError * /* we */ - ); - /* - * Xcms information - */ - struct { - XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ - XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ - XPointer perVisualIntensityMaps; - /* linked list of XcmsIntensityMap */ - } cms; - struct _XIMFilter *im_filters; - struct _XSQEvent *qfree; /* unallocated event queue elements */ - unsigned long next_event_serial_num; /* inserted into next queue elt */ - struct _XExten *flushes; /* Flush hooks */ - struct _XConnectionInfo *im_fd_info; /* _XRegisterInternalConnection */ - int im_fd_length; /* number of im_fd_info */ - struct _XConnWatchInfo *conn_watchers; /* XAddConnectionWatch */ - int watcher_count; /* number of conn_watchers */ - XPointer filedes; /* struct pollfd cache for _XWaitForReadable */ - int (*savedsynchandler)( /* user synchandler when Xlib usurps */ - Display * /* dpy */ - ); - XID resource_max; /* allocator max ID */ - int xcmisc_opcode; /* major opcode for XC-MISC */ - struct _XkbInfoRec *xkb_info; /* XKB info */ - struct _XtransConnInfo *trans_conn; /* transport connection object */ - struct _X11XCBPrivate *xcb; /* XCB glue private data */ - - /* Generic event cookie handling */ - unsigned int next_cookie; /* next event cookie */ - /* vector for wire to generic event, index is (extension - 128) */ - Bool (*generic_event_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* Xlib event */, - xEvent * /* wire event */); - /* vector for event copy, index is (extension - 128) */ - Bool (*generic_event_copy_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* in */, - XGenericEventCookie * /* out*/); - void *cookiejar; /* cookie events returned but not claimed */ -}; - -#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) - -/* - * define the following if you want the Data macro to be a procedure instead - */ -#ifdef CRAY -#define DataRoutineIsProcedure -#endif /* CRAY */ - -#ifndef _XEVENT_ -/* - * _QEvent datatype for use in input queueing. - */ -typedef struct _XSQEvent -{ - struct _XSQEvent *next; - XEvent event; - unsigned long qserial_num; /* so multi-threaded code can find new ones */ -} _XQEvent; -#endif - -#include -#ifdef __sgi -#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ -#endif -#include -#define _XBCOPYFUNC _Xbcopy -#include -#include - -/* Utek leaves kernel macros around in include files (bleah) */ -#ifdef dirty -#undef dirty -#endif - -#include -#include - -#include - -_XFUNCPROTOBEGIN - -/* - * The following definitions can be used for locking requests in multi-threaded - * address spaces. - */ -#ifdef XTHREADS -/* Author: Stephen Gildea, MIT X Consortium - * - * declarations for C Threads locking - */ - -typedef struct _LockInfoRec *LockInfoPtr; - -/* interfaces for locking.c */ -struct _XLockPtrs { - /* used by all, including extensions; do not move */ - void (*lock_display)( - Display *dpy -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line -#endif - ); - void (*unlock_display)( - Display *dpy -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line -#endif - ); -}; - -#if defined(WIN32) && !defined(_XLIBINT_) -#define _XCreateMutex_fn (*_XCreateMutex_fn_p) -#define _XFreeMutex_fn (*_XFreeMutex_fn_p) -#define _XLockMutex_fn (*_XLockMutex_fn_p) -#define _XUnlockMutex_fn (*_XUnlockMutex_fn_p) -#define _Xglobal_lock (*_Xglobal_lock_p) -#endif - -/* in XlibInt.c */ -extern void (*_XCreateMutex_fn)( - LockInfoPtr /* lock */ -); -extern void (*_XFreeMutex_fn)( - LockInfoPtr /* lock */ -); -extern void (*_XLockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif -); -extern void (*_XUnlockMutex_fn)( - LockInfoPtr /* lock */ -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ -#endif -); - -extern LockInfoPtr _Xglobal_lock; - -#if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d),__FILE__,__LINE__) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d),__FILE__,__LINE__) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock,__FILE__,__LINE__) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock,__FILE__,__LINE__) -#else -/* used everywhere, so must be fast if not using threads */ -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock) -#endif -#define _XCreateMutex(lock) if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock); -#define _XFreeMutex(lock) if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock); - -#else /* XTHREADS */ -#define LockDisplay(dis) -#define _XLockMutex(lock) -#define _XUnlockMutex(lock) -#define UnlockDisplay(dis) -#define _XCreateMutex(lock) -#define _XFreeMutex(lock) -#endif - -#define Xfree(ptr) free((ptr)) - -/* - * Note that some machines do not return a valid pointer for malloc(0), in - * which case we provide an alternate under the control of the - * define MALLOC_0_RETURNS_NULL. This is necessary because some - * Xlib code expects malloc(0) to return a valid pointer to storage. - */ -#if defined(MALLOC_0_RETURNS_NULL) || defined(__clang_analyzer__) - -# define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) -# define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) -# define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) - -#else - -# define Xmalloc(size) malloc((size)) -# define Xrealloc(ptr, size) realloc((ptr), (size)) -# define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) - -#endif - -#include - -#define LOCKED 1 -#define UNLOCKED 0 - -#ifndef BUFSIZE -#define BUFSIZE 2048 /* X output buffer size. */ -#endif -#ifndef PTSPERBATCH -#define PTSPERBATCH 1024 /* point batching */ -#endif -#ifndef WLNSPERBATCH -#define WLNSPERBATCH 50 /* wide line batching */ -#endif -#ifndef ZLNSPERBATCH -#define ZLNSPERBATCH 1024 /* thin line batching */ -#endif -#ifndef WRCTSPERBATCH -#define WRCTSPERBATCH 10 /* wide line rectangle batching */ -#endif -#ifndef ZRCTSPERBATCH -#define ZRCTSPERBATCH 256 /* thin line rectangle batching */ -#endif -#ifndef FRCTSPERBATCH -#define FRCTSPERBATCH 256 /* filled rectangle batching */ -#endif -#ifndef FARCSPERBATCH -#define FARCSPERBATCH 256 /* filled arc batching */ -#endif -#ifndef CURSORFONT -#define CURSORFONT "cursor" /* standard cursor fonts */ -#endif - -/* - * Display flags - */ -#define XlibDisplayIOError (1L << 0) -#define XlibDisplayClosing (1L << 1) -#define XlibDisplayNoXkb (1L << 2) -#define XlibDisplayPrivSync (1L << 3) -#define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */ -#define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */ -#define XlibDisplayReply (1L << 5) /* in _XReply */ -#define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */ -#define XlibDisplayDfltRMDB (1L << 7) /* mark if RM db from XGetDefault */ - -/* - * X Protocol packetizing macros. - */ - -/* Need to start requests on 64 bit word boundaries - * on a CRAY computer so add a NoOp (127) if needed. - * A character pointer on a CRAY computer will be non-zero - * after shifting right 61 bits of it is not pointing to - * a word boundary. - */ -#ifdef WORD64 -#define WORD64ALIGN if ((long)dpy->bufptr >> 61) {\ - dpy->last_req = dpy->bufptr;\ - *(dpy->bufptr) = X_NoOperation;\ - *(dpy->bufptr+1) = 0;\ - *(dpy->bufptr+2) = 0;\ - *(dpy->bufptr+3) = 1;\ - dpy->request++;\ - dpy->bufptr += 4;\ - } -#else /* else does not require alignment on 64-bit boundaries */ -#define WORD64ALIGN -#endif /* WORD64 */ - -/** - * Return a len-sized request buffer for the request type. This function may - * flush the output queue. - * - * @param dpy The display connection - * @param type The request type - * @param len Length of the request in bytes - * - * @returns A pointer to the request buffer with a few default values - * initialized. - */ -extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); - -/* GetReqSized is the same as GetReq but allows the caller to specify the - * size in bytes. 'sz' must be a multiple of 4! */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetReqSized(name, sz, req) \ - req = (x##name##Req *) _XGetRequest(dpy, X_##name, sz) -#else -#define GetReqSized(name, sz, req) \ - req = (x/**/name/**/Req *) _XGetRequest(dpy, X_/**/name, sz) -#endif - - -/* - * GetReq - Get the next available X request packet in the buffer and - * return it. - * - * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc. - * "req" is the name of the request pointer. - * - */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetReq(name, req) \ - GetReqSized(name, SIZEOF(x##name##Req), req) -#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ -#define GetReq(name, req) \ - GetReqSized(name, SIZEOF(x/**/name/**/Req), req) -#endif - -/* GetReqExtra is the same as GetReq, but allocates "n" additional - bytes after the request. "n" must be a multiple of 4! */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetReqExtra(name, n, req) \ - GetReqSized(name, SIZEOF(x##name##Req) + n, req) -#else -#define GetReqExtra(name, n, req) \ - GetReqSized(name, SIZEOF(x/**/name/**/Req) + n, req) -#endif - - -/* - * GetResReq is for those requests that have a resource ID - * (Window, Pixmap, GContext, etc.) as their single argument. - * "rid" is the name of the resource. - */ - -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetResReq(name, rid, req) \ - req = (xResourceReq *) _XGetRequest(dpy, X_##name, SIZEOF(xResourceReq)); \ - req->id = (rid) -#else -#define GetResReq(name, rid, req) \ - req = (xResourceReq *) _XGetRequest(dpy, X_/**/name, SIZEOF(xResourceReq)); \ - req->id = (rid) -#endif - -/* - * GetEmptyReq is for those requests that have no arguments - * at all. - */ -#if !defined(UNIXCPP) || defined(ANSICPP) -#define GetEmptyReq(name, req) \ - req = (xReq *) _XGetRequest(dpy, X_##name, SIZEOF(xReq)) -#else -#define GetEmptyReq(name, req) \ - req = (xReq *) _XGetRequest(dpy, X_/**/name, SIZEOF(xReq)) -#endif - -#ifdef WORD64 -#define MakeBigReq(req,n) \ - { \ - char _BRdat[4]; \ - unsigned long _BRlen = req->length - 1; \ - req->length = 0; \ - memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - memcpy(((char *)req) + 4, _BRdat, 4); \ - Data32(dpy, (long *)&_BRdat, 4); \ - } -#else -#ifdef LONG64 -#define MakeBigReq(req,n) \ - { \ - CARD64 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } -#else -#define MakeBigReq(req,n) \ - { \ - CARD32 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } -#endif -#endif - -#ifndef __clang_analyzer__ -#define SetReqLen(req,n,badlen) \ - if ((req->length + n) > (unsigned)65535) { \ - if (dpy->bigreq_size) { \ - MakeBigReq(req,n) \ - } else { \ - n = badlen; \ - req->length += n; \ - } \ - } else \ - req->length += n -#else -#define SetReqLen(req,n,badlen) \ - req->length += n -#endif - -#define SyncHandle() \ - if (dpy->synchandler) (*dpy->synchandler)(dpy) - -extern void _XFlushGCCache(Display *dpy, GC gc); -#define FlushGC(dpy, gc) \ - if ((gc)->dirty) _XFlushGCCache((dpy), (gc)) -/* - * Data - Place data in the buffer and pad the end to provide - * 32 bit word alignment. Transmit if the buffer fills. - * - * "dpy" is a pointer to a Display. - * "data" is a pinter to a data buffer. - * "len" is the length of the data buffer. - */ -#ifndef DataRoutineIsProcedure -#define Data(dpy, data, len) {\ - if (dpy->bufptr + (len) <= dpy->bufmax) {\ - memcpy(dpy->bufptr, data, (int)len);\ - dpy->bufptr += ((len) + 3) & ~3;\ - } else\ - _XSend(dpy, data, len);\ - } -#endif /* DataRoutineIsProcedure */ - - -/* Allocate bytes from the buffer. No padding is done, so if - * the length is not a multiple of 4, the caller must be - * careful to leave the buffer aligned after sending the - * current request. - * - * "type" is the type of the pointer being assigned to. - * "ptr" is the pointer being assigned to. - * "n" is the number of bytes to allocate. - * - * Example: - * xTextElt *elt; - * BufAlloc (xTextElt *, elt, nbytes) - */ - -#define BufAlloc(type, ptr, n) \ - if (dpy->bufptr + (n) > dpy->bufmax) \ - _XFlush (dpy); \ - ptr = (type) dpy->bufptr; \ - memset(ptr, '\0', n); \ - dpy->bufptr += (n); - -#ifdef WORD64 -#define Data16(dpy, data, len) _XData16(dpy, (short *)data, len) -#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) -#else -#define Data16(dpy, data, len) Data((dpy), (char *)(data), (len)) -#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) -#define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) -#ifdef LONG64 -#define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) -extern int _XData32( - Display *dpy, - register long *data, - unsigned len -); -extern void _XRead32( - Display *dpy, - register long *data, - long len -); -#else -#define Data32(dpy, data, len) Data((dpy), (char *)(data), (len)) -#define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) -#endif -#endif /* not WORD64 */ - -#define PackData16(dpy,data,len) Data16 (dpy, data, len) -#define PackData32(dpy,data,len) Data32 (dpy, data, len) - -/* Xlib manual is bogus */ -#define PackData(dpy,data,len) PackData16 (dpy, data, len) - -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ - (((cs)->rbearing|(cs)->lbearing| \ - (cs)->ascent|(cs)->descent) == 0)) - -/* - * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit - * character. If the character is in the column and exists, then return the - * appropriate metrics (note that fonts with common per-character metrics will - * return min_bounds). If none of these hold true, try again with the default - * char. - */ -#define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \ -{ \ - cs = def; \ - if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_1D(fs,cs) \ - CI_GET_CHAR_INFO_1D (fs, fs->default_char, NULL, cs) - - - -/* - * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and - * column. This is used for fonts that have more than row zero. - */ -#define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ -{ \ - cs = def; \ - if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ - col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[((row - fs->min_byte1) * \ - (fs->max_char_or_byte2 - \ - fs->min_char_or_byte2 + 1)) + \ - (col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_2D(fs,cs) \ -{ \ - unsigned int r = (fs->default_char >> 8); \ - unsigned int c = (fs->default_char & 0xff); \ - CI_GET_CHAR_INFO_2D (fs, r, c, NULL, cs); \ -} - - -#ifdef MUSTCOPY - -/* for when 32-bit alignment is not good enough */ -#define OneDataCard32(dpy,dstaddr,srcvar) \ - { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); } - -#else - -/* srcvar must be a variable for large architecture version */ -#define OneDataCard32(dpy,dstaddr,srcvar) \ - { *(CARD32 *)(dstaddr) = (srcvar); } - -#endif /* MUSTCOPY */ - -typedef struct _XInternalAsync { - struct _XInternalAsync *next; - /* - * handler arguments: - * rep is the generic reply that caused this handler - * to be invoked. It must also be passed to _XGetAsyncReply. - * buf and len are opaque values that must be passed to - * _XGetAsyncReply or _XGetAsyncData. - * data is the closure stored in this struct. - * The handler returns True iff it handled this reply. - */ - Bool (*handler)( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ - ); - XPointer data; -} _XAsyncHandler; - -typedef struct _XAsyncEState { - unsigned long min_sequence_number; - unsigned long max_sequence_number; - unsigned char error_code; - unsigned char major_opcode; - unsigned short minor_opcode; - unsigned char last_error_received; - int error_count; -} _XAsyncErrorState; - -extern void _XDeqAsyncHandler(Display *dpy, _XAsyncHandler *handler); -#define DeqAsyncHandler(dpy,handler) { \ - if (dpy->async_handlers == (handler)) \ - dpy->async_handlers = (handler)->next; \ - else \ - _XDeqAsyncHandler(dpy, handler); \ - } - -typedef void (*FreeFuncType) ( - Display* /* display */ -); - -typedef int (*FreeModmapType) ( - XModifierKeymap* /* modmap */ -); - -/* - * This structure is private to the library. - */ -typedef struct _XFreeFuncs { - FreeFuncType atoms; /* _XFreeAtomTable */ - FreeModmapType modifiermap; /* XFreeModifiermap */ - FreeFuncType key_bindings; /* _XFreeKeyBindings */ - FreeFuncType context_db; /* _XFreeContextDB */ - FreeFuncType defaultCCCs; /* _XcmsFreeDefaultCCCs */ - FreeFuncType clientCmaps; /* _XcmsFreeClientCmaps */ - FreeFuncType intensityMaps; /* _XcmsFreeIntensityMaps */ - FreeFuncType im_filters; /* _XFreeIMFilters */ - FreeFuncType xkb; /* _XkbFreeInfo */ -} _XFreeFuncRec; - -/* types for InitExt.c */ -typedef int (*CreateGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*CopyGCType)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*FlushGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*FreeGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - -typedef int (*CreateFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - -typedef int (*FreeFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - -typedef int (*CloseDisplayType) ( - Display* /* display */, - XExtCodes* /* codes */ -); - -typedef int (*ErrorType) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ -); - -typedef char* (*ErrorStringType) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ -); - -typedef void (*PrintErrorType)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ -); - -typedef void (*BeforeFlushType)( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ -); - -/* - * This structure is private to the library. - */ -typedef struct _XExten { /* private to extension mechanism */ - struct _XExten *next; /* next in list */ - XExtCodes codes; /* public information, all extension told */ - CreateGCType create_GC; /* routine to call when GC created */ - CopyGCType copy_GC; /* routine to call when GC copied */ - FlushGCType flush_GC; /* routine to call when GC flushed */ - FreeGCType free_GC; /* routine to call when GC freed */ - CreateFontType create_Font; /* routine to call when Font created */ - FreeFontType free_Font; /* routine to call when Font freed */ - CloseDisplayType close_display; /* routine to call when connection closed */ - ErrorType error; /* who to call when an error occurs */ - ErrorStringType error_string; /* routine to supply error string */ - char *name; /* name of this extension */ - PrintErrorType error_values; /* routine to supply error values */ - BeforeFlushType before_flush; /* routine to call when sending data */ - struct _XExten *next_flush; /* next in list of those with flushes */ -} _XExtension; - -/* extension hooks */ - -#ifdef DataRoutineIsProcedure -extern void Data(Display *dpy, char *data, long len); -#endif -extern int _XError( - Display* /* dpy */, - xError* /* rep */ -); -extern int _XIOError( - Display* /* dpy */ -) _X_NORETURN; -extern int (*_XIOErrorFunction)( - Display* /* dpy */ -); -extern int (*_XErrorFunction)( - Display* /* dpy */, - XErrorEvent* /* error_event */ -); -extern void _XEatData( - Display* /* dpy */, - unsigned long /* n */ -); -extern char *_XAllocScratch( - Display* /* dpy */, - unsigned long /* nbytes */ -); -extern char *_XAllocTemp( - Display* /* dpy */, - unsigned long /* nbytes */ -); -extern void _XFreeTemp( - Display* /* dpy */, - char* /* buf */, - unsigned long /* nbytes */ -); -extern Visual *_XVIDtoVisual( - Display* /* dpy */, - VisualID /* id */ -); -extern unsigned long _XSetLastRequestRead( - Display* /* dpy */, - xGenericReply* /* rep */ -); -extern int _XGetHostname( - char* /* buf */, - int /* maxlen */ -); -extern Screen *_XScreenOfWindow( - Display* /* dpy */, - Window /* w */ -); -extern Bool _XAsyncErrorHandler( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ -); -extern char *_XGetAsyncReply( - Display* /* dpy */, - char* /* replbuf */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - int /* extra */, - Bool /* discard */ -); -extern void _XGetAsyncData( - Display* /* dpy */, - char * /* data */, - char * /* buf */, - int /* len */, - int /* skip */, - int /* datalen */, - int /* discardtotal */ -); -extern void _XFlush( - Display* /* dpy */ -); -extern int _XEventsQueued( - Display* /* dpy */, - int /* mode */ -); -extern void _XReadEvents( - Display* /* dpy */ -); -extern int _XRead( - Display* /* dpy */, - char* /* data */, - long /* size */ -); -extern void _XReadPad( - Display* /* dpy */, - char* /* data */, - long /* size */ -); -extern void _XSend( - Display* /* dpy */, - _Xconst char* /* data */, - long /* size */ -); -extern Status _XReply( - Display* /* dpy */, - xReply* /* rep */, - int /* extra */, - Bool /* discard */ -); -extern void _XEnq( - Display* /* dpy */, - xEvent* /* event */ -); -extern void _XDeq( - Display* /* dpy */, - _XQEvent* /* prev */, - _XQEvent* /* qelt */ -); - -extern Bool _XUnknownWireEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ -); - -extern Bool _XUnknownWireEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* re */, - xEvent* /* event */ -); - -extern Bool _XUnknownCopyEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ -); - -extern Status _XUnknownNativeEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ -); - -extern Bool _XWireToEvent(Display *dpy, XEvent *re, xEvent *event); -extern Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we); -extern Bool _XPollfdCacheInit(Display *dpy); -extern void _XPollfdCacheAdd(Display *dpy, int fd); -extern void _XPollfdCacheDel(Display *dpy, int fd); -extern XID _XAllocID(Display *dpy); -extern void _XAllocIDs(Display *dpy, XID *ids, int count); - -extern int _XFreeExtData( - XExtData* /* extension */ -); - -extern int (*XESetCreateGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetCopyGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetFlushGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetFreeGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); - -extern int (*XESetCreateFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); - -extern int (*XESetFreeFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); - -extern int (*XESetCloseDisplay( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XExtCodes* -); - -extern int (*XESetError( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ - ) /* proc */ -))( - Display*, xError*, XExtCodes*, int* -); - -extern char* (*XESetErrorString( - Display* /* display */, - int /* extension */, - char* (*) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ - ) /* proc */ -))( - Display*, int, XExtCodes*, char*, int -); - -extern void (*XESetPrintErrorValues ( - Display* /* display */, - int /* extension */, - void (*)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ - ) /* proc */ -))( - Display*, XErrorEvent*, void* -); - -extern Bool (*XESetWireToEvent( - Display* /* display */, - int /* event_number */, - Bool (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); - -extern Bool (*XESetWireToEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, xEvent* -); - -extern Bool (*XESetCopyEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, XGenericEventCookie* -); - - -extern Status (*XESetEventToWire( - Display* /* display */, - int /* event_number */, - Status (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); - -extern Bool (*XESetWireToError( - Display* /* display */, - int /* error_number */, - Bool (*) ( - Display* /* display */, - XErrorEvent* /* he */, - xError* /* we */ - ) /* proc */ -))( - Display*, XErrorEvent*, xError* -); - -extern void (*XESetBeforeFlush( - Display* /* display */, - int /* error_number */, - void (*) ( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ - ) /* proc */ -))( - Display*, XExtCodes*, _Xconst char*, long -); - -/* internal connections for IMs */ - -typedef void (*_XInternalConnectionProc)( - Display* /* dpy */, - int /* fd */, - XPointer /* call_data */ -); - - -extern Status _XRegisterInternalConnection( - Display* /* dpy */, - int /* fd */, - _XInternalConnectionProc /* callback */, - XPointer /* call_data */ -); - -extern void _XUnregisterInternalConnection( - Display* /* dpy */, - int /* fd */ -); - -extern void _XProcessInternalConnection( - Display* /* dpy */, - struct _XConnectionInfo* /* conn_info */ -); - -/* Display structure has pointers to these */ - -struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ - int fd; - _XInternalConnectionProc read_callback; - XPointer call_data; - XPointer *watch_data; /* set/used by XConnectionWatchProc */ - struct _XConnectionInfo *next; -}; - -struct _XConnWatchInfo { /* info from XAddConnectionWatch */ - XConnectionWatchProc fn; - XPointer client_data; - struct _XConnWatchInfo *next; -}; - -#ifdef __UNIXOS2__ -extern char* __XOS2RedirRoot( - char* -); -#endif - -extern int _XTextHeight( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* count */ -); - -extern int _XTextHeight16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* count */ -); - -#if defined(WIN32) - -extern int _XOpenFile( - _Xconst char* /* path */, - int /* flags */ -); - -extern int _XOpenFileMode( - _Xconst char* /* path */, - int /* flags */, - mode_t /* mode */ -); - -extern void* _XFopenFile( - _Xconst char* /* path */, - _Xconst char* /* mode */ -); - -extern int _XAccessFile( - _Xconst char* /* path */ -); -#else -#define _XOpenFile(path,flags) open(path,flags) -#define _XOpenFileMode(path,flags,mode) open(path,flags,mode) -#define _XFopenFile(path,mode) fopen(path,mode) -#endif - -/* EvToWire.c */ -extern Status _XEventToWire(Display *dpy, XEvent *re, xEvent *event); - -extern int _XF86LoadQueryLocaleFont( - Display* /* dpy */, - _Xconst char* /* name*/, - XFontStruct** /* xfp*/, - Font* /* fidp */ -); - -extern void _XProcessWindowAttributes ( - register Display *dpy, - xChangeWindowAttributesReq *req, - register unsigned long valuemask, - register XSetWindowAttributes *attributes); - -extern int _XDefaultError( - Display *dpy, - XErrorEvent *event); - -extern int _XDefaultIOError( - Display *dpy); - -extern void _XSetClipRectangles ( - register Display *dpy, - GC gc, - int clip_x_origin, int clip_y_origin, - XRectangle *rectangles, - int n, - int ordering); - -Status _XGetWindowAttributes( - register Display *dpy, - Window w, - XWindowAttributes *attr); - -int _XPutBackEvent ( - register Display *dpy, - register XEvent *event); - -extern Bool _XIsEventCookie( - Display *dpy, - XEvent *ev); - -extern void _XFreeEventCookies( - Display *dpy); - -extern void _XStoreEventCookie( - Display *dpy, - XEvent *ev); - -extern Bool _XFetchEventCookie( - Display *dpy, - XGenericEventCookie *ev); - -extern Bool _XCopyEventCookie( - Display *dpy, - XGenericEventCookie *in, - XGenericEventCookie *out); - -/* lcFile.c */ - -extern void xlocaledir( - char *buf, - int buf_len -); - -_XFUNCPROTOEND - -#endif /* _X11_XLIBINT_H_ */ diff --git a/shell/linux-deps/include/X11/Xlocale.h b/shell/linux-deps/include/X11/Xlocale.h deleted file mode 100644 index 98946e53a..000000000 --- a/shell/linux-deps/include/X11/Xlocale.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - -Copyright 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -#ifndef _X11_XLOCALE_H_ -#define _X11_XLOCALE_H_ - -#include -#include - -#ifndef X_LOCALE -#include -#else - -#define LC_ALL 0 -#define LC_COLLATE 1 -#define LC_CTYPE 2 -#define LC_MONETARY 3 -#define LC_NUMERIC 4 -#define LC_TIME 5 - -_XFUNCPROTOBEGIN -extern char *_Xsetlocale( - int /* category */, - _Xconst char* /* name */ -); -_XFUNCPROTOEND - -#define setlocale _Xsetlocale - -#include - -#endif /* X_LOCALE */ - -#endif /* _X11_XLOCALE_H_ */ diff --git a/shell/linux-deps/include/X11/Xmd.h b/shell/linux-deps/include/X11/Xmd.h deleted file mode 100644 index f3868b36d..000000000 --- a/shell/linux-deps/include/X11/Xmd.h +++ /dev/null @@ -1,185 +0,0 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ -#ifndef XMD_H -# define XMD_H 1 -/* - * Xmd.h: MACHINE DEPENDENT DECLARATIONS. - */ - -/* - * Special per-machine configuration flags. - */ -# if defined(__sun) && defined(__SVR4) -# include /* Solaris: defines _LP64 if necessary */ -# endif - -# if defined (_LP64) || defined(__LP64__) || \ - defined(__alpha) || defined(__alpha__) || \ - defined(__ia64__) || defined(ia64) || \ - defined(__sparc64__) || \ - defined(__s390x__) || \ - defined(__amd64__) || defined(amd64) || \ - defined(__powerpc64__) -# define LONG64 /* 32/64-bit architecture */ -# endif - -/* - * Stuff to handle large architecture machines; the constants were generated - * on a 32-bit machine and must correspond to the protocol. - */ -# ifdef WORD64 -# define MUSTCOPY -# endif /* WORD64 */ - - -/* - * Definition of macro used to set constants for size of network structures; - * machines with preprocessors that can't handle all of the sz_ symbols - * can define this macro to be sizeof(x) if and only if their compiler doesn't - * pad out structures (esp. the xTextElt structure which contains only two - * one-byte fields). Network structures should always define sz_symbols. - * - * The sz_ prefix is used instead of something more descriptive so that the - * symbols are no more than 32 characters long (which causes problems for some - * compilers and preprocessors). - * - * The extra indirection is to get macro arguments to expand correctly before - * the concatenation, rather than afterward. - */ -# define _SIZEOF(x) sz_##x -# define SIZEOF(x) _SIZEOF(x) - -/* - * Bitfield suffixes for the protocol structure elements, if you - * need them. Note that bitfields are not guaranteed to be signed - * (or even unsigned) according to ANSI C. - */ -# ifdef WORD64 -typedef long INT64; -typedef unsigned long CARD64; -# define B32 :32 -# define B16 :16 -# ifdef UNSIGNEDBITFIELDS -typedef unsigned int INT32; -typedef unsigned int INT16; -# else -typedef signed int INT32; -typedef signed int INT16; -# endif -# else -# define B32 -# define B16 -# ifdef LONG64 -typedef long INT64; -typedef int INT32; -# else -typedef long INT32; -# endif -typedef short INT16; -# endif - -typedef signed char INT8; - -# ifdef LONG64 -typedef unsigned long CARD64; -typedef unsigned int CARD32; -# else -typedef unsigned long CARD32; -# endif -# if !defined(WORD64) && !defined(LONG64) -typedef unsigned long long CARD64; -# endif -typedef unsigned short CARD16; -typedef unsigned char CARD8; - -typedef CARD32 BITS32; -typedef CARD16 BITS16; - -typedef CARD8 BYTE; -typedef CARD8 BOOL; - -/* - * definitions for sign-extending bitfields on 64-bit architectures - */ -# if defined(WORD64) && defined(UNSIGNEDBITFIELDS) -# define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) -# define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) -# define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val)) -# define cvtINT8toShort(val) cvtINT8toInt(val) -# define cvtINT16toShort(val) cvtINT16toInt(val) -# define cvtINT32toShort(val) cvtINT32toInt(val) -# define cvtINT8toLong(val) cvtINT8toInt(val) -# define cvtINT16toLong(val) cvtINT16toInt(val) -# define cvtINT32toLong(val) cvtINT32toInt(val) -# else -# define cvtINT8toInt(val) (val) -# define cvtINT16toInt(val) (val) -# define cvtINT32toInt(val) (val) -# define cvtINT8toShort(val) (val) -# define cvtINT16toShort(val) (val) -# define cvtINT32toShort(val) (val) -# define cvtINT8toLong(val) (val) -# define cvtINT16toLong(val) (val) -# define cvtINT32toLong(val) (val) -# endif /* WORD64 and UNSIGNEDBITFIELDS */ - - - -# ifdef MUSTCOPY -/* - * This macro must not cast or else pointers will get aligned and be wrong - */ -# define NEXTPTR(p,t) (((char *) p) + SIZEOF(t)) -# else /* else not MUSTCOPY, this is used for 32-bit machines */ -/* - * this version should leave result of type (t *), but that should only be - * used when not in MUSTCOPY - */ -# define NEXTPTR(p,t) (((t *)(p)) + 1) -# endif /* MUSTCOPY - used machines whose C structs don't line up with proto */ - -#endif /* XMD_H */ diff --git a/shell/linux-deps/include/X11/Xos.h b/shell/linux-deps/include/X11/Xos.h deleted file mode 100644 index 646716b4f..000000000 --- a/shell/linux-deps/include/X11/Xos.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * - * The X Window System is a Trademark of The Open Group. - * - */ - -/* This is a collection of things to try and minimize system dependencies - * in a "significant" number of source files. - */ - -#ifndef _XOS_H_ -# define _XOS_H_ - -# include - -/* - * Get major data types (esp. caddr_t) - */ - -# include - -# if defined(__SCO__) || defined(__UNIXWARE__) -# include -# endif - - -/* - * Just about everyone needs the strings routines. We provide both forms here, - * index/rindex and strchr/strrchr, so any systems that don't provide them all - * need to have #defines here. - * - * These macros are defined this way, rather than, e.g.: - * #defined index(s,c) strchr(s,c) - * because someone might be using them as function pointers, and such - * a change would break compatibility for anyone who's relying on them - * being the way they currently are. So we're stuck with them this way, - * which can be really inconvenient. :-( - */ - -# include -# if defined(__SCO__) || defined(__UNIXWARE__) || defined(__sun) -# include -# else -# ifndef index -# define index(s,c) (strchr((s),(c))) -# endif -# ifndef rindex -# define rindex(s,c) (strrchr((s),(c))) -# endif -# endif - -/* - * Get open(2) constants - */ -# if defined(X_NOT_POSIX) -# include -# if defined(USL) || defined(__i386__) && (defined(SYSV) || defined(SVR4)) -# include -# endif -# ifdef WIN32 -# include -# else -# include -# endif -# else /* X_NOT_POSIX */ -# include -# include -# endif /* X_NOT_POSIX else */ - -/* - * Get struct timeval and struct tm - */ - -# if defined(_POSIX_SOURCE) && defined(SVR4) -/* need to omit _POSIX_SOURCE in order to get what we want in SVR4 */ -# undef _POSIX_SOURCE -# include -# define _POSIX_SOURCE -# elif defined(WIN32) -# include -# if !defined(_WINSOCKAPI_) && !defined(_WILLWINSOCK_) && !defined(_TIMEVAL_DEFINED) && !defined(_STRUCT_TIMEVAL) -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -# define _TIMEVAL_DEFINED -# endif -# include -# define gettimeofday(t) \ -{ \ - struct _timeb _gtodtmp; \ - _ftime (&_gtodtmp); \ - (t)->tv_sec = _gtodtmp.time; \ - (t)->tv_usec = _gtodtmp.millitm * 1000; \ -} -# else -# include -# include -# endif /* defined(_POSIX_SOURCE) && defined(SVR4) */ - -/* define X_GETTIMEOFDAY macro, a portable gettimeofday() */ -# if defined(_XOPEN_XPG4) || defined(_XOPEN_UNIX) /* _XOPEN_UNIX is XPG4.2 */ -# define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) -# else -# if defined(SVR4) || defined(__SVR4) || defined(WIN32) -# define X_GETTIMEOFDAY(t) gettimeofday(t) -# else -# define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) -# endif -# endif /* XPG4 else */ - - -# ifdef __GNU__ -# define PATH_MAX 4096 -# define MAXPATHLEN 4096 -# define OPEN_MAX 256 /* We define a reasonable limit. */ -# endif - -/* use POSIX name for signal */ -# if defined(X_NOT_POSIX) && defined(SYSV) && !defined(SIGCHLD) -# define SIGCHLD SIGCLD -# endif - -# include - -#endif /* _XOS_H_ */ diff --git a/shell/linux-deps/include/X11/Xos_r.h b/shell/linux-deps/include/X11/Xos_r.h deleted file mode 100644 index f963b6410..000000000 --- a/shell/linux-deps/include/X11/Xos_r.h +++ /dev/null @@ -1,1095 +0,0 @@ -/* -Copyright 1996, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. -*/ - -/* - * Various and sundry Thread-Safe functions used by X11, Motif, and CDE. - * - * Use this file in MT-safe code where you would have included - * for readdir() - * for getgrgid() or getgrnam() - * for gethostbyname(), gethostbyaddr(), or getservbyname() - * for getpwnam() or getpwuid() - * for strtok() - * for asctime(), ctime(), localtime(), or gmtime() - * for getlogin() or ttyname() - * or their thread-safe analogs. - * - * If you are on a platform that defines XTHREADS but does not have - * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock - * and _Xos_processUnlock macros before including this header. - * - * For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined - * to obtain either Xlib-only or Xt-based versions of these macros. These - * macros won't result in truly thread-safe calls, but they are better than - * nothing. If you do not want locking in this situation define - * XOS_USE_NO_LOCKING. - * - * NOTE: On systems lacking appropriate _r functions Gethostbyname(), - * Gethostbyaddr(), and Getservbyname() do NOT copy the host or - * protocol lists! - * - * NOTE: On systems lacking appropriate _r functions Getgrgid() and - * Getgrnam() do NOT copy the list of group members! - * - * This header is nominally intended to simplify porting X11, Motif, and - * CDE; it may be useful to other people too. The structure below is - * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec) - * went through lots of drafts, and some vendors shipped systems based - * on draft API that were changed later. Unfortunately POSIX did not - * provide a feature-test macro for distinguishing each of the drafts. - */ - -/* - * This header has several parts. Search for "Effective prototypes" - * to locate the beginning of a section. - */ - -/* This header can be included multiple times with different defines! */ -#ifndef _XOS_R_H_ -# define _XOS_R_H_ - -# include -# include - -# ifndef X_NOT_POSIX -# ifdef _POSIX_SOURCE -# include -# else -# define _POSIX_SOURCE -# include -# undef _POSIX_SOURCE -# endif -# ifndef LINE_MAX -# define X_LINE_MAX 2048 -# else -# define X_LINE_MAX LINE_MAX -# endif -# endif -#endif /* _XOS_R_H */ - -#ifndef WIN32 - -#ifdef __cplusplus -extern "C" { -#endif - -# if defined(XOS_USE_XLIB_LOCKING) -# ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */ -typedef struct _LockInfoRec *LockInfoPtr; -extern LockInfoPtr _Xglobal_lock; -# endif -# ifndef _Xos_isThreadInitialized -# define _Xos_isThreadInitialized (_Xglobal_lock) -# endif -# if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -# ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */ -# include /* for NeedFunctionPrototypes */ -extern void (*_XLockMutex_fn)( -# if NeedFunctionPrototypes - LockInfoPtr /* lock */, char * /* file */, int /* line */ -# endif -); -extern void (*_XUnlockMutex_fn)( -# if NeedFunctionPrototypes - LockInfoPtr /* lock */, char * /* file */, int /* line */ -# endif -); -# endif -# ifndef _Xos_processLock -# define _Xos_processLock \ - (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0) -# endif -# ifndef _Xos_processUnlock -# define _Xos_processUnlock \ - (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0) -# endif -# else -# ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */ -# include /* for NeedFunctionPrototypes */ -extern void (*_XLockMutex_fn)( -# if NeedFunctionPrototypes - LockInfoPtr /* lock */ -# endif -); -extern void (*_XUnlockMutex_fn)( -# if NeedFunctionPrototypes - LockInfoPtr /* lock */ -# endif -); -# endif -# ifndef _Xos_processLock -# define _Xos_processLock \ - (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0) -# endif -# ifndef _Xos_processUnlock -# define _Xos_processUnlock \ - (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0) -# endif -# endif -# elif defined(XOS_USE_XT_LOCKING) -# ifndef _XtThreadsI_h -extern void (*_XtProcessLock)(void); -# endif -# ifndef _XtintrinsicP_h -# include /* for NeedFunctionPrototypes */ -extern void XtProcessLock( -# if NeedFunctionPrototypes - void -# endif -); -extern void XtProcessUnlock( -# if NeedFunctionPrototypes - void -# endif -); -# endif -# ifndef _Xos_isThreadInitialized -# define _Xos_isThreadInitialized _XtProcessLock -# endif -# ifndef _Xos_processLock -# define _Xos_processLock XtProcessLock() -# endif -# ifndef _Xos_processUnlock -# define _Xos_processUnlock XtProcessUnlock() -# endif -# elif defined(XOS_USE_NO_LOCKING) -# ifndef _Xos_isThreadInitialized -# define _Xos_isThreadInitialized 0 -# endif -# ifndef _Xos_processLock -# define _Xos_processLock 0 -# endif -# ifndef _Xos_processUnlock -# define _Xos_processUnlock 0 -# endif -# endif - -#endif /* !defined WIN32 */ - -/* - * Solaris defines the POSIX thread-safe feature test macro, but - * uses the older SVR4 thread-safe functions unless the POSIX ones - * are specifically requested. Fix the feature test macro. - */ -#if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ - (_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS) -# undef _POSIX_THREAD_SAFE_FUNCTIONS -#endif - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * #define X_INCLUDE_PWD_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xgetpwparams; - * - * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams); - * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams); - */ - -#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H) -# include -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI) -# define XOS_USE_MTSAFE_PWDAPI 1 -# endif -#endif - -#undef X_NEEDS_PWPARAMS -#if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H) -/* Do nothing */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -# if defined(X_NOT_POSIX) && !defined(__i386__) && !defined(SYSV) -extern struct passwd *getpwuid(), *getpwnam(); -# endif -typedef int _Xgetpwparams; /* dummy */ -# define _XGetpwuid(u,p) getpwuid((u)) -# define _XGetpwnam(u,p) getpwnam((u)) - -#elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI) -/* UnixWare 2.0, or other systems with thread support but no _r API. */ -# define X_NEEDS_PWPARAMS -typedef struct { - struct passwd pws; - char pwbuf[1024]; - struct passwd* pwp; - size_t len; -} _Xgetpwparams; - -/* - * NetBSD and FreeBSD, at least, are missing several of the unixware passwd - * fields. - */ - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ - defined(__APPLE__) || defined(__DragonFly__) -static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p) -{ - memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)); - - (p).pws.pw_name = (p).pwbuf; - (p).len = strlen((p).pwp->pw_name); - strcpy((p).pws.pw_name, (p).pwp->pw_name); - - (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1; - (p).len = strlen((p).pwp->pw_passwd); - strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd); - - (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1; - (p).len = strlen((p).pwp->pw_class); - strcpy((p).pws.pw_class, (p).pwp->pw_class); - - (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1; - (p).len = strlen((p).pwp->pw_gecos); - strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos); - - (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1; - (p).len = strlen((p).pwp->pw_dir); - strcpy((p).pws.pw_dir, (p).pwp->pw_dir); - - (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1; - (p).len = strlen((p).pwp->pw_shell); - strcpy((p).pws.pw_shell, (p).pwp->pw_shell); - - (p).pwp = &(p).pws; -} - -#else -# define _Xpw_copyPasswd(p) \ - (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \ - ((p).pws.pw_name = (p).pwbuf), \ - ((p).len = strlen((p).pwp->pw_name)), \ - strcpy((p).pws.pw_name, (p).pwp->pw_name), \ - ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_passwd)), \ - strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \ - ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_age)), \ - strcpy((p).pws.pw_age, (p).pwp->pw_age), \ - ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_comment)), \ - strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \ - ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_gecos)), \ - strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \ - ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_dir)), \ - strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \ - ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \ - ((p).len = strlen((p).pwp->pw_shell)), \ - strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \ - ((p).pwp = &(p).pws), \ - 0 ) -#endif -# define _XGetpwuid(u,p) \ -( (_Xos_processLock), \ - (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \ - (_Xos_processUnlock), \ - (p).pwp ) -# define _XGetpwnam(u,p) \ -( (_Xos_processLock), \ - (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \ - (_Xos_processUnlock), \ - (p).pwp ) - -#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__) -# define X_NEEDS_PWPARAMS -typedef struct { - struct passwd pws; - char pwbuf[X_LINE_MAX]; -} _Xgetpwparams; -# if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4) -# define _XGetpwuid(u,p) \ -((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws) -# define _XGetpwnam(u,p) \ -((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws) -# else /* SVR4 */ -# define _XGetpwuid(u,p) \ -((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws) -# define _XGetpwnam(u,p) \ -((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws) -# endif /* SVR4 */ - -#else /* _POSIX_THREAD_SAFE_FUNCTIONS */ -# define X_NEEDS_PWPARAMS -typedef struct { - struct passwd pws; - char pwbuf[X_LINE_MAX]; - struct passwd* pwp; -} _Xgetpwparams; -typedef int _Xgetpwret; -# define _XGetpwuid(u,p) \ -((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \ - (p).pwp : NULL) -# define _XGetpwnam(u,p) \ -((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \ - (p).pwp : NULL) -#endif /* X_INCLUDE_PWD_H */ - -#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H) -# define _XOS_INCLUDED_PWD_H -#endif - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * NOTE: On systems lacking the appropriate _r functions Gethostbyname(), - * Gethostbyaddr(), and Getservbyname() do NOT copy the host or - * protocol lists! - * - * #define X_INCLUDE_NETDB_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xgethostbynameparams; - * typedef ... _Xgetservbynameparams; - * - * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams); - * struct hostent* _XGethostbyaddr(const char* addr, int len, int type, - * _Xgethostbynameparams); - * struct servent* _XGetservbyname(const char* name, const char* proto, - * _Xgetservbynameparams); - */ - -#undef XTHREADS_NEEDS_BYNAMEPARAMS -#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \ - && !defined(WIN32) -# include -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI) -# define XOS_USE_MTSAFE_NETDBAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xgethostbynameparams; /* dummy */ -typedef int _Xgetservbynameparams; /* dummy */ -# define _XGethostbyname(h,hp) gethostbyname((h)) -# define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t)) -# define _XGetservbyname(s,p,sp) getservbyname((s),(p)) - -#elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI) -/* WARNING: The h_addr_list and s_aliases values are *not* copied! */ - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -#include -#endif - -typedef struct { - struct hostent hent; - char h_name[MAXHOSTNAMELEN]; - struct hostent *hptr; -} _Xgethostbynameparams; -typedef struct { - struct servent sent; - char s_name[255]; - char s_proto[255]; - struct servent *sptr; -} _Xgetservbynameparams; - -# define XTHREADS_NEEDS_BYNAMEPARAMS - -# define _Xg_copyHostent(hp) \ - (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \ - strcpy((hp).h_name, (hp).hptr->h_name), \ - ((hp).hent.h_name = (hp).h_name), \ - ((hp).hptr = &(hp).hent), \ - 0 ) -# define _Xg_copyServent(sp) \ - (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \ - strcpy((sp).s_name, (sp).sptr->s_name), \ - ((sp).sent.s_name = (sp).s_name), \ - strcpy((sp).s_proto, (sp).sptr->s_proto), \ - ((sp).sent.s_proto = (sp).s_proto), \ - ((sp).sptr = &(sp).sent), \ - 0 ) -# define _XGethostbyname(h,hp) \ - ((_Xos_processLock), \ - (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \ - (_Xos_processUnlock), \ - (hp).hptr ) -# define _XGethostbyaddr(a,al,t,hp) \ - ((_Xos_processLock), \ - (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \ - (_Xos_processUnlock), \ - (hp).hptr ) -# define _XGetservbyname(s,p,sp) \ - ((_Xos_processLock), \ - (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \ - (_Xos_processUnlock), \ - (sp).sptr ) - -#elif defined(XUSE_NETDB_R_API) -/* - * POSIX does not specify _r equivalents for API, but some - * vendors provide them anyway. Use them only when explicitly asked. - */ -# ifdef _POSIX_REENTRANT_FUNCTIONS -# ifndef _POSIX_THREAD_SAFE_FUNCTIONS -# endif -# endif -# ifdef _POSIX_THREAD_SAFE_FUNCTIONS -# define X_POSIX_THREAD_SAFE_FUNCTIONS 1 -# endif - -# define XTHREADS_NEEDS_BYNAMEPARAMS - -# ifndef X_POSIX_THREAD_SAFE_FUNCTIONS -typedef struct { - struct hostent hent; - char hbuf[X_LINE_MAX]; - int herr; -} _Xgethostbynameparams; -typedef struct { - struct servent sent; - char sbuf[X_LINE_MAX]; -} _Xgetservbynameparams; -# define _XGethostbyname(h,hp) \ - gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr) -# define _XGethostbyaddr(a,al,t,hp) \ - gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr) -# define _XGetservbyname(s,p,sp) \ - getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf)) -# else -typedef struct { - struct hostent hent; - struct hostent_data hdata; -} _Xgethostbynameparams; -typedef struct { - struct servent sent; - struct servent_data sdata; -} _Xgetservbynameparams; -# define _XGethostbyname(h,hp) \ - (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \ - ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent)) -# define _XGethostbyaddr(a,al,t,hp) \ - (bzero((char*)&(hp).hdata,sizeof((hp).hdata)), \ - ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent)) -# define _XGetservbyname(s,p,sp) \ - (bzero((char*)&(sp).sdata,sizeof((sp).sdata)), \ - ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) ) -# endif -# ifdef X_POSIX_THREAD_SAFE_FUNCTIONS -# undef X_POSIX_THREAD_SAFE_FUNCTIONS -# endif - -#else -/* The regular API is assumed to be MT-safe under POSIX. */ -typedef int _Xgethostbynameparams; /* dummy */ -typedef int _Xgetservbynameparams; /* dummy */ -# define _XGethostbyname(h,hp) gethostbyname((h)) -# define _XGethostbyaddr(a,al,t,hp) gethostbyaddr((a),(al),(t)) -# define _XGetservbyname(s,p,sp) getservbyname((s),(p)) -#endif /* X_INCLUDE_NETDB_H */ - -#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) -# define _XOS_INCLUDED_NETDB_H -#endif - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * #define X_INCLUDE_DIRENT_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xreaddirparams; - * - * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams); - */ - -#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H) -# include -# if !defined(X_NOT_POSIX) || defined(SYSV) -# include -# else -# include -# ifndef dirent -# define dirent direct -# endif -# endif -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI) -# define XOS_USE_MTSAFE_DIRENTAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xreaddirparams; /* dummy */ -# define _XReaddir(d,p) readdir(d) - -#elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI) -/* Systems with thread support but no _r API. */ -typedef struct { - struct dirent *result; - struct dirent dir_entry; -# ifdef _POSIX_PATH_MAX - char buf[_POSIX_PATH_MAX]; -# elif defined(NAME_MAX) - char buf[NAME_MAX]; -# else - char buf[255]; -# endif -} _Xreaddirparams; - -# define _XReaddir(d,p) \ - ( (_Xos_processLock), \ - (((p).result = readdir((d))) ? \ - (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \ - ((p).result = &(p).dir_entry), 0) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) - -#else -typedef struct { - struct dirent *result; - struct dirent dir_entry; -# ifdef _POSIX_PATH_MAX - char buf[_POSIX_PATH_MAX]; -# elif defined(NAME_MAX) - char buf[NAME_MAX]; -# else - char buf[255]; -# endif -} _Xreaddirparams; - -# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__) -/* POSIX final API, returns (int)0 on success. */ -# define _XReaddir(d,p) \ - (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result) -# elif defined(_POSIX_REENTRANT_FUNCTIONS) -/* POSIX draft API, returns (int)0 on success. */ -# define _XReaddir(d,p) \ - (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry)) -# elif defined(SVR4) -/* Pre-POSIX API, returns non-NULL on success. */ -# define _XReaddir(d,p) (readdir_r((d), &(p).dir_entry)) -# else -/* We have no idea what is going on. Fake it all using process locks. */ -# define _XReaddir(d,p) \ - ( (_Xos_processLock), \ - (((p).result = readdir((d))) ? \ - (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \ - ((p).result = &(p).dir_entry), 0) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) -# endif -#endif /* X_INCLUDE_DIRENT_H */ - -#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H) -# define _XOS_INCLUDED_DIRENT_H -#endif - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * #define X_INCLUDE_UNISTD_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xgetloginparams; - * typedef ... _Xttynameparams; - * - * char *_XGetlogin(_Xgetloginparams); - * char *_XTtyname(int, _Xttynameparams); - */ - -#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H) -/* already included by */ -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI) -# define XOS_USE_MTSAFE_UNISTDAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xgetloginparams; /* dummy */ -typedef int _Xttynameparams; /* dummy */ -# define _XGetlogin(p) getlogin() -# define _XTtyname(f) ttyname((f)) - -#elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI) -/* Systems with thread support but no _r API. */ -typedef struct { - char *result; -# if defined(MAXLOGNAME) - char buf[MAXLOGNAME]; -# elif defined(LOGIN_NAME_MAX) - char buf[LOGIN_NAME_MAX]; -# else - char buf[64]; -# endif -} _Xgetloginparams; -typedef struct { - char *result; -# ifdef TTY_NAME_MAX - char buf[TTY_NAME_MAX]; -# elif defined(_POSIX_TTY_NAME_MAX) - char buf[_POSIX_TTY_NAME_MAX]; -# elif defined(_POSIX_PATH_MAX) - char buf[_POSIX_PATH_MAX]; -# else - char buf[256]; -# endif -} _Xttynameparams; - -# define _XGetlogin(p) \ - ( (_Xos_processLock), \ - (((p).result = getlogin()) ? \ - (strncpy((p).buf, (p).result, sizeof((p).buf)), \ - ((p).buf[sizeof((p).buf)-1] = '\0'), \ - ((p).result = (p).buf), 0) : 0), \ - (_Xos_processUnlock), \ - (p).result ) -#define _XTtyname(f,p) \ - ( (_Xos_processLock), \ - (((p).result = ttyname(f)) ? \ - (strncpy((p).buf, (p).result, sizeof((p).buf)), \ - ((p).buf[sizeof((p).buf)-1] = '\0'), \ - ((p).result = (p).buf), 0) : 0), \ - (_Xos_processUnlock), \ - (p).result ) - -#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS) -/* POSIX API. - * - * extern int getlogin_r(char *, size_t); - * extern int ttyname_r(int, char *, size_t); - */ -typedef struct { -# if defined(MAXLOGNAME) - char buf[MAXLOGNAME]; -# elif defined(LOGIN_NAME_MAX) - char buf[LOGIN_NAME_MAX]; -# else - char buf[64]; -# endif -} _Xgetloginparams; -typedef struct { -# ifdef TTY_NAME_MAX - char buf[TTY_NAME_MAX]; -# elif defined(_POSIX_TTY_NAME_MAX) - char buf[_POSIX_TTY_NAME_MAX]; -# elif defined(_POSIX_PATH_MAX) - char buf[_POSIX_PATH_MAX]; -# else - char buf[256]; -# endif -} _Xttynameparams; - -# define _XGetlogin(p) (getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf) -# define _XTtyname(f,p) \ - (ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf) - -#else -/* Pre-POSIX API. - * - * extern char *getlogin_r(char *, size_t); - * extern char *ttyname_r(int, char *, size_t); - */ -typedef struct { -# if defined(MAXLOGNAME) - char buf[MAXLOGNAME]; -# elif defined(LOGIN_NAME_MAX) - char buf[LOGIN_NAME_MAX]; -# else - char buf[64]; -# endif -} _Xgetloginparams; -typedef struct { -# ifdef TTY_NAME_MAX - char buf[TTY_NAME_MAX]; -# elif defined(_POSIX_TTY_NAME_MAX) - char buf[_POSIX_TTY_NAME_MAX]; -# elif defined(_POSIX_PATH_MAX) - char buf[_POSIX_PATH_MAX]; -# else - char buf[256]; -# endif -} _Xttynameparams; - -# define _XGetlogin(p) getlogin_r((p).buf, sizeof((p).buf)) -# define _XTtyname(f,p) ttyname_r((f), (p).buf, sizeof((p).buf)) -#endif /* X_INCLUDE_UNISTD_H */ - -#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H) -# define _XOS_INCLUDED_UNISTD_H -#endif - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * #define X_INCLUDE_STRING_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xstrtokparams; - * - * char *_XStrtok(char *, const char*, _Xstrtokparams); - */ - -#if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H) -/* has already been included by */ -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI) -# define XOS_USE_MTSAFE_STRINGAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xstrtokparams; /* dummy */ -# define _XStrtok(s1,s2,p) \ - ( p = 0, (void)p, strtok((s1),(s2)) ) - -#elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI) -/* Systems with thread support but no _r API. */ -typedef char *_Xstrtokparams; -# define _XStrtok(s1,s2,p) \ - ( (_Xos_processLock), \ - ((p) = strtok((s1),(s2))), \ - (_Xos_processUnlock), \ - (p) ) - -#else -/* POSIX or pre-POSIX API. */ -typedef char * _Xstrtokparams; -# define _XStrtok(s1,s2,p) strtok_r((s1),(s2),&(p)) -#endif /* X_INCLUDE_STRING_H */ - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * #define X_INCLUDE_TIME_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xatimeparams; - * typedef ... _Xctimeparams; - * typedef ... _Xgtimeparams; - * typedef ... _Xltimeparams; - * - * char *_XAsctime(const struct tm *, _Xatimeparams); - * char *_XCtime(const time_t *, _Xctimeparams); - * struct tm *_XGmtime(const time_t *, _Xgtimeparams); - * struct tm *_XLocaltime(const time_t *, _Xltimeparams); - */ - -#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H) -# include -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI) -# define XOS_USE_MTSAFE_TIMEAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xatimeparams; /* dummy */ -# define _XAsctime(t,p) asctime((t)) -typedef int _Xctimeparams; /* dummy */ -# define _XCtime(t,p) ctime((t)) -typedef int _Xgtimeparams; /* dummy */ -# define _XGmtime(t,p) gmtime((t)) -typedef int _Xltimeparams; /* dummy */ -# define _XLocaltime(t,p) localtime((t)) - -#elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI) -/* Systems with thread support but no _r API. */ -typedef struct { -# ifdef TIMELEN - char buf[TIMELEN]; -# else - char buf[26]; -# endif - char *result; -} _Xctimeparams, _Xatimeparams; -typedef struct { - struct tm buf; - struct tm *result; -} _Xgtimeparams, _Xltimeparams; -# define _XAsctime(t,p) \ - ( (_Xos_processLock), \ - (((p).result = asctime((t))) ? \ - (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) -# define _XCtime(t,p) \ - ( (_Xos_processLock), \ - (((p).result = ctime((t))) ? \ - (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) -# define _XGmtime(t,p) \ - ( (_Xos_processLock), \ - (((p).result = gmtime(t)) ? \ - (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) -# define _XLocaltime(t,p) \ - ( (_Xos_processLock), \ - (((p).result = localtime(t)) ? \ - (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \ - 0), \ - (_Xos_processUnlock), \ - (p).result ) - -#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(hpV4) -/* Returns (int)0 on success. - * - * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen); - * extern int ctime_r(const time_t *timer, char *buffer, int buflen); - * extern int gmtime_r(const time_t *timer, struct tm *result); - * extern int localtime_r(const time_t *timer, struct tm *result); - */ -# ifdef TIMELEN -typedef char _Xatimeparams[TIMELEN]; -typedef char _Xctimeparams[TIMELEN]; -# else -typedef char _Xatimeparams[26]; -typedef char _Xctimeparams[26]; -# endif -typedef struct tm _Xgtimeparams; -typedef struct tm _Xltimeparams; -# define _XAsctime(t,p) (asctime_r((t),(p),sizeof((p))) ? NULL : (p)) -# define _XCtime(t,p) (ctime_r((t),(p),sizeof((p))) ? NULL : (p)) -# define _XGmtime(t,p) (gmtime_r((t),&(p)) ? NULL : &(p)) -# define _XLocaltime(t,p) (localtime_r((t),&(p)) ? NULL : &(p)) - -#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun) -/* Returns NULL on failure. Solaris 2.5 - * - * extern char *asctime_r(const struct tm *tm,char *buf, int buflen); - * extern char *ctime_r(const time_t *clock, char *buf, int buflen); - * extern struct tm *gmtime_r(const time_t *clock, struct tm *res); - * extern struct tm *localtime_r(const time_t *clock, struct tm *res); - */ -# ifdef TIMELEN -typedef char _Xatimeparams[TIMELEN]; -typedef char _Xctimeparams[TIMELEN]; -# else -typedef char _Xatimeparams[26]; -typedef char _Xctimeparams[26]; -# endif -typedef struct tm _Xgtimeparams; -typedef struct tm _Xltimeparams; -# define _XAsctime(t,p) asctime_r((t),(p),sizeof((p))) -# define _XCtime(t,p) ctime_r((t),(p),sizeof((p))) -# define _XGmtime(t,p) gmtime_r((t),&(p)) -# define _XLocaltime(t,p) localtime_r((t),&(p)) - -#else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */ -/* POSIX final API. - * extern char *asctime_r(const struct tm *timeptr, char *buffer); - * extern char *ctime_r(const time_t *timer, char *buffer); - * extern struct tm *gmtime_r(const time_t *timer, struct tm *result); - * extern struct tm *localtime_r(const time_t *timer, struct tm *result); - */ -# ifdef TIMELEN -typedef char _Xatimeparams[TIMELEN]; -typedef char _Xctimeparams[TIMELEN]; -# else -typedef char _Xatimeparams[26]; -typedef char _Xctimeparams[26]; -# endif -typedef struct tm _Xgtimeparams; -typedef struct tm _Xltimeparams; -# define _XAsctime(t,p) asctime_r((t),(p)) -# define _XCtime(t,p) ctime_r((t),(p)) -# define _XGmtime(t,p) gmtime_r((t),&(p)) -# define _XLocaltime(t,p) localtime_r((t),&(p)) -#endif /* X_INCLUDE_TIME_H */ - -#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H) -# define _XOS_INCLUDED_TIME_H -#endif - - -/***** wrappers *****/ - -/* - * Effective prototypes for wrappers: - * - * NOTE: On systems lacking appropriate _r functions Getgrgid() and - * Getgrnam() do NOT copy the list of group members! - * - * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent() - * are not included in POSIX. - * - * #define X_INCLUDE_GRP_H - * #define XOS_USE_..._LOCKING - * #include - * - * typedef ... _Xgetgrparams; - * - * struct group *_XGetgrgid(gid_t, _Xgetgrparams); - * struct group *_XGetgrnam(const char *, _Xgetgrparams); - */ - -#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H) -# include -# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI) -# define XOS_USE_MTSAFE_GRPAPI 1 -# endif -#endif - -#if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H) -/* Do nothing. */ - -#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API) -/* Use regular, unsafe API. */ -typedef int _Xgetgrparams; /* dummy */ -#define _XGetgrgid(g,p) getgrgid((g)) -#define _XGetgrnam(n,p) getgrnam((n)) - -#elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI) -/* Systems with thread support but no _r API. UnixWare 2.0. */ -typedef struct { - struct group grp; - char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */ - struct group *pgrp; - size_t len; -} _Xgetgrparams; -#ifdef SVR4 -/* Copy the gr_passwd field too. */ -# define _Xgrp_copyGroup(p) \ - ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \ - ((p).grp.gr_name = (p).buf), \ - ((p).len = strlen((p).pgrp->gr_name)), \ - strcpy((p).grp.gr_name, (p).pgrp->gr_name), \ - ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \ - ((p).pgrp = &(p).grp), \ - 0 ) -#else -# define _Xgrp_copyGroup(p) \ - ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \ - ((p).grp.gr_name = (p).buf), \ - strcpy((p).grp.gr_name, (p).pgrp->gr_name), \ - ((p).pgrp = &(p).grp), \ - 0 ) -#endif -#define _XGetgrgid(g,p) \ - ( (_Xos_processLock), \ - (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \ - (_Xos_processUnlock), \ - (p).pgrp ) -#define _XGetgrnam(n,p) \ - ( (_Xos_processLock), \ - (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \ - (_Xos_processUnlock), \ - (p).pgrp ) - -#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun) -/* Non-POSIX API. Solaris. - * - * extern struct group *getgrgid_r(gid_t, struct group *, char *, int); - * extern struct group *getgrnam_r(const char *, struct group *, char *, int); - */ -typedef struct { - struct group grp; - char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */ -} _Xgetgrparams; -#define _XGetgrgid(g,p) getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) -#define _XGetgrnam(n,p) getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) - -#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) -/* Non-POSIX API. - * extern int getgrgid_r(gid_t, struct group *, char *, int); - * extern int getgrnam_r(const char *, struct group *, char *, int); - */ -typedef struct { - struct group grp; - char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */ -} _Xgetgrparams; -#define _XGetgrgid(g,p) \ - ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp)) -#define _XGetgrnam(n,p) \ - ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp)) - -#else -/* POSIX final API. - * - * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **); - * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **); - */ -typedef struct { - struct group grp; - char buf[X_LINE_MAX]; /* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */ - struct group *result; -} _Xgetgrparams; - -#define _XGetgrgid(g,p) \ - ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \ - NULL : (p).result)) -#define _XGetgrnam(n,p) \ - ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \ - NULL : (p).result)) -#endif - -#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H) -# define _XOS_INCLUDED_GRP_H -#endif - - -#ifdef __cplusplus -} /* Close scope of 'extern "C"' declaration which encloses file. */ -#endif diff --git a/shell/linux-deps/include/X11/Xosdefs.h b/shell/linux-deps/include/X11/Xosdefs.h deleted file mode 100644 index 33eaee436..000000000 --- a/shell/linux-deps/include/X11/Xosdefs.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * O/S-dependent (mis)feature macro definitions - * -Copyright 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - */ - -#ifndef _XOSDEFS_H_ -# define _XOSDEFS_H_ - -/* - * X_NOT_POSIX means does not have POSIX header files. Lack of this - * symbol does NOT mean that the POSIX environment is the default. - * You may still have to define _POSIX_SOURCE to get it. - */ - - -# ifdef _SCO_DS -# ifndef __SCO__ -# define __SCO__ -# endif -# endif - -# ifdef __i386__ -# ifdef SYSV -# if !defined(__SCO__) && \ - !defined(__UNIXWARE__) && !defined(__sun) -# if !defined(_POSIX_SOURCE) -# define X_NOT_POSIX -# endif -# endif -# endif -# endif - -# ifdef __sun -/* Imake configs define SVR4 on Solaris, but cc & gcc only define __SVR4 - * This check allows non-Imake configured programs to build correctly. - */ -# if defined(__SVR4) && !defined(SVR4) -# define SVR4 1 -# endif -# ifdef SVR4 -/* define this to whatever it needs to be */ -# define X_POSIX_C_SOURCE 199300L -# endif -# endif - -# ifdef WIN32 -# ifndef _POSIX_ -# define X_NOT_POSIX -# endif -# endif - - -# ifdef __APPLE__ -# define NULL_NOT_ZERO - -/* Defining any of these will sanitize the namespace to JUST want is defined by - * that particular standard. If that happens, we don't get some expected - * prototypes, typedefs, etc (like fd_mask). We can define _DARWIN_C_SOURCE to - * loosen our belts a tad. - */ -# if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) -# ifndef _DARWIN_C_SOURCE -# define _DARWIN_C_SOURCE -# endif -# endif - -# endif - -# ifdef __GNU__ -# ifndef PATH_MAX -# define PATH_MAX 4096 -# endif -# ifndef MAXPATHLEN -# define MAXPATHLEN 4096 -# endif -# endif - -# if defined(__SCO__) || defined(__UNIXWARE__) -# ifndef PATH_MAX -# define PATH_MAX 1024 -# endif -# ifndef MAXPATHLEN -# define MAXPATHLEN 1024 -# endif -# endif - -# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) \ - || defined(__APPLE__) || defined(__DragonFly__) -# ifndef CSRG_BASED -# define CSRG_BASED -# endif -# endif - -#endif /* _XOSDEFS_H_ */ - diff --git a/shell/linux-deps/include/X11/Xpoll.h b/shell/linux-deps/include/X11/Xpoll.h deleted file mode 100644 index e96ea12bb..000000000 --- a/shell/linux-deps/include/X11/Xpoll.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - -Copyright 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -/* - * Copyright © 2005 Daniel Stone - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Daniel Stone not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. Daniel Stone makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * DANIEL STONE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DANIEL STONE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef _XPOLL_H_ -#define _XPOLL_H_ - -#ifndef WIN32 - -#ifndef USE_POLL - -#include - -#include /* Get the FD_* macros. */ - -#include - -#ifdef CSRG_BASED -#include -# if BSD < 199103 -typedef long fd_mask; -# endif -#endif - -#define XFD_SETSIZE 256 - -#ifndef FD_SETSIZE -#define FD_SETSIZE XFD_SETSIZE -#endif - -#ifndef NBBY -#define NBBY 8 /* number of bits in a byte */ -#endif - -#ifndef NFDBITS -#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ -#endif - -#ifndef howmany -#define howmany(x,y) (((x)+((y)-1))/(y)) -#endif - -#if defined(BSD) && BSD < 198911 -typedef struct fd_set { - fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; -} fd_set; -#endif - -# define Select(n,r,w,e,t) select(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t) - -#define __X_FDS_BITS __fds_bits - -#ifndef __FDS_BITS -# define __FDS_BITS(p) ((p)->__X_FDS_BITS) -#endif - -#define __XFDS_BITS(p, n) (__FDS_BITS(p))[n] - -#ifndef FD_SET -#define FD_SET(n, p) (__XFDS_BITS(p, ((n)/NFDBITS)) |= ((fd_mask)1 << ((n) % NFDBITS))) -#endif -#ifndef FD_CLR -#define FD_CLR(n, p) (__XFDS_BITS((p), ((n)/NFDBITS)) &= ~((fd_mask)1 << ((n) % NFDBITS))) -#endif -#ifndef FD_ISSET -#define FD_ISSET(n, p) ((__XFDS_BITS((p), ((n)/NFDBITS))) & ((fd_mask)1 << ((n) % NFDBITS))) -#endif -#ifndef FD_ZERO -#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) -#endif - -/* - * The howmany(FD_SETSIZE, NFDBITS) computes the number of elements in the - * array. before accessing an element in the array we check it exists. - * If it does not exist then the compiler discards the code to access it. - */ -#define XFD_ANYSET(p) \ - ((howmany(FD_SETSIZE, NFDBITS) > 0 && (__XFDS_BITS(p, 0))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 1 && (__XFDS_BITS(p, 1))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 2 && (__XFDS_BITS(p, 2))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 3 && (__XFDS_BITS(p, 3))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 4 && (__XFDS_BITS(p, 4))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 5 && (__XFDS_BITS(p, 5))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 6 && (__XFDS_BITS(p, 6))) || \ - (howmany(FD_SETSIZE, NFDBITS) > 7 && (__XFDS_BITS(p, 7)))) - -#define XFD_COPYSET(src,dst) { \ - int __i__; \ - for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ - __XFDS_BITS((dst), __i__) = __XFDS_BITS((src), __i__); \ - } -#define XFD_ANDSET(dst,b1,b2) { \ - int __i__; \ - for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ - __XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) & (__XFDS_BITS((b2), __i__))); \ - } -#define XFD_ORSET(dst,b1,b2) { \ - int __i__; \ - for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ - __XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) | (__XFDS_BITS((b2), __i__))); \ - } -#define XFD_UNSET(dst,b1) { \ - int __i__; \ - for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ - __XFDS_BITS((dst), __i__) &= ~(__XFDS_BITS((b1), __i__)); \ - } - -#else /* USE_POLL */ -#include -#endif /* USE_POLL */ - -#else /* WIN32 */ - -#define XFD_SETSIZE 256 -#ifndef FD_SETSIZE -#define FD_SETSIZE XFD_SETSIZE -#endif -#include - -#define Select(n,r,w,e,t) select(0,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t) - -#define XFD_SETCOUNT(p) (((fd_set FAR *)(p))->fd_count) -#define XFD_FD(p,i) (((fd_set FAR *)(p))->fd_array[i]) -#define XFD_ANYSET(p) XFD_SETCOUNT(p) - -#define XFD_COPYSET(src,dst) { \ - u_int __i; \ - FD_ZERO(dst); \ - for (__i = 0; __i < XFD_SETCOUNT(src) ; __i++) { \ - XFD_FD(dst,__i) = XFD_FD(src,__i); \ - } \ - XFD_SETCOUNT(dst) = XFD_SETCOUNT(src); \ -} - -#define XFD_ANDSET(dst,b1,b2) { \ - u_int __i; \ - FD_ZERO(dst); \ - for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \ - if (FD_ISSET(XFD_FD(b1,__i), b2)) \ - FD_SET(XFD_FD(b1,__i), dst); \ - } \ -} - -#define XFD_ORSET(dst,b1,b2) { \ - u_int __i; \ - if (dst != b1) XFD_COPYSET(b1,dst); \ - for (__i = 0; __i < XFD_SETCOUNT(b2) ; __i++) { \ - if (!FD_ISSET(XFD_FD(b2,__i), dst)) \ - FD_SET(XFD_FD(b2,__i), dst); \ - } \ -} - -/* this one is really sub-optimal */ -#define XFD_UNSET(dst,b1) { \ - u_int __i; \ - for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \ - FD_CLR(XFD_FD(b1,__i), dst); \ - } \ -} - -/* we have to pay the price of having an array here, unlike with bitmasks - calling twice FD_SET with the same fd is not transparent, so be careful */ -#undef FD_SET -#define FD_SET(fd,set) do { \ - if (XFD_SETCOUNT(set) < FD_SETSIZE && !FD_ISSET(fd,set)) \ - XFD_FD(set,XFD_SETCOUNT(set)++)=(fd); \ -} while(0) - -#define getdtablesize() FD_SETSIZE - -#endif /* WIN32 */ - -#endif /* _XPOLL_H_ */ diff --git a/shell/linux-deps/include/X11/Xproto.h b/shell/linux-deps/include/X11/Xproto.h deleted file mode 100644 index 495d44194..000000000 --- a/shell/linux-deps/include/X11/Xproto.h +++ /dev/null @@ -1,2157 +0,0 @@ -/* Definitions for the X window system used by server and c bindings */ - -/* - * This packet-construction scheme makes the following assumptions: - * - * 1. The compiler is able - * to generate code which addresses one- and two-byte quantities. - * In the worst case, this would be done with bit-fields. If bit-fields - * are used it may be necessary to reorder the request fields in this file, - * depending on the order in which the machine assigns bit fields to - * machine words. There may also be a problem with sign extension, - * as K+R specify that bitfields are always unsigned. - * - * 2. 2- and 4-byte fields in packet structures must be ordered by hand - * such that they are naturally-aligned, so that no compiler will ever - * insert padding bytes. - * - * 3. All packets are hand-padded to a multiple of 4 bytes, for - * the same reason. - */ - -#ifndef XPROTO_H -#define XPROTO_H - -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#include -#include - -/* - * Define constants for the sizes of the network packets. The sz_ prefix is - * used instead of something more descriptive so that the symbols are no more - * than 32 characters in length (which causes problems for some compilers). - */ -#define sz_xSegment 8 -#define sz_xPoint 4 -#define sz_xRectangle 8 -#define sz_xArc 12 -#define sz_xConnClientPrefix 12 -#define sz_xConnSetupPrefix 8 -#define sz_xConnSetup 32 -#define sz_xPixmapFormat 8 -#define sz_xDepth 8 -#define sz_xVisualType 24 -#define sz_xWindowRoot 40 -#define sz_xTimecoord 8 -#define sz_xHostEntry 4 -#define sz_xCharInfo 12 -#define sz_xFontProp 8 -#define sz_xTextElt 2 -#define sz_xColorItem 12 -#define sz_xrgb 8 -#define sz_xGenericReply 32 -#define sz_xGetWindowAttributesReply 44 -#define sz_xGetGeometryReply 32 -#define sz_xQueryTreeReply 32 -#define sz_xInternAtomReply 32 -#define sz_xGetAtomNameReply 32 -#define sz_xGetPropertyReply 32 -#define sz_xListPropertiesReply 32 -#define sz_xGetSelectionOwnerReply 32 -#define sz_xGrabPointerReply 32 -#define sz_xQueryPointerReply 32 -#define sz_xGetMotionEventsReply 32 -#define sz_xTranslateCoordsReply 32 -#define sz_xGetInputFocusReply 32 -#define sz_xQueryKeymapReply 40 -#define sz_xQueryFontReply 60 -#define sz_xQueryTextExtentsReply 32 -#define sz_xListFontsReply 32 -#define sz_xGetFontPathReply 32 -#define sz_xGetImageReply 32 -#define sz_xListInstalledColormapsReply 32 -#define sz_xAllocColorReply 32 -#define sz_xAllocNamedColorReply 32 -#define sz_xAllocColorCellsReply 32 -#define sz_xAllocColorPlanesReply 32 -#define sz_xQueryColorsReply 32 -#define sz_xLookupColorReply 32 -#define sz_xQueryBestSizeReply 32 -#define sz_xQueryExtensionReply 32 -#define sz_xListExtensionsReply 32 -#define sz_xSetMappingReply 32 -#define sz_xGetKeyboardControlReply 52 -#define sz_xGetPointerControlReply 32 -#define sz_xGetScreenSaverReply 32 -#define sz_xListHostsReply 32 -#define sz_xSetModifierMappingReply 32 -#define sz_xError 32 -#define sz_xEvent 32 -#define sz_xKeymapEvent 32 -#define sz_xReq 4 -#define sz_xResourceReq 8 -#define sz_xCreateWindowReq 32 -#define sz_xChangeWindowAttributesReq 12 -#define sz_xChangeSaveSetReq 8 -#define sz_xReparentWindowReq 16 -#define sz_xConfigureWindowReq 12 -#define sz_xCirculateWindowReq 8 -#define sz_xInternAtomReq 8 -#define sz_xChangePropertyReq 24 -#define sz_xDeletePropertyReq 12 -#define sz_xGetPropertyReq 24 -#define sz_xSetSelectionOwnerReq 16 -#define sz_xConvertSelectionReq 24 -#define sz_xSendEventReq 44 -#define sz_xGrabPointerReq 24 -#define sz_xGrabButtonReq 24 -#define sz_xUngrabButtonReq 12 -#define sz_xChangeActivePointerGrabReq 16 -#define sz_xGrabKeyboardReq 16 -#define sz_xGrabKeyReq 16 -#define sz_xUngrabKeyReq 12 -#define sz_xAllowEventsReq 8 -#define sz_xGetMotionEventsReq 16 -#define sz_xTranslateCoordsReq 16 -#define sz_xWarpPointerReq 24 -#define sz_xSetInputFocusReq 12 -#define sz_xOpenFontReq 12 -#define sz_xQueryTextExtentsReq 8 -#define sz_xListFontsReq 8 -#define sz_xSetFontPathReq 8 -#define sz_xCreatePixmapReq 16 -#define sz_xCreateGCReq 16 -#define sz_xChangeGCReq 12 -#define sz_xCopyGCReq 16 -#define sz_xSetDashesReq 12 -#define sz_xSetClipRectanglesReq 12 -#define sz_xCopyAreaReq 28 -#define sz_xCopyPlaneReq 32 -#define sz_xPolyPointReq 12 -#define sz_xPolySegmentReq 12 -#define sz_xFillPolyReq 16 -#define sz_xPutImageReq 24 -#define sz_xGetImageReq 20 -#define sz_xPolyTextReq 16 -#define sz_xImageTextReq 16 -#define sz_xCreateColormapReq 16 -#define sz_xCopyColormapAndFreeReq 12 -#define sz_xAllocColorReq 16 -#define sz_xAllocNamedColorReq 12 -#define sz_xAllocColorCellsReq 12 -#define sz_xAllocColorPlanesReq 16 -#define sz_xFreeColorsReq 12 -#define sz_xStoreColorsReq 8 -#define sz_xStoreNamedColorReq 16 -#define sz_xQueryColorsReq 8 -#define sz_xLookupColorReq 12 -#define sz_xCreateCursorReq 32 -#define sz_xCreateGlyphCursorReq 32 -#define sz_xRecolorCursorReq 20 -#define sz_xQueryBestSizeReq 12 -#define sz_xQueryExtensionReq 8 -#define sz_xChangeKeyboardControlReq 8 -#define sz_xBellReq 4 -#define sz_xChangePointerControlReq 12 -#define sz_xSetScreenSaverReq 12 -#define sz_xChangeHostsReq 8 -#define sz_xListHostsReq 4 -#define sz_xChangeModeReq 4 -#define sz_xRotatePropertiesReq 12 -#define sz_xReply 32 -#define sz_xGrabKeyboardReply 32 -#define sz_xListFontsWithInfoReply 60 -#define sz_xSetPointerMappingReply 32 -#define sz_xGetKeyboardMappingReply 32 -#define sz_xGetPointerMappingReply 32 -#define sz_xGetModifierMappingReply 32 -#define sz_xListFontsWithInfoReq 8 -#define sz_xPolyLineReq 12 -#define sz_xPolyArcReq 12 -#define sz_xPolyRectangleReq 12 -#define sz_xPolyFillRectangleReq 12 -#define sz_xPolyFillArcReq 12 -#define sz_xPolyText8Req 16 -#define sz_xPolyText16Req 16 -#define sz_xImageText8Req 16 -#define sz_xImageText16Req 16 -#define sz_xSetPointerMappingReq 4 -#define sz_xForceScreenSaverReq 4 -#define sz_xSetCloseDownModeReq 4 -#define sz_xClearAreaReq 16 -#define sz_xSetAccessControlReq 4 -#define sz_xGetKeyboardMappingReq 8 -#define sz_xSetModifierMappingReq 4 -#define sz_xPropIconSize 24 -#define sz_xChangeKeyboardMappingReq 8 - - -/* For the purpose of the structure definitions in this file, -we must redefine the following types in terms of Xmd.h's types, which may -include bit fields. All of these are #undef'd at the end of this file, -restoring the definitions in X.h. */ - -#define Window CARD32 -#define Drawable CARD32 -#define Font CARD32 -#define Pixmap CARD32 -#define Cursor CARD32 -#define Colormap CARD32 -#define GContext CARD32 -#define Atom CARD32 -#define VisualID CARD32 -#define Time CARD32 -#define KeyCode CARD8 -#define KeySym CARD32 - -#define X_TCP_PORT 6000 /* add display number */ - -#define xTrue 1 -#define xFalse 0 - - -typedef CARD16 KeyButMask; - -/***************** - connection setup structure. This is followed by - numRoots xWindowRoot structs. -*****************/ - -typedef struct { - CARD8 byteOrder; - BYTE pad; - CARD16 majorVersion B16, minorVersion B16; - CARD16 nbytesAuthProto B16; /* Authorization protocol */ - CARD16 nbytesAuthString B16; /* Authorization string */ - CARD16 pad2 B16; -} xConnClientPrefix; - -typedef struct { - CARD8 success; - BYTE lengthReason; /*num bytes in string following if failure */ - CARD16 majorVersion B16, - minorVersion B16; - CARD16 length B16; /* 1/4 additional bytes in setup info */ -} xConnSetupPrefix; - - -typedef struct { - CARD32 release B32; - CARD32 ridBase B32, - ridMask B32; - CARD32 motionBufferSize B32; - CARD16 nbytesVendor B16; /* number of bytes in vendor string */ - CARD16 maxRequestSize B16; - CARD8 numRoots; /* number of roots structs to follow */ - CARD8 numFormats; /* number of pixmap formats */ - CARD8 imageByteOrder; /* LSBFirst, MSBFirst */ - CARD8 bitmapBitOrder; /* LeastSignificant, MostSign...*/ - CARD8 bitmapScanlineUnit, /* 8, 16, 32 */ - bitmapScanlinePad; /* 8, 16, 32 */ - KeyCode minKeyCode, maxKeyCode; - CARD32 pad2 B32; -} xConnSetup; - -typedef struct { - CARD8 depth; - CARD8 bitsPerPixel; - CARD8 scanLinePad; - CARD8 pad1; - CARD32 pad2 B32; -} xPixmapFormat; - -/* window root */ - -typedef struct { - CARD8 depth; - CARD8 pad1; - CARD16 nVisuals B16; /* number of xVisualType structures following */ - CARD32 pad2 B32; - } xDepth; - -typedef struct { - VisualID visualID B32; -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 bitsPerRGB; - CARD16 colormapEntries B16; - CARD32 redMask B32, greenMask B32, blueMask B32; - CARD32 pad B32; - } xVisualType; - -typedef struct { - Window windowId B32; - Colormap defaultColormap B32; - CARD32 whitePixel B32, blackPixel B32; - CARD32 currentInputMask B32; - CARD16 pixWidth B16, pixHeight B16; - CARD16 mmWidth B16, mmHeight B16; - CARD16 minInstalledMaps B16, maxInstalledMaps B16; - VisualID rootVisualID B32; - CARD8 backingStore; - BOOL saveUnders; - CARD8 rootDepth; - CARD8 nDepths; /* number of xDepth structures following */ -} xWindowRoot; - - -/***************************************************************** - * Structure Defns - * Structures needed for replies - *****************************************************************/ - -/* Used in GetMotionEvents */ - -typedef struct { - CARD32 time B32; - INT16 x B16, y B16; -} xTimecoord; - -typedef struct { - CARD8 family; - BYTE pad; - CARD16 length B16; -} xHostEntry; - -typedef struct { - INT16 leftSideBearing B16, - rightSideBearing B16, - characterWidth B16, - ascent B16, - descent B16; - CARD16 attributes B16; -} xCharInfo; - -typedef struct { - Atom name B32; - CARD32 value B32; -} xFontProp; - -/* - * non-aligned big-endian font ID follows this struct - */ -typedef struct { /* followed by string */ - CARD8 len; /* number of *characters* in string, or FontChange (255) - for font change, or 0 if just delta given */ - INT8 delta; -} xTextElt; - - -typedef struct { - CARD32 pixel B32; - CARD16 red B16, green B16, blue B16; - CARD8 flags; /* DoRed, DoGreen, DoBlue booleans */ - CARD8 pad; -} xColorItem; - - -typedef struct { - CARD16 red B16, green B16, blue B16, pad B16; -} xrgb; - -typedef CARD8 KEYCODE; - - -/***************** - * XRep: - * meant to be 32 byte quantity - *****************/ - -/* GenericReply is the common format of all replies. The "data" items - are specific to each individual reply type. */ - -typedef struct { - BYTE type; /* X_Reply */ - BYTE data1; /* depends on reply type */ - CARD16 sequenceNumber B16; /* of last request received by server */ - CARD32 length B32; /* 4 byte quantities beyond size of GenericReply */ - CARD32 data00 B32; - CARD32 data01 B32; - CARD32 data02 B32; - CARD32 data03 B32; - CARD32 data04 B32; - CARD32 data05 B32; - } xGenericReply; - -/* Individual reply formats. */ - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 backingStore; - CARD16 sequenceNumber B16; - CARD32 length B32; /* NOT 0; this is an extra-large reply */ - VisualID visualID B32; -#if defined(__cplusplus) || defined(c_plusplus) - CARD16 c_class B16; -#else - CARD16 class B16; -#endif - CARD8 bitGravity; - CARD8 winGravity; - CARD32 backingBitPlanes B32; - CARD32 backingPixel B32; - BOOL saveUnder; - BOOL mapInstalled; - CARD8 mapState; - BOOL override; - Colormap colormap B32; - CARD32 allEventMasks B32; - CARD32 yourEventMask B32; - CARD16 doNotPropagateMask B16; - CARD16 pad B16; - } xGetWindowAttributesReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 depth; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window root B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; - CARD16 borderWidth B16; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xGetGeometryReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - Window root B32, parent B32; - CARD16 nChildren B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xQueryTreeReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Atom atom B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xInternAtomReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* of additional bytes */ - CARD16 nameLength B16; /* # of characters in name */ - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetAtomNameReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 format; - CARD16 sequenceNumber B16; - CARD32 length B32; /* of additional bytes */ - Atom propertyType B32; - CARD32 bytesAfter B32; - CARD32 nItems B32; /* # of 8, 16, or 32-bit entities in reply */ - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xGetPropertyReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nProperties B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListPropertiesReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window owner B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetSelectionOwnerReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE status; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGrabPointerReply; - -typedef xGrabPointerReply xGrabKeyboardReply; - -typedef struct { - BYTE type; /* X_Reply */ - BOOL sameScreen; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window root B32, child B32; - INT16 rootX B16, rootY B16, winX B16, winY B16; - CARD16 mask B16; - CARD16 pad1 B16; - CARD32 pad B32; - } xQueryPointerReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 nEvents B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetMotionEventsReply; - -typedef struct { - BYTE type; /* X_Reply */ - BOOL sameScreen; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window child B32; - INT16 dstX B16, dstY B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xTranslateCoordsReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 revertTo; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window focus B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xGetInputFocusReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 2, NOT 0; this is an extra-large reply */ - BYTE map[32]; - } xQueryKeymapReply; - -/* Warning: this MUST match (up to component renaming) xListFontsWithInfoReply */ -typedef struct _xQueryFontReply { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* definitely > 0, even if "nCharInfos" is 0 */ - xCharInfo minBounds; -#ifndef WORD64 - CARD32 walign1 B32; -#endif - xCharInfo maxBounds; -#ifndef WORD64 - CARD32 walign2 B32; -#endif - CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; - CARD16 defaultChar B16; - CARD16 nFontProps B16; /* followed by this many xFontProp structures */ - CARD8 drawDirection; - CARD8 minByte1, maxByte1; - BOOL allCharsExist; - INT16 fontAscent B16, fontDescent B16; - CARD32 nCharInfos B32; /* followed by this many xCharInfo structures */ -} xQueryFontReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 drawDirection; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - INT16 fontAscent B16, fontDescent B16; - INT16 overallAscent B16, overallDescent B16; - INT32 overallWidth B32, overallLeft B32, overallRight B32; - CARD32 pad B32; - } xQueryTextExtentsReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nFonts B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListFontsReply; - -/* Warning: this MUST match (up to component renaming) xQueryFontReply */ -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nameLength; /* 0 indicates end-of-reply-sequence */ - CARD16 sequenceNumber B16; - CARD32 length B32; /* definitely > 0, even if "nameLength" is 0 */ - xCharInfo minBounds; -#ifndef WORD64 - CARD32 walign1 B32; -#endif - xCharInfo maxBounds; -#ifndef WORD64 - CARD32 walign2 B32; -#endif - CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; - CARD16 defaultChar B16; - CARD16 nFontProps B16; /* followed by this many xFontProp structures */ - CARD8 drawDirection; - CARD8 minByte1, maxByte1; - BOOL allCharsExist; - INT16 fontAscent B16, fontDescent B16; - CARD32 nReplies B32; /* hint as to how many more replies might be coming */ -} xListFontsWithInfoReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPaths B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetFontPathReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 depth; - CARD16 sequenceNumber B16; - CARD32 length B32; - VisualID visual B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetImageReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nColormaps B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListInstalledColormapsReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 red B16, green B16, blue B16; - CARD16 pad2 B16; - CARD32 pixel B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xAllocColorReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD32 pixel B32; - CARD16 exactRed B16, exactGreen B16, exactBlue B16; - CARD16 screenRed B16, screenGreen B16, screenBlue B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xAllocNamedColorReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPixels B16, nMasks B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xAllocColorCellsReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPixels B16; - CARD16 pad2 B16; - CARD32 redMask B32, greenMask B32, blueMask B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - } xAllocColorPlanesReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nColors B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryColorsReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 exactRed B16, exactGreen B16, exactBlue B16; - CARD16 screenRed B16, screenGreen B16, screenBlue B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xLookupColorReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 width B16, height B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryBestSizeReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - BOOL present; - CARD8 major_opcode; - CARD8 first_event; - CARD8 first_error; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryExtensionReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nExtensions; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListExtensionsReply; - - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 success; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xSetMappingReply; -typedef xSetMappingReply xSetPointerMappingReply; -typedef xSetMappingReply xSetModifierMappingReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nElts; /* how many elements does the map have */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetPointerMappingReply; - -typedef struct { - BYTE type; - CARD8 keySymsPerKeyCode; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xGetKeyboardMappingReply; - -typedef struct { - BYTE type; - CARD8 numKeyPerModifier; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xGetModifierMappingReply; - -typedef struct { - BYTE type; /* X_Reply */ - BOOL globalAutoRepeat; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 5 */ - CARD32 ledMask B32; - CARD8 keyClickPercent, bellPercent; - CARD16 bellPitch B16, bellDuration B16; - CARD16 pad B16; - BYTE map[32]; /* bit masks start here */ - } xGetKeyboardControlReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 accelNumerator B16, accelDenominator B16; - CARD16 threshold B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetPointerControlReply; - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 timeout B16, interval B16; - BOOL preferBlanking; - BOOL allowExposures; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetScreenSaverReply; - -typedef struct { - BYTE type; /* X_Reply */ - BOOL enabled; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nHosts B16; - CARD16 pad1 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListHostsReply; - - - - -/***************************************************************** - * Xerror - * All errors are 32 bytes - *****************************************************************/ - -typedef struct { - BYTE type; /* X_Error */ - BYTE errorCode; - CARD16 sequenceNumber B16; /* the nth request from this client */ - CARD32 resourceID B32; - CARD16 minorCode B16; - CARD8 majorCode; - BYTE pad1; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xError; - -/***************************************************************** - * xEvent - * All events are 32 bytes - *****************************************************************/ - -typedef struct _xEvent { - union { - struct { - BYTE type; - BYTE detail; - CARD16 sequenceNumber B16; - } u; - struct { - CARD32 pad00 B32; - Time time B32; - Window root B32, event B32, child B32; - INT16 rootX B16, rootY B16, eventX B16, eventY B16; - KeyButMask state B16; - BOOL sameScreen; - BYTE pad1; - } keyButtonPointer; - struct { - CARD32 pad00 B32; - Time time B32; - Window root B32, event B32, child B32; - INT16 rootX B16, rootY B16, eventX B16, eventY B16; - KeyButMask state B16; - BYTE mode; /* really XMode */ - BYTE flags; /* sameScreen and focus booleans, packed together */ -#define ELFlagFocus (1<<0) -#define ELFlagSameScreen (1<<1) - } enterLeave; - struct { - CARD32 pad00 B32; - Window window B32; - BYTE mode; /* really XMode */ - BYTE pad1, pad2, pad3; - } focus; - struct { - CARD32 pad00 B32; - Window window B32; - CARD16 x B16, y B16, width B16, height B16; - CARD16 count B16; - CARD16 pad2 B16; - } expose; - struct { - CARD32 pad00 B32; - Drawable drawable B32; - CARD16 x B16, y B16, width B16, height B16; - CARD16 minorEvent B16; - CARD16 count B16; - BYTE majorEvent; - BYTE pad1, pad2, pad3; - } graphicsExposure; - struct { - CARD32 pad00 B32; - Drawable drawable B32; - CARD16 minorEvent B16; - BYTE majorEvent; - BYTE bpad; - } noExposure; - struct { - CARD32 pad00 B32; - Window window B32; - CARD8 state; - BYTE pad1, pad2, pad3; - } visibility; - struct { - CARD32 pad00 B32; - Window parent B32, window B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - BOOL override; - BYTE bpad; - } createNotify; -/* - * The event fields in the structures for DestroyNotify, UnmapNotify, - * MapNotify, ReparentNotify, ConfigureNotify, CirculateNotify, GravityNotify, - * must be at the same offset because server internal code is depending upon - * this to patch up the events before they are delivered. - * Also note that MapRequest, ConfigureRequest and CirculateRequest have - * the same offset for the event window. - */ - struct { - CARD32 pad00 B32; - Window event B32, window B32; - } destroyNotify; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - BOOL fromConfigure; - BYTE pad1, pad2, pad3; - } unmapNotify; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - BOOL override; - BYTE pad1, pad2, pad3; - } mapNotify; - struct { - CARD32 pad00 B32; - Window parent B32, window B32; - } mapRequest; - struct { - CARD32 pad00 B32; - Window event B32, window B32, parent B32; - INT16 x B16, y B16; - BOOL override; - BYTE pad1, pad2, pad3; - } reparent; - struct { - CARD32 pad00 B32; - Window event B32, window B32, aboveSibling B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - BOOL override; - BYTE bpad; - } configureNotify; - struct { - CARD32 pad00 B32; - Window parent B32, window B32, sibling B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - CARD16 valueMask B16; - CARD32 pad1 B32; - } configureRequest; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - INT16 x B16, y B16; - CARD32 pad1 B32, pad2 B32, pad3 B32, pad4 B32; - } gravity; - struct { - CARD32 pad00 B32; - Window window B32; - CARD16 width B16, height B16; - } resizeRequest; - struct { -/* The event field in the circulate record is really the parent when this - is used as a CirculateRequest instead of a CirculateNotify */ - CARD32 pad00 B32; - Window event B32, window B32, parent B32; - BYTE place; /* Top or Bottom */ - BYTE pad1, pad2, pad3; - } circulate; - struct { - CARD32 pad00 B32; - Window window B32; - Atom atom B32; - Time time B32; - BYTE state; /* NewValue or Deleted */ - BYTE pad1; - CARD16 pad2 B16; - } property; - struct { - CARD32 pad00 B32; - Time time B32; - Window window B32; - Atom atom B32; - } selectionClear; - struct { - CARD32 pad00 B32; - Time time B32; - Window owner B32, requestor B32; - Atom selection B32, target B32, property B32; - } selectionRequest; - struct { - CARD32 pad00 B32; - Time time B32; - Window requestor B32; - Atom selection B32, target B32, property B32; - } selectionNotify; - struct { - CARD32 pad00 B32; - Window window B32; - Colormap colormap B32; -#if defined(__cplusplus) || defined(c_plusplus) - BOOL c_new; -#else - BOOL new; -#endif - BYTE state; /* Installed or UnInstalled */ - BYTE pad1, pad2; - } colormap; - struct { - CARD32 pad00 B32; - CARD8 request; - KeyCode firstKeyCode; - CARD8 count; - BYTE pad1; - } mappingNotify; - struct { - CARD32 pad00 B32; - Window window B32; - union { - struct { - Atom type B32; - INT32 longs0 B32; - INT32 longs1 B32; - INT32 longs2 B32; - INT32 longs3 B32; - INT32 longs4 B32; - } l; - struct { - Atom type B32; - INT16 shorts0 B16; - INT16 shorts1 B16; - INT16 shorts2 B16; - INT16 shorts3 B16; - INT16 shorts4 B16; - INT16 shorts5 B16; - INT16 shorts6 B16; - INT16 shorts7 B16; - INT16 shorts8 B16; - INT16 shorts9 B16; - } s; - struct { - Atom type B32; - INT8 bytes[20]; - } b; - } u; - } clientMessage; - } u; -} xEvent; - -/********************************************************* - * - * Generic event - * - * Those events are not part of the core protocol spec and can be used by - * various extensions. - * type is always GenericEvent - * extension is the minor opcode of the extension the event belongs to. - * evtype is the actual event type, unique __per extension__. - * - * GenericEvents can be longer than 32 bytes, with the length field - * specifying the number of 4 byte blocks after the first 32 bytes. - * - * - */ -typedef struct -{ - BYTE type; - CARD8 extension; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 evtype B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xGenericEvent; - - - -/* KeymapNotify events are not included in the above union because they - are different from all other events: they do not have a "detail" - or "sequenceNumber", so there is room for a 248-bit key mask. */ - -typedef struct { - BYTE type; - BYTE map[31]; - } xKeymapEvent; - -#define XEventSize (sizeof(xEvent)) - -/* XReply is the union of all the replies above whose "fixed part" -fits in 32 bytes. It does NOT include GetWindowAttributesReply, -QueryFontReply, QueryKeymapReply, or GetKeyboardControlReply -ListFontsWithInfoReply */ - -typedef union { - xGenericReply generic; - xGetGeometryReply geom; - xQueryTreeReply tree; - xInternAtomReply atom; - xGetAtomNameReply atomName; - xGetPropertyReply property; - xListPropertiesReply listProperties; - xGetSelectionOwnerReply selection; - xGrabPointerReply grabPointer; - xGrabKeyboardReply grabKeyboard; - xQueryPointerReply pointer; - xGetMotionEventsReply motionEvents; - xTranslateCoordsReply coords; - xGetInputFocusReply inputFocus; - xQueryTextExtentsReply textExtents; - xListFontsReply fonts; - xGetFontPathReply fontPath; - xGetImageReply image; - xListInstalledColormapsReply colormaps; - xAllocColorReply allocColor; - xAllocNamedColorReply allocNamedColor; - xAllocColorCellsReply colorCells; - xAllocColorPlanesReply colorPlanes; - xQueryColorsReply colors; - xLookupColorReply lookupColor; - xQueryBestSizeReply bestSize; - xQueryExtensionReply extension; - xListExtensionsReply extensions; - xSetModifierMappingReply setModifierMapping; - xGetModifierMappingReply getModifierMapping; - xSetPointerMappingReply setPointerMapping; - xGetKeyboardMappingReply getKeyboardMapping; - xGetPointerMappingReply getPointerMapping; - xGetPointerControlReply pointerControl; - xGetScreenSaverReply screenSaver; - xListHostsReply hosts; - xError error; - xEvent event; -} xReply; - - - -/***************************************************************** - * REQUESTS - *****************************************************************/ - - -/* Request structure */ - -typedef struct _xReq { - CARD8 reqType; - CARD8 data; /* meaning depends on request type */ - CARD16 length B16; /* length in 4 bytes quantities - of whole request, including this header */ -} xReq; - -/***************************************************************** - * structures that follow request. - *****************************************************************/ - -/* ResourceReq is used for any request which has a resource ID - (or Atom or Time) as its one and only argument. */ - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD32 id B32; /* a Window, Drawable, Font, GContext, Pixmap, etc. */ - } xResourceReq; - -typedef struct { - CARD8 reqType; - CARD8 depth; - CARD16 length B16; - Window wid B32, parent B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; -#if defined(__cplusplus) || defined(c_plusplus) - CARD16 c_class B16; -#else - CARD16 class B16; -#endif - VisualID visual B32; - CARD32 mask B32; -} xCreateWindowReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - CARD32 valueMask B32; -} xChangeWindowAttributesReq; - -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - Window window B32; -} xChangeSaveSetReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32, parent B32; - INT16 x B16, y B16; -} xReparentWindowReq; - -typedef struct { - CARD8 reqType; - CARD8 pad; - CARD16 length B16; - Window window B32; - CARD16 mask B16; - CARD16 pad2 B16; -} xConfigureWindowReq; - -typedef struct { - CARD8 reqType; - CARD8 direction; - CARD16 length B16; - Window window B32; -} xCirculateWindowReq; - -typedef struct { /* followed by padded string */ - CARD8 reqType; - BOOL onlyIfExists; - CARD16 length B16; - CARD16 nbytes B16; /* number of bytes in string */ - CARD16 pad B16; -} xInternAtomReq; - -typedef struct { - CARD8 reqType; - CARD8 mode; - CARD16 length B16; - Window window B32; - Atom property B32, type B32; - CARD8 format; - BYTE pad[3]; - CARD32 nUnits B32; /* length of stuff following, depends on format */ -} xChangePropertyReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Atom property B32; -} xDeletePropertyReq; - -typedef struct { - CARD8 reqType; -#if defined(__cplusplus) || defined(c_plusplus) - BOOL c_delete; -#else - BOOL delete; -#endif - CARD16 length B16; - Window window B32; - Atom property B32, type B32; - CARD32 longOffset B32; - CARD32 longLength B32; -} xGetPropertyReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Atom selection B32; - Time time B32; -} xSetSelectionOwnerReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window requestor B32; - Atom selection B32, target B32, property B32; - Time time B32; - } xConvertSelectionReq; - -typedef struct { - CARD8 reqType; - BOOL propagate; - CARD16 length B16; - Window destination B32; - CARD32 eventMask B32; -#ifdef WORD64 - /* the structure should have been quad-aligned */ - BYTE eventdata[SIZEOF(xEvent)]; -#else - xEvent event; -#endif /* WORD64 */ -} xSendEventReq; - -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 eventMask B16; - BYTE pointerMode, keyboardMode; - Window confineTo B32; - Cursor cursor B32; - Time time B32; -} xGrabPointerReq; - -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 eventMask B16; - BYTE pointerMode, keyboardMode; - Window confineTo B32; - Cursor cursor B32; - CARD8 button; - BYTE pad; - CARD16 modifiers B16; -} xGrabButtonReq; - -typedef struct { - CARD8 reqType; - CARD8 button; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD16 pad B16; -} xUngrabButtonReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cursor B32; - Time time B32; - CARD16 eventMask B16; - CARD16 pad2 B16; -} xChangeActivePointerGrabReq; - -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - Time time B32; - BYTE pointerMode, keyboardMode; - CARD16 pad B16; -} xGrabKeyboardReq; - -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD8 key; - BYTE pointerMode, keyboardMode; - BYTE pad1, pad2, pad3; -} xGrabKeyReq; - -typedef struct { - CARD8 reqType; - CARD8 key; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD16 pad B16; -} xUngrabKeyReq; - -typedef struct { - CARD8 reqType; - CARD8 mode; - CARD16 length B16; - Time time B32; -} xAllowEventsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Time start B32, stop B32; -} xGetMotionEventsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window srcWid B32, dstWid B32; - INT16 srcX B16, srcY B16; -} xTranslateCoordsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window srcWid B32, dstWid B32; - INT16 srcX B16, srcY B16; - CARD16 srcWidth B16, srcHeight B16; - INT16 dstX B16, dstY B16; -} xWarpPointerReq; - -typedef struct { - CARD8 reqType; - CARD8 revertTo; - CARD16 length B16; - Window focus B32; - Time time B32; -} xSetInputFocusReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Font fid B32; - CARD16 nbytes B16; - BYTE pad1, pad2; /* string follows on word boundary */ -} xOpenFontReq; - -typedef struct { - CARD8 reqType; - BOOL oddLength; - CARD16 length B16; - Font fid B32; - } xQueryTextExtentsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 maxNames B16; - CARD16 nbytes B16; /* followed immediately by string bytes */ -} xListFontsReq; - -typedef xListFontsReq xListFontsWithInfoReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 nFonts B16; - BYTE pad1, pad2; /* LISTofSTRING8 follows on word boundary */ -} xSetFontPathReq; - -typedef struct { - CARD8 reqType; - CARD8 depth; - CARD16 length B16; - Pixmap pid B32; - Drawable drawable B32; - CARD16 width B16, height B16; -} xCreatePixmapReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - Drawable drawable B32; - CARD32 mask B32; -} xCreateGCReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - CARD32 mask B32; -} xChangeGCReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext srcGC B32, dstGC B32; - CARD32 mask B32; -} xCopyGCReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - CARD16 dashOffset B16; - CARD16 nDashes B16; /* length LISTofCARD8 of values following */ -} xSetDashesReq; - -typedef struct { - CARD8 reqType; - BYTE ordering; - CARD16 length B16; - GContext gc B32; - INT16 xOrigin B16, yOrigin B16; -} xSetClipRectanglesReq; - -typedef struct { - CARD8 reqType; - BOOL exposures; - CARD16 length B16; - Window window B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; -} xClearAreaReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable srcDrawable B32, dstDrawable B32; - GContext gc B32; - INT16 srcX B16, srcY B16, dstX B16, dstY B16; - CARD16 width B16, height B16; -} xCopyAreaReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable srcDrawable B32, dstDrawable B32; - GContext gc B32; - INT16 srcX B16, srcY B16, dstX B16, dstY B16; - CARD16 width B16, height B16; - CARD32 bitPlane B32; -} xCopyPlaneReq; - -typedef struct { - CARD8 reqType; - BYTE coordMode; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; -} xPolyPointReq; - -typedef xPolyPointReq xPolyLineReq; /* same request structure */ - -/* The following used for PolySegment, PolyRectangle, PolyArc, PolyFillRectangle, PolyFillArc */ - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; -} xPolySegmentReq; - -typedef xPolySegmentReq xPolyArcReq; -typedef xPolySegmentReq xPolyRectangleReq; -typedef xPolySegmentReq xPolyFillRectangleReq; -typedef xPolySegmentReq xPolyFillArcReq; - -typedef struct _FillPolyReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - BYTE shape; - BYTE coordMode; - CARD16 pad1 B16; -} xFillPolyReq; - - -typedef struct _PutImageReq { - CARD8 reqType; - CARD8 format; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - CARD16 width B16, height B16; - INT16 dstX B16, dstY B16; - CARD8 leftPad; - CARD8 depth; - CARD16 pad B16; -} xPutImageReq; - -typedef struct { - CARD8 reqType; - CARD8 format; - CARD16 length B16; - Drawable drawable B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; - CARD32 planeMask B32; -} xGetImageReq; - -/* the following used by PolyText8 and PolyText16 */ - -typedef struct { - CARD8 reqType; - CARD8 pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - INT16 x B16, y B16; /* items (xTextElt) start after struct */ -} xPolyTextReq; - -typedef xPolyTextReq xPolyText8Req; -typedef xPolyTextReq xPolyText16Req; - -typedef struct { - CARD8 reqType; - BYTE nChars; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - INT16 x B16, y B16; -} xImageTextReq; - -typedef xImageTextReq xImageText8Req; -typedef xImageTextReq xImageText16Req; - -typedef struct { - CARD8 reqType; - BYTE alloc; - CARD16 length B16; - Colormap mid B32; - Window window B32; - VisualID visual B32; -} xCreateColormapReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap mid B32; - Colormap srcCmap B32; -} xCopyColormapAndFreeReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 red B16, green B16, blue B16; - CARD16 pad2 B16; -} xAllocColorReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 nbytes B16; /* followed by structure */ - BYTE pad1, pad2; -} xAllocNamedColorReq; - -typedef struct { - CARD8 reqType; - BOOL contiguous; - CARD16 length B16; - Colormap cmap B32; - CARD16 colors B16, planes B16; -} xAllocColorCellsReq; - -typedef struct { - CARD8 reqType; - BOOL contiguous; - CARD16 length B16; - Colormap cmap B32; - CARD16 colors B16, red B16, green B16, blue B16; -} xAllocColorPlanesReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD32 planeMask B32; -} xFreeColorsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; -} xStoreColorsReq; - -typedef struct { - CARD8 reqType; - CARD8 flags; /* DoRed, DoGreen, DoBlue, as in xColorItem */ - CARD16 length B16; - Colormap cmap B32; - CARD32 pixel B32; - CARD16 nbytes B16; /* number of name string bytes following structure */ - BYTE pad1, pad2; - } xStoreNamedColorReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; -} xQueryColorsReq; - -typedef struct { /* followed by string of length len */ - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 nbytes B16; /* number of string bytes following structure*/ - BYTE pad1, pad2; -} xLookupColorReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cid B32; - Pixmap source B32, mask B32; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; - CARD16 x B16, y B16; -} xCreateCursorReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cid B32; - Font source B32, mask B32; - CARD16 sourceChar B16, maskChar B16; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; -} xCreateGlyphCursorReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cursor B32; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; -} xRecolorCursorReq; - -typedef struct { - CARD8 reqType; -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD16 length B16; - Drawable drawable B32; - CARD16 width B16, height B16; -} xQueryBestSizeReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 nbytes B16; /* number of string bytes following structure */ - BYTE pad1, pad2; -} xQueryExtensionReq; - -typedef struct { - CARD8 reqType; - CARD8 numKeyPerModifier; - CARD16 length B16; -} xSetModifierMappingReq; - -typedef struct { - CARD8 reqType; - CARD8 nElts; /* how many elements in the map */ - CARD16 length B16; -} xSetPointerMappingReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - KeyCode firstKeyCode; - CARD8 count; - CARD16 pad1 B16; -} xGetKeyboardMappingReq; - -typedef struct { - CARD8 reqType; - CARD8 keyCodes; - CARD16 length B16; - KeyCode firstKeyCode; - CARD8 keySymsPerKeyCode; - CARD16 pad1 B16; -} xChangeKeyboardMappingReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD32 mask B32; -} xChangeKeyboardControlReq; - -typedef struct { - CARD8 reqType; - INT8 percent; /* -100 to 100 */ - CARD16 length B16; -} xBellReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - INT16 accelNum B16, accelDenum B16; - INT16 threshold B16; - BOOL doAccel, doThresh; -} xChangePointerControlReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - INT16 timeout B16, interval B16; - BYTE preferBlank, allowExpose; - CARD16 pad2 B16; -} xSetScreenSaverReq; - -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - CARD8 hostFamily; - BYTE pad; - CARD16 hostLength B16; -} xChangeHostsReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - } xListHostsReq; - -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - } xChangeModeReq; - -typedef xChangeModeReq xSetAccessControlReq; -typedef xChangeModeReq xSetCloseDownModeReq; -typedef xChangeModeReq xForceScreenSaverReq; - -typedef struct { /* followed by LIST of ATOM */ - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - CARD16 nAtoms B16; - INT16 nPositions B16; - } xRotatePropertiesReq; - - - -/* Reply codes */ - -#define X_Reply 1 /* Normal reply */ -#define X_Error 0 /* Error */ - -/* Request codes */ - -#define X_CreateWindow 1 -#define X_ChangeWindowAttributes 2 -#define X_GetWindowAttributes 3 -#define X_DestroyWindow 4 -#define X_DestroySubwindows 5 -#define X_ChangeSaveSet 6 -#define X_ReparentWindow 7 -#define X_MapWindow 8 -#define X_MapSubwindows 9 -#define X_UnmapWindow 10 -#define X_UnmapSubwindows 11 -#define X_ConfigureWindow 12 -#define X_CirculateWindow 13 -#define X_GetGeometry 14 -#define X_QueryTree 15 -#define X_InternAtom 16 -#define X_GetAtomName 17 -#define X_ChangeProperty 18 -#define X_DeleteProperty 19 -#define X_GetProperty 20 -#define X_ListProperties 21 -#define X_SetSelectionOwner 22 -#define X_GetSelectionOwner 23 -#define X_ConvertSelection 24 -#define X_SendEvent 25 -#define X_GrabPointer 26 -#define X_UngrabPointer 27 -#define X_GrabButton 28 -#define X_UngrabButton 29 -#define X_ChangeActivePointerGrab 30 -#define X_GrabKeyboard 31 -#define X_UngrabKeyboard 32 -#define X_GrabKey 33 -#define X_UngrabKey 34 -#define X_AllowEvents 35 -#define X_GrabServer 36 -#define X_UngrabServer 37 -#define X_QueryPointer 38 -#define X_GetMotionEvents 39 -#define X_TranslateCoords 40 -#define X_WarpPointer 41 -#define X_SetInputFocus 42 -#define X_GetInputFocus 43 -#define X_QueryKeymap 44 -#define X_OpenFont 45 -#define X_CloseFont 46 -#define X_QueryFont 47 -#define X_QueryTextExtents 48 -#define X_ListFonts 49 -#define X_ListFontsWithInfo 50 -#define X_SetFontPath 51 -#define X_GetFontPath 52 -#define X_CreatePixmap 53 -#define X_FreePixmap 54 -#define X_CreateGC 55 -#define X_ChangeGC 56 -#define X_CopyGC 57 -#define X_SetDashes 58 -#define X_SetClipRectangles 59 -#define X_FreeGC 60 -#define X_ClearArea 61 -#define X_CopyArea 62 -#define X_CopyPlane 63 -#define X_PolyPoint 64 -#define X_PolyLine 65 -#define X_PolySegment 66 -#define X_PolyRectangle 67 -#define X_PolyArc 68 -#define X_FillPoly 69 -#define X_PolyFillRectangle 70 -#define X_PolyFillArc 71 -#define X_PutImage 72 -#define X_GetImage 73 -#define X_PolyText8 74 -#define X_PolyText16 75 -#define X_ImageText8 76 -#define X_ImageText16 77 -#define X_CreateColormap 78 -#define X_FreeColormap 79 -#define X_CopyColormapAndFree 80 -#define X_InstallColormap 81 -#define X_UninstallColormap 82 -#define X_ListInstalledColormaps 83 -#define X_AllocColor 84 -#define X_AllocNamedColor 85 -#define X_AllocColorCells 86 -#define X_AllocColorPlanes 87 -#define X_FreeColors 88 -#define X_StoreColors 89 -#define X_StoreNamedColor 90 -#define X_QueryColors 91 -#define X_LookupColor 92 -#define X_CreateCursor 93 -#define X_CreateGlyphCursor 94 -#define X_FreeCursor 95 -#define X_RecolorCursor 96 -#define X_QueryBestSize 97 -#define X_QueryExtension 98 -#define X_ListExtensions 99 -#define X_ChangeKeyboardMapping 100 -#define X_GetKeyboardMapping 101 -#define X_ChangeKeyboardControl 102 -#define X_GetKeyboardControl 103 -#define X_Bell 104 -#define X_ChangePointerControl 105 -#define X_GetPointerControl 106 -#define X_SetScreenSaver 107 -#define X_GetScreenSaver 108 -#define X_ChangeHosts 109 -#define X_ListHosts 110 -#define X_SetAccessControl 111 -#define X_SetCloseDownMode 112 -#define X_KillClient 113 -#define X_RotateProperties 114 -#define X_ForceScreenSaver 115 -#define X_SetPointerMapping 116 -#define X_GetPointerMapping 117 -#define X_SetModifierMapping 118 -#define X_GetModifierMapping 119 -#define X_NoOperation 127 - -/* restore these definitions back to the typedefs in X.h */ -#undef Window -#undef Drawable -#undef Font -#undef Pixmap -#undef Cursor -#undef Colormap -#undef GContext -#undef Atom -#undef VisualID -#undef Time -#undef KeyCode -#undef KeySym - -#endif /* XPROTO_H */ diff --git a/shell/linux-deps/include/X11/Xprotostr.h b/shell/linux-deps/include/X11/Xprotostr.h deleted file mode 100644 index a9e854d37..000000000 --- a/shell/linux-deps/include/X11/Xprotostr.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef XPROTOSTRUCTS_H -#define XPROTOSTRUCTS_H - -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ -#include - -/* Used by PolySegment */ - -typedef struct _xSegment { - INT16 x1 B16, y1 B16, x2 B16, y2 B16; -} xSegment; - -/* POINT */ - -typedef struct _xPoint { - INT16 x B16, y B16; -} xPoint; - -typedef struct _xRectangle { - INT16 x B16, y B16; - CARD16 width B16, height B16; -} xRectangle; - -/* ARC */ - -typedef struct _xArc { - INT16 x B16, y B16; - CARD16 width B16, height B16; - INT16 angle1 B16, angle2 B16; -} xArc; - -#endif /* XPROTOSTRUCTS_H */ diff --git a/shell/linux-deps/include/X11/Xregion.h b/shell/linux-deps/include/X11/Xregion.h deleted file mode 100644 index c25d70b41..000000000 --- a/shell/linux-deps/include/X11/Xregion.h +++ /dev/null @@ -1,189 +0,0 @@ -/************************************************************************ - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -#ifndef _X11_XREGION_H_ -#define _X11_XREGION_H_ - -typedef struct { - short x1, x2, y1, y2; -} Box, BOX, BoxRec, *BoxPtr; - -typedef struct { - short x, y, width, height; -}RECTANGLE, RectangleRec, *RectanglePtr; - -#define TRUE 1 -#define FALSE 0 -#define MAXSHORT 32767 -#define MINSHORT -MAXSHORT -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - - -/* - * clip region - */ - -typedef struct _XRegion { - long size; - long numRects; - BOX *rects; - BOX extents; -} REGION; - -/* Xutil.h contains the declaration: - * typedef struct _XRegion *Region; - */ - -/* 1 if two BOXs overlap. - * 0 if two BOXs do not overlap. - * Remember, x2 and y2 are not in the region - */ -#define EXTENTCHECK(r1, r2) \ - ((r1)->x2 > (r2)->x1 && \ - (r1)->x1 < (r2)->x2 && \ - (r1)->y2 > (r2)->y1 && \ - (r1)->y1 < (r2)->y2) - -/* - * update region extents - */ -#define EXTENTS(r,idRect){\ - if((r)->x1 < (idRect)->extents.x1)\ - (idRect)->extents.x1 = (r)->x1;\ - if((r)->y1 < (idRect)->extents.y1)\ - (idRect)->extents.y1 = (r)->y1;\ - if((r)->x2 > (idRect)->extents.x2)\ - (idRect)->extents.x2 = (r)->x2;\ - if((r)->y2 > (idRect)->extents.y2)\ - (idRect)->extents.y2 = (r)->y2;\ - } - -/* - * Check to see if there is enough memory in the present region. - */ -#define MEMCHECK(reg, rect, firstrect){\ - if ((reg)->numRects >= ((reg)->size - 1)){\ - (firstrect) = (BOX *) Xrealloc \ - ((char *)(firstrect), (unsigned) (2 * (sizeof(BOX)) * ((reg)->size)));\ - if ((firstrect) == 0)\ - return(0);\ - (reg)->size *= 2;\ - (rect) = &(firstrect)[(reg)->numRects];\ - }\ - } - -/* this routine checks to see if the previous rectangle is the same - * or subsumes the new rectangle to add. - */ - -#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\ - (!(((Reg)->numRects > 0)&&\ - ((R-1)->y1 == (Ry1)) &&\ - ((R-1)->y2 == (Ry2)) &&\ - ((R-1)->x1 <= (Rx1)) &&\ - ((R-1)->x2 >= (Rx2)))) - -/* add a rectangle to the given Region */ -#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\ - if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\ - CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ - (r)->x1 = (rx1);\ - (r)->y1 = (ry1);\ - (r)->x2 = (rx2);\ - (r)->y2 = (ry2);\ - EXTENTS((r), (reg));\ - (reg)->numRects++;\ - (r)++;\ - }\ - } - - - -/* add a rectangle to the given Region */ -#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\ - if ((rx1 < rx2) && (ry1 < ry2) &&\ - CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\ - (r)->x1 = (rx1);\ - (r)->y1 = (ry1);\ - (r)->x2 = (rx2);\ - (r)->y2 = (ry2);\ - (reg)->numRects++;\ - (r)++;\ - }\ - } - -#define EMPTY_REGION(pReg) pReg->numRects = 0 - -#define REGION_NOT_EMPTY(pReg) pReg->numRects - -#define INBOX(r, x, y) \ - ( ( ((r).x2 > x)) && \ - ( ((r).x1 <= x)) && \ - ( ((r).y2 > y)) && \ - ( ((r).y1 <= y)) ) - -/* - * number of points to buffer before sending them off - * to scanlines() : Must be an even number - */ -#define NUMPTSTOBUFFER 200 - -/* - * used to allocate buffers for points and link - * the buffers together - */ -typedef struct _POINTBLOCK { - XPoint pts[NUMPTSTOBUFFER]; - struct _POINTBLOCK *next; -} POINTBLOCK; - -#endif /* _X11_XREGION_H_ */ diff --git a/shell/linux-deps/include/X11/Xresource.h b/shell/linux-deps/include/X11/Xresource.h deleted file mode 100644 index 6dbb3ce46..000000000 --- a/shell/linux-deps/include/X11/Xresource.h +++ /dev/null @@ -1,358 +0,0 @@ - -/*********************************************************** - -Copyright 1987, 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifndef _X11_XRESOURCE_H_ -#define _X11_XRESOURCE_H_ - -#ifndef _XP_PRINT_SERVER_ -#include -#endif - -/**************************************************************** - **************************************************************** - *** *** - *** *** - *** X Resource Manager Intrinsics *** - *** *** - *** *** - **************************************************************** - ****************************************************************/ - -_XFUNCPROTOBEGIN - -/**************************************************************** - * - * Memory Management - * - ****************************************************************/ - -extern char *Xpermalloc( - unsigned int /* size */ -); - -/**************************************************************** - * - * Quark Management - * - ****************************************************************/ - -typedef int XrmQuark, *XrmQuarkList; -#define NULLQUARK ((XrmQuark) 0) - -typedef char *XrmString; -#define NULLSTRING ((XrmString) 0) - -/* find quark for string, create new quark if none already exists */ -extern XrmQuark XrmStringToQuark( - _Xconst char* /* string */ -); - -extern XrmQuark XrmPermStringToQuark( - _Xconst char* /* string */ -); - -/* find string for quark */ -extern XrmString XrmQuarkToString( - XrmQuark /* quark */ -); - -extern XrmQuark XrmUniqueQuark( - void -); - -#define XrmStringsEqual(a1, a2) (strcmp(a1, a2) == 0) - - -/**************************************************************** - * - * Conversion of Strings to Lists - * - ****************************************************************/ - -typedef enum {XrmBindTightly, XrmBindLoosely} XrmBinding, *XrmBindingList; - -extern void XrmStringToQuarkList( - _Xconst char* /* string */, - XrmQuarkList /* quarks_return */ -); - -extern void XrmStringToBindingQuarkList( - _Xconst char* /* string */, - XrmBindingList /* bindings_return */, - XrmQuarkList /* quarks_return */ -); - -/**************************************************************** - * - * Name and Class lists. - * - ****************************************************************/ - -typedef XrmQuark XrmName; -typedef XrmQuarkList XrmNameList; -#define XrmNameToString(name) XrmQuarkToString(name) -#define XrmStringToName(string) XrmStringToQuark(string) -#define XrmStringToNameList(str, name) XrmStringToQuarkList(str, name) - -typedef XrmQuark XrmClass; -typedef XrmQuarkList XrmClassList; -#define XrmClassToString(c_class) XrmQuarkToString(c_class) -#define XrmStringToClass(c_class) XrmStringToQuark(c_class) -#define XrmStringToClassList(str,c_class) XrmStringToQuarkList(str, c_class) - - - -/**************************************************************** - * - * Resource Representation Types and Values - * - ****************************************************************/ - -typedef XrmQuark XrmRepresentation; -#define XrmStringToRepresentation(string) XrmStringToQuark(string) -#define XrmRepresentationToString(type) XrmQuarkToString(type) - -typedef struct { - unsigned int size; - XPointer addr; -} XrmValue, *XrmValuePtr; - - -/**************************************************************** - * - * Resource Manager Functions - * - ****************************************************************/ - -typedef struct _XrmHashBucketRec *XrmHashBucket; -typedef XrmHashBucket *XrmHashTable; -typedef XrmHashTable XrmSearchList[]; -typedef struct _XrmHashBucketRec *XrmDatabase; - - -extern void XrmDestroyDatabase( - XrmDatabase /* database */ -); - -extern void XrmQPutResource( - XrmDatabase* /* database */, - XrmBindingList /* bindings */, - XrmQuarkList /* quarks */, - XrmRepresentation /* type */, - XrmValue* /* value */ -); - -extern void XrmPutResource( - XrmDatabase* /* database */, - _Xconst char* /* specifier */, - _Xconst char* /* type */, - XrmValue* /* value */ -); - -extern void XrmQPutStringResource( - XrmDatabase* /* database */, - XrmBindingList /* bindings */, - XrmQuarkList /* quarks */, - _Xconst char* /* value */ -); - -extern void XrmPutStringResource( - XrmDatabase* /* database */, - _Xconst char* /* specifier */, - _Xconst char* /* value */ -); - -extern void XrmPutLineResource( - XrmDatabase* /* database */, - _Xconst char* /* line */ -); - -extern Bool XrmQGetResource( - XrmDatabase /* database */, - XrmNameList /* quark_name */, - XrmClassList /* quark_class */, - XrmRepresentation* /* quark_type_return */, - XrmValue* /* value_return */ -); - -extern Bool XrmGetResource( - XrmDatabase /* database */, - _Xconst char* /* str_name */, - _Xconst char* /* str_class */, - char** /* str_type_return */, - XrmValue* /* value_return */ -); - -extern Bool XrmQGetSearchList( - XrmDatabase /* database */, - XrmNameList /* names */, - XrmClassList /* classes */, - XrmSearchList /* list_return */, - int /* list_length */ -); - -extern Bool XrmQGetSearchResource( - XrmSearchList /* list */, - XrmName /* name */, - XrmClass /* class */, - XrmRepresentation* /* type_return */, - XrmValue* /* value_return */ -); - -/**************************************************************** - * - * Resource Database Management - * - ****************************************************************/ - -#ifndef _XP_PRINT_SERVER_ - -extern void XrmSetDatabase( - Display* /* display */, - XrmDatabase /* database */ -); - -extern XrmDatabase XrmGetDatabase( - Display* /* display */ -); - -#endif /* !_XP_PRINT_SERVER_ */ - -extern XrmDatabase XrmGetFileDatabase( - _Xconst char* /* filename */ -); - -extern Status XrmCombineFileDatabase( - _Xconst char* /* filename */, - XrmDatabase* /* target */, - Bool /* override */ -); - -extern XrmDatabase XrmGetStringDatabase( - _Xconst char* /* data */ /* null terminated string */ -); - -extern void XrmPutFileDatabase( - XrmDatabase /* database */, - _Xconst char* /* filename */ -); - -extern void XrmMergeDatabases( - XrmDatabase /* source_db */, - XrmDatabase* /* target_db */ -); - -extern void XrmCombineDatabase( - XrmDatabase /* source_db */, - XrmDatabase* /* target_db */, - Bool /* override */ -); - -#define XrmEnumAllLevels 0 -#define XrmEnumOneLevel 1 - -extern Bool XrmEnumerateDatabase( - XrmDatabase /* db */, - XrmNameList /* name_prefix */, - XrmClassList /* class_prefix */, - int /* mode */, - Bool (*)( - XrmDatabase* /* db */, - XrmBindingList /* bindings */, - XrmQuarkList /* quarks */, - XrmRepresentation* /* type */, - XrmValue* /* value */, - XPointer /* closure */ - ) /* proc */, - XPointer /* closure */ -); - -extern const char *XrmLocaleOfDatabase( - XrmDatabase /* database */ -); - - -/**************************************************************** - * - * Command line option mapping to resource entries - * - ****************************************************************/ - -typedef enum { - XrmoptionNoArg, /* Value is specified in OptionDescRec.value */ - XrmoptionIsArg, /* Value is the option string itself */ - XrmoptionStickyArg, /* Value is characters immediately following option */ - XrmoptionSepArg, /* Value is next argument in argv */ - XrmoptionResArg, /* Resource and value in next argument in argv */ - XrmoptionSkipArg, /* Ignore this option and the next argument in argv */ - XrmoptionSkipLine, /* Ignore this option and the rest of argv */ - XrmoptionSkipNArgs /* Ignore this option and the next - OptionDescRes.value arguments in argv */ -} XrmOptionKind; - -typedef struct { - char *option; /* Option abbreviation in argv */ - char *specifier; /* Resource specifier */ - XrmOptionKind argKind; /* Which style of option it is */ - XPointer value; /* Value to provide if XrmoptionNoArg */ -} XrmOptionDescRec, *XrmOptionDescList; - - -extern void XrmParseCommand( - XrmDatabase* /* database */, - XrmOptionDescList /* table */, - int /* table_count */, - _Xconst char* /* name */, - int* /* argc_in_out */, - char** /* argv_in_out */ -); - -_XFUNCPROTOEND - -#endif /* _X11_XRESOURCE_H_ */ -/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/shell/linux-deps/include/X11/Xthreads.h b/shell/linux-deps/include/X11/Xthreads.h deleted file mode 100644 index 3d4420825..000000000 --- a/shell/linux-deps/include/X11/Xthreads.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * -Copyright 1993, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * * - */ - -#ifndef _XTHREADS_H_ -# define _XTHREADS_H_ - -/* Redefine these to XtMalloc/XtFree or whatever you want before including - * this header file. - */ -# ifndef xmalloc -# define xmalloc malloc -# endif -# ifndef xfree -# define xfree free -# endif - -# ifdef CTHREADS -# include -typedef cthread_t xthread_t; -typedef struct condition xcondition_rec; -typedef struct mutex xmutex_rec; -# define xthread_init() cthread_init() -# define xthread_self cthread_self -# define xthread_fork(func,closure) cthread_fork(func,closure) -# define xthread_yield() cthread_yield() -# define xthread_exit(v) cthread_exit(v) -# define xthread_set_name(t,str) cthread_set_name(t,str) -# define xmutex_init(m) mutex_init(m) -# define xmutex_clear(m) mutex_clear(m) -# define xmutex_lock(m) mutex_lock(m) -# define xmutex_unlock(m) mutex_unlock(m) -# define xmutex_set_name(m,str) mutex_set_name(m,str) -# define xcondition_init(cv) condition_init(cv) -# define xcondition_clear(cv) condition_clear(cv) -# define xcondition_wait(cv,m) condition_wait(cv,m) -# define xcondition_signal(cv) condition_signal(cv) -# define xcondition_broadcast(cv) condition_broadcast(cv) -# define xcondition_set_name(cv,str) condition_set_name(cv,str) -# else /* !CTHREADS */ -# if defined(SVR4) -# include -# include -typedef thread_t xthread_t; -typedef thread_key_t xthread_key_t; -typedef cond_t xcondition_rec; -typedef mutex_t xmutex_rec; -# if defined(__UNIXWARE__) -extern xthread_t (*_x11_thr_self)(); -# define xthread_self (_x11_thr_self) -# else -# define xthread_self thr_self -# endif -# define xthread_fork(func,closure) thr_create(NULL,0,func,closure,THR_NEW_LWP|THR_DETACHED,NULL) -# define xthread_yield() thr_yield() -# define xthread_exit(v) thr_exit(v) -# define xthread_key_create(kp,d) thr_keycreate(kp,d) -# ifdef __sun -# define xthread_key_delete(k) 0 -# else -# define xthread_key_delete(k) thr_keydelete(k) -# endif -# define xthread_set_specific(k,v) thr_setspecific(k,v) -# define xthread_get_specific(k,vp) thr_getspecific(k,vp) -# define xmutex_init(m) mutex_init(m,USYNC_THREAD,0) -# define xmutex_clear(m) mutex_destroy(m) -# define xmutex_lock(m) mutex_lock(m) -# define xmutex_unlock(m) mutex_unlock(m) -# define xcondition_init(cv) cond_init(cv,USYNC_THREAD,0) -# define xcondition_clear(cv) cond_destroy(cv) -# define xcondition_wait(cv,m) cond_wait(cv,m) -# define xcondition_signal(cv) cond_signal(cv) -# define xcondition_broadcast(cv) cond_broadcast(cv) -# else /* !SVR4 */ -# ifdef WIN32 -# include -typedef DWORD xthread_t; -typedef DWORD xthread_key_t; -struct _xthread_waiter { - HANDLE sem; - struct _xthread_waiter *next; -}; -typedef struct { - CRITICAL_SECTION cs; - struct _xthread_waiter *waiters; -} xcondition_rec; -typedef CRITICAL_SECTION xmutex_rec; -# define xthread_init() _Xthread_init() -# define xthread_self GetCurrentThreadId -# define xthread_fork(func,closure) { \ - DWORD _tmptid; \ - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, (LPVOID)closure, 0, \ - &_tmptid); \ -} -# define xthread_yield() Sleep(0) -# define xthread_exit(v) ExitThread((DWORD)(v)) -# define xthread_key_create(kp,d) *(kp) = TlsAlloc() -# define xthread_key_delete(k) TlsFree(k) -# define xthread_set_specific(k,v) TlsSetValue(k,v) -# define xthread_get_specific(k,vp) TlsGetValue(k) -# define xmutex_init(m) InitializeCriticalSection(m) -# define xmutex_clear(m) DeleteCriticalSection(m) -# define _XMUTEX_NESTS -# define xmutex_lock(m) EnterCriticalSection(m) -# define xmutex_unlock(m) LeaveCriticalSection(m) -# define xcondition_init(cv) { \ - InitializeCriticalSection(&(cv)->cs); \ - (cv)->waiters = NULL; \ -} -# define xcondition_clear(cv) DeleteCriticalSection(&(cv)->cs) -extern struct _xthread_waiter *_Xthread_waiter(); -# define xcondition_wait(cv,m) { \ - struct _xthread_waiter *_tmpthr = _Xthread_waiter(); \ - EnterCriticalSection(&(cv)->cs); \ - _tmpthr->next = (cv)->waiters; \ - (cv)->waiters = _tmpthr; \ - LeaveCriticalSection(&(cv)->cs); \ - LeaveCriticalSection(m); \ - WaitForSingleObject(_tmpthr->sem, INFINITE); \ - EnterCriticalSection(m); \ -} -# define xcondition_signal(cv) { \ - EnterCriticalSection(&(cv)->cs); \ - if ((cv)->waiters) { \ - ReleaseSemaphore((cv)->waiters->sem, 1, NULL); \ - (cv)->waiters = (cv)->waiters->next; \ - } \ - LeaveCriticalSection(&(cv)->cs); \ -} -# define xcondition_broadcast(cv) { \ - struct _xthread_waiter *_tmpthr; \ - EnterCriticalSection(&(cv)->cs); \ - for (_tmpthr = (cv)->waiters; _tmpthr; _tmpthr = _tmpthr->next) \ - ReleaseSemaphore(_tmpthr->sem, 1, NULL); \ - (cv)->waiters = NULL; \ - LeaveCriticalSection(&(cv)->cs); \ -} -# else /* !WIN32 */ -# ifdef USE_TIS_SUPPORT -/* - * TIS support is intended for thread safe libraries. - * This should not be used for general client programming. - */ -# include -typedef pthread_t xthread_t; -typedef pthread_key_t xthread_key_t; -typedef pthread_cond_t xcondition_rec; -typedef pthread_mutex_t xmutex_rec; -# define xthread_self tis_self -# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ - pthread_create(&_tmpxthr,NULL,func,closure); } -# define xthread_yield() pthread_yield_np() -# define xthread_exit(v) pthread_exit(v) -# define xthread_key_create(kp,d) tis_key_create(kp,d) -# define xthread_key_delete(k) tis_key_delete(k) -# define xthread_set_specific(k,v) tis_setspecific(k,v) -# define xthread_get_specific(k,vp) *(vp) = tis_getspecific(k) -# define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -# define xmutex_init(m) tis_mutex_init(m) -# define xmutex_clear(m) tis_mutex_destroy(m) -# define xmutex_lock(m) tis_mutex_lock(m) -# define xmutex_unlock(m) tis_mutex_unlock(m) -# define xcondition_init(c) tis_cond_init(c) -# define xcondition_clear(c) tis_cond_destroy(c) -# define xcondition_wait(c,m) tis_cond_wait(c,m) -# define xcondition_signal(c) tis_cond_signal(c) -# define xcondition_broadcast(c) tis_cond_broadcast(c) -# else -# ifdef USE_NBSD_THREADLIB -/* - * NetBSD threadlib support is intended for thread safe libraries. - * This should not be used for general client programming. - */ -# include -typedef thr_t xthread_t; -typedef thread_key_t xthread_key_t; -typedef cond_t xcondition_rec; -typedef mutex_t xmutex_rec; -# define xthread_self thr_self -# define xthread_fork(func,closure) { thr_t _tmpxthr; \ - /* XXX Create it detached? --thorpej */ \ - thr_create(&_tmpxthr,NULL,func,closure); } -# define xthread_yield() thr_yield() -# define xthread_exit(v) thr_exit(v) -# define xthread_key_create(kp,d) thr_keycreate(kp,d) -# define xthread_key_delete(k) thr_keydelete(k) -# define xthread_set_specific(k,v) thr_setspecific(k,v) -# define xthread_get_specific(k,vp) *(vp) = thr_getspecific(k) -# define XMUTEX_INITIALIZER MUTEX_INITIALIZER -# define xmutex_init(m) mutex_init(m, 0) -# define xmutex_clear(m) mutex_destroy(m) -# define xmutex_lock(m) mutex_lock(m) -# define xmutex_unlock(m) mutex_unlock(m) -# define xcondition_init(c) cond_init(c, 0, 0) -# define xcondition_clear(c) cond_destroy(c) -# define xcondition_wait(c,m) cond_wait(c,m) -# define xcondition_signal(c) cond_signal(c) -# define xcondition_broadcast(c) cond_broadcast(c) -# else -# include -typedef pthread_t xthread_t; -typedef pthread_key_t xthread_key_t; -typedef pthread_cond_t xcondition_rec; -typedef pthread_mutex_t xmutex_rec; -# define xthread_self pthread_self -# define xthread_yield() pthread_yield() -# define xthread_exit(v) pthread_exit(v) -# define xthread_set_specific(k,v) pthread_setspecific(k,v) -# define xmutex_clear(m) pthread_mutex_destroy(m) -# define xmutex_lock(m) pthread_mutex_lock(m) -# define xmutex_unlock(m) pthread_mutex_unlock(m) -# ifndef XPRE_STANDARD_API -# define xthread_key_create(kp,d) pthread_key_create(kp,d) -# define xthread_key_delete(k) pthread_key_delete(k) -# define xthread_get_specific(k,vp) *(vp) = pthread_getspecific(k) -# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ - pthread_create(&_tmpxthr,NULL,func,closure); } -# define XMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -# define xmutex_init(m) pthread_mutex_init(m, NULL) -# define xcondition_init(c) pthread_cond_init(c, NULL) -# else /* XPRE_STANDARD_API */ -# define xthread_key_create(kp,d) pthread_keycreate(kp,d) -# define xthread_key_delete(k) 0 -# define xthread_get_specific(k,vp) pthread_getspecific(k,vp) -# define xthread_fork(func,closure) { pthread_t _tmpxthr; \ - pthread_create(&_tmpxthr,pthread_attr_default,func,closure); } -# define xmutex_init(m) pthread_mutex_init(m, pthread_mutexattr_default) -# define xcondition_init(c) pthread_cond_init(c, pthread_condattr_default) -# endif /* XPRE_STANDARD_API */ -# define xcondition_clear(c) pthread_cond_destroy(c) -# define xcondition_wait(c,m) pthread_cond_wait(c,m) -# define xcondition_signal(c) pthread_cond_signal(c) -# define xcondition_broadcast(c) pthread_cond_broadcast(c) -# if defined(_DECTHREADS_) -static xthread_t _X_no_thread_id; -# define xthread_have_id(id) !pthread_equal(id, _X_no_thread_id) -# define xthread_clear_id(id) id = _X_no_thread_id -# define xthread_equal(id1,id2) pthread_equal(id1, id2) -# endif /* _DECTHREADS_ */ -# if defined(__linux__) -# define xthread_have_id(id) !pthread_equal(id, 0) -# define xthread_clear_id(id) id = 0 -# define xthread_equal(id1,id2) pthread_equal(id1, id2) -# endif /* linux */ -# if defined(_CMA_VENDOR_) && defined(_CMA__IBM) && (_CMA_VENDOR_ == _CMA__IBM) -# ifdef DEBUG /* too much of a hack to enable normally */ -/* see also cma__obj_set_name() */ -# define xmutex_set_name(m,str) ((char**)(m)->field1)[5] = (str) -# define xcondition_set_name(cv,str) ((char**)(cv)->field1)[5] = (str) -# endif /* DEBUG */ -# endif /* _CMA_VENDOR_ == _CMA__IBM */ -# endif /* USE_NBSD_THREADLIB */ -# endif /* USE_TIS_SUPPORT */ -# endif /* WIN32 */ -# endif /* SVR4 */ -# endif /* CTHREADS */ -typedef xcondition_rec *xcondition_t; -typedef xmutex_rec *xmutex_t; -# ifndef xcondition_malloc -# define xcondition_malloc() (xcondition_t)xmalloc(sizeof(xcondition_rec)) -# endif -# ifndef xcondition_free -# define xcondition_free(c) xfree((char *)c) -# endif -# ifndef xmutex_malloc -# define xmutex_malloc() (xmutex_t)xmalloc(sizeof(xmutex_rec)) -# endif -# ifndef xmutex_free -# define xmutex_free(m) xfree((char *)m) -# endif -# ifndef xthread_have_id -# define xthread_have_id(id) id -# endif -# ifndef xthread_clear_id -# define xthread_clear_id(id) id = 0 -# endif -# ifndef xthread_equal -# define xthread_equal(id1,id2) ((id1) == (id2)) -# endif -/* aids understood by some debuggers */ -# ifndef xthread_set_name -# define xthread_set_name(t,str) -# endif -# ifndef xmutex_set_name -# define xmutex_set_name(m,str) -# endif -# ifndef xcondition_set_name -# define xcondition_set_name(cv,str) -# endif - -#endif /* _XTHREADS_H_ */ diff --git a/shell/linux-deps/include/X11/Xtrans/Xtrans.c b/shell/linux-deps/include/X11/Xtrans/Xtrans.c deleted file mode 100644 index f59bd61fa..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtrans.c +++ /dev/null @@ -1,1380 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -/* - * The transport table contains a definition for every transport (protocol) - * family. All operations that can be made on the transport go through this - * table. - * - * Each transport is assigned a unique transport id. - * - * New transports can be added by adding an entry in this table. - * For compatiblity, the transport ids should never be renumbered. - * Always add to the end of the list. - */ - -#define TRANS_TLI_INET_INDEX 1 -#define TRANS_TLI_TCP_INDEX 2 -#define TRANS_TLI_TLI_INDEX 3 -#define TRANS_SOCKET_UNIX_INDEX 4 -#define TRANS_SOCKET_LOCAL_INDEX 5 -#define TRANS_SOCKET_INET_INDEX 6 -#define TRANS_SOCKET_TCP_INDEX 7 -#define TRANS_DNET_INDEX 8 -#define TRANS_LOCAL_LOCAL_INDEX 9 -#define TRANS_LOCAL_PTS_INDEX 10 -#define TRANS_LOCAL_NAMED_INDEX 11 -/* 12 used to be ISC, but that's gone. */ -#define TRANS_LOCAL_SCO_INDEX 13 -#define TRANS_SOCKET_INET6_INDEX 14 -#define TRANS_LOCAL_PIPE_INDEX 15 - - -static -Xtransport_table Xtransports[] = { -#if defined(STREAMSCONN) - { &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX }, - { &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX }, - { &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX }, -#endif /* STREAMSCONN */ -#if defined(TCPCONN) - { &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX }, -#if defined(IPv6) && defined(AF_INET6) - { &TRANS(SocketINET6Funcs), TRANS_SOCKET_INET6_INDEX }, -#endif /* IPv6 */ - { &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX }, -#endif /* TCPCONN */ -#if defined(UNIXCONN) -#if !defined(LOCALCONN) - { &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX }, -#endif /* !LOCALCONN */ - { &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX }, -#endif /* UNIXCONN */ -#if defined(LOCALCONN) - { &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX }, -#ifndef sun - { &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX }, -#endif /* sun */ -#if defined(SVR4) || defined(__SVR4) - { &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX }, -#endif -#ifdef sun - { &TRANS(PIPEFuncs), TRANS_LOCAL_PIPE_INDEX }, -#endif /* sun */ -#if defined(__SCO__) || defined(__UNIXWARE__) - { &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX }, -#endif /* __SCO__ || __UNIXWARE__ */ -#endif /* LOCALCONN */ -}; - -#define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table)) - - -#ifdef WIN32 -#define ioctl ioctlsocket -#endif - - - -/* - * These are a few utility function used by the public interface functions. - */ - -void -TRANS(FreeConnInfo) (XtransConnInfo ciptr) - -{ - PRMSG (3,"FreeConnInfo(%p)\n", ciptr, 0, 0); - - if (ciptr->addr) - xfree (ciptr->addr); - - if (ciptr->peeraddr) - xfree (ciptr->peeraddr); - - if (ciptr->port) - xfree (ciptr->port); - - xfree ((char *) ciptr); -} - - -#define PROTOBUFSIZE 20 - -static Xtransport * -TRANS(SelectTransport) (char *protocol) - -{ - char protobuf[PROTOBUFSIZE]; - int i; - - PRMSG (3,"SelectTransport(%s)\n", protocol, 0, 0); - - /* - * Force Protocol to be lowercase as a way of doing - * a case insensitive match. - */ - - strncpy (protobuf, protocol, PROTOBUFSIZE - 1); - protobuf[PROTOBUFSIZE-1] = '\0'; - - for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++) - if (isupper (protobuf[i])) - protobuf[i] = tolower (protobuf[i]); - - /* Look at all of the configured protocols */ - - for (i = 0; i < NUMTRANS; i++) - { - if (!strcmp (protobuf, Xtransports[i].transport->TransName)) - return Xtransports[i].transport; - } - - return NULL; -} - -#ifndef TEST_t -static -#endif /* TEST_t */ -int -TRANS(ParseAddress) (char *address, char **protocol, char **host, char **port) - -{ - /* - * For the font library, the address is a string formatted - * as "protocol/host:port[/catalogue]". Note that the catologue - * is optional. At this time, the catologue info is ignored, but - * we have to parse it anyways. - * - * Other than fontlib, the address is a string formatted - * as "protocol/host:port". - * - * If the protocol part is missing, then assume TCP. - * If the protocol part and host part are missing, then assume local. - * If a "::" is found then assume DNET. - */ - - char *mybuf, *tmpptr; - char *_protocol, *_host, *_port; - char hostnamebuf[256]; - int _host_len; - - PRMSG (3,"ParseAddress(%s)\n", address, 0, 0); - - /* Copy the string so it can be changed */ - - tmpptr = mybuf = (char *) xalloc (strlen (address) + 1); - strcpy (mybuf, address); - - /* Parse the string to get each component */ - - /* Get the protocol part */ - - _protocol = mybuf; - - - if ( ((mybuf = strchr (mybuf,'/')) == NULL) && - ((mybuf = strrchr (tmpptr,':')) == NULL) ) - { - /* address is in a bad format */ - *protocol = NULL; - *host = NULL; - *port = NULL; - xfree (tmpptr); - return 0; - } - - if (*mybuf == ':') - { - /* - * If there is a hostname, then assume tcp, otherwise - * it must be local. - */ - if (mybuf == tmpptr) - { - /* There is neither a protocol or host specified */ - _protocol = "local"; - } - else - { - /* There is a hostname specified */ - _protocol = "tcp"; - mybuf = tmpptr; /* reset to the begining of the host ptr */ - } - } - else - { - /* *mybuf == '/' */ - - *mybuf ++= '\0'; /* put a null at the end of the protocol */ - - if (strlen(_protocol) == 0) - { - /* - * If there is a hostname, then assume tcp, otherwise - * it must be local. - */ - if (*mybuf != ':') - _protocol = "tcp"; - else - _protocol = "local"; - } - } - - /* Get the host part */ - - _host = mybuf; - - if ((mybuf = strrchr (mybuf,':')) == NULL) - { - *protocol = NULL; - *host = NULL; - *port = NULL; - xfree (tmpptr); - return 0; - } - - /* Check for DECnet */ - - if ((mybuf != _host) && (*(mybuf - 1) == ':') -#if defined(IPv6) && defined(AF_INET6) - /* An IPv6 address can end in :: so three : in a row is assumed to be - an IPv6 host and not a DECnet node with a : in it's name, unless - DECnet is specifically requested */ - && ( ((mybuf - 1) == _host) || (*(mybuf - 2) != ':') || - ((_protocol != NULL) && (strcmp(_protocol, "dnet") == 0)) ) -#endif - ) - { - _protocol = "dnet"; - *(mybuf - 1) = '\0'; - } - - *mybuf ++= '\0'; - - _host_len = strlen(_host); - if (_host_len == 0) - { - TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); - _host = hostnamebuf; - } -#if defined(IPv6) && defined(AF_INET6) - /* hostname in IPv6 [numeric_addr]:0 form? */ - else if ( (_host_len > 3) && - ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0)) - && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) { - struct sockaddr_in6 sin6; - - *(_host + _host_len - 1) = '\0'; - - /* Verify address is valid IPv6 numeric form */ - if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) { - /* It is. Use it as such. */ - _host++; - _protocol = "inet6"; - } else { - /* It's not, restore it just in case some other code can use it. */ - *(_host + _host_len - 1) = ']'; - } - } -#endif - - - /* Get the port */ - - _port = mybuf; - -#if defined(FONT_t) || defined(FS_t) - /* - * Is there an optional catalogue list? - */ - - if ((mybuf = strchr (mybuf,'/')) != NULL) - *mybuf ++= '\0'; - - /* - * The rest, if any, is the (currently unused) catalogue list. - * - * _catalogue = mybuf; - */ -#endif - -#ifdef HAVE_LAUNCHD - /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */ - if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) { - _protocol="local"; - _host=""; - _port=address+6; - } -#endif - - /* - * Now that we have all of the components, allocate new - * string space for them. - */ - - if ((*protocol = (char *) xalloc(strlen (_protocol) + 1)) == NULL) - { - /* Malloc failed */ - *port = NULL; - *host = NULL; - *protocol = NULL; - xfree (tmpptr); - return 0; - } - else - strcpy (*protocol, _protocol); - - if ((*host = (char *) xalloc (strlen (_host) + 1)) == NULL) - { - /* Malloc failed */ - *port = NULL; - *host = NULL; - xfree (*protocol); - *protocol = NULL; - xfree (tmpptr); - return 0; - } - else - strcpy (*host, _host); - - if ((*port = (char *) xalloc (strlen (_port) + 1)) == NULL) - { - /* Malloc failed */ - *port = NULL; - xfree (*host); - *host = NULL; - xfree (*protocol); - *protocol = NULL; - xfree (tmpptr); - return 0; - } - else - strcpy (*port, _port); - - xfree (tmpptr); - - return 1; -} - - -/* - * TRANS(Open) does all of the real work opening a connection. The only - * funny part about this is the type parameter which is used to decide which - * type of open to perform. - */ - -static XtransConnInfo -TRANS(Open) (int type, char *address) - -{ - char *protocol = NULL, *host = NULL, *port = NULL; - XtransConnInfo ciptr = NULL; - Xtransport *thistrans; - - PRMSG (2,"Open(%d,%s)\n", type, address, 0); - -#if defined(WIN32) && defined(TCPCONN) - if (TRANS(WSAStartup)()) - { - PRMSG (1,"Open: WSAStartup failed\n", 0, 0, 0); - return NULL; - } -#endif - - /* Parse the Address */ - - if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) - { - PRMSG (1,"Open: Unable to Parse address %s\n", address, 0, 0); - return NULL; - } - - /* Determine the transport type */ - - if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL) - { - PRMSG (1,"Open: Unable to find transport for %s\n", - protocol, 0, 0); - - xfree (protocol); - xfree (host); - xfree (port); - return NULL; - } - - /* Open the transport */ - - switch (type) - { - case XTRANS_OPEN_COTS_CLIENT: -#ifdef TRANS_CLIENT - ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port); -#endif /* TRANS_CLIENT */ - break; - case XTRANS_OPEN_COTS_SERVER: -#ifdef TRANS_SERVER - ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port); -#endif /* TRANS_SERVER */ - break; - case XTRANS_OPEN_CLTS_CLIENT: -#ifdef TRANS_CLIENT - ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port); -#endif /* TRANS_CLIENT */ - break; - case XTRANS_OPEN_CLTS_SERVER: -#ifdef TRANS_SERVER - ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port); -#endif /* TRANS_SERVER */ - break; - default: - PRMSG (1,"Open: Unknown Open type %d\n", type, 0, 0); - } - - if (ciptr == NULL) - { - if (!(thistrans->flags & TRANS_DISABLED)) - { - PRMSG (1,"Open: transport open failed for %s/%s:%s\n", - protocol, host, port); - } - xfree (protocol); - xfree (host); - xfree (port); - return NULL; - } - - ciptr->transptr = thistrans; - ciptr->port = port; /* We need this for TRANS(Reopen) */ - - xfree (protocol); - xfree (host); - - return ciptr; -} - - -#ifdef TRANS_REOPEN - -/* - * We might want to create an XtransConnInfo object based on a previously - * opened connection. For example, the font server may clone itself and - * pass file descriptors to the parent. - */ - -static XtransConnInfo -TRANS(Reopen) (int type, int trans_id, int fd, char *port) - -{ - XtransConnInfo ciptr = NULL; - Xtransport *thistrans = NULL; - char *save_port; - int i; - - PRMSG (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port); - - /* Determine the transport type */ - - for (i = 0; i < NUMTRANS; i++) - if (Xtransports[i].transport_id == trans_id) - { - thistrans = Xtransports[i].transport; - break; - } - - if (thistrans == NULL) - { - PRMSG (1,"Reopen: Unable to find transport id %d\n", - trans_id, 0, 0); - - return NULL; - } - - if ((save_port = (char *) xalloc (strlen (port) + 1)) == NULL) - { - PRMSG (1,"Reopen: Unable to malloc port string\n", 0, 0, 0); - - return NULL; - } - - strcpy (save_port, port); - - /* Get a new XtransConnInfo object */ - - switch (type) - { - case XTRANS_OPEN_COTS_SERVER: - ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port); - break; - case XTRANS_OPEN_CLTS_SERVER: - ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port); - break; - default: - PRMSG (1,"Reopen: Bad Open type %d\n", type, 0, 0); - } - - if (ciptr == NULL) - { - PRMSG (1,"Reopen: transport open failed\n", 0, 0, 0); - return NULL; - } - - ciptr->transptr = thistrans; - ciptr->port = save_port; - - return ciptr; -} - -#endif /* TRANS_REOPEN */ - - - -/* - * These are the public interfaces to this Transport interface. - * These are the only functions that should have knowledge of the transport - * table. - */ - -#ifdef TRANS_CLIENT - -XtransConnInfo -TRANS(OpenCOTSClient) (char *address) - -{ - PRMSG (2,"OpenCOTSClient(%s)\n", address, 0, 0); - return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address); -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -XtransConnInfo -TRANS(OpenCOTSServer) (char *address) - -{ - PRMSG (2,"OpenCOTSServer(%s)\n", address, 0, 0); - return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address); -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -XtransConnInfo -TRANS(OpenCLTSClient) (char *address) - -{ - PRMSG (2,"OpenCLTSClient(%s)\n", address, 0, 0); - return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address); -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -XtransConnInfo -TRANS(OpenCLTSServer) (char *address) - -{ - PRMSG (2,"OpenCLTSServer(%s)\n", address, 0, 0); - return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address); -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - -XtransConnInfo -TRANS(ReopenCOTSServer) (int trans_id, int fd, char *port) - -{ - PRMSG (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port); - return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port); -} - -XtransConnInfo -TRANS(ReopenCLTSServer) (int trans_id, int fd, char *port) - -{ - PRMSG (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port); - return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port); -} - - -int -TRANS(GetReopenInfo) (XtransConnInfo ciptr, - int *trans_id, int *fd, char **port) - -{ - int i; - - for (i = 0; i < NUMTRANS; i++) - if (Xtransports[i].transport == ciptr->transptr) - { - *trans_id = Xtransports[i].transport_id; - *fd = ciptr->fd; - - if ((*port = (char *) xalloc (strlen (ciptr->port) + 1)) == NULL) - return 0; - else - { - strcpy (*port, ciptr->port); - return 1; - } - } - - return 0; -} - -#endif /* TRANS_REOPEN */ - - -int -TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg) - -{ - int fd = ciptr->fd; - int ret = 0; - - PRMSG (2,"SetOption(%d,%d,%d)\n", fd, option, arg); - - /* - * For now, all transport type use the same stuff for setting options. - * As long as this is true, we can put the common code here. Once a more - * complicated transport such as shared memory or an OSI implementation - * that uses the session and application libraries is implemented, this - * code may have to move to a transport dependent function. - * - * ret = ciptr->transptr->SetOption (ciptr, option, arg); - */ - - switch (option) - { - case TRANS_NONBLOCKING: - switch (arg) - { - case 0: - /* Set to blocking mode */ - break; - case 1: /* Set to non-blocking mode */ - -#if defined(O_NONBLOCK) && !defined(SCO325) - ret = fcntl (fd, F_GETFL, 0); - if (ret != -1) - ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK); -#else -#ifdef FIOSNBIO - { - int arg; - arg = 1; - ret = ioctl (fd, FIOSNBIO, &arg); - } -#else -#if defined(WIN32) - { -#ifdef WIN32 - u_long arg; -#else - int arg; -#endif - arg = 1; -/* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail - * eventually with EWOULDBLOCK */ - ret = ioctl (fd, FIONBIO, &arg); - } -#else - ret = fcntl (fd, F_GETFL, 0); -#ifdef FNDELAY - ret = fcntl (fd, F_SETFL, ret | FNDELAY); -#else - ret = fcntl (fd, F_SETFL, ret | O_NDELAY); -#endif -#endif /* AIXV3 || uniosu */ -#endif /* FIOSNBIO */ -#endif /* O_NONBLOCK */ - break; - default: - /* Unknown option */ - break; - } - break; - case TRANS_CLOSEONEXEC: -#ifdef F_SETFD -#ifdef FD_CLOEXEC - ret = fcntl (fd, F_SETFD, FD_CLOEXEC); -#else - ret = fcntl (fd, F_SETFD, 1); -#endif /* FD_CLOEXEC */ -#endif /* F_SETFD */ - break; - } - - return ret; -} - -#ifdef TRANS_SERVER - -int -TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) - -{ - return ciptr->transptr->CreateListener (ciptr, port, flags); -} - -int -TRANS(NoListen) (char * protocol) - -{ - Xtransport *trans; - int i = 0, ret = 0; - - if ((trans = TRANS(SelectTransport)(protocol)) == NULL) - { - PRMSG (1,"TransNoListen: unable to find transport: %s\n", - protocol, 0, 0); - - return -1; - } - if (trans->flags & TRANS_ALIAS) { - if (trans->nolisten) - while (trans->nolisten[i]) { - ret |= TRANS(NoListen)(trans->nolisten[i]); - i++; - } - } - - trans->flags |= TRANS_NOLISTEN; - return ret; -} - -int -TRANS(ResetListener) (XtransConnInfo ciptr) - -{ - if (ciptr->transptr->ResetListener) - return ciptr->transptr->ResetListener (ciptr); - else - return TRANS_RESET_NOOP; -} - - -XtransConnInfo -TRANS(Accept) (XtransConnInfo ciptr, int *status) - -{ - XtransConnInfo newciptr; - - PRMSG (2,"Accept(%d)\n", ciptr->fd, 0, 0); - - newciptr = ciptr->transptr->Accept (ciptr, status); - - if (newciptr) - newciptr->transptr = ciptr->transptr; - - return newciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -int -TRANS(Connect) (XtransConnInfo ciptr, char *address) - -{ - char *protocol; - char *host; - char *port; - int ret; - - PRMSG (2,"Connect(%d,%s)\n", ciptr->fd, address, 0); - - if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) - { - PRMSG (1,"Connect: Unable to Parse address %s\n", - address, 0, 0); - return -1; - } - -#ifdef HAVE_LAUNCHD - if (!host) host=strdup(""); -#endif - - if (!port || !*port) - { - PRMSG (1,"Connect: Missing port specification in %s\n", - address, 0, 0); - if (protocol) xfree (protocol); - if (host) xfree (host); - return -1; - } - - ret = ciptr->transptr->Connect (ciptr, host, port); - - if (protocol) xfree (protocol); - if (host) xfree (host); - if (port) xfree (port); - - return ret; -} - -#endif /* TRANS_CLIENT */ - - -int -TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) - -{ - return ciptr->transptr->BytesReadable (ciptr, pend); -} - -int -TRANS(Read) (XtransConnInfo ciptr, char *buf, int size) - -{ - return ciptr->transptr->Read (ciptr, buf, size); -} - -int -TRANS(Write) (XtransConnInfo ciptr, char *buf, int size) - -{ - return ciptr->transptr->Write (ciptr, buf, size); -} - -int -TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - return ciptr->transptr->Readv (ciptr, buf, size); -} - -int -TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - return ciptr->transptr->Writev (ciptr, buf, size); -} - -int -TRANS(Disconnect) (XtransConnInfo ciptr) - -{ - return ciptr->transptr->Disconnect (ciptr); -} - -int -TRANS(Close) (XtransConnInfo ciptr) - -{ - int ret; - - PRMSG (2,"Close(%d)\n", ciptr->fd, 0, 0); - - ret = ciptr->transptr->Close (ciptr); - - TRANS(FreeConnInfo) (ciptr); - - return ret; -} - -int -TRANS(CloseForCloning) (XtransConnInfo ciptr) - -{ - int ret; - - PRMSG (2,"CloseForCloning(%d)\n", ciptr->fd, 0, 0); - - ret = ciptr->transptr->CloseForCloning (ciptr); - - TRANS(FreeConnInfo) (ciptr); - - return ret; -} - -int -TRANS(IsLocal) (XtransConnInfo ciptr) - -{ - return (ciptr->family == AF_UNIX); -} - - -int -TRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, - Xtransaddr **addrp) - -{ - PRMSG (2,"GetMyAddr(%d)\n", ciptr->fd, 0, 0); - - *familyp = ciptr->family; - *addrlenp = ciptr->addrlen; - - if ((*addrp = (Xtransaddr *) xalloc (ciptr->addrlen)) == NULL) - { - PRMSG (1,"GetMyAddr: malloc failed\n", 0, 0, 0); - return -1; - } - memcpy(*addrp, ciptr->addr, ciptr->addrlen); - - return 0; -} - -int -TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, - Xtransaddr **addrp) - -{ - PRMSG (2,"GetPeerAddr(%d)\n", ciptr->fd, 0, 0); - - *familyp = ciptr->family; - *addrlenp = ciptr->peeraddrlen; - - if ((*addrp = (Xtransaddr *) xalloc (ciptr->peeraddrlen)) == NULL) - { - PRMSG (1,"GetPeerAddr: malloc failed\n", 0, 0, 0); - return -1; - } - memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen); - - return 0; -} - - -int -TRANS(GetConnectionNumber) (XtransConnInfo ciptr) - -{ - return ciptr->fd; -} - - -/* - * These functions are really utility functions, but they require knowledge - * of the internal data structures, so they have to be part of the Transport - * Independant API. - */ - -#ifdef TRANS_SERVER - -static int -complete_network_count (void) - -{ - int count = 0; - int found_local = 0; - int i; - - /* - * For a complete network, we only need one LOCALCONN transport to work - */ - - for (i = 0; i < NUMTRANS; i++) - { - if (Xtransports[i].transport->flags & TRANS_ALIAS - || Xtransports[i].transport->flags & TRANS_NOLISTEN) - continue; - - if (Xtransports[i].transport->flags & TRANS_LOCAL) - found_local = 1; - else - count++; - } - - return (count + found_local); -} - - -#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD -extern int xquartz_launchd_fd; -#endif - -int -TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret, - XtransConnInfo **ciptrs_ret) - -{ - char buffer[256]; /* ??? What size ?? */ - XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; - int status, i, j; - -#if defined(IPv6) && defined(AF_INET6) - int ipv6_succ = 0; -#endif - PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n", - port ? port : "NULL", ciptrs_ret, 0); - - *count_ret = 0; - -#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD - fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd); - if(xquartz_launchd_fd != -1) { - if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX, - xquartz_launchd_fd, getenv("DISPLAY"))))==NULL) - fprintf(stderr,"Got NULL while trying to Reopen launchd port\n"); - else - temp_ciptrs[(*count_ret)++] = ciptr; - } -#endif - - for (i = 0; i < NUMTRANS; i++) - { - Xtransport *trans = Xtransports[i].transport; - unsigned int flags = 0; - - if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) - continue; - - snprintf(buffer, sizeof(buffer), "%s/:%s", - trans->TransName, port ? port : ""); - - PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n", - buffer, 0, 0); - - if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL) - { - if (trans->flags & TRANS_DISABLED) - continue; - - PRMSG (1, - "MakeAllCOTSServerListeners: failed to open listener for %s\n", - trans->TransName, 0, 0); - continue; - } -#if defined(IPv6) && defined(AF_INET6) - if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX - && ipv6_succ)) - flags |= ADDR_IN_USE_ALLOWED; -#endif - - if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0) - { - if (status == TRANS_ADDR_IN_USE) - { - /* - * We failed to bind to the specified address because the - * address is in use. It must be that a server is already - * running at this address, and this function should fail. - */ - - PRMSG (1, - "MakeAllCOTSServerListeners: server already running\n", - 0, 0, 0); - - for (j = 0; j < *count_ret; j++) - TRANS(Close) (temp_ciptrs[j]); - - *count_ret = 0; - *ciptrs_ret = NULL; - *partial = 0; - return -1; - } - else - { - PRMSG (1, - "MakeAllCOTSServerListeners: failed to create listener for %s\n", - trans->TransName, 0, 0); - - continue; - } - } - -#if defined(IPv6) && defined(AF_INET6) - if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX) - ipv6_succ = 1; -#endif - - PRMSG (5, - "MakeAllCOTSServerListeners: opened listener for %s, %d\n", - trans->TransName, ciptr->fd, 0); - - temp_ciptrs[*count_ret] = ciptr; - (*count_ret)++; - } - - *partial = (*count_ret < complete_network_count()); - - PRMSG (5, - "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n", - *partial, *count_ret, complete_network_count()); - - if (*count_ret > 0) - { - if ((*ciptrs_ret = (XtransConnInfo *) xalloc ( - *count_ret * sizeof (XtransConnInfo))) == NULL) - { - return -1; - } - - for (i = 0; i < *count_ret; i++) - { - (*ciptrs_ret)[i] = temp_ciptrs[i]; - } - } - else - *ciptrs_ret = NULL; - - return 0; -} - -int -TRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret, - XtransConnInfo **ciptrs_ret) - -{ - char buffer[256]; /* ??? What size ?? */ - XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; - int status, i, j; - - PRMSG (2,"MakeAllCLTSServerListeners(%s,%p)\n", - port ? port : "NULL", ciptrs_ret, 0); - - *count_ret = 0; - - for (i = 0; i < NUMTRANS; i++) - { - Xtransport *trans = Xtransports[i].transport; - - if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) - continue; - - snprintf(buffer, sizeof(buffer), "%s/:%s", - trans->TransName, port ? port : ""); - - PRMSG (5,"MakeAllCLTSServerListeners: opening %s\n", - buffer, 0, 0); - - if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL) - { - PRMSG (1, - "MakeAllCLTSServerListeners: failed to open listener for %s\n", - trans->TransName, 0, 0); - continue; - } - - if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0) - { - if (status == TRANS_ADDR_IN_USE) - { - /* - * We failed to bind to the specified address because the - * address is in use. It must be that a server is already - * running at this address, and this function should fail. - */ - - PRMSG (1, - "MakeAllCLTSServerListeners: server already running\n", - 0, 0, 0); - - for (j = 0; j < *count_ret; j++) - TRANS(Close) (temp_ciptrs[j]); - - *count_ret = 0; - *ciptrs_ret = NULL; - *partial = 0; - return -1; - } - else - { - PRMSG (1, - "MakeAllCLTSServerListeners: failed to create listener for %s\n", - trans->TransName, 0, 0); - - continue; - } - } - - PRMSG (5, - "MakeAllCLTSServerListeners: opened listener for %s, %d\n", - trans->TransName, ciptr->fd, 0); - temp_ciptrs[*count_ret] = ciptr; - (*count_ret)++; - } - - *partial = (*count_ret < complete_network_count()); - - PRMSG (5, - "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n", - *partial, *count_ret, complete_network_count()); - - if (*count_ret > 0) - { - if ((*ciptrs_ret = (XtransConnInfo *) xalloc ( - *count_ret * sizeof (XtransConnInfo))) == NULL) - { - return -1; - } - - for (i = 0; i < *count_ret; i++) - { - (*ciptrs_ret)[i] = temp_ciptrs[i]; - } - } - else - *ciptrs_ret = NULL; - - return 0; -} - -#endif /* TRANS_SERVER */ - - - -/* - * These routines are not part of the X Transport Interface, but they - * may be used by it. - */ - - -#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) - -/* - * emulate readv - */ - -static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) - -{ - int i, len, total; - char *base; - - ESET(0); - for (i = 0, total = 0; i < iovcnt; i++, iov++) { - len = iov->iov_len; - base = iov->iov_base; - while (len > 0) { - register int nbytes; - nbytes = TRANS(Read) (ciptr, base, len); - if (nbytes < 0 && total == 0) return -1; - if (nbytes <= 0) return total; - ESET(0); - len -= nbytes; - total += nbytes; - base += nbytes; - } - } - return total; -} - -#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ - -#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) - -/* - * emulate writev - */ - -static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) - -{ - int i, len, total; - char *base; - - ESET(0); - for (i = 0, total = 0; i < iovcnt; i++, iov++) { - len = iov->iov_len; - base = iov->iov_base; - while (len > 0) { - register int nbytes; - nbytes = TRANS(Write) (ciptr, base, len); - if (nbytes < 0 && total == 0) return -1; - if (nbytes <= 0) return total; - ESET(0); - len -= nbytes; - total += nbytes; - base += nbytes; - } - } - return total; -} - -#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ - - -#if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__) -#ifndef NEED_UTSNAME -#define NEED_UTSNAME -#endif -#include -#endif - -/* - * TRANS(GetHostname) - similar to gethostname but allows special processing. - */ - -int TRANS(GetHostname) (char *buf, int maxlen) - -{ - int len; - -#ifdef NEED_UTSNAME - struct utsname name; - - uname (&name); - len = strlen (name.nodename); - if (len >= maxlen) len = maxlen - 1; - strncpy (buf, name.nodename, len); - buf[len] = '\0'; -#else - buf[0] = '\0'; - (void) gethostname (buf, maxlen); - buf [maxlen - 1] = '\0'; - len = strlen(buf); -#endif /* NEED_UTSNAME */ - return len; -} diff --git a/shell/linux-deps/include/X11/Xtrans/Xtrans.h b/shell/linux-deps/include/X11/Xtrans/Xtrans.h deleted file mode 100644 index cb83196f1..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtrans.h +++ /dev/null @@ -1,478 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _XTRANS_H_ -#define _XTRANS_H_ - -#include -#include - -#ifndef WIN32 -#include -#endif - - -/* - * Set the functions names according to where this code is being compiled. - */ - -#ifdef X11_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _X11Trans##func -#else -#define TRANS(func) _X11Trans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_X11Trans"; -#endif -#endif /* X11_t */ - -#ifdef XSERV_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _XSERVTrans##func -#else -#define TRANS(func) _XSERVTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_XSERVTrans"; -#endif -#define X11_t -#endif /* XSERV_t */ - -#ifdef XIM_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _XimXTrans##func -#else -#define TRANS(func) _XimXTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_XimTrans"; -#endif -#endif /* XIM_t */ - -#ifdef FS_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _FSTrans##func -#else -#define TRANS(func) _FSTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_FSTrans"; -#endif -#endif /* FS_t */ - -#ifdef FONT_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _FontTrans##func -#else -#define TRANS(func) _FontTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_FontTrans"; -#endif -#endif /* FONT_t */ - -#ifdef ICE_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _IceTrans##func -#else -#define TRANS(func) _IceTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_IceTrans"; -#endif -#endif /* ICE_t */ - -#ifdef TEST_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _TESTTrans##func -#else -#define TRANS(func) _TESTTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_TESTTrans"; -#endif -#endif /* TEST_t */ - -#ifdef LBXPROXY_t -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _LBXPROXYTrans##func -#else -#define TRANS(func) _LBXPROXYTrans/**/func -#endif -#define X11_t /* The server defines this - so should the LBX proxy */ -#ifdef XTRANSDEBUG -static char* __xtransname = "_LBXPROXYTrans"; -#endif -#endif /* LBXPROXY_t */ - -#if !defined(TRANS) -#if !defined(UNIXCPP) || defined(ANSICPP) -#define TRANS(func) _XTrans##func -#else -#define TRANS(func) _XTrans/**/func -#endif -#ifdef XTRANSDEBUG -static char* __xtransname = "_XTrans"; -#endif -#endif /* !TRANS */ - - -/* - * Create a single address structure that can be used wherever - * an address structure is needed. struct sockaddr is not big enough - * to hold a sockadd_un, so we create this definition to have a single - * structure that is big enough for all the structures we might need. - * - * This structure needs to be independent of the socket/TLI interface used. - */ - -#if defined(IPv6) && defined(AF_INET6) -typedef struct sockaddr_storage Xtransaddr; -#else -#define XTRANS_MAX_ADDR_LEN 128 /* large enough to hold sun_path */ - -typedef struct { - unsigned char addr[XTRANS_MAX_ADDR_LEN]; -} Xtransaddr; -#endif - -#ifdef LONG64 -typedef int BytesReadable_t; -#else -typedef long BytesReadable_t; -#endif - - -#if defined(WIN32) || defined(USG) - -/* - * TRANS(Readv) and TRANS(Writev) use struct iovec, normally found - * in Berkeley systems in . See the readv(2) and writev(2) - * manual pages for details. - */ - -struct iovec { - caddr_t iov_base; - int iov_len; -}; - -#else -#include -#endif - -typedef struct _XtransConnInfo *XtransConnInfo; - - -/* - * Transport Option definitions - */ - -#define TRANS_NONBLOCKING 1 -#define TRANS_CLOSEONEXEC 2 - - -/* - * Return values of Connect (0 is success) - */ - -#define TRANS_CONNECT_FAILED -1 -#define TRANS_TRY_CONNECT_AGAIN -2 -#define TRANS_IN_PROGRESS -3 - - -/* - * Return values of CreateListener (0 is success) - */ - -#define TRANS_CREATE_LISTENER_FAILED -1 -#define TRANS_ADDR_IN_USE -2 - - -/* - * Return values of Accept (0 is success) - */ - -#define TRANS_ACCEPT_BAD_MALLOC -1 -#define TRANS_ACCEPT_FAILED -2 -#define TRANS_ACCEPT_MISC_ERROR -3 - - -/* - * ResetListener return values - */ - -#define TRANS_RESET_NOOP 1 -#define TRANS_RESET_NEW_FD 2 -#define TRANS_RESET_FAILURE 3 - - -/* - * Function prototypes for the exposed interface - */ - -void TRANS(FreeConnInfo) ( - XtransConnInfo /* ciptr */ -); - -#ifdef TRANS_CLIENT - -XtransConnInfo TRANS(OpenCOTSClient)( - char * /* address */ -); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - -XtransConnInfo TRANS(OpenCOTSServer)( - char * /* address */ -); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_CLIENT - -XtransConnInfo TRANS(OpenCLTSClient)( - char * /* address */ -); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - -XtransConnInfo TRANS(OpenCLTSServer)( - char * /* address */ -); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_REOPEN - -XtransConnInfo TRANS(ReopenCOTSServer)( - int, /* trans_id */ - int, /* fd */ - char * /* port */ -); - -XtransConnInfo TRANS(ReopenCLTSServer)( - int, /* trans_id */ - int, /* fd */ - char * /* port */ -); - -int TRANS(GetReopenInfo)( - XtransConnInfo, /* ciptr */ - int *, /* trans_id */ - int *, /* fd */ - char ** /* port */ -); - -#endif /* TRANS_REOPEN */ - - -int TRANS(SetOption)( - XtransConnInfo, /* ciptr */ - int, /* option */ - int /* arg */ -); - -#ifdef TRANS_SERVER - -int TRANS(CreateListener)( - XtransConnInfo, /* ciptr */ - char *, /* port */ - unsigned int /* flags */ -); - -int TRANS(NoListen) ( - char* /* protocol*/ -); - -int TRANS(ResetListener)( - XtransConnInfo /* ciptr */ -); - -XtransConnInfo TRANS(Accept)( - XtransConnInfo, /* ciptr */ - int * /* status */ -); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_CLIENT - -int TRANS(Connect)( - XtransConnInfo, /* ciptr */ - char * /* address */ -); - -#endif /* TRANS_CLIENT */ - -int TRANS(BytesReadable)( - XtransConnInfo, /* ciptr */ - BytesReadable_t * /* pend */ -); - -int TRANS(Read)( - XtransConnInfo, /* ciptr */ - char *, /* buf */ - int /* size */ -); - -int TRANS(Write)( - XtransConnInfo, /* ciptr */ - char *, /* buf */ - int /* size */ -); - -int TRANS(Readv)( - XtransConnInfo, /* ciptr */ - struct iovec *, /* buf */ - int /* size */ -); - -int TRANS(Writev)( - XtransConnInfo, /* ciptr */ - struct iovec *, /* buf */ - int /* size */ -); - -int TRANS(Disconnect)( - XtransConnInfo /* ciptr */ -); - -int TRANS(Close)( - XtransConnInfo /* ciptr */ -); - -int TRANS(CloseForCloning)( - XtransConnInfo /* ciptr */ -); - -int TRANS(IsLocal)( - XtransConnInfo /* ciptr */ -); - -int TRANS(GetMyAddr)( - XtransConnInfo, /* ciptr */ - int *, /* familyp */ - int *, /* addrlenp */ - Xtransaddr ** /* addrp */ -); - -int TRANS(GetPeerAddr)( - XtransConnInfo, /* ciptr */ - int *, /* familyp */ - int *, /* addrlenp */ - Xtransaddr ** /* addrp */ -); - -int TRANS(GetConnectionNumber)( - XtransConnInfo /* ciptr */ -); - -#ifdef TRANS_SERVER - -int TRANS(MakeAllCOTSServerListeners)( - char *, /* port */ - int *, /* partial */ - int *, /* count_ret */ - XtransConnInfo ** /* ciptrs_ret */ -); - -int TRANS(MakeAllCLTSServerListeners)( - char *, /* port */ - int *, /* partial */ - int *, /* count_ret */ - XtransConnInfo ** /* ciptrs_ret */ -); - -#endif /* TRANS_SERVER */ - - -/* - * Function Prototypes for Utility Functions. - */ - -#ifdef X11_t - -int TRANS(ConvertAddress)( - int *, /* familyp */ - int *, /* addrlenp */ - Xtransaddr ** /* addrp */ -); - -#endif /* X11_t */ - -#ifdef ICE_t - -char * -TRANS(GetMyNetworkId)( - XtransConnInfo /* ciptr */ -); - -char * -TRANS(GetPeerNetworkId)( - XtransConnInfo /* ciptr */ -); - -#endif /* ICE_t */ - -int -TRANS(GetHostname) ( - char * /* buf */, - int /* maxlen */ -); - -#if defined(WIN32) && defined(TCPCONN) -int TRANS(WSAStartup)(); -#endif - -#endif /* _XTRANS_H_ */ diff --git a/shell/linux-deps/include/X11/Xtrans/Xtransint.h b/shell/linux-deps/include/X11/Xtrans/Xtransint.h deleted file mode 100644 index dd1f683b3..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtransint.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _XTRANSINT_H_ -#define _XTRANSINT_H_ - -/* - * XTRANSDEBUG will enable the PRMSG() macros used in the X Transport - * Interface code. Each use of the PRMSG macro has a level associated with - * it. XTRANSDEBUG is defined to be a level. If the invocation level is =< - * the value of XTRANSDEBUG, then the message will be printed out to stderr. - * Recommended levels are: - * - * XTRANSDEBUG=1 Error messages - * XTRANSDEBUG=2 API Function Tracing - * XTRANSDEBUG=3 All Function Tracing - * XTRANSDEBUG=4 printing of intermediate values - * XTRANSDEBUG=5 really detailed stuff -#define XTRANSDEBUG 2 - * - * Defining XTRANSDEBUGTIMESTAMP will cause printing timestamps with each - * message. - */ - -#ifndef XTRANSDEBUG -# define XTRANSDEBUG 1 -#endif - -#ifdef WIN32 -# define _WILLWINSOCK_ -#endif - -#include "Xtrans.h" - -#ifdef XTRANSDEBUG -# include -#endif /* XTRANSDEBUG */ - -#include - -#ifndef WIN32 -# include -# include -# include - -/* - * Moved the setting of NEED_UTSNAME to this header file from Xtrans.c, - * to avoid a race condition. JKJ (6/5/97) - */ - -# if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__) -# ifndef NEED_UTSNAME -# define NEED_UTSNAME -# endif -# include -# endif - -# define ESET(val) errno = val -# define EGET() errno - -#else /* WIN32 */ - -# include /* for USHRT_MAX */ - -# define ESET(val) WSASetLastError(val) -# define EGET() WSAGetLastError() - -#endif /* WIN32 */ - -#include - -#ifdef X11_t -#define X_TCP_PORT 6000 -#endif - -struct _XtransConnInfo { - struct _Xtransport *transptr; - int index; - char *priv; - int flags; - int fd; - char *port; - int family; - char *addr; - int addrlen; - char *peeraddr; - int peeraddrlen; -}; - -#define XTRANS_OPEN_COTS_CLIENT 1 -#define XTRANS_OPEN_COTS_SERVER 2 -#define XTRANS_OPEN_CLTS_CLIENT 3 -#define XTRANS_OPEN_CLTS_SERVER 4 - - -typedef struct _Xtransport { - char *TransName; - int flags; - -#ifdef TRANS_CLIENT - - XtransConnInfo (*OpenCOTSClient)( - struct _Xtransport *, /* transport */ - char *, /* protocol */ - char *, /* host */ - char * /* port */ - ); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - char ** nolisten; - XtransConnInfo (*OpenCOTSServer)( - struct _Xtransport *, /* transport */ - char *, /* protocol */ - char *, /* host */ - char * /* port */ - ); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_CLIENT - - XtransConnInfo (*OpenCLTSClient)( - struct _Xtransport *, /* transport */ - char *, /* protocol */ - char *, /* host */ - char * /* port */ - ); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - - XtransConnInfo (*OpenCLTSServer)( - struct _Xtransport *, /* transport */ - char *, /* protocol */ - char *, /* host */ - char * /* port */ - ); - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - - XtransConnInfo (*ReopenCOTSServer)( - struct _Xtransport *, /* transport */ - int, /* fd */ - char * /* port */ - ); - - XtransConnInfo (*ReopenCLTSServer)( - struct _Xtransport *, /* transport */ - int, /* fd */ - char * /* port */ - ); - -#endif /* TRANS_REOPEN */ - - - int (*SetOption)( - XtransConnInfo, /* connection */ - int, /* option */ - int /* arg */ - ); - -#ifdef TRANS_SERVER -/* Flags */ -# define ADDR_IN_USE_ALLOWED 1 - - int (*CreateListener)( - XtransConnInfo, /* connection */ - char *, /* port */ - unsigned int /* flags */ - ); - - int (*ResetListener)( - XtransConnInfo /* connection */ - ); - - XtransConnInfo (*Accept)( - XtransConnInfo, /* connection */ - int * /* status */ - ); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_CLIENT - - int (*Connect)( - XtransConnInfo, /* connection */ - char *, /* host */ - char * /* port */ - ); - -#endif /* TRANS_CLIENT */ - - int (*BytesReadable)( - XtransConnInfo, /* connection */ - BytesReadable_t * /* pend */ - ); - - int (*Read)( - XtransConnInfo, /* connection */ - char *, /* buf */ - int /* size */ - ); - - int (*Write)( - XtransConnInfo, /* connection */ - char *, /* buf */ - int /* size */ - ); - - int (*Readv)( - XtransConnInfo, /* connection */ - struct iovec *, /* buf */ - int /* size */ - ); - - int (*Writev)( - XtransConnInfo, /* connection */ - struct iovec *, /* buf */ - int /* size */ - ); - - int (*Disconnect)( - XtransConnInfo /* connection */ - ); - - int (*Close)( - XtransConnInfo /* connection */ - ); - - int (*CloseForCloning)( - XtransConnInfo /* connection */ - ); - -} Xtransport; - - -typedef struct _Xtransport_table { - Xtransport *transport; - int transport_id; -} Xtransport_table; - - -/* - * Flags for the flags member of Xtransport. - */ - -#define TRANS_ALIAS (1<<0) /* record is an alias, don't create server */ -#define TRANS_LOCAL (1<<1) /* local transport */ -#define TRANS_DISABLED (1<<2) /* Don't open this one */ -#define TRANS_NOLISTEN (1<<3) /* Don't listen on this one */ -#define TRANS_NOUNLINK (1<<4) /* Don't unlink transport endpoints */ -#define TRANS_ABSTRACT (1<<5) /* Use abstract sockets if available */ -#define TRANS_NOXAUTH (1<<6) /* Don't verify authentication (because it's secure some other way at the OS layer) */ - -/* Flags to preserve when setting others */ -#define TRANS_KEEPFLAGS (TRANS_NOUNLINK|TRANS_ABSTRACT) - -/* - * readv() and writev() don't exist or don't work correctly on some - * systems, so they may be emulated. - */ - -#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) - -#define READV(ciptr, iov, iovcnt) TRANS(ReadV)(ciptr, iov, iovcnt) - -static int TRANS(ReadV)( - XtransConnInfo, /* ciptr */ - struct iovec *, /* iov */ - int /* iovcnt */ -); - -#else - -#define READV(ciptr, iov, iovcnt) readv(ciptr->fd, iov, iovcnt) - -#endif /* CRAY || (SYSV && __i386__) || WIN32 || __sxg__ || */ - - -#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) - -#define WRITEV(ciptr, iov, iovcnt) TRANS(WriteV)(ciptr, iov, iovcnt) - -static int TRANS(WriteV)( - XtransConnInfo, /* ciptr */ - struct iovec *, /* iov */ - int /* iovcnt */ -); - -#else - -#define WRITEV(ciptr, iov, iovcnt) writev(ciptr->fd, iov, iovcnt) - -#endif /* CRAY || WIN32 || __sxg__ */ - - -static int is_numeric ( - const char * /* str */ -); - -#ifdef TRANS_SERVER -static int trans_mkdir ( - const char *, /* path */ - int /* mode */ -); -#endif - -/* - * Some XTRANSDEBUG stuff - */ - -#if defined(XTRANSDEBUG) -/* add hack to the format string to avoid warnings about extra arguments - * to fprintf. - */ -#ifdef XTRANSDEBUGTIMESTAMP -#if defined(XSERV_t) && defined(TRANS_SERVER) -/* Use ErrorF() for the X server */ -#define PRMSG(lvl,x,a,b,c) if (lvl <= XTRANSDEBUG){ \ - int hack= 0, saveerrno=errno; \ - struct timeval tp;\ - gettimeofday(&tp,0); \ - ErrorF("%s",__xtransname); \ - ErrorF(x+hack,a,b,c); \ - ErrorF("timestamp (ms): %d\n",tp.tv_sec*1000+tp.tv_usec/1000); \ - errno=saveerrno; \ - } else ((void)0) -#else -#define PRMSG(lvl,x,a,b,c) if (lvl <= XTRANSDEBUG){ \ - int hack= 0, saveerrno=errno; \ - struct timeval tp;\ - gettimeofday(&tp,0); \ - fprintf(stderr, "%s", __xtransname); fflush(stderr); \ - fprintf(stderr, x+hack,a,b,c); fflush(stderr); \ - fprintf(stderr, "timestamp (ms): %d\n",tp.tv_sec*1000+tp.tv_usec/1000); \ - fflush(stderr); \ - errno=saveerrno; \ - } else ((void)0) -#endif /* XSERV_t && TRANS_SERVER */ -#else /* XTRANSDEBUGTIMESTAMP */ -#if defined(XSERV_t) && defined(TRANS_SERVER) -/* Use ErrorF() for the X server */ -#define PRMSG(lvl,x,a,b,c) if (lvl <= XTRANSDEBUG){ \ - int hack= 0, saveerrno=errno; \ - ErrorF("%s",__xtransname); \ - ErrorF(x+hack,a,b,c); \ - errno=saveerrno; \ - } else ((void)0) -#else -#define PRMSG(lvl,x,a,b,c) if (lvl <= XTRANSDEBUG){ \ - int hack= 0, saveerrno=errno; \ - fprintf(stderr, "%s", __xtransname); fflush(stderr); \ - fprintf(stderr, x+hack,a,b,c); fflush(stderr); \ - errno=saveerrno; \ - } else ((void)0) -#endif /* XSERV_t && TRANS_SERVER */ -#endif /* XTRANSDEBUGTIMESTAMP */ -#else -#define PRMSG(lvl,x,a,b,c) ((void)0) -#endif /* XTRANSDEBUG */ - -#endif /* _XTRANSINT_H_ */ diff --git a/shell/linux-deps/include/X11/Xtrans/Xtranslcl.c b/shell/linux-deps/include/X11/Xtrans/Xtranslcl.c deleted file mode 100644 index ca04e7f03..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtranslcl.c +++ /dev/null @@ -1,2562 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * - * The connection code/ideas in lib/X and server/os for SVR4/Intel - * environments was contributed by the following companies/groups: - * - * MetroLink Inc - * NCR - * Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems - * SGCS - * Unix System Laboratories (USL) / Novell - * XFree86 - * - * The goal is to have common connection code among all SVR4/Intel vendors. - * - * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, - * IN NO EVENT SHALL THESE COMPANIES * BE LIABLE FOR ANY SPECIAL, INDIRECT - * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE - * OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#if defined(SVR4) || defined(__SVR4) -#include -#endif -#ifdef sun -# include -#else -# include -#endif -#include -#include - -/* - * The local transports should be treated the same as a UNIX domain socket - * wrt authentication, etc. Because of this, we will use struct sockaddr_un - * for the address format. This will simplify the code in other places like - * The X Server. - */ - -#include -#ifndef X_NO_SYS_UN -#include -#endif - - -/* Types of local connections supported: - * - PTS - * - named pipes - * - SCO - */ -#if !defined(sun) -# define LOCAL_TRANS_PTS -#endif -#if defined(SVR4) || defined(__SVR4) -# define LOCAL_TRANS_NAMED -#endif -#if defined(__SCO__) || defined(__UNIXWARE__) -# define LOCAL_TRANS_SCO -#endif - -static int TRANS(LocalClose)(XtransConnInfo ciptr); - -/* - * These functions actually implement the local connection mechanisms. - */ - -/* Type Not Supported */ - -static int -TRANS(OpenFail)(XtransConnInfo ciptr, char *port) - -{ - return -1; -} - -#ifdef TRANS_REOPEN - -static int -TRANS(ReopenFail)(XtransConnInfo ciptr, int fd, char *port) - -{ - return 0; -} - -#endif /* TRANS_REOPEN */ - - - -static int -TRANS(FillAddrInfo)(XtransConnInfo ciptr, char *sun_path, char *peer_sun_path) - -{ - struct sockaddr_un *sunaddr; - struct sockaddr_un *p_sunaddr; - - ciptr->family = AF_UNIX; - ciptr->addrlen = sizeof (struct sockaddr_un); - - if ((sunaddr = (struct sockaddr_un *) xalloc (ciptr->addrlen)) == NULL) - { - PRMSG(1,"FillAddrInfo: failed to allocate memory for addr\n", 0, 0, 0); - return 0; - } - - sunaddr->sun_family = AF_UNIX; - - if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) { - PRMSG(1, "FillAddrInfo: path too long\n", 0, 0, 0); - xfree((char *) sunaddr); - return 0; - } - strcpy (sunaddr->sun_path, sun_path); -#if defined(BSD44SOCKETS) - sunaddr->sun_len = strlen (sunaddr->sun_path); -#endif - - ciptr->addr = (char *) sunaddr; - - ciptr->peeraddrlen = sizeof (struct sockaddr_un); - - if ((p_sunaddr = (struct sockaddr_un *) xalloc ( - ciptr->peeraddrlen)) == NULL) - { - PRMSG(1, - "FillAddrInfo: failed to allocate memory for peer addr\n", - 0,0,0); - xfree ((char *) sunaddr); - ciptr->addr = NULL; - - return 0; - } - - p_sunaddr->sun_family = AF_UNIX; - - if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) { - PRMSG(1, "FillAddrInfo: peer path too long\n", 0, 0, 0); - xfree((char *) p_sunaddr); - return 0; - } - strcpy (p_sunaddr->sun_path, peer_sun_path); -#if defined(BSD44SOCKETS) - p_sunaddr->sun_len = strlen (p_sunaddr->sun_path); -#endif - - ciptr->peeraddr = (char *) p_sunaddr; - - return 1; -} - - - -#ifdef LOCAL_TRANS_PTS -/* PTS */ - -#if defined(SYSV) && !defined(__SCO__) -#define SIGNAL_T int -#else -#define SIGNAL_T void -#endif /* SYSV */ - -typedef SIGNAL_T (*PFV)(); - -extern PFV signal(); - -extern char *ptsname( - int -); - -static void _dummy(int sig) - -{ -} -#endif /* LOCAL_TRANS_PTS */ - -#ifndef sun -#define X_STREAMS_DIR "/dev/X" -#define DEV_SPX "/dev/spx" -#else -#ifndef X11_t -#define X_STREAMS_DIR "/dev/X" -#else -#define X_STREAMS_DIR "/tmp/.X11-pipe" -#endif -#endif - -#define DEV_PTMX "/dev/ptmx" - -#if defined(X11_t) - -#define PTSNODENAME "/dev/X/server." -#ifdef sun -#define NAMEDNODENAME "/tmp/.X11-pipe/X" -#else -#define NAMEDNODENAME "/dev/X/Nserver." - -#define SCORNODENAME "/dev/X%1sR" -#define SCOSNODENAME "/dev/X%1sS" -#endif /* !sun */ -#endif -#if defined(XIM_t) -#ifdef sun -#define NAMEDNODENAME "/tmp/.XIM-pipe/XIM" -#else -#define PTSNODENAME "/dev/X/XIM." -#define NAMEDNODENAME "/dev/X/NXIM." -#define SCORNODENAME "/dev/XIM.%sR" -#define SCOSNODENAME "/dev/XIM.%sS" -#endif -#endif -#if defined(FS_t) || defined (FONT_t) -#ifdef sun -#define NAMEDNODENAME "/tmp/.font-pipe/fs" -#else -/* - * USL has already defined something here. We need to check with them - * and see if their choice is usable here. - */ -#define PTSNODENAME "/dev/X/fontserver." -#define NAMEDNODENAME "/dev/X/Nfontserver." -#define SCORNODENAME "/dev/fontserver.%sR" -#define SCOSNODENAME "/dev/fontserver.%sS" -#endif -#endif -#if defined(ICE_t) -#ifdef sun -#define NAMEDNODENAME "/tmp/.ICE-pipe/" -#else -#define PTSNODENAME "/dev/X/ICE." -#define NAMEDNODENAME "/dev/X/NICE." -#define SCORNODENAME "/dev/ICE.%sR" -#define SCOSNODENAME "/dev/ICE.%sS" -#endif -#endif -#if defined(TEST_t) -#ifdef sun -#define NAMEDNODENAME "/tmp/.Test-unix/test" -#endif -#define PTSNODENAME "/dev/X/transtest." -#define NAMEDNODENAME "/dev/X/Ntranstest." -#define SCORNODENAME "/dev/transtest.%sR" -#define SCOSNODENAME "/dev/transtest.%sS" -#endif - - - -#ifdef LOCAL_TRANS_PTS -#ifdef TRANS_CLIENT - -static int -TRANS(PTSOpenClient)(XtransConnInfo ciptr, char *port) - -{ -#ifdef PTSNODENAME - int fd,server,exitval,alarm_time,ret; - char server_path[64]; - char *slave, namelen; - char buf[20]; /* MAX_PATH_LEN?? */ - PFV savef; - pid_t saved_pid; -#endif - - PRMSG(2,"PTSOpenClient(%s)\n", port, 0,0 ); - -#if !defined(PTSNODENAME) - PRMSG(1,"PTSOpenClient: Protocol is not supported by a pts connection\n", 0,0,0); - return -1; -#else - if (port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) sprintf(server_path, "%s", port); - } else { - (void) sprintf(server_path, "%s%s", PTSNODENAME, port); - } - } else { - (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid()); - } - - - /* - * Open the node the on which the server is listening. - */ - - if ((server = open (server_path, O_RDWR)) < 0) { - PRMSG(1,"PTSOpenClient: failed to open %s\n", server_path, 0,0); - return -1; - } - - - /* - * Open the streams based pipe that will be this connection. - */ - - if ((fd = open(DEV_PTMX, O_RDWR)) < 0) { - PRMSG(1,"PTSOpenClient: failed to open %s\n", DEV_PTMX, 0,0); - close(server); - return(-1); - } - - (void) grantpt(fd); - (void) unlockpt(fd); - - slave = ptsname(fd); /* get name */ - - if( slave == NULL ) { - PRMSG(1,"PTSOpenClient: failed to get ptsname()\n", 0,0,0); - close(fd); - close(server); - return -1; - } - - /* - * This is neccesary for the case where a program is setuid to non-root. - * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will - * set the owner of the pt device incorrectly if the uid is not restored - * before it is called. The problem is that once it gets restored, it - * cannot be changed back to its original condition, hence the fork(). - */ - - if(!(saved_pid=fork())) { - uid_t saved_euid; - - saved_euid = geteuid(); - /** sets the euid to the actual/real uid **/ - if (setuid( getuid() ) == -1) { - exit(1); - } - if( chown( slave, saved_euid, -1 ) < 0 ) { - exit( 1 ); - } - - exit( 0 ); - } - - waitpid(saved_pid, &exitval, 0); - if (WIFEXITED(exitval) && WEXITSTATUS(exitval) != 0) { - close(fd); - close(server); - PRMSG(1, "PTSOpenClient: cannot set the owner of %s\n", - slave, 0, 0); - return(-1); - } - if (chmod(slave, 0666) < 0) { - close(fd); - close(server); - PRMSG(1,"PTSOpenClient: Cannot chmod %s\n", slave, 0,0); - return(-1); - } - - /* - * write slave name to server - */ - - namelen = strlen(slave); - buf[0] = namelen; - (void) sprintf(&buf[1], slave); - (void) write(server, buf, namelen+1); - (void) close(server); - - /* - * wait for server to respond - */ - - savef = signal(SIGALRM, _dummy); - alarm_time = alarm (30); /* CONNECT_TIMEOUT */ - - ret = read(fd, buf, 1); - - (void) alarm(alarm_time); - (void) signal(SIGALRM, savef); - - if (ret != 1) { - PRMSG(1, - "PTSOpenClient: failed to get acknoledgement from server\n", 0, 0, 0); - (void) close(fd); - fd = -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0) - { - PRMSG(1,"PTSOpenClient: failed to fill in addr info\n", 0, 0, 0); - close(fd); - return -1; - } - - return(fd); - -#endif /* !PTSNODENAME */ -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static int -TRANS(PTSOpenServer)(XtransConnInfo ciptr, char *port) - -{ -#ifdef PTSNODENAME - int fd, server; - char server_path[64], *slave; - int mode; -#endif - - PRMSG(2,"PTSOpenServer(%s)\n", port, 0,0 ); - -#if !defined(PTSNODENAME) - PRMSG(1,"PTSOpenServer: Protocol is not supported by a pts connection\n", 0,0,0); - return -1; -#else - if (port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) sprintf(server_path, "%s", port); - } else { - (void) sprintf(server_path, "%s%s", PTSNODENAME, port); - } - } else { - (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid()); - } - -#ifdef HAS_STICKY_DIR_BIT - mode = 01777; -#else - mode = 0777; -#endif - if (trans_mkdir(X_STREAMS_DIR, mode) == -1) { - PRMSG (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n", - X_STREAMS_DIR, errno, 0); - return(-1); - } - -#if 0 - if( (fd=open(server_path, O_RDWR)) >= 0 ) { - /* - * This doesn't prevent the server from starting up, and doesn't - * prevent clients from trying to connect to the in-use PTS (which - * is often in use by something other than another server). - */ - PRMSG(1, "PTSOpenServer: A server is already running on port %s\n", port, 0,0 ); - PRMSG(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path, 0,0 ); - close(fd); - return(-1); - } -#else - /* Just remove the old path (which is what happens with UNIXCONN) */ -#endif - - unlink(server_path); - - if( (fd=open(DEV_PTMX, O_RDWR)) < 0) { - PRMSG(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX, 0,0 ); - return(-1); - } - - grantpt(fd); - unlockpt(fd); - - if( (slave=ptsname(fd)) == NULL) { - PRMSG(1, "PTSOpenServer: Unable to get slave device name\n", 0,0,0 ); - close(fd); - return(-1); - } - - if( link(slave,server_path) < 0 ) { - PRMSG(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path,0 ); - close(fd); - return(-1); - } - - if( chmod(server_path, 0666) < 0 ) { - PRMSG(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path,0,0 ); - close(fd); - return(-1); - } - - if( (server=open(server_path, O_RDWR)) < 0 ) { - PRMSG(1, "PTSOpenServer: Unable to open server device %s\n", server_path,0,0 ); - close(fd); - return(-1); - } - - close(server); - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"PTSOpenServer: failed to fill in addr info\n", 0, 0, 0); - close(fd); - return -1; - } - - return fd; - -#endif /* !PTSNODENAME */ -} - -static int -TRANS(PTSAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) - -{ - int newfd; - int in; - unsigned char length; - char buf[256]; - struct sockaddr_un *sunaddr; - - PRMSG(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd,0); - - if( (in=read(ciptr->fd,&length,1)) <= 0 ){ - if( !in ) { - PRMSG(2, - "PTSAccept: Incoming connection closed\n",0,0,0); - } - else { - PRMSG(1, - "PTSAccept: Error reading incoming connection. errno=%d \n", - errno,0,0); - } - *status = TRANS_ACCEPT_MISC_ERROR; - return -1; - } - - if( (in=read(ciptr->fd,buf,length)) <= 0 ){ - if( !in ) { - PRMSG(2, - "PTSAccept: Incoming connection closed\n",0,0,0); - } - else { - PRMSG(1, -"PTSAccept: Error reading device name for new connection. errno=%d \n", - errno,0,0); - } - *status = TRANS_ACCEPT_MISC_ERROR; - return -1; - } - - buf[length] = '\0'; - - if( (newfd=open(buf,O_RDWR)) < 0 ) { - PRMSG(1, "PTSAccept: Failed to open %s\n",buf,0,0); - *status = TRANS_ACCEPT_MISC_ERROR; - return -1; - } - - write(newfd,"1",1); - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - newciptr->addrlen=ciptr->addrlen; - if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) { - PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n", - 0,0,0); - close(newfd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); - - newciptr->peeraddrlen=sizeof(struct sockaddr_un); - if( (sunaddr=(struct sockaddr_un *)xalloc(newciptr->peeraddrlen)) == NULL ) { - PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n", - 0,0,0); - xfree(newciptr->addr); - close(newfd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - sunaddr->sun_family=AF_UNIX; - strcpy(sunaddr->sun_path,buf); -#if defined(BSD44SOCKETS) - sunaddr->sun_len=strlen(sunaddr->sun_path); -#endif - - newciptr->peeraddr=(char *)sunaddr; - - *status = 0; - - return newfd; -} - -#endif /* TRANS_SERVER */ -#endif /* LOCAL_TRANS_PTS */ - - -#ifdef LOCAL_TRANS_NAMED - -/* NAMED */ - -#ifdef TRANS_CLIENT - -static int -TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, char *port) - -{ -#ifdef NAMEDNODENAME - int fd; - char server_path[64]; - struct stat filestat; -# ifndef sun - extern int isastream(int); -# endif -#endif - - PRMSG(2,"NAMEDOpenClient(%s)\n", port, 0,0 ); - -#if !defined(NAMEDNODENAME) - PRMSG(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n", 0,0,0); - return -1; -#else - if ( port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) snprintf(server_path, sizeof(server_path), "%s", port); - } else { - (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port); - } - } else { - (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid()); - } - - if ((fd = open(server_path, O_RDWR)) < 0) { - PRMSG(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path, 0,0 ); - return -1; - } - - if (fstat(fd, &filestat) < 0 ) { - PRMSG(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path, 0,0 ); - (void) close(fd); - return -1; - } - - if ((filestat.st_mode & S_IFMT) != S_IFIFO) { - PRMSG(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path, 0,0 ); - /* Is this really a failure? */ - (void) close(fd); - return -1; - } - - - if (isastream(fd) <= 0) { - PRMSG(1,"NAMEDOpenClient: %s is not a streams device\n", server_path, 0,0 ); - (void) close(fd); - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"NAMEDOpenClient: failed to fill in addr info\n", - 0,0,0); - close(fd); - return -1; - } - - return(fd); - -#endif /* !NAMEDNODENAME */ -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - - -#ifdef NAMEDNODENAME -static int -TRANS(NAMEDOpenPipe)(const char *server_path) -{ - PRMSG(2,"NAMEDOpenPipe(%s)\n", server_path, 0,0 ); - - int fd, pipefd[2]; - struct stat sbuf; - int mode; - -#if defined(sun) && defined(X11_t) - mode = 0775; /* Solaris requires uid or gid 0 to create X11 pipes */ -#else -#ifdef HAS_STICKY_DIR_BIT - mode = 01777; -#else - mode = 0777; -#endif -#endif - if (trans_mkdir(X_STREAMS_DIR, mode) == -1) { - PRMSG (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n", - X_STREAMS_DIR, errno, 0); - return(-1); - } - - if(stat(server_path, &sbuf) != 0) { - if (errno == ENOENT) { - if ((fd = creat(server_path, (mode_t)0666)) == -1) { - PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 ); - return(-1); - } - close(fd); - if (chmod(server_path, (mode_t)0666) < 0) { - PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 ); - return(-1); - } - } else { - PRMSG(1, "NAMEDOpenPipe: stat on %s failed\n", server_path, 0,0 ); - return(-1); - } - } - - if( pipe(pipefd) != 0) { - PRMSG(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno, 0,0 ); - return(-1); - } - - if( ioctl(pipefd[0], I_PUSH, "connld") != 0) { - PRMSG(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 ); - close(pipefd[0]); - close(pipefd[1]); - return(-1); - } - - if( fattach(pipefd[0], server_path) != 0) { - PRMSG(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno, 0 ); - close(pipefd[0]); - close(pipefd[1]); - return(-1); - } - - return(pipefd[1]); -} -#endif - -static int -TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, char *port) -{ -#ifdef NAMEDNODENAME - int fd; - char server_path[64]; -#endif - - PRMSG(2,"NAMEDOpenServer(%s)\n", port, 0,0 ); - -#if !defined(NAMEDNODENAME) - PRMSG(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n", 0,0,0); - return -1; -#else - if ( port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) snprintf(server_path, sizeof(server_path), "%s", port); - } else { - (void) snprintf(server_path, sizeof(server_path), "%s%s", - NAMEDNODENAME, port); - } - } else { - (void) snprintf(server_path, sizeof(server_path), "%s%ld", - NAMEDNODENAME, (long)getpid()); - } - - fd = TRANS(NAMEDOpenPipe)(server_path); - if (fd < 0) { - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"NAMEDOpenServer: failed to fill in addr info\n", 0,0,0); - TRANS(LocalClose)(ciptr); - return -1; - } - - return fd; - -#endif /* !NAMEDNODENAME */ -} - -static int -TRANS(NAMEDResetListener) (XtransConnInfo ciptr) - -{ - int status = TRANS_RESET_NOOP; - struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr; - struct stat statb; - - PRMSG(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd, 0 ); - - if (ciptr->fd != -1) { - /* - * see if the pipe has disappeared - */ - - if (stat (sockname->sun_path, &statb) == -1 || - (statb.st_mode & S_IFMT) != S_IFIFO) { - PRMSG(3, "Pipe %s trashed, recreating\n", sockname->sun_path, 0, 0); - TRANS(LocalClose)(ciptr); - ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path); - if (ciptr->fd >= 0) - return TRANS_RESET_NEW_FD; - else - return TRANS_CREATE_LISTENER_FAILED; - } - } - return TRANS_RESET_NOOP; -} - -static int -TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) - -{ - struct strrecvfd str; - - PRMSG(2,"NAMEDAccept(%x->%d)\n", ciptr, ciptr->fd, 0 ); - - if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) { - PRMSG(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 ); - *status = TRANS_ACCEPT_MISC_ERROR; - return(-1); - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - newciptr->family=ciptr->family; - newciptr->addrlen=ciptr->addrlen; - if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) { - PRMSG(1, - "NAMEDAccept: failed to allocate memory for pipe addr\n", - 0,0,0); - close(str.fd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); - - newciptr->peeraddrlen=newciptr->addrlen; - if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) { - PRMSG(1, - "NAMEDAccept: failed to allocate memory for peer addr\n", - 0,0,0); - xfree(newciptr->addr); - close(str.fd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen); - - *status = 0; - - return str.fd; -} - -#endif /* TRANS_SERVER */ - -#endif /* LOCAL_TRANS_NAMED */ - - - -#if defined(LOCAL_TRANS_SCO) - -/* - * connect_spipe is used by the SCO connection type. - */ -static int -connect_spipe(int fd1, int fd2) -{ - long temp; - struct strfdinsert sbuf; - - sbuf.databuf.maxlen = -1; - sbuf.databuf.len = -1; - sbuf.databuf.buf = NULL; - sbuf.ctlbuf.maxlen = sizeof(long); - sbuf.ctlbuf.len = sizeof(long); - sbuf.ctlbuf.buf = (caddr_t)&temp; - sbuf.offset = 0; - sbuf.fildes = fd2; - sbuf.flags = 0; - - if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 ) - return(-1); - - return(0); -} - -/* - * named_spipe is used by the SCO connection type. - */ - -static int -named_spipe(int fd, char *path) - -{ - int oldUmask, ret; - struct stat sbuf; - - oldUmask = umask(0); - - (void) fstat(fd, &sbuf); - ret = mknod(path, 0020666, sbuf.st_rdev); - - umask(oldUmask); - - if (ret < 0) { - ret = -1; - } else { - ret = fd; - } - - return(ret); -} - -#endif /* defined(LOCAL_TRANS_SCO) */ - - - - -#ifdef LOCAL_TRANS_SCO -/* SCO */ - -/* - * 2002-11-09 (jkj@sco.com) - * - * This code has been modified to match what is in the actual SCO X server. - * This greatly helps inter-operability between X11R6 and X11R5 (the native - * SCO server). Mainly, it relies on streams nodes existing in /dev, not - * creating them or unlinking them, which breaks the native X server. - * - * However, this is only for the X protocol. For all other protocols, we - * do in fact create the nodes, as only X11R6 will use them, and this makes - * it possible to have both types of clients running, otherwise we get all - * kinds of nasty errors on startup for anything that doesnt use the X - * protocol (like SM, when KDE starts up). - */ - -#ifdef TRANS_CLIENT - -static int -TRANS(SCOOpenClient)(XtransConnInfo ciptr, char *port) -{ -#ifdef SCORNODENAME - int fd, server, fl, ret; - char server_path[64]; - struct strbuf ctlbuf; - unsigned long alarm_time; - void (*savef)(); - long temp; - extern int getmsg(), putmsg(); -#endif - - PRMSG(2,"SCOOpenClient(%s)\n", port, 0,0 ); - if (!port || !port[0]) - port = "0"; - -#if !defined(SCORNODENAME) - PRMSG(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n", 0,0,0); - return -1; -#else - (void) sprintf(server_path, SCORNODENAME, port); - - if ((server = open(server_path, O_RDWR)) < 0) { - PRMSG(1,"SCOOpenClient: failed to open %s\n", server_path, 0,0 ); - return -1; - } - - if ((fd = open(DEV_SPX, O_RDWR)) < 0) { - PRMSG(1,"SCOOpenClient: failed to open %s\n", DEV_SPX, 0,0 ); - close(server); - return -1; - } - - (void) write(server, &server, 1); - ctlbuf.len = 0; - ctlbuf.maxlen = sizeof(long); - ctlbuf.buf = (caddr_t)&temp; - fl = 0; - - savef = signal(SIGALRM, _dummy); - alarm_time = alarm(10); - - ret = getmsg(server, &ctlbuf, 0, &fl); - - (void) alarm(alarm_time); - (void) signal(SIGALRM, savef); - - if (ret < 0) { - PRMSG(1,"SCOOpenClient: error from getmsg\n", 0,0,0 ); - close(fd); - close(server); - return -1; - } - - /* The msg we got via getmsg is the result of an - * I_FDINSERT, so if we do a putmsg with whatever - * we recieved, we're doing another I_FDINSERT ... - */ - (void) putmsg(fd, &ctlbuf, 0, 0); - (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY); - - (void) close(server); - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - -#if defined(X11_t) && defined(__SCO__) - ciptr->flags |= TRANS_NOUNLINK; -#endif - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"SCOOpenClient: failed to fill addr info\n", 0, 0, 0); - close(fd); - return -1; - } - - return(fd); - -#endif /* !SCORNODENAME */ -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static int -TRANS(SCOOpenServer)(XtransConnInfo ciptr, char *port) -{ -#ifdef SCORNODENAME - char serverR_path[64]; - char serverS_path[64]; - struct flock mylock; - int fdr = -1; - int fds = -1; -#endif - - PRMSG(2,"SCOOpenServer(%s)\n", port, 0,0 ); - if (!port || !port[0]) - port = "0"; - -#if !defined(SCORNODENAME) - PRMSG(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n", 0,0,0); - return -1; -#else - (void) sprintf(serverR_path, SCORNODENAME, port); - (void) sprintf(serverS_path, SCOSNODENAME, port); - -#if !defined(X11_t) || !defined(__SCO__) - unlink(serverR_path); - unlink(serverS_path); - - if ((fds = open(DEV_SPX, O_RDWR)) < 0 || - (fdr = open(DEV_SPX, O_RDWR)) < 0 ) { - PRMSG(1,"SCOOpenServer: failed to open %s\n", DEV_SPX, 0,0 ); - if (fds >= 0) - close(fds); - if (fdr >= 0) - close(fdr); - return -1; - } - - if (named_spipe (fds, serverS_path) == -1) { - PRMSG(1,"SCOOpenServer: failed to create %s\n", serverS_path, 0, 0); - close (fdr); - close (fds); - return -1; - } - - if (named_spipe (fdr, serverR_path) == -1) { - PRMSG(1,"SCOOpenServer: failed to create %s\n", serverR_path, 0, 0); - close (fdr); - close (fds); - return -1; - } -#else /* X11_t */ - - fds = open (serverS_path, O_RDWR | O_NDELAY); - if (fds < 0) { - PRMSG(1,"SCOOpenServer: failed to open %s\n", serverS_path, 0, 0); - return -1; - } - - /* - * Lock the connection device for the duration of the server. - * This resolves multiple server starts especially on SMP machines. - */ - mylock.l_type = F_WRLCK; - mylock.l_whence = 0; - mylock.l_start = 0; - mylock.l_len = 0; - if (fcntl (fds, F_SETLK, &mylock) < 0) { - PRMSG(1,"SCOOpenServer: failed to lock %s\n", serverS_path, 0, 0); - close (fds); - return -1; - } - - fdr = open (serverR_path, O_RDWR | O_NDELAY); - if (fdr < 0) { - PRMSG(1,"SCOOpenServer: failed to open %s\n", serverR_path, 0, 0); - close (fds); - return -1; - } -#endif /* X11_t */ - - if (connect_spipe(fds, fdr)) { - PRMSG(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n", - serverS_path, 0, 0); - close (fdr); - close (fds); - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - -#if defined(X11_t) && defined(__SCO__) - ciptr->flags |= TRANS_NOUNLINK; -#endif - if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) { - PRMSG(1,"SCOOpenServer: failed to fill in addr info\n", 0,0,0); - close(fds); - close(fdr); - return -1; - } - - return(fds); - -#endif /* !SCORNODENAME */ -} - -static int -TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) -{ - char c; - int fd; - - PRMSG(2,"SCOAccept(%d)\n", ciptr->fd, 0,0 ); - - if (read(ciptr->fd, &c, 1) < 0) { - PRMSG(1,"SCOAccept: can't read from client\n",0,0,0); - *status = TRANS_ACCEPT_MISC_ERROR; - return(-1); - } - - if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) { - PRMSG(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX, 0,0 ); - *status = TRANS_ACCEPT_MISC_ERROR; - return(-1); - } - - if (connect_spipe (ciptr->fd, fd) < 0) { - PRMSG(1,"SCOAccept: ioctl(I_FDINSERT) failed\n", 0, 0, 0); - close (fd); - *status = TRANS_ACCEPT_MISC_ERROR; - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - newciptr->addrlen=ciptr->addrlen; - if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) { - PRMSG(1, - "SCOAccept: failed to allocate memory for peer addr\n", - 0,0,0); - close(fd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); -#if defined(__SCO__) - newciptr->flags |= TRANS_NOUNLINK; -#endif - - newciptr->peeraddrlen=newciptr->addrlen; - if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) { - PRMSG(1, - "SCOAccept: failed to allocate memory for peer addr\n", - 0,0,0); - xfree(newciptr->addr); - close(fd); - *status = TRANS_ACCEPT_BAD_MALLOC; - return -1; - } - - memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen); - - *status = 0; - - return(fd); -} - -#endif /* TRANS_SERVER */ -#endif /* LOCAL_TRANS_SCO */ - - - -#ifdef TRANS_REOPEN -#ifdef LOCAL_TRANS_PTS - -static int -TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, char *port) - -{ -#ifdef PTSNODENAME - char server_path[64]; -#endif - - PRMSG(2,"PTSReopenServer(%d,%s)\n", fd, port, 0 ); - -#if !defined(PTSNODENAME) - PRMSG(1,"PTSReopenServer: Protocol is not supported by a pts connection\n", 0,0,0); - return 0; -#else - if (port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) sprintf(server_path, "%s", port); - } else { - (void) sprintf(server_path, "%s%s", PTSNODENAME, port); - } - } else { - (void) sprintf(server_path, "%s%ld", PTSNODENAME, (long)getpid()); - } - - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"PTSReopenServer: failed to fill in addr info\n", - 0,0,0); - return 0; - } - - return 1; - -#endif /* !PTSNODENAME */ -} - -#endif /* LOCAL_TRANS_PTS */ - -#ifdef LOCAL_TRANS_NAMED - -static int -TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd, char *port) - -{ -#ifdef NAMEDNODENAME - char server_path[64]; -#endif - - PRMSG(2,"NAMEDReopenServer(%s)\n", port, 0,0 ); - -#if !defined(NAMEDNODENAME) - PRMSG(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n", 0,0,0); - return 0; -#else - if ( port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) sprintf(server_path, "%s", port); - } else { - (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port); - } - } else { - (void) sprintf(server_path, "%s%ld", NAMEDNODENAME, (long)getpid()); - } - - if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) - { - PRMSG(1,"NAMEDReopenServer: failed to fill in addr info\n", - 0,0,0); - return 0; - } - - return 1; - -#endif /* !NAMEDNODENAME */ -} - -#endif /* LOCAL_TRANS_NAMED */ - - -#ifdef LOCAL_TRANS_SCO -static int -TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, char *port) - -{ -#ifdef SCORNODENAME - char serverR_path[64], serverS_path[64]; -#endif - - PRMSG(2,"SCOReopenServer(%s)\n", port, 0,0 ); - if (!port || !port[0]) - port = "0"; - -#if !defined(SCORNODENAME) - PRMSG(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n", 0,0,0); - return 0; -#else - (void) sprintf(serverR_path, SCORNODENAME, port); - (void) sprintf(serverS_path, SCOSNODENAME, port); - -#if defined(X11_t) && defined(__SCO__) - ciptr->flags |= TRANS_NOUNLINK; -#endif - if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) - { - PRMSG(1, "SCOReopenServer: failed to fill in addr info\n", 0,0,0); - return 0; - } - - return 1; - -#endif /* SCORNODENAME */ -} - -#endif /* LOCAL_TRANS_SCO */ - -#endif /* TRANS_REOPEN */ - - - -/* - * This table contains all of the entry points for the different local - * connection mechanisms. - */ - -typedef struct _LOCALtrans2dev { - char *transname; - -#ifdef TRANS_CLIENT - - int (*devcotsopenclient)( - XtransConnInfo, char * /*port*/ -); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - - int (*devcotsopenserver)( - XtransConnInfo, char * /*port*/ -); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_CLIENT - - int (*devcltsopenclient)( - XtransConnInfo, char * /*port*/ -); - -#endif /* TRANS_CLIENT */ - -#ifdef TRANS_SERVER - - int (*devcltsopenserver)( - XtransConnInfo, char * /*port*/ -); - -#endif /* TRANS_SERVER */ - -#ifdef TRANS_REOPEN - - int (*devcotsreopenserver)( - XtransConnInfo, - int, /* fd */ - char * /* port */ -); - - int (*devcltsreopenserver)( - XtransConnInfo, - int, /* fd */ - char * /* port */ -); - -#endif /* TRANS_REOPEN */ - -#ifdef TRANS_SERVER - - int (*devreset)( - XtransConnInfo /* ciptr */ -); - - int (*devaccept)( - XtransConnInfo, XtransConnInfo, int * -); - -#endif /* TRANS_SERVER */ - -} LOCALtrans2dev; - -static LOCALtrans2dev LOCALtrans2devtab[] = { -#ifdef LOCAL_TRANS_PTS -{"", -#ifdef TRANS_CLIENT - TRANS(PTSOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(PTSOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(PTSReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - NULL, /* ResetListener */ - TRANS(PTSAccept) -#endif /* TRANS_SERVER */ -}, - -{"local", -#ifdef TRANS_CLIENT - TRANS(PTSOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(PTSOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(PTSReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - NULL, /* ResetListener */ - TRANS(PTSAccept) -#endif /* TRANS_SERVER */ -}, - -{"pts", -#ifdef TRANS_CLIENT - TRANS(PTSOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(PTSOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(PTSReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - NULL, /* ResetListener */ - TRANS(PTSAccept) -#endif /* TRANS_SERVER */ -}, -#else /* !LOCAL_TRANS_PTS */ -{"", -#ifdef TRANS_CLIENT - TRANS(NAMEDOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(NAMEDOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(NAMEDReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - TRANS(NAMEDResetListener), - TRANS(NAMEDAccept) -#endif /* TRANS_SERVER */ -}, - -{"local", -#ifdef TRANS_CLIENT - TRANS(NAMEDOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(NAMEDOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(NAMEDReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - TRANS(NAMEDResetListener), - TRANS(NAMEDAccept) -#endif /* TRANS_SERVER */ -}, -#endif /* !LOCAL_TRANS_PTS */ - -#ifdef LOCAL_TRANS_NAMED -{"named", -#ifdef TRANS_CLIENT - TRANS(NAMEDOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(NAMEDOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(NAMEDReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - TRANS(NAMEDResetListener), - TRANS(NAMEDAccept) -#endif /* TRANS_SERVER */ -}, - -#ifdef sun /* Alias "pipe" to named, since that's what Solaris called it */ -{"pipe", -#ifdef TRANS_CLIENT - TRANS(NAMEDOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(NAMEDOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(NAMEDReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - TRANS(NAMEDResetListener), - TRANS(NAMEDAccept) -#endif /* TRANS_SERVER */ -}, -#endif /* sun */ -#endif /* LOCAL_TRANS_NAMED */ - - -#ifdef LOCAL_TRANS_SCO -{"sco", -#ifdef TRANS_CLIENT - TRANS(SCOOpenClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SCOOpenServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(OpenFail), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(OpenFail), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SCOReopenServer), - TRANS(ReopenFail), -#endif -#ifdef TRANS_SERVER - NULL, /* ResetListener */ - TRANS(SCOAccept) -#endif /* TRANS_SERVER */ -}, -#endif /* LOCAL_TRANS_SCO */ -}; - -#define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev)) - -static char *XLOCAL=NULL; -static char *workingXLOCAL=NULL; -static char *freeXLOCAL=NULL; - -#if defined(__SCO__) -#define DEF_XLOCAL "SCO:UNIX:PTS" -#elif defined(__UNIXWARE__) -#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO" -#elif defined(sun) -#define DEF_XLOCAL "UNIX:NAMED" -#else -#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO" -#endif - -static void -TRANS(LocalInitTransports)(char *protocol) - -{ - PRMSG(3,"LocalInitTransports(%s)\n", protocol, 0,0 ); - - if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") ) - { - workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (protocol) + 1); - if (workingXLOCAL) - strcpy (workingXLOCAL, protocol); - } - else { - XLOCAL=(char *)getenv("XLOCAL"); - if(XLOCAL==NULL) - XLOCAL=DEF_XLOCAL; - workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (XLOCAL) + 1); - if (workingXLOCAL) - strcpy (workingXLOCAL, XLOCAL); - } -} - -static void -TRANS(LocalEndTransports)(void) - -{ - PRMSG(3,"LocalEndTransports()\n", 0,0,0 ); - xfree(freeXLOCAL); -} - -#define TYPEBUFSIZE 32 - -#ifdef TRANS_CLIENT - -static LOCALtrans2dev * -TRANS(LocalGetNextTransport)(void) - -{ - int i,j; - char *typetocheck; - char typebuf[TYPEBUFSIZE]; - PRMSG(3,"LocalGetNextTransport()\n", 0,0,0 ); - - while(1) - { - if( workingXLOCAL == NULL || *workingXLOCAL == '\0' ) - return NULL; - - typetocheck=workingXLOCAL; - workingXLOCAL=strchr(workingXLOCAL,':'); - if(workingXLOCAL && *workingXLOCAL) - *workingXLOCAL++='\0'; - - for(i=0;i -#endif - -/* - * Make sure 'host' is really local. - */ - -static int -HostReallyLocal (char *host) - -{ - /* - * The 'host' passed to this function may have been generated - * by either uname() or gethostname(). We try both if possible. - */ - -#ifdef NEED_UTSNAME - struct utsname name; -#endif - char buf[256]; - -#ifdef NEED_UTSNAME - if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0) - return (1); -#endif - - buf[0] = '\0'; - (void) gethostname (buf, 256); - buf[255] = '\0'; - - if (strcmp (host, buf) == 0) - return (1); - - return (0); -} - - -static XtransConnInfo -TRANS(LocalOpenClient)(int type, char *protocol, char *host, char *port) - -{ - LOCALtrans2dev *transptr; - XtransConnInfo ciptr; - int index; - - PRMSG(3,"LocalOpenClient()\n", 0,0,0 ); - - /* - * Make sure 'host' is really local. If not, we return failure. - * The reason we make this check is because a process may advertise - * a "local" address for which it can accept connections, but if a - * process on a remote machine tries to connect to this address, - * we know for sure it will fail. - */ - - if (strcmp (host, "unix") != 0 && !HostReallyLocal (host)) - { - PRMSG (1, - "LocalOpenClient: Cannot connect to non-local host %s\n", - host, 0, 0); - return NULL; - } - - -#if defined(X11_t) - /* - * X has a well known port, that is transport dependant. It is easier - * to handle it here, than try and come up with a transport independent - * representation that can be passed in and resolved the usual way. - * - * The port that is passed here is really a string containing the idisplay - * from ConnectDisplay(). Since that is what we want for the local transports, - * we don't have to do anything special. - */ -#endif /* X11_t */ - - if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) - { - PRMSG(1,"LocalOpenClient: calloc(1,%d) failed\n", - sizeof(struct _XtransConnInfo),0,0 ); - return NULL; - } - - ciptr->fd = -1; - - TRANS(LocalInitTransports)(protocol); - - index = 0; - for(transptr=TRANS(LocalGetNextTransport)(); - transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++) - { - switch( type ) - { - case XTRANS_OPEN_COTS_CLIENT: - ciptr->fd=transptr->devcotsopenclient(ciptr,port); - break; - case XTRANS_OPEN_CLTS_CLIENT: - ciptr->fd=transptr->devcltsopenclient(ciptr,port); - break; - case XTRANS_OPEN_COTS_SERVER: - case XTRANS_OPEN_CLTS_SERVER: - PRMSG(1, - "LocalOpenClient: Should not be opening a server with this function\n", - 0,0,0); - break; - default: - PRMSG(1, - "LocalOpenClient: Unknown Open type %d\n", - type, 0,0 ); - } - if( ciptr->fd >= 0 ) - break; - } - - TRANS(LocalEndTransports)(); - - if( ciptr->fd < 0 ) - { - xfree(ciptr); - return NULL; - } - - ciptr->priv=(char *)transptr; - ciptr->index = index; - - return ciptr; -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(LocalOpenServer)(int type, char *protocol, char *host, char *port) - -{ - int i; - XtransConnInfo ciptr; - - PRMSG(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port); - -#if defined(X11_t) - /* - * For X11, the port will be in the format xserverN where N is the - * display number. All of the local connections just need to know - * the display number because they don't do any name resolution on - * the port. This just truncates port to the display portion. - */ -#endif /* X11_t */ - - if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) - { - PRMSG(1,"LocalOpenServer: calloc(1,%d) failed\n", - sizeof(struct _XtransConnInfo),0,0 ); - return NULL; - } - - for(i=1;ifd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port); - break; - case XTRANS_OPEN_CLTS_SERVER: - ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port); - break; - default: - PRMSG(1,"LocalOpenServer: Unknown Open type %d\n", - type ,0,0); - } - if( ciptr->fd >= 0 ) { - ciptr->priv=(char *)&LOCALtrans2devtab[i]; - ciptr->index=i; - ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); - return ciptr; - } - } - - xfree(ciptr); - return NULL; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(LocalReopenServer)(int type, int index, int fd, char *port) - -{ - XtransConnInfo ciptr; - int stat = 0; - - PRMSG(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd); - - if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) - { - PRMSG(1,"LocalReopenServer: calloc(1,%d) failed\n", - sizeof(struct _XtransConnInfo),0,0 ); - return NULL; - } - - ciptr->fd = fd; - - switch( type ) - { - case XTRANS_OPEN_COTS_SERVER: - stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port); - break; - case XTRANS_OPEN_CLTS_SERVER: - stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port); - break; - default: - PRMSG(1,"LocalReopenServer: Unknown Open type %d\n", - type ,0,0); - } - - if( stat > 0 ) { - ciptr->priv=(char *)&LOCALtrans2devtab[index]; - ciptr->index=index; - ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); - return ciptr; - } - - xfree(ciptr); - return NULL; -} - -#endif /* TRANS_REOPEN */ - - - -/* - * This is the Local implementation of the X Transport service layer - */ - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(LocalOpenCOTSClient)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - PRMSG(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port); - - return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port); -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - char *typetocheck = NULL; - int found = 0; - char typebuf[TYPEBUFSIZE]; - - PRMSG(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port); - - /* Check if this local type is in the XLOCAL list */ - TRANS(LocalInitTransports)("local"); - typetocheck = workingXLOCAL; - while (typetocheck && !found) { - int j; - - workingXLOCAL = strchr(workingXLOCAL, ':'); - if (workingXLOCAL && *workingXLOCAL) - *workingXLOCAL++ = '\0'; - strncpy(typebuf, typetocheck, TYPEBUFSIZE); - for (j = 0; j < TYPEBUFSIZE; j++) - if (isupper(typebuf[j])) - typebuf[j] = tolower(typebuf[j]); - if (!strcmp(thistrans->TransName, typebuf)) - found = 1; - typetocheck = workingXLOCAL; - } - TRANS(LocalEndTransports)(); - - if (!found) { - PRMSG(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName,0,0); - thistrans->flags |= TRANS_DISABLED; - return NULL; - } - - return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port); -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(LocalOpenCLTSClient)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - PRMSG(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port); - - return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port); -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(LocalOpenCLTSServer)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - PRMSG(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port); - - return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port); -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, char *port) - -{ - int index; - - PRMSG(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port, 0); - - for(index=1;indexTransName, - LOCALtrans2devtab[index].transname) == 0 ) - break; - } - - if (index >= NUMTRANSPORTS) - { - return (NULL); - } - - return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER, - index, fd, port); -} - -static XtransConnInfo -TRANS(LocalReopenCLTSServer)(Xtransport *thistrans, int fd, char *port) - -{ - int index; - - PRMSG(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port, 0); - - for(index=1;indexTransName, - LOCALtrans2devtab[index].transname) == 0 ) - break; - } - - if (index >= NUMTRANSPORTS) - { - return (NULL); - } - - return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER, - index, fd, port); -} - -#endif /* TRANS_REOPEN */ - - - -static int -TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg) - -{ - PRMSG(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg); - - return -1; -} - - -#ifdef TRANS_SERVER - -static int -TRANS(LocalCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags) - -{ - PRMSG(2,"LocalCreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port); - - return 0; -} - -static int -TRANS(LocalResetListener)(XtransConnInfo ciptr) - -{ - LOCALtrans2dev *transptr; - - PRMSG(2,"LocalResetListener(%x)\n",ciptr,0,0); - - transptr=(LOCALtrans2dev *)ciptr->priv; - if (transptr->devreset != NULL) { - return transptr->devreset(ciptr); - } - return TRANS_RESET_NOOP; -} - - -static XtransConnInfo -TRANS(LocalAccept)(XtransConnInfo ciptr, int *status) - -{ - XtransConnInfo newciptr; - LOCALtrans2dev *transptr; - - PRMSG(2,"LocalAccept(%x->%d)\n", ciptr, ciptr->fd,0); - - transptr=(LOCALtrans2dev *)ciptr->priv; - - if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL ) - { - PRMSG(1,"LocalAccept: calloc(1,%d) failed\n", - sizeof(struct _XtransConnInfo),0,0 ); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - newciptr->fd=transptr->devaccept(ciptr,newciptr,status); - - if( newciptr->fd < 0 ) - { - xfree(newciptr); - return NULL; - } - - newciptr->priv=(char *)transptr; - newciptr->index = ciptr->index; - - *status = 0; - - return newciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -static int -TRANS(LocalConnect)(XtransConnInfo ciptr, char *host, char *port) - -{ - PRMSG(2,"LocalConnect(%x->%d,%s)\n", ciptr, ciptr->fd, port); - - return 0; -} - -#endif /* TRANS_CLIENT */ - - -static int -TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend ) - -{ - PRMSG(2,"LocalBytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend); - -#if defined(SCO325) - return ioctl(ciptr->fd, I_NREAD, (char *)pend); -#else - return ioctl(ciptr->fd, FIONREAD, (char *)pend); -#endif -} - -static int -TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG(2,"LocalRead(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return read(ciptr->fd,buf,size); -} - -static int -TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG(2,"LocalWrite(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return write(ciptr->fd,buf,size); -} - -static int -TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG(2,"LocalReadv(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return READV(ciptr,buf,size); -} - -static int -TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG(2,"LocalWritev(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return WRITEV(ciptr,buf,size); -} - -static int -TRANS(LocalDisconnect)(XtransConnInfo ciptr) - -{ - PRMSG(2,"LocalDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0); - - return 0; -} - -static int -TRANS(LocalClose)(XtransConnInfo ciptr) - -{ - struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr; - int ret; - - PRMSG(2,"LocalClose(%x->%d)\n", ciptr, ciptr->fd ,0); - - ret=close(ciptr->fd); - - if(ciptr->flags - && sockname - && sockname->sun_family == AF_UNIX - && sockname->sun_path[0] ) - { - if (!(ciptr->flags & TRANS_NOUNLINK)) - unlink(sockname->sun_path); - } - - return ret; -} - -static int -TRANS(LocalCloseForCloning)(XtransConnInfo ciptr) - -{ - int ret; - - PRMSG(2,"LocalCloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0); - - /* Don't unlink path */ - - ret=close(ciptr->fd); - - return ret; -} - - -/* - * MakeAllCOTSServerListeners() will go through the entire Xtransports[] - * array defined in Xtrans.c and try to OpenCOTSServer() for each entry. - * We will add duplicate entries to that table so that the OpenCOTSServer() - * function will get called once for each type of local transport. - * - * The TransName is in lowercase, so it will never match during a normal - * call to SelectTransport() in Xtrans.c. - */ - -#ifdef TRANS_SERVER -static char * local_aliases[] = { -# ifdef LOCAL_TRANS_PTS - "pts", -# endif - "named", -# ifdef sun - "pipe", /* compatibility with Solaris Xlib */ -# endif -# ifdef LOCAL_TRANS_SCO - "sco", -# endif - NULL }; -#endif - -Xtransport TRANS(LocalFuncs) = { - /* Local Interface */ - "local", - TRANS_ALIAS | TRANS_LOCAL, -#ifdef TRANS_CLIENT - TRANS(LocalOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - local_aliases, - TRANS(LocalOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(LocalOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(LocalReopenCOTSServer), - TRANS(LocalReopenCLTSServer), -#endif - TRANS(LocalSetOption), -#ifdef TRANS_SERVER - TRANS(LocalCreateListener), - TRANS(LocalResetListener), - TRANS(LocalAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalConnect), -#endif /* TRANS_CLIENT */ - TRANS(LocalBytesReadable), - TRANS(LocalRead), - TRANS(LocalWrite), - TRANS(LocalReadv), - TRANS(LocalWritev), - TRANS(LocalDisconnect), - TRANS(LocalClose), - TRANS(LocalCloseForCloning), -}; - -#ifdef LOCAL_TRANS_PTS - -Xtransport TRANS(PTSFuncs) = { - /* Local Interface */ - "pts", - TRANS_LOCAL, -#ifdef TRANS_CLIENT - TRANS(LocalOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(LocalOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(LocalOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(LocalReopenCOTSServer), - TRANS(LocalReopenCLTSServer), -#endif - TRANS(LocalSetOption), -#ifdef TRANS_SERVER - TRANS(LocalCreateListener), - TRANS(LocalResetListener), - TRANS(LocalAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalConnect), -#endif /* TRANS_CLIENT */ - TRANS(LocalBytesReadable), - TRANS(LocalRead), - TRANS(LocalWrite), - TRANS(LocalReadv), - TRANS(LocalWritev), - TRANS(LocalDisconnect), - TRANS(LocalClose), - TRANS(LocalCloseForCloning), -}; - -#endif /* LOCAL_TRANS_PTS */ - -#ifdef LOCAL_TRANS_NAMED - -Xtransport TRANS(NAMEDFuncs) = { - /* Local Interface */ - "named", - TRANS_LOCAL, -#ifdef TRANS_CLIENT - TRANS(LocalOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(LocalOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(LocalOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(LocalReopenCOTSServer), - TRANS(LocalReopenCLTSServer), -#endif - TRANS(LocalSetOption), -#ifdef TRANS_SERVER - TRANS(LocalCreateListener), - TRANS(LocalResetListener), - TRANS(LocalAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalConnect), -#endif /* TRANS_CLIENT */ - TRANS(LocalBytesReadable), - TRANS(LocalRead), - TRANS(LocalWrite), - TRANS(LocalReadv), - TRANS(LocalWritev), - TRANS(LocalDisconnect), - TRANS(LocalClose), - TRANS(LocalCloseForCloning), -}; - -#ifdef sun -Xtransport TRANS(PIPEFuncs) = { - /* Local Interface */ - "pipe", - TRANS_ALIAS | TRANS_LOCAL, -#ifdef TRANS_CLIENT - TRANS(LocalOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(LocalOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(LocalOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(LocalReopenCOTSServer), - TRANS(LocalReopenCLTSServer), -#endif - TRANS(LocalSetOption), -#ifdef TRANS_SERVER - TRANS(LocalCreateListener), - TRANS(LocalResetListener), - TRANS(LocalAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalConnect), -#endif /* TRANS_CLIENT */ - TRANS(LocalBytesReadable), - TRANS(LocalRead), - TRANS(LocalWrite), - TRANS(LocalReadv), - TRANS(LocalWritev), - TRANS(LocalDisconnect), - TRANS(LocalClose), - TRANS(LocalCloseForCloning), -}; -#endif /* sun */ -#endif /* LOCAL_TRANS_NAMED */ - - -#ifdef LOCAL_TRANS_SCO -Xtransport TRANS(SCOFuncs) = { - /* Local Interface */ - "sco", - TRANS_LOCAL, -#ifdef TRANS_CLIENT - TRANS(LocalOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(LocalOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(LocalOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(LocalReopenCOTSServer), - TRANS(LocalReopenCLTSServer), -#endif - TRANS(LocalSetOption), -#ifdef TRANS_SERVER - TRANS(LocalCreateListener), - TRANS(LocalResetListener), - TRANS(LocalAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(LocalConnect), -#endif /* TRANS_CLIENT */ - TRANS(LocalBytesReadable), - TRANS(LocalRead), - TRANS(LocalWrite), - TRANS(LocalReadv), - TRANS(LocalWritev), - TRANS(LocalDisconnect), - TRANS(LocalClose), - TRANS(LocalCloseForCloning), -}; -#endif /* LOCAL_TRANS_SCO */ diff --git a/shell/linux-deps/include/X11/Xtrans/Xtranssock.c b/shell/linux-deps/include/X11/Xtrans/Xtranssock.c deleted file mode 100644 index 5f65738b9..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtranssock.c +++ /dev/null @@ -1,2501 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the copyright holders shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from the copyright holders. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#ifdef XTHREADS -#include -#endif - -#ifndef WIN32 - -#if defined(TCPCONN) || defined(UNIXCONN) -#include -#include -#include -#endif - -#if defined(TCPCONN) || defined(UNIXCONN) -#define X_INCLUDE_NETDB_H -#define XOS_USE_NO_LOCKING -#include -#endif - -#ifdef UNIXCONN -#ifndef X_NO_SYS_UN -#include -#endif -#include -#endif - - -#ifndef NO_TCP_H -#if defined(linux) || defined(__GLIBC__) -#include -#endif /* osf */ -#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -#include -#include -#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __DragonFly__ */ -#include -#endif /* !NO_TCP_H */ - -#include -#if defined(SVR4) || defined(__SVR4) -#include -#endif - -#if (defined(__i386__) && defined(SYSV)) && !defined(SCO325) && !defined(sun) -#include -#endif - -#if defined(__i386__) && defined(SYSV) -#include -#endif - -#include - -#else /* !WIN32 */ - -#include -#include -#include -#undef close -#define close closesocket -#define ECONNREFUSED WSAECONNREFUSED -#define EADDRINUSE WSAEADDRINUSE -#define EPROTOTYPE WSAEPROTOTYPE -#undef EWOULDBLOCK -#define EWOULDBLOCK WSAEWOULDBLOCK -#define EINPROGRESS WSAEINPROGRESS -#undef EINTR -#define EINTR WSAEINTR -#define X_INCLUDE_NETDB_H -#define XOS_USE_MTSAFE_NETDBAPI -#include -#endif /* WIN32 */ - -#if defined(SO_DONTLINGER) && defined(SO_LINGER) -#undef SO_DONTLINGER -#endif - -/* others don't need this */ -#define SocketInitOnce() /**/ - -#ifdef linux -#define HAVE_ABSTRACT_SOCKETS -#endif - -#define MIN_BACKLOG 128 -#ifdef SOMAXCONN -#if SOMAXCONN > MIN_BACKLOG -#define BACKLOG SOMAXCONN -#endif -#endif -#ifndef BACKLOG -#define BACKLOG MIN_BACKLOG -#endif - -/* - * This is the Socket implementation of the X Transport service layer - * - * This file contains the implementation for both the UNIX and INET domains, - * and can be built for either one, or both. - * - */ - -typedef struct _Sockettrans2dev { - char *transname; - int family; - int devcotsname; - int devcltsname; - int protocol; -} Sockettrans2dev; - -static Sockettrans2dev Sockettrans2devtab[] = { -#ifdef TCPCONN - {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, -#if !defined(IPv6) || !defined(AF_INET6) - {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, -#else /* IPv6 */ - {"tcp",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0}, - {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, /* fallback */ - {"inet6",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0}, -#endif -#endif /* TCPCONN */ -#ifdef UNIXCONN - {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0}, -#if !defined(LOCALCONN) - {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0}, -#endif /* !LOCALCONN */ -#endif /* UNIXCONN */ -}; - -#define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev)) - -#ifdef TCPCONN -static int TRANS(SocketINETClose) (XtransConnInfo ciptr); -#endif - -#ifdef UNIXCONN - - -#if defined(X11_t) -#define UNIX_PATH "/tmp/.X11-unix/X" -#define UNIX_DIR "/tmp/.X11-unix" -#endif /* X11_t */ -#if defined(XIM_t) -#define UNIX_PATH "/tmp/.XIM-unix/XIM" -#define UNIX_DIR "/tmp/.XIM-unix" -#endif /* XIM_t */ -#if defined(FS_t) || defined(FONT_t) -#define UNIX_PATH "/tmp/.font-unix/fs" -#define UNIX_DIR "/tmp/.font-unix" -#endif /* FS_t || FONT_t */ -#if defined(ICE_t) -#define UNIX_PATH "/tmp/.ICE-unix/" -#define UNIX_DIR "/tmp/.ICE-unix" -#endif /* ICE_t */ -#if defined(TEST_t) -#define UNIX_PATH "/tmp/.Test-unix/test" -#define UNIX_DIR "/tmp/.Test-unix" -#endif -#if defined(LBXPROXY_t) -#define UNIX_PATH "/tmp/.X11-unix/X" -#define UNIX_DIR "/tmp/.X11-unix" -#endif - - -#endif /* UNIXCONN */ - -#define PORTBUFSIZE 32 - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 255 -#endif - -#if defined HAVE_SOCKLEN_T || (defined(IPv6) && defined(AF_INET6)) -# define SOCKLEN_T socklen_t -#elif defined(SVR4) || defined(__SVR4) || defined(__SCO__) -# define SOCKLEN_T size_t -#else -# define SOCKLEN_T int -#endif - -/* - * These are some utility function used by the real interface function below. - */ - -static int -TRANS(SocketSelectFamily) (int first, char *family) - -{ - int i; - - PRMSG (3,"SocketSelectFamily(%s)\n", family, 0, 0); - - for (i = first + 1; i < NUMSOCKETFAMILIES;i++) - { - if (!strcmp (family, Sockettrans2devtab[i].transname)) - return i; - } - - return (first == -1 ? -2 : -1); -} - - -/* - * This function gets the local address of the socket and stores it in the - * XtransConnInfo structure for the connection. - */ - -static int -TRANS(SocketINETGetAddr) (XtransConnInfo ciptr) - -{ -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage socknamev6; -#else - struct sockaddr_in socknamev4; -#endif - void *socknamePtr; - SOCKLEN_T namelen; - - PRMSG (3,"SocketINETGetAddr(%p)\n", ciptr, 0, 0); - -#if defined(IPv6) && defined(AF_INET6) - namelen = sizeof(socknamev6); - socknamePtr = &socknamev6; -#else - namelen = sizeof(socknamev4); - socknamePtr = &socknamev4; -#endif - - bzero(socknamePtr, namelen); - - if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr, - (void *)&namelen) < 0) - { -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - PRMSG (1,"SocketINETGetAddr: getsockname() failed: %d\n", - EGET(),0, 0); - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) - { - PRMSG (1, - "SocketINETGetAddr: Can't allocate space for the addr\n", - 0, 0, 0); - return -1; - } - -#if defined(IPv6) && defined(AF_INET6) - ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family; -#else - ciptr->family = socknamev4.sin_family; -#endif - ciptr->addrlen = namelen; - memcpy (ciptr->addr, socknamePtr, ciptr->addrlen); - - return 0; -} - - -/* - * This function gets the remote address of the socket and stores it in the - * XtransConnInfo structure for the connection. - */ - -static int -TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) - -{ -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage socknamev6; -#endif - struct sockaddr_in socknamev4; - void *socknamePtr; - SOCKLEN_T namelen; - -#if defined(IPv6) && defined(AF_INET6) - if (ciptr->family == AF_INET6) - { - namelen = sizeof(socknamev6); - socknamePtr = &socknamev6; - } - else -#endif - { - namelen = sizeof(socknamev4); - socknamePtr = &socknamev4; - } - - bzero(socknamePtr, namelen); - - PRMSG (3,"SocketINETGetPeerAddr(%p)\n", ciptr, 0, 0); - - if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr, - (void *)&namelen) < 0) - { -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - PRMSG (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n", - EGET(), 0, 0); - return -1; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) - { - PRMSG (1, - "SocketINETGetPeerAddr: Can't allocate space for the addr\n", - 0, 0, 0); - return -1; - } - - ciptr->peeraddrlen = namelen; - memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen); - - return 0; -} - - -static XtransConnInfo -TRANS(SocketOpen) (int i, int type) - -{ - XtransConnInfo ciptr; - - PRMSG (3,"SocketOpen(%d,%d)\n", i, type, 0); - - if ((ciptr = (XtransConnInfo) xcalloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) - { - PRMSG (1, "SocketOpen: malloc failed\n", 0, 0, 0); - return NULL; - } - - if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type, - Sockettrans2devtab[i].protocol)) < 0 -#ifndef WIN32 -#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t) - || ciptr->fd >= sysconf(_SC_OPEN_MAX) -#endif -#endif - ) { -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - PRMSG (2, "SocketOpen: socket() failed for %s\n", - Sockettrans2devtab[i].transname, 0, 0); - - xfree ((char *) ciptr); - return NULL; - } - -#ifdef TCP_NODELAY - if (Sockettrans2devtab[i].family == AF_INET -#if defined(IPv6) && defined(AF_INET6) - || Sockettrans2devtab[i].family == AF_INET6 -#endif - ) - { - /* - * turn off TCP coalescence for INET sockets - */ - - int tmp = 1; - setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY, - (char *) &tmp, sizeof (int)); - } -#endif - - return ciptr; -} - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(SocketReopen) (int i, int type, int fd, char *port) - -{ - XtransConnInfo ciptr; - int portlen; - struct sockaddr *addr; - - PRMSG (3,"SocketReopen(%d,%d,%s)\n", type, fd, port); - - if (port == NULL) { - PRMSG (1, "SocketReopen: port was null!\n", 0, 0, 0); - return NULL; - } - - portlen = strlen(port) + 1; // include space for trailing null -#ifdef SOCK_MAXADDRLEN - if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) { - PRMSG (1, "SocketReopen: invalid portlen %d\n", portlen, 0, 0); - return NULL; - } - if (portlen < 14) portlen = 14; -#else - if (portlen < 0 || portlen > 14) { - PRMSG (1, "SocketReopen: invalid portlen %d\n", portlen, 0, 0); - return NULL; - } -#endif /*SOCK_MAXADDRLEN*/ - - if ((ciptr = (XtransConnInfo) xcalloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) - { - PRMSG (1, "SocketReopen: malloc(ciptr) failed\n", 0, 0, 0); - return NULL; - } - - ciptr->fd = fd; - - if ((addr = (struct sockaddr *) xcalloc (1, portlen + 2)) == NULL) { - PRMSG (1, "SocketReopen: malloc(addr) failed\n", 0, 0, 0); - return NULL; - } - ciptr->addr = (char *) addr; - ciptr->addrlen = portlen + 2; - - if ((ciptr->peeraddr = (char *) xcalloc (1, portlen + 2)) == NULL) { - PRMSG (1, "SocketReopen: malloc(portaddr) failed\n", 0, 0, 0); - return NULL; - } - ciptr->peeraddrlen = portlen + 2; - - /* Initialize ciptr structure as if it were a normally-opened unix socket */ - ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK; -#ifdef BSD44SOCKETS - addr->sa_len = portlen + 1; -#endif - addr->sa_family = AF_UNIX; -#ifdef HAS_STRLCPY - strlcpy(addr->sa_data, port, portlen); -#else - strncpy(addr->sa_data, port, portlen); -#endif - ciptr->family = AF_UNIX; - memcpy(ciptr->peeraddr, ciptr->addr, sizeof(struct sockaddr)); - ciptr->port = rindex(addr->sa_data, ':'); - if (ciptr->port == NULL) { - if (is_numeric(addr->sa_data)) { - ciptr->port = addr->sa_data; - } - } else if (ciptr->port[0] == ':') { - ciptr->port++; - } - /* port should now point to portnum or NULL */ - return ciptr; -} - -#endif /* TRANS_REOPEN */ - - -/* - * These functions are the interface supplied in the Xtransport structure - */ - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol, - char *host, char *port, int previndex) -{ - XtransConnInfo ciptr; - int i = previndex; - - PRMSG (2, "SocketOpenCOTSClient(%s,%s,%s)\n", - protocol, host, port); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) { - if ((ciptr = TRANS(SocketOpen) ( - i, Sockettrans2devtab[i].devcotsname)) != NULL) { - /* Save the index for later use */ - - ciptr->index = i; - break; - } - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketOpenCOTSClient: Unable to open socket for %s\n", - transname, 0, 0); - else - PRMSG (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n", - transname, 0, 0); - return NULL; - } - - return ciptr; -} - -static XtransConnInfo -TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol, - char *host, char *port) -{ - return TRANS(SocketOpenCOTSClientBase)( - thistrans->TransName, protocol, host, port, -1); -} - - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i = -1; - - PRMSG (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { - if ((ciptr = TRANS(SocketOpen) ( - i, Sockettrans2devtab[i].devcotsname)) != NULL) - break; - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketOpenCOTSServer: Unable to open socket for %s\n", - thistrans->TransName, 0, 0); - else - PRMSG (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n", - thistrans->TransName, 0, 0); - return NULL; - } - - /* - * Using this prevents the bind() check for an existing server listening - * on the same port, but it is required for other reasons. - */ -#ifdef SO_REUSEADDR - - /* - * SO_REUSEADDR only applied to AF_INET && AF_INET6 - */ - - if (Sockettrans2devtab[i].family == AF_INET -#if defined(IPv6) && defined(AF_INET6) - || Sockettrans2devtab[i].family == AF_INET6 -#endif - ) - { - int one = 1; - setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR, - (char *) &one, sizeof (int)); - } -#endif -#ifdef IPV6_V6ONLY - if (Sockettrans2devtab[i].family == AF_INET6) - { - int one = 1; - setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); - } -#endif - /* Save the index for later use */ - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(SocketOpenCLTSClient) (Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i = -1; - - PRMSG (2,"SocketOpenCLTSClient(%s,%s,%s)\n", protocol, host, port); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { - if ((ciptr = TRANS(SocketOpen) ( - i, Sockettrans2devtab[i].devcotsname)) != NULL) - break; - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketOpenCLTSClient: Unable to open socket for %s\n", - thistrans->TransName, 0, 0); - else - PRMSG (1,"SocketOpenCLTSClient: Unable to determine socket type for %s\n", - thistrans->TransName, 0, 0); - return NULL; - } - - /* Save the index for later use */ - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(SocketOpenCLTSServer) (Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i = -1; - - PRMSG (2,"SocketOpenCLTSServer(%s,%s,%s)\n", protocol, host, port); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { - if ((ciptr = TRANS(SocketOpen) ( - i, Sockettrans2devtab[i].devcotsname)) != NULL) - break; - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketOpenCLTSServer: Unable to open socket for %s\n", - thistrans->TransName, 0, 0); - else - PRMSG (1,"SocketOpenCLTSServer: Unable to determine socket type for %s\n", - thistrans->TransName, 0, 0); - return NULL; - } - -#ifdef IPV6_V6ONLY - if (Sockettrans2devtab[i].family == AF_INET6) - { - int one = 1; - setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); - } -#endif - /* Save the index for later use */ - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, char *port) - -{ - XtransConnInfo ciptr; - int i = -1; - - PRMSG (2, - "SocketReopenCOTSServer(%d, %s)\n", fd, port, 0); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { - if ((ciptr = TRANS(SocketReopen) ( - i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) - break; - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketReopenCOTSServer: Unable to open socket for %s\n", - thistrans->TransName, 0, 0); - else - PRMSG (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n", - thistrans->TransName, 0, 0); - return NULL; - } - - /* Save the index for later use */ - - ciptr->index = i; - - return ciptr; -} - -static XtransConnInfo -TRANS(SocketReopenCLTSServer) (Xtransport *thistrans, int fd, char *port) - -{ - XtransConnInfo ciptr; - int i = -1; - - PRMSG (2, - "SocketReopenCLTSServer(%d, %s)\n", fd, port, 0); - - SocketInitOnce(); - - while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { - if ((ciptr = TRANS(SocketReopen) ( - i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) - break; - } - if (i < 0) { - if (i == -1) - PRMSG (1,"SocketReopenCLTSServer: Unable to open socket for %s\n", - thistrans->TransName, 0, 0); - else - PRMSG (1,"SocketReopenCLTSServer: Unable to determine socket type for %s\n", - thistrans->TransName, 0, 0); - return NULL; - } - - /* Save the index for later use */ - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_REOPEN */ - - -static int -TRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg) - -{ - PRMSG (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); - - return -1; -} - -#ifdef UNIXCONN -static int -set_sun_path(const char *port, const char *upath, char *path, int abstract) -{ - struct sockaddr_un s; - int maxlen = sizeof(s.sun_path) - 1; - const char *at = ""; - - if (!port || !*port || !path) - return -1; - -#ifdef HAVE_ABSTRACT_SOCKETS - if (port[0] == '@') - upath = ""; - else if (abstract) - at = "@"; -#endif - - if (*port == '/') /* a full pathname */ - upath = ""; - - if (strlen(port) + strlen(upath) > maxlen) - return -1; - sprintf(path, "%s%s%s", at, upath, port); - return 0; -} -#endif - -#ifdef TRANS_SERVER - -static int -TRANS(SocketCreateListener) (XtransConnInfo ciptr, - struct sockaddr *sockname, - int socknamelen, unsigned int flags) - -{ - SOCKLEN_T namelen = socknamelen; - int fd = ciptr->fd; - int retry; - - PRMSG (3, "SocketCreateListener(%x,%p)\n", ciptr, fd, 0); - - if (Sockettrans2devtab[ciptr->index].family == AF_INET -#if defined(IPv6) && defined(AF_INET6) - || Sockettrans2devtab[ciptr->index].family == AF_INET6 -#endif - ) - retry = 20; - else - retry = 0; - - while (bind (fd, (struct sockaddr *) sockname, namelen) < 0) - { - if (errno == EADDRINUSE) { - if (flags & ADDR_IN_USE_ALLOWED) - break; - else - return TRANS_ADDR_IN_USE; - } - - if (retry-- == 0) { - PRMSG (1, "SocketCreateListener: failed to bind listener\n", - 0, 0, 0); - close (fd); - return TRANS_CREATE_LISTENER_FAILED; - } -#ifdef SO_REUSEADDR - sleep (1); -#else - sleep (10); -#endif /* SO_REUSEDADDR */ - } - - if (Sockettrans2devtab[ciptr->index].family == AF_INET -#if defined(IPv6) && defined(AF_INET6) - || Sockettrans2devtab[ciptr->index].family == AF_INET6 -#endif - ) { -#ifdef SO_DONTLINGER - setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0); -#else -#ifdef SO_LINGER - { - static int linger[2] = { 0, 0 }; - setsockopt (fd, SOL_SOCKET, SO_LINGER, - (char *) linger, sizeof (linger)); - } -#endif -#endif -} - - if (listen (fd, BACKLOG) < 0) - { - PRMSG (1, "SocketCreateListener: listen() failed\n", 0, 0, 0); - close (fd); - return TRANS_CREATE_LISTENER_FAILED; - } - - /* Set a flag to indicate that this connection is a listener */ - - ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); - - return 0; -} - -#ifdef TCPCONN -static int -TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) - -{ -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage sockname; -#else - struct sockaddr_in sockname; -#endif - unsigned short sport; - SOCKLEN_T namelen = sizeof(sockname); - int status; - long tmpport; -#ifdef XTHREADS_NEEDS_BYNAMEPARAMS - _Xgetservbynameparams sparams; -#endif - struct servent *servp; - -#ifdef X11_t - char portbuf[PORTBUFSIZE]; -#endif - - PRMSG (2, "SocketINETCreateListener(%s)\n", port, 0, 0); - -#ifdef X11_t - /* - * X has a well known port, that is transport dependent. It is easier - * to handle it here, than try and come up with a transport independent - * representation that can be passed in and resolved the usual way. - * - * The port that is passed here is really a string containing the idisplay - * from ConnectDisplay(). - */ - - if (is_numeric (port)) - { - /* fixup the server port address */ - tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf (portbuf,"%lu", tmpport); - port = portbuf; - } -#endif - - if (port && *port) - { - /* Check to see if the port string is just a number (handles X11) */ - - if (!is_numeric (port)) - { - if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) - { - PRMSG (1, - "SocketINETCreateListener: Unable to get service for %s\n", - port, 0, 0); - return TRANS_CREATE_LISTENER_FAILED; - } - /* we trust getservbyname to return a valid number */ - sport = servp->s_port; - } - else - { - tmpport = strtol (port, (char**)NULL, 10); - /* - * check that somehow the port address isn't negative or in - * the range of reserved port addresses. This can happen and - * be very bad if the server is suid-root and the user does - * something (dumb) like `X :60049`. - */ - if (tmpport < 1024 || tmpport > USHRT_MAX) - return TRANS_CREATE_LISTENER_FAILED; - - sport = (unsigned short) tmpport; - } - } - else - sport = 0; - - bzero(&sockname, sizeof(sockname)); -#if defined(IPv6) && defined(AF_INET6) - if (Sockettrans2devtab[ciptr->index].family == AF_INET) { - namelen = sizeof (struct sockaddr_in); -#ifdef BSD44SOCKETS - ((struct sockaddr_in *)&sockname)->sin_len = namelen; -#endif - ((struct sockaddr_in *)&sockname)->sin_family = AF_INET; - ((struct sockaddr_in *)&sockname)->sin_port = htons(sport); - ((struct sockaddr_in *)&sockname)->sin_addr.s_addr = htonl(INADDR_ANY); - } else { - namelen = sizeof (struct sockaddr_in6); -#ifdef SIN6_LEN - ((struct sockaddr_in6 *)&sockname)->sin6_len = sizeof(sockname); -#endif - ((struct sockaddr_in6 *)&sockname)->sin6_family = AF_INET6; - ((struct sockaddr_in6 *)&sockname)->sin6_port = htons(sport); - ((struct sockaddr_in6 *)&sockname)->sin6_addr = in6addr_any; - } -#else -#ifdef BSD44SOCKETS - sockname.sin_len = sizeof (sockname); -#endif - sockname.sin_family = AF_INET; - sockname.sin_port = htons (sport); - sockname.sin_addr.s_addr = htonl (INADDR_ANY); -#endif - - if ((status = TRANS(SocketCreateListener) (ciptr, - (struct sockaddr *) &sockname, namelen, flags)) < 0) - { - PRMSG (1, - "SocketINETCreateListener: ...SocketCreateListener() failed\n", - 0, 0, 0); - return status; - } - - if (TRANS(SocketINETGetAddr) (ciptr) < 0) - { - PRMSG (1, - "SocketINETCreateListener: ...SocketINETGetAddr() failed\n", - 0, 0, 0); - return TRANS_CREATE_LISTENER_FAILED; - } - - return 0; -} - -#endif /* TCPCONN */ - - -#ifdef UNIXCONN - -static int -TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port, - unsigned int flags) - -{ - struct sockaddr_un sockname; - int namelen; - int oldUmask; - int status; - unsigned int mode; - char tmpport[108]; - - int abstract = 0; -#ifdef HAVE_ABSTRACT_SOCKETS - abstract = ciptr->transptr->flags & TRANS_ABSTRACT; -#endif - - PRMSG (2, "SocketUNIXCreateListener(%s)\n", - port ? port : "NULL", 0, 0); - - /* Make sure the directory is created */ - - oldUmask = umask (0); - -#ifdef UNIX_DIR -#ifdef HAS_STICKY_DIR_BIT - mode = 01777; -#else - mode = 0777; -#endif - if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) { - PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n", - UNIX_DIR, errno, 0); - (void) umask (oldUmask); - return TRANS_CREATE_LISTENER_FAILED; - } -#endif - - memset(&sockname, 0, sizeof(sockname)); - sockname.sun_family = AF_UNIX; - - if (!(port && *port)) { - snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid()); - port = tmpport; - } - if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { - PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); - return TRANS_CREATE_LISTENER_FAILED; - } - -#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) - sockname.sun_len = strlen(sockname.sun_path); -#endif - -#if defined(BSD44SOCKETS) || defined(SUN_LEN) - namelen = SUN_LEN(&sockname); -#else - namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); -#endif - - if (abstract) { - sockname.sun_path[0] = '\0'; - namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]); - } - else - unlink (sockname.sun_path); - - if ((status = TRANS(SocketCreateListener) (ciptr, - (struct sockaddr *) &sockname, namelen, flags)) < 0) - { - PRMSG (1, - "SocketUNIXCreateListener: ...SocketCreateListener() failed\n", - 0, 0, 0); - (void) umask (oldUmask); - return status; - } - - /* - * Now that the listener is esablished, create the addr info for - * this connection. getpeername() doesn't work for UNIX Domain Sockets - * on some systems (hpux at least), so we will just do it manually, instead - * of calling something like TRANS(SocketUNIXGetAddr). - */ - - namelen = sizeof (sockname); /* this will always make it the same size */ - - if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) - { - PRMSG (1, - "SocketUNIXCreateListener: Can't allocate space for the addr\n", - 0, 0, 0); - (void) umask (oldUmask); - return TRANS_CREATE_LISTENER_FAILED; - } - - if (abstract) - sockname.sun_path[0] = '@'; - - ciptr->family = sockname.sun_family; - ciptr->addrlen = namelen; - memcpy (ciptr->addr, &sockname, ciptr->addrlen); - - (void) umask (oldUmask); - - return 0; -} - - -static int -TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr) - -{ - /* - * See if the unix domain socket has disappeared. If it has, recreate it. - */ - - struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr; - struct stat statb; - int status = TRANS_RESET_NOOP; - unsigned int mode; - int abstract = 0; -#ifdef HAVE_ABSTRACT_SOCKETS - abstract = ciptr->transptr->flags & TRANS_ABSTRACT; -#endif - - PRMSG (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd, 0); - - if (!abstract && ( - stat (unsock->sun_path, &statb) == -1 || - ((statb.st_mode & S_IFMT) != -#if defined(NCR) || defined(SCO325) || !defined(S_IFSOCK) - S_IFIFO -#else - S_IFSOCK -#endif - ))) - { - int oldUmask = umask (0); - -#ifdef UNIX_DIR -#ifdef HAS_STICKY_DIR_BIT - mode = 01777; -#else - mode = 0777; -#endif - if (trans_mkdir(UNIX_DIR, mode) == -1) { - PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n", - UNIX_DIR, errno, 0); - (void) umask (oldUmask); - return TRANS_RESET_FAILURE; - } -#endif - - close (ciptr->fd); - unlink (unsock->sun_path); - - if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) - { - TRANS(FreeConnInfo) (ciptr); - (void) umask (oldUmask); - return TRANS_RESET_FAILURE; - } - - if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0) - { - close (ciptr->fd); - TRANS(FreeConnInfo) (ciptr); - return TRANS_RESET_FAILURE; - } - - if (listen (ciptr->fd, BACKLOG) < 0) - { - close (ciptr->fd); - TRANS(FreeConnInfo) (ciptr); - (void) umask (oldUmask); - return TRANS_RESET_FAILURE; - } - - umask (oldUmask); - - status = TRANS_RESET_NEW_FD; - } - - return status; -} - -#endif /* UNIXCONN */ - - -#ifdef TCPCONN - -static XtransConnInfo -TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status) - -{ - XtransConnInfo newciptr; - struct sockaddr_in sockname; - SOCKLEN_T namelen = sizeof(sockname); - - PRMSG (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd, 0); - - if ((newciptr = (XtransConnInfo) xcalloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) - { - PRMSG (1, "SocketINETAccept: malloc failed\n", 0, 0, 0); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - if ((newciptr->fd = accept (ciptr->fd, - (struct sockaddr *) &sockname, (void *)&namelen)) < 0) - { -#ifdef WIN32 - errno = WSAGetLastError(); -#endif - PRMSG (1, "SocketINETAccept: accept() failed\n", 0, 0, 0); - xfree (newciptr); - *status = TRANS_ACCEPT_FAILED; - return NULL; - } - -#ifdef TCP_NODELAY - { - /* - * turn off TCP coalescence for INET sockets - */ - - int tmp = 1; - setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY, - (char *) &tmp, sizeof (int)); - } -#endif - - /* - * Get this address again because the transport may give a more - * specific address now that a connection is established. - */ - - if (TRANS(SocketINETGetAddr) (newciptr) < 0) - { - PRMSG (1, - "SocketINETAccept: ...SocketINETGetAddr() failed:\n", - 0, 0, 0); - close (newciptr->fd); - xfree (newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0) - { - PRMSG (1, - "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n", - 0, 0, 0); - close (newciptr->fd); - if (newciptr->addr) xfree (newciptr->addr); - xfree (newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - *status = 0; - - return newciptr; -} - -#endif /* TCPCONN */ - - -#ifdef UNIXCONN -static XtransConnInfo -TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) - -{ - XtransConnInfo newciptr; - struct sockaddr_un sockname; - SOCKLEN_T namelen = sizeof sockname; - - PRMSG (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd, 0); - - if ((newciptr = (XtransConnInfo) xcalloc ( - 1, sizeof(struct _XtransConnInfo))) == NULL) - { - PRMSG (1, "SocketUNIXAccept: malloc() failed\n", 0, 0, 0); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - if ((newciptr->fd = accept (ciptr->fd, - (struct sockaddr *) &sockname, (void *)&namelen)) < 0) - { - PRMSG (1, "SocketUNIXAccept: accept() failed\n", 0, 0, 0); - xfree (newciptr); - *status = TRANS_ACCEPT_FAILED; - return NULL; - } - - ciptr->addrlen = namelen; - /* - * Get the socket name and the peer name from the listener socket, - * since this is unix domain. - */ - - if ((newciptr->addr = (char *) xalloc (ciptr->addrlen)) == NULL) - { - PRMSG (1, - "SocketUNIXAccept: Can't allocate space for the addr\n", - 0, 0, 0); - close (newciptr->fd); - xfree (newciptr); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - /* - * if the socket is abstract, we already modified the address to have a - * @ instead of the initial NUL, so no need to do that again here. - */ - - newciptr->addrlen = ciptr->addrlen; - memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); - - if ((newciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL) - { - PRMSG (1, - "SocketUNIXAccept: Can't allocate space for the addr\n", - 0, 0, 0); - close (newciptr->fd); - if (newciptr->addr) xfree (newciptr->addr); - xfree (newciptr); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - newciptr->peeraddrlen = ciptr->addrlen; - memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen); - - newciptr->family = AF_UNIX; - - *status = 0; - - return newciptr; -} - -#endif /* UNIXCONN */ - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -#ifdef TCPCONN - -#if defined(IPv6) && defined(AF_INET6) -struct addrlist { - struct addrinfo * addr; - struct addrinfo * firstaddr; - char port[PORTBUFSIZE]; - char host[MAXHOSTNAMELEN]; -}; -static struct addrlist *addrlist = NULL; -#endif - - -static int -TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) - -{ - struct sockaddr * socketaddr = NULL; - int socketaddrlen = 0; - int res; -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo hints; - char ntopbuf[INET6_ADDRSTRLEN]; - int resetonce = 0; -#endif - struct sockaddr_in sockname; -#ifdef XTHREADS_NEEDS_BYNAMEPARAMS - _Xgethostbynameparams hparams; - _Xgetservbynameparams sparams; -#endif - struct hostent *hostp; - struct servent *servp; - unsigned long tmpaddr; -#ifdef X11_t - char portbuf[PORTBUFSIZE]; -#endif - - long tmpport; - char hostnamebuf[256]; /* tmp space */ - - PRMSG (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port); - - if (!host) - { - hostnamebuf[0] = '\0'; - (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); - host = hostnamebuf; - } - -#ifdef X11_t - /* - * X has a well known port, that is transport dependent. It is easier - * to handle it here, than try and come up with a transport independent - * representation that can be passed in and resolved the usual way. - * - * The port that is passed here is really a string containing the idisplay - * from ConnectDisplay(). - */ - - if (is_numeric (port)) - { - tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf (portbuf, "%lu", tmpport); - port = portbuf; - } -#endif - -#if defined(IPv6) && defined(AF_INET6) - { - if (addrlist != NULL) { - if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) { - if (addrlist->firstaddr) - freeaddrinfo(addrlist->firstaddr); - addrlist->firstaddr = NULL; - } - } else { - addrlist = malloc(sizeof(struct addrlist)); - addrlist->firstaddr = NULL; - } - - if (addrlist->firstaddr == NULL) { - strncpy(addrlist->port, port, sizeof(addrlist->port)); - addrlist->port[sizeof(addrlist->port) - 1] = '\0'; - strncpy(addrlist->host, host, sizeof(addrlist->host)); - addrlist->host[sizeof(addrlist->host) - 1] = '\0'; - - bzero(&hints,sizeof(hints)); - hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname; - - res = getaddrinfo(host,port,&hints,&addrlist->firstaddr); - if (res != 0) { - PRMSG (1, "SocketINETConnect() can't get address " - "for %s:%s: %s\n", host, port, gai_strerror(res)); - ESET(EINVAL); - return TRANS_CONNECT_FAILED; - } - for (res = 0, addrlist->addr = addrlist->firstaddr; - addrlist->addr ; res++) { - addrlist->addr = addrlist->addr->ai_next; - } - PRMSG(4,"Got New Address list with %d addresses\n", res, 0, 0); - res = 0; - addrlist->addr = NULL; - } - - while (socketaddr == NULL) { - if (addrlist->addr == NULL) { - if (resetonce) { - /* Already checked entire list - no usable addresses */ - PRMSG (1, "SocketINETConnect() no usable address " - "for %s:%s\n", host, port, 0); - return TRANS_CONNECT_FAILED; - } else { - /* Go back to beginning of list */ - resetonce = 1; - addrlist->addr = addrlist->firstaddr; - } - } - - socketaddr = addrlist->addr->ai_addr; - socketaddrlen = addrlist->addr->ai_addrlen; - - if (addrlist->addr->ai_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr; - - PRMSG (4,"SocketINETConnect() sockname.sin_addr = %s\n", - inet_ntop(addrlist->addr->ai_family,&sin->sin_addr, - ntopbuf,sizeof(ntopbuf)), 0, 0); - - PRMSG (4,"SocketINETConnect() sockname.sin_port = %d\n", - ntohs(sin->sin_port), 0, 0); - - if (Sockettrans2devtab[ciptr->index].family == AF_INET6) { - if (strcmp(Sockettrans2devtab[ciptr->index].transname, - "tcp") == 0) { - XtransConnInfo newciptr; - - /* - * Our socket is an IPv6 socket, but the address is - * IPv4. Close it and get an IPv4 socket. This is - * needed for IPv4 connections to work on platforms - * that don't allow IPv4 over IPv6 sockets. - */ - TRANS(SocketINETClose)(ciptr); - newciptr = TRANS(SocketOpenCOTSClientBase)( - "tcp", "tcp", host, port, ciptr->index); - if (newciptr) - ciptr->fd = newciptr->fd; - if (!newciptr || - Sockettrans2devtab[newciptr->index].family != - AF_INET) { - socketaddr = NULL; - PRMSG (4,"SocketINETConnect() Cannot get IPv4 " - " socketfor IPv4 address\n", 0,0,0); - } - if (newciptr) - xfree(newciptr); - } else { - socketaddr = NULL; - PRMSG (4,"SocketINETConnect Skipping IPv4 address\n", - 0,0,0); - } - } - } else if (addrlist->addr->ai_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr; - - PRMSG (4,"SocketINETConnect() sockname.sin6_addr = %s\n", - inet_ntop(addrlist->addr->ai_family, - &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf)), - 0, 0); - PRMSG (4,"SocketINETConnect() sockname.sin6_port = %d\n", - ntohs(sin6->sin6_port), 0, 0); - - if (Sockettrans2devtab[ciptr->index].family == AF_INET) { - if (strcmp(Sockettrans2devtab[ciptr->index].transname, - "tcp") == 0) { - XtransConnInfo newciptr; - - /* - * Close the IPv4 socket and try to open an IPv6 socket. - */ - TRANS(SocketINETClose)(ciptr); - newciptr = TRANS(SocketOpenCOTSClientBase)( - "tcp", "tcp", host, port, -1); - if (newciptr) - ciptr->fd = newciptr->fd; - if (!newciptr || - Sockettrans2devtab[newciptr->index].family != - AF_INET6) { - socketaddr = NULL; - PRMSG (4,"SocketINETConnect() Cannot get IPv6 " - "socket for IPv6 address\n", 0,0,0); - } - if (newciptr) - xfree(newciptr); - } - else - { - socketaddr = NULL; - PRMSG (4,"SocketINETConnect() Skipping IPv6 address\n", - 0,0,0); - } - } - } else { - socketaddr = NULL; /* Unsupported address type */ - } - if (socketaddr == NULL) { - addrlist->addr = addrlist->addr->ai_next; - } - } - } -#else - { - /* - * Build the socket name. - */ - -#ifdef BSD44SOCKETS - sockname.sin_len = sizeof (struct sockaddr_in); -#endif - sockname.sin_family = AF_INET; - - /* - * fill in sin_addr - */ - -#ifndef INADDR_NONE -#define INADDR_NONE ((in_addr_t) 0xffffffff) -#endif - - /* check for ww.xx.yy.zz host string */ - - if (isascii (host[0]) && isdigit (host[0])) { - tmpaddr = inet_addr (host); /* returns network byte order */ - } else { - tmpaddr = INADDR_NONE; - } - - PRMSG (4,"SocketINETConnect() inet_addr(%s) = %x\n", host, tmpaddr, 0); - - if (tmpaddr == INADDR_NONE) { - if ((hostp = _XGethostbyname(host,hparams)) == NULL) { - PRMSG (1,"SocketINETConnect: Can't get address for %s\n", - host, 0, 0); - ESET(EINVAL); - return TRANS_CONNECT_FAILED; - } - if (hostp->h_addrtype != AF_INET) { /* is IP host? */ - PRMSG (1,"SocketINETConnect: not INET host%s\n", host, 0, 0); - ESET(EPROTOTYPE); - return TRANS_CONNECT_FAILED; - } - - memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr, - sizeof (sockname.sin_addr)); - - } else { - sockname.sin_addr.s_addr = tmpaddr; - } - - /* - * fill in sin_port - */ - - /* Check for number in the port string */ - - if (!is_numeric (port)) { - if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) { - PRMSG (1,"SocketINETConnect: can't get service for %s\n", - port, 0, 0); - return TRANS_CONNECT_FAILED; - } - sockname.sin_port = htons (servp->s_port); - } else { - tmpport = strtol (port, (char**)NULL, 10); - if (tmpport < 1024 || tmpport > USHRT_MAX) - return TRANS_CONNECT_FAILED; - sockname.sin_port = htons (((unsigned short) tmpport)); - } - - PRMSG (4,"SocketINETConnect: sockname.sin_port = %d\n", - ntohs(sockname.sin_port), 0, 0); - socketaddr = (struct sockaddr *) &sockname; - socketaddrlen = sizeof(sockname); - } -#endif - - /* - * Turn on socket keepalive so the client process will eventually - * be notified with a SIGPIPE signal if the display server fails - * to respond to a periodic transmission of messages - * on the connected socket. - * This is useful to avoid hung application processes when the - * processes are not spawned from the xdm session and - * the display server terminates abnormally. - * (Someone turned off the power switch.) - */ - - { - int tmp = 1; - setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE, - (char *) &tmp, sizeof (int)); - } - - /* - * Do the connect() - */ - - if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0) - { -#ifdef WIN32 - int olderrno = WSAGetLastError(); -#else - int olderrno = errno; -#endif - - /* - * If the error was ECONNREFUSED, the server may be overloaded - * and we should try again. - * - * If the error was EWOULDBLOCK or EINPROGRESS then the socket - * was non-blocking and we should poll using select - * - * If the error was EINTR, the connect was interrupted and we - * should try again. - * - * If multiple addresses are found for a host then we should - * try to connect again with a different address for a larger - * number of errors that made us quit before, since those - * could be caused by trying to use an IPv6 address to contact - * a machine with an IPv4-only server or other reasons that - * only affect one of a set of addresses. - */ - - if (olderrno == ECONNREFUSED || olderrno == EINTR -#if defined(IPv6) && defined(AF_INET6) - || (((addrlist->addr->ai_next != NULL) || - (addrlist->addr != addrlist->firstaddr)) && - (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT || - olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT -#if defined(EHOSTDOWN) - || olderrno == EHOSTDOWN -#endif - )) -#endif - ) - res = TRANS_TRY_CONNECT_AGAIN; - else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) - res = TRANS_IN_PROGRESS; - else - { - PRMSG (2,"SocketINETConnect: Can't connect: errno = %d\n", - olderrno,0, 0); - - res = TRANS_CONNECT_FAILED; - } - } else { - res = 0; - - - /* - * Sync up the address fields of ciptr. - */ - - if (TRANS(SocketINETGetAddr) (ciptr) < 0) - { - PRMSG (1, - "SocketINETConnect: ...SocketINETGetAddr() failed:\n", - 0, 0, 0); - res = TRANS_CONNECT_FAILED; - } - - else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0) - { - PRMSG (1, - "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n", - 0, 0, 0); - res = TRANS_CONNECT_FAILED; - } - } - -#if defined(IPv6) && defined(AF_INET6) - if (res != 0) { - addrlist->addr = addrlist->addr->ai_next; - } -#endif - - return res; -} - -#endif /* TCPCONN */ - - - -#ifdef UNIXCONN - -/* - * Make sure 'host' is really local. - */ - -static int -UnixHostReallyLocal (char *host) - -{ - char hostnamebuf[256]; - - TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); - - if (strcmp (hostnamebuf, host) == 0) - { - return (1); - } else { -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *localhostaddr; - struct addrinfo *otherhostaddr; - struct addrinfo *i, *j; - int equiv = 0; - - if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0) - return 0; - if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) { - freeaddrinfo(localhostaddr); - return 0; - } - - for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) { - for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) { - if (i->ai_family == j->ai_family) { - if (i->ai_family == AF_INET) { - struct sockaddr_in *sinA - = (struct sockaddr_in *) i->ai_addr; - struct sockaddr_in *sinB - = (struct sockaddr_in *) j->ai_addr; - struct in_addr *A = &sinA->sin_addr; - struct in_addr *B = &sinB->sin_addr; - - if (memcmp(A,B,sizeof(struct in_addr)) == 0) { - equiv = 1; - } - } else if (i->ai_family == AF_INET6) { - struct sockaddr_in6 *sinA - = (struct sockaddr_in6 *) i->ai_addr; - struct sockaddr_in6 *sinB - = (struct sockaddr_in6 *) j->ai_addr; - struct in6_addr *A = &sinA->sin6_addr; - struct in6_addr *B = &sinB->sin6_addr; - - if (memcmp(A,B,sizeof(struct in6_addr)) == 0) { - equiv = 1; - } - } - } - } - } - - freeaddrinfo(localhostaddr); - freeaddrinfo(otherhostaddr); - return equiv; -#else - /* - * A host may have more than one network address. If any of the - * network addresses of 'host' (specified to the connect call) - * match any of the network addresses of 'hostname' (determined - * by TRANS(GetHostname)), then the two hostnames are equivalent, - * and we know that 'host' is really a local host. - */ - char specified_local_addr_list[10][4]; - int scount, equiv, i, j; -#ifdef XTHREADS_NEEDS_BYNAMEPARAMS - _Xgethostbynameparams hparams; -#endif - struct hostent *hostp; - - if ((hostp = _XGethostbyname (host,hparams)) == NULL) - return (0); - - scount = 0; - while (hostp->h_addr_list[scount] && scount <= 8) - { - /* - * The 2nd call to gethostname() overrides the data - * from the 1st call, so we must save the address list. - */ - - specified_local_addr_list[scount][0] = - hostp->h_addr_list[scount][0]; - specified_local_addr_list[scount][1] = - hostp->h_addr_list[scount][1]; - specified_local_addr_list[scount][2] = - hostp->h_addr_list[scount][2]; - specified_local_addr_list[scount][3] = - hostp->h_addr_list[scount][3]; - scount++; - } - if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL) - return (0); - - equiv = 0; - i = 0; - - while (i < scount && !equiv) - { - j = 0; - - while (hostp->h_addr_list[j]) - { - if ((specified_local_addr_list[i][0] == - hostp->h_addr_list[j][0]) && - (specified_local_addr_list[i][1] == - hostp->h_addr_list[j][1]) && - (specified_local_addr_list[i][2] == - hostp->h_addr_list[j][2]) && - (specified_local_addr_list[i][3] == - hostp->h_addr_list[j][3])) - { - /* They're equal, so we're done */ - - equiv = 1; - break; - } - - j++; - } - - i++; - } - return (equiv); -#endif - } -} - -static int -TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) - -{ - struct sockaddr_un sockname; - SOCKLEN_T namelen; - - - int abstract = 0; -#ifdef HAVE_ABSTRACT_SOCKETS - abstract = ciptr->transptr->flags & TRANS_ABSTRACT; -#endif - - PRMSG (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port); - - /* - * Make sure 'host' is really local. If not, we return failure. - * The reason we make this check is because a process may advertise - * a "local" network ID for which it can accept connections, but if - * a process on a remote machine tries to connect to this network ID, - * we know for sure it will fail. - */ - - if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host)) - { - PRMSG (1, - "SocketUNIXConnect: Cannot connect to non-local host %s\n", - host, 0, 0); - return TRANS_CONNECT_FAILED; - } - - - /* - * Check the port. - */ - - if (!port || !*port) - { - PRMSG (1,"SocketUNIXConnect: Missing port specification\n", - 0, 0, 0); - return TRANS_CONNECT_FAILED; - } - - /* - * Build the socket name. - */ - - sockname.sun_family = AF_UNIX; - - if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { - PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); - return TRANS_CONNECT_FAILED; - } - -#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) - sockname.sun_len = strlen (sockname.sun_path); -#endif - -#if defined(BSD44SOCKETS) || defined(SUN_LEN) - namelen = SUN_LEN (&sockname); -#else - namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); -#endif - - - - /* - * Adjust the socket path if using abstract sockets. - * Done here because otherwise all the strlen() calls above would fail. - */ - - if (abstract) { - sockname.sun_path[0] = '\0'; - } - - /* - * Do the connect() - */ - - if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0) - { - int olderrno = errno; - int connected = 0; - - if (!connected) - { - errno = olderrno; - - /* - * If the error was ENOENT, the server may be starting up; we used - * to suggest to try again in this case with - * TRANS_TRY_CONNECT_AGAIN, but this introduced problems for - * processes still referencing stale sockets in their environment. - * Hence, we now return a hard error, TRANS_CONNECT_FAILED, and it - * is suggested that higher level stacks handle retries on their - * level when they face a slow starting server. - * - * If the error was EWOULDBLOCK or EINPROGRESS then the socket - * was non-blocking and we should poll using select - * - * If the error was EINTR, the connect was interrupted and we - * should try again. - */ - - if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) - return TRANS_IN_PROGRESS; - else if (olderrno == EINTR) - return TRANS_TRY_CONNECT_AGAIN; - else if (olderrno == ENOENT || olderrno == ECONNREFUSED) { - /* If opening as abstract socket failed, try again normally */ - if (abstract) { - ciptr->transptr->flags &= ~(TRANS_ABSTRACT); - return TRANS_TRY_CONNECT_AGAIN; - } else { - return TRANS_CONNECT_FAILED; - } - } else { - PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n", - EGET(),0, 0); - - return TRANS_CONNECT_FAILED; - } - } - } - - /* - * Get the socket name and the peer name from the connect socket, - * since this is unix domain. - */ - - if ((ciptr->addr = (char *) xalloc(namelen)) == NULL || - (ciptr->peeraddr = (char *) xalloc(namelen)) == NULL) - { - PRMSG (1, - "SocketUNIXCreateListener: Can't allocate space for the addr\n", - 0, 0, 0); - return TRANS_CONNECT_FAILED; - } - - if (abstract) - sockname.sun_path[0] = '@'; - - ciptr->family = AF_UNIX; - ciptr->addrlen = namelen; - ciptr->peeraddrlen = namelen; - memcpy (ciptr->addr, &sockname, ciptr->addrlen); - memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); - - return 0; -} - -#endif /* UNIXCONN */ - -#endif /* TRANS_CLIENT */ - - -static int -TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) - -{ - PRMSG (2,"SocketBytesReadable(%p,%d,%p)\n", - ciptr, ciptr->fd, pend); -#ifdef WIN32 - { - int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend); - if (ret == SOCKET_ERROR) errno = WSAGetLastError(); - return ret; - } -#else -#if defined(__i386__) && defined(SYSV) && !defined(SCO325) - return ioctl (ciptr->fd, I_NREAD, (char *) pend); -#else - return ioctl (ciptr->fd, FIONREAD, (char *) pend); -#endif /* __i386__ && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */ -#endif /* WIN32 */ -} - - -static int -TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size); - -#if defined(WIN32) - { - int ret = recv ((SOCKET)ciptr->fd, buf, size, 0); -#ifdef WIN32 - if (ret == SOCKET_ERROR) errno = WSAGetLastError(); -#endif - return ret; - } -#else - return read (ciptr->fd, buf, size); -#endif /* WIN32 */ -} - - -static int -TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); - -#if defined(WIN32) - { - int ret = send ((SOCKET)ciptr->fd, buf, size, 0); -#ifdef WIN32 - if (ret == SOCKET_ERROR) errno = WSAGetLastError(); -#endif - return ret; - } -#else - return write (ciptr->fd, buf, size); -#endif /* WIN32 */ -} - - -static int -TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); - - return READV (ciptr, buf, size); -} - - -static int -TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); - - return WRITEV (ciptr, buf, size); -} - - -static int -TRANS(SocketDisconnect) (XtransConnInfo ciptr) - -{ - PRMSG (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd, 0); - -#ifdef WIN32 - { - int ret = shutdown (ciptr->fd, 2); - if (ret == SOCKET_ERROR) errno = WSAGetLastError(); - return ret; - } -#else - return shutdown (ciptr->fd, 2); /* disallow further sends and receives */ -#endif -} - - -#ifdef TCPCONN -static int -TRANS(SocketINETClose) (XtransConnInfo ciptr) - -{ - PRMSG (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd, 0); - -#ifdef WIN32 - { - int ret = close (ciptr->fd); - if (ret == SOCKET_ERROR) errno = WSAGetLastError(); - return ret; - } -#else - return close (ciptr->fd); -#endif -} - -#endif /* TCPCONN */ - - -#ifdef UNIXCONN -static int -TRANS(SocketUNIXClose) (XtransConnInfo ciptr) -{ - /* - * If this is the server side, then once the socket is closed, - * it must be unlinked to completely close it - */ - - struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr; - int ret; - - PRMSG (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd, 0); - - ret = close(ciptr->fd); - - if (ciptr->flags - && sockname - && sockname->sun_family == AF_UNIX - && sockname->sun_path[0]) - { - if (!(ciptr->flags & TRANS_NOUNLINK - || ciptr->transptr->flags & TRANS_ABSTRACT)) - unlink (sockname->sun_path); - } - - return ret; -} - -static int -TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) - -{ - /* - * Don't unlink path. - */ - - int ret; - - PRMSG (2,"SocketUNIXCloseForCloning(%p,%d)\n", - ciptr, ciptr->fd, 0); - - ret = close(ciptr->fd); - - return ret; -} - -#endif /* UNIXCONN */ - - -#ifdef TCPCONN -# ifdef TRANS_SERVER -static char* tcp_nolisten[] = { - "inet", -#if defined(IPv6) && defined(AF_INET6) - "inet6", -#endif - NULL -}; -# endif - -Xtransport TRANS(SocketTCPFuncs) = { - /* Socket Interface */ - "tcp", - TRANS_ALIAS, -#ifdef TRANS_CLIENT - TRANS(SocketOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - tcp_nolisten, - TRANS(SocketOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SocketOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SocketReopenCOTSServer), - TRANS(SocketReopenCLTSServer), -#endif - TRANS(SocketSetOption), -#ifdef TRANS_SERVER - TRANS(SocketINETCreateListener), - NULL, /* ResetListener */ - TRANS(SocketINETAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketINETConnect), -#endif /* TRANS_CLIENT */ - TRANS(SocketBytesReadable), - TRANS(SocketRead), - TRANS(SocketWrite), - TRANS(SocketReadv), - TRANS(SocketWritev), - TRANS(SocketDisconnect), - TRANS(SocketINETClose), - TRANS(SocketINETClose), - }; - -Xtransport TRANS(SocketINETFuncs) = { - /* Socket Interface */ - "inet", - 0, -#ifdef TRANS_CLIENT - TRANS(SocketOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(SocketOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SocketOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SocketReopenCOTSServer), - TRANS(SocketReopenCLTSServer), -#endif - TRANS(SocketSetOption), -#ifdef TRANS_SERVER - TRANS(SocketINETCreateListener), - NULL, /* ResetListener */ - TRANS(SocketINETAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketINETConnect), -#endif /* TRANS_CLIENT */ - TRANS(SocketBytesReadable), - TRANS(SocketRead), - TRANS(SocketWrite), - TRANS(SocketReadv), - TRANS(SocketWritev), - TRANS(SocketDisconnect), - TRANS(SocketINETClose), - TRANS(SocketINETClose), - }; - -#if defined(IPv6) && defined(AF_INET6) -Xtransport TRANS(SocketINET6Funcs) = { - /* Socket Interface */ - "inet6", - 0, -#ifdef TRANS_CLIENT - TRANS(SocketOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(SocketOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SocketOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SocketReopenCOTSServer), - TRANS(SocketReopenCLTSServer), -#endif - TRANS(SocketSetOption), -#ifdef TRANS_SERVER - TRANS(SocketINETCreateListener), - NULL, /* ResetListener */ - TRANS(SocketINETAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketINETConnect), -#endif /* TRANS_CLIENT */ - TRANS(SocketBytesReadable), - TRANS(SocketRead), - TRANS(SocketWrite), - TRANS(SocketReadv), - TRANS(SocketWritev), - TRANS(SocketDisconnect), - TRANS(SocketINETClose), - TRANS(SocketINETClose), - }; -#endif /* IPv6 */ -#endif /* TCPCONN */ - -#ifdef UNIXCONN -#if !defined(LOCALCONN) -Xtransport TRANS(SocketLocalFuncs) = { - /* Socket Interface */ - "local", -#ifdef HAVE_ABSTRACT_SOCKETS - TRANS_ABSTRACT, -#else - 0, -#endif -#ifdef TRANS_CLIENT - TRANS(SocketOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(SocketOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SocketOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SocketReopenCOTSServer), - TRANS(SocketReopenCLTSServer), -#endif - TRANS(SocketSetOption), -#ifdef TRANS_SERVER - TRANS(SocketUNIXCreateListener), - TRANS(SocketUNIXResetListener), - TRANS(SocketUNIXAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketUNIXConnect), -#endif /* TRANS_CLIENT */ - TRANS(SocketBytesReadable), - TRANS(SocketRead), - TRANS(SocketWrite), - TRANS(SocketReadv), - TRANS(SocketWritev), - TRANS(SocketDisconnect), - TRANS(SocketUNIXClose), - TRANS(SocketUNIXCloseForCloning), - }; -#endif /* !LOCALCONN */ -# ifdef TRANS_SERVER -# if !defined(LOCALCONN) -static char* unix_nolisten[] = { "local" , NULL }; -# endif -# endif - -Xtransport TRANS(SocketUNIXFuncs) = { - /* Socket Interface */ - "unix", -#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) - TRANS_ALIAS, -#else - 0, -#endif -#ifdef TRANS_CLIENT - TRANS(SocketOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER -#if !defined(LOCALCONN) - unix_nolisten, -#else - NULL, -#endif - TRANS(SocketOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(SocketOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(SocketReopenCOTSServer), - TRANS(SocketReopenCLTSServer), -#endif - TRANS(SocketSetOption), -#ifdef TRANS_SERVER - TRANS(SocketUNIXCreateListener), - TRANS(SocketUNIXResetListener), - TRANS(SocketUNIXAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(SocketUNIXConnect), -#endif /* TRANS_CLIENT */ - TRANS(SocketBytesReadable), - TRANS(SocketRead), - TRANS(SocketWrite), - TRANS(SocketReadv), - TRANS(SocketWritev), - TRANS(SocketDisconnect), - TRANS(SocketUNIXClose), - TRANS(SocketUNIXCloseForCloning), - }; - -#endif /* UNIXCONN */ diff --git a/shell/linux-deps/include/X11/Xtrans/Xtranstli.c b/shell/linux-deps/include/X11/Xtrans/Xtranstli.c deleted file mode 100644 index a9dfc21da..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtranstli.c +++ /dev/null @@ -1,1418 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - -#include -#include - - -/* - * This is the TLI implementation of the X Transport service layer - */ - -typedef struct _TLItrans2dev { - char *transname; - char *protofamily; - char *devcotsname; - char *devcltsname; - int family; -} TLItrans2dev; - -static TLItrans2dev TLItrans2devtab[] = { - {"inet","inet","/dev/tcp","/dev/udp",AF_INET}, - {"tcp","inet","/dev/tcp","/dev/udp",AF_INET}, - {"tli","loopback","/dev/ticots","/dev/ticlts",AF_UNIX}, -}; - -#define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev)) - -/* - * The local TLI connection, is a form of a local connection, so use a - * sockaddr_un for the address so that it will be treated just like the other - * local transports such as UNIX domain sockets, pts, and named. - */ - -#if defined(X11_t) -#define TLINODENAME "TLI:xserver" -#endif - -#if defined(XIM_t) -#define TLINODENAME "TLI:xim" -#endif - -#if defined(FS_t) || defined(FONT_t) -#define TLINODENAME "TLI:fontserver" -#endif - -#if defined(ICE_t) -#define TLINODENAME "TLI:ICE" -#endif - -#if defined(TEST_t) -#define TLINODENAME "TLI:test" -#endif - -#ifndef PORTBUFSIZE -#ifdef TRANS_SERVER -#define PORTBUFSIZE 64 -#else -#ifdef TRANS_CLIENT -#define PORTBUFSIZE 64 -#endif -#endif -#endif - - -/* - * These are some utility function used by the real interface function below. - */ - -static int -TRANS(TLISelectFamily)(char *family) - -{ - int i; - - PRMSG(3,"TLISelectFamily(%s)\n", family, 0,0 ); - - for(i=0;ifd,&netbuf,LOCALNAME) < 0 ) - { - PRMSG(1,"TLIGetAddr: t_getname(LOCALNAME) failed: %d\n", - errno, 0,0 ); - return -1; - } - - PRMSG(4,"TLIGetAddr: got family %d len %d\n", - ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 ); - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if( ciptr->addr ) - xfree(ciptr->addr); - - if( (ciptr->addr=(char *)xalloc(netbuf.len)) == NULL ) - { - PRMSG(1, "TLIGetAddr: Can't allocate space for the addr\n", - 0,0,0); - return -1; - } - - ciptr->family=((struct sockaddr *) &sockname)->sa_family; - ciptr->addrlen=netbuf.len; - memcpy(ciptr->addr,&sockname,ciptr->addrlen); - - return 0; -} - - -/* - * This function gets the remote address of the socket and stores it in the - * XtransConnInfo structure for the connection. - */ - -static int -TRANS(TLIGetPeerAddr)(XtransConnInfo ciptr) - -{ - Xtransaddr sockname; - struct netbuf netbuf; - - PRMSG(3,"TLIGetPeerAddr(%x)\n", ciptr, 0,0 ); - - netbuf.buf=(char *)&sockname; - netbuf.len=sizeof(sockname); - netbuf.maxlen=sizeof(sockname); - - if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 ) - { - PRMSG(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n", - errno, 0,0 ); - return -1; - } - - PRMSG(4,"TLIGetPeerAddr: got family %d len %d\n", - ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 ); - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if( ciptr->peeraddr ) - xfree(ciptr->peeraddr); - - if( (ciptr->peeraddr=(char *)xalloc(netbuf.len)) == NULL ) - { - PRMSG(1, - "TLIGetPeerAddr: Can't allocate space for the addr\n", - 0,0,0); - return -1; - } - - ciptr->peeraddrlen=netbuf.len; - memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen); - - return 0; -} - - -/* - * This function will establish a local name for the transport. This function - * do extra work for the local tli connection. It must create a sockaddr_un - * format address so that it will look like an AF_UNIX connection to the - * higher layer. - * - * This function will only be called by the OPENC?TSClient() functions since - * the local address is set up in the CreateListner() for the server ends. - */ - -static int -TRANS(TLITLIBindLocal)(int fd, int family, char *port) - -{ - struct sockaddr_un *sunaddr=NULL; - struct t_bind *req=NULL; - - PRMSG(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port); - - if( family == AF_UNIX ) - { - if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL ) - { - PRMSG(1, - "TLITLIBindLocal() failed to allocate a t_bind\n", - 0,0,0 ); - return -1; - } - - if( (sunaddr=(struct sockaddr_un *) - malloc(sizeof(struct sockaddr_un))) == NULL ) - { - PRMSG(1, - "TLITLIBindLocal: failed to allocate a sockaddr_un\n", - 0,0,0 ); - t_free((char *)req,T_BIND); - return -1; - } - - sunaddr->sun_family=AF_UNIX; - -#ifdef nuke - if( *port == '/' ) { /* A full pathname */ - (void) strcpy(sunaddr->sun_path, port); - } else { - (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port ); - } -#endif /*NUKE*/ - - (void) sprintf(sunaddr->sun_path,"%s%d", - TLINODENAME, getpid()^time(NULL) ); - - PRMSG(4, "TLITLIBindLocal: binding to %s\n", - sunaddr->sun_path, 0,0); - - req->addr.buf=(char *)sunaddr; - req->addr.len=sizeof(*sunaddr); - req->addr.maxlen=sizeof(*sunaddr); - } - - if( t_bind(fd, req, NULL) < 0 ) - { - PRMSG(1, - "TLIBindLocal: Unable to bind TLI device to %s\n", - port, 0,0 ); - if (sunaddr) - free((char *) sunaddr); - if (req) - t_free((char *)req,T_BIND); - return -1; - } - return 0; -} - -static XtransConnInfo -TRANS(TLIOpen)(char *device) - -{ - XtransConnInfo ciptr; - - PRMSG(3,"TLIOpen(%s)\n", device, 0,0 ); - - if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) - { - PRMSG(1, "TLIOpen: calloc failed\n", 0,0,0 ); - return NULL; - } - - if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 ) - { - PRMSG(1, "TLIOpen: t_open failed for %s\n", device, 0,0 ); - free(ciptr); - return NULL; - } - - return ciptr; -} - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(TLIReopen)(char *device, int fd, char *port) - -{ - XtransConnInfo ciptr; - - PRMSG(3,"TLIReopen(%s,%d, %s)\n", device, fd, port ); - - if (t_sync (fd) < 0) - { - PRMSG(1, "TLIReopen: t_sync failed\n", 0,0,0 ); - return NULL; - } - - if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL ) - { - PRMSG(1, "TLIReopen: calloc failed\n", 0,0,0 ); - return NULL; - } - - ciptr->fd = fd; - - return ciptr; -} - -#endif /* TRANS_REOPEN */ - - -static int -TRANS(TLIAddrToNetbuf)(int tlifamily, char *host, char *port, - struct netbuf *netbufp) - -{ - struct netconfig *netconfigp; - struct nd_hostserv nd_hostserv; - struct nd_addrlist *nd_addrlistp = NULL; - void *handlep; - long lport; - - PRMSG(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port ); - - if( (handlep=setnetconfig()) == NULL ) - return -1; - - lport = strtol (port, (char**)NULL, 10); - if (lport < 1024 || lport > USHRT_MAX) - return -1; - - nd_hostserv.h_host = host; - if( port && *port ) { - nd_hostserv.h_serv = port; - } else { - nd_hostserv.h_serv = NULL; - } - - while( (netconfigp=getnetconfig(handlep)) != NULL ) - { - if( strcmp(netconfigp->nc_protofmly, - TLItrans2devtab[tlifamily].protofamily) != 0 ) - continue; - PRMSG(5,"TLIAddrToNetbuf: Trying to resolve %s.%s for %s\n", - host, port, TLItrans2devtab[tlifamily].protofamily ); - if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 ) - { - /* we have at least one address to use */ - - PRMSG(5, "TLIAddrToNetbuf: found address for %s.%s\n", host, port, 0 ); - PRMSG(5, "TLIAddrToNetbuf: %s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs), - 0,0 ); - - memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf, - nd_addrlistp->n_addrs->len); - netbufp->len=nd_addrlistp->n_addrs->len; - endnetconfig(handlep); - return 0; - } - } - endnetconfig(handlep); - - return -1; -} - -/* - * These functions are the interface supplied in the Xtransport structure - */ - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(TLIOpenCOTSClient)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1,"TLIOpenCOTSClient: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL ) - { - PRMSG(1,"TLIOpenCOTSClient: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 ) - { - PRMSG(1, - "TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n", - errno, 0,0 ); - t_close(ciptr->fd); - xfree(ciptr); - return NULL; - } - - if( TRANS(TLIGetAddr)(ciptr) < 0 ) - { - PRMSG(1, - "TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n", - errno, 0,0 ); - t_close(ciptr->fd); - xfree(ciptr); - return NULL; - } - - /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */ - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(TLIOpenCOTSServer)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1, - "TLIOpenCOTSServer: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL ) - { - PRMSG(1, - "TLIOpenCOTSServer: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - /* Set the family type */ - - ciptr->family = TLItrans2devtab[i].family; - - - /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */ - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -static XtransConnInfo -TRANS(TLIOpenCLTSClient)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1, - "TLIOpenCLTSClient: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL ) - { - PRMSG(1, - "TLIOpenCLTSClient: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 ) - { - PRMSG(1, - "TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n", - errno, 0,0 ); - t_close(ciptr->fd); - xfree(ciptr); - return NULL; - } - - if( TRANS(TLIGetAddr)(ciptr) < 0 ) - { - PRMSG(1, - "TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n", - errno, 0,0 ); - t_close(ciptr->fd); - xfree(ciptr); - return NULL; - } - - return ciptr; -} - -#endif /* TRANS_CLIENT */ - - -#ifdef TRANS_SERVER - -static XtransConnInfo -TRANS(TLIOpenCLTSServer)(Xtransport *thistrans, char *protocol, - char *host, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1, - "TLIOpenCLTSServer: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL ) - { - PRMSG(1, - "TLIOpenCLTSServer: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - return ciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_REOPEN - -static XtransConnInfo -TRANS(TLIReopenCOTSServer)(Xtransport *thistrans, int fd, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port, 0 ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1, - "TLIReopenCOTSServer: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIReopen)( - TLItrans2devtab[i].devcotsname, fd, port)) == NULL ) - { - PRMSG(1, - "TLIReopenCOTSServer: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */ - - ciptr->index = i; - - return ciptr; -} - - -static XtransConnInfo -TRANS(TLIReopenCLTSServer)(Xtransport *thistrans, int fd, char *port) - -{ - XtransConnInfo ciptr; - int i; - - PRMSG(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port, 0 ); - - if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 ) - { - PRMSG(1, - "TLIReopenCLTSServer: Unable to determine device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - if( (ciptr=TRANS(TLIReopen)( - TLItrans2devtab[i].devcltsname, fd, port)) == NULL ) - { - PRMSG(1, - "TLIReopenCLTSServer: Unable to open device for %s\n", - thistrans->TransName, 0,0 ); - return NULL; - } - - ciptr->index = i; - - return ciptr; -} - -#endif /* TRANS_REOPEN */ - - -static int -TRANS(TLISetOption)(XtransConnInfo ciptr, int option, int arg) - -{ - PRMSG(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg ); - - return -1; -} - - -#ifdef TRANS_SERVER - -static int -TRANS(TLICreateListener)(XtransConnInfo ciptr, struct t_bind *req) - -{ - struct t_bind *ret; - - PRMSG(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req ); - - if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL ) - { - PRMSG(1, "TLICreateListener: failed to allocate a t_bind\n", - 0,0,0 ); - t_free((char *)req,T_BIND); - return TRANS_CREATE_LISTENER_FAILED; - } - - if( t_bind(ciptr->fd, req, ret) < 0 ) - { - PRMSG(1, "TLICreateListener: t_bind failed\n", 0,0,0 ); - t_free((char *)req,T_BIND); - t_free((char *)ret,T_BIND); - return TRANS_CREATE_LISTENER_FAILED; - } - - if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 ) - { - PRMSG(1, "TLICreateListener: unable to bind to %x\n", - req, 0,0 ); - t_free((char *)req,T_BIND); - t_free((char *)ret,T_BIND); - return TRANS_ADDR_IN_USE; - } - - /* - * Everything looks good: fill in the XtransConnInfo structure. - */ - - if( (ciptr->addr=(char *)xalloc(ret->addr.len)) == NULL ) - { - PRMSG(1, - "TLICreateListener: Unable to allocate space for the address\n", - 0,0,0 ); - t_free((char *)req,T_BIND); - t_free((char *)ret, T_BIND); - return TRANS_CREATE_LISTENER_FAILED; - } - - ciptr->addrlen=ret->addr.len; - memcpy(ciptr->addr,ret->addr.buf,ret->addr.len); - - t_free((char *)req,T_BIND); - t_free((char *)ret, T_BIND); - - return 0; -} - - -static int -TRANS(TLIINETCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags) - -{ - char portbuf[PORTBUFSIZE]; - struct t_bind *req; - struct sockaddr_in *sinaddr; - long tmpport; - - PRMSG(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr, - ciptr->fd, port ? port : "NULL" ); - -#ifdef X11_t - /* - * X has a well known port, that is transport dependent. It is easier - * to handle it here, than try and come up with a transport independent - * representation that can be passed in and resolved the usual way. - * - * The port that is passed here is really a string containing the idisplay - * from ConnectDisplay(). - */ - - if (is_numeric (port)) - { - tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf(portbuf,"%u", tmpport); - port = portbuf; - } -#endif - - if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL ) - { - PRMSG(1, - "TLIINETCreateListener: failed to allocate a t_bind\n", - 0,0,0 ); - return TRANS_CREATE_LISTENER_FAILED; - } - - if( port && *port ) { - if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0) - { - PRMSG(1, - "TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n", - port, 0,0 ); - t_free((char *)req,T_BIND); - return TRANS_CREATE_LISTENER_FAILED; - } - } else { - sinaddr=(struct sockaddr_in *) req->addr.buf; - sinaddr->sin_family=AF_INET; - sinaddr->sin_port=htons(0); - sinaddr->sin_addr.s_addr=0; - } - - /* Set the qlen */ - - req->qlen=1; - - return TRANS(TLICreateListener)(ciptr, req); -} - - -static int -TRANS(TLITLICreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags) - -{ - struct t_bind *req; - struct sockaddr_un *sunaddr; - int ret_value; - - PRMSG(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd, - port ? port : "NULL"); - - if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL ) - { - PRMSG(1, - "TLITLICreateListener: failed to allocate a t_bind\n", - 0,0,0 ); - return TRANS_CREATE_LISTENER_FAILED; - } - - if( (sunaddr=(struct sockaddr_un *) - malloc(sizeof(struct sockaddr_un))) == NULL ) - { - PRMSG(1, - "TLITLICreateListener: failed to allocate a sockaddr_un\n", - 0,0,0 ); - t_free((char *)req,T_BIND); - return TRANS_CREATE_LISTENER_FAILED; - } - - sunaddr->sun_family=AF_UNIX; - if( port && *port ) { - if( *port == '/' ) { /* A full pathname */ - (void) strcpy(sunaddr->sun_path, port); - } else { - (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port ); - } - } else { - (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid()); - } - - req->addr.buf=(char *)sunaddr; - req->addr.len=sizeof(*sunaddr); - req->addr.maxlen=sizeof(*sunaddr); - - /* Set the qlen */ - - req->qlen=1; - - ret_value = TRANS(TLICreateListener)(ciptr, req); - - free((char *) sunaddr); - - return ret_value; -} - - -static XtransConnInfo -TRANS(TLIAccept)(XtransConnInfo ciptr, int *status) - -{ - struct t_call *call; - XtransConnInfo newciptr; - int i; - - PRMSG(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd, 0 ); - - if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL ) - { - PRMSG(1, "TLIAccept() failed to allocate a t_call\n", 0,0,0 ); - *status = TRANS_ACCEPT_BAD_MALLOC; - return NULL; - } - - if( t_listen(ciptr->fd,call) < 0 ) - { - extern char *t_errlist[]; - extern int t_errno; - PRMSG(1, "TLIAccept() t_listen() failed\n", 0,0,0 ); - PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 ); - t_free((char *)call,T_CALL); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - /* - * Now we need to set up the new endpoint for the incoming connection. - */ - - i=ciptr->index; /* Makes the next line more readable */ - - if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL ) - { - PRMSG(1, "TLIAccept() failed to open a new endpoint\n", 0,0,0 ); - t_free((char *)call,T_CALL); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 ) - { - PRMSG(1, - "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n", - errno, 0,0 ); - t_free((char *)call,T_CALL); - t_close(newciptr->fd); - xfree(newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - - if( t_accept(ciptr->fd,newciptr->fd,call) < 0 ) - { - extern char *t_errlist[]; - extern int t_errno; - PRMSG(1, "TLIAccept() t_accept() failed\n", 0,0,0 ); - PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 ); - if( t_errno == TLOOK ) - { - int evtype = t_look(ciptr->fd); - PRMSG(1, "TLIAccept() t_look() returned %d\n", evtype,0,0 ); - switch( evtype ) - { - case T_DISCONNECT: - if( t_rcvdis(ciptr->fd, NULL) < 0 ) - { - PRMSG(1, "TLIAccept() t_rcvdis() failed\n", 0,0,0 ); - PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 ); - } - break; - default: - break; - } - } - t_free((char *)call,T_CALL); - t_close(newciptr->fd); - free(newciptr); - *status = TRANS_ACCEPT_FAILED; - return NULL; - } - - t_free((char *)call,T_CALL); - - if( TRANS(TLIGetAddr)(newciptr) < 0 ) - { - PRMSG(1, - "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n", - errno, 0,0 ); - t_close(newciptr->fd); - xfree(newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - if( TRANS(TLIGetPeerAddr)(newciptr) < 0 ) - { - PRMSG(1, - "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n", - errno, 0,0 ); - t_close(newciptr->fd); - xfree(newciptr->addr); - xfree(newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - if( ioctl(newciptr->fd, I_POP,"timod") < 0 ) - { - PRMSG(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n", - errno,0,0 ); - t_close(newciptr->fd); - xfree(newciptr->addr); - xfree(newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 ) - { - PRMSG(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n", - errno,0,0 ); - t_close(newciptr->fd); - xfree(newciptr->addr); - xfree(newciptr); - *status = TRANS_ACCEPT_MISC_ERROR; - return NULL; - } - - *status = 0; - - return newciptr; -} - -#endif /* TRANS_SERVER */ - - -#ifdef TRANS_CLIENT - -static int -TRANS(TLIConnect)(XtransConnInfo ciptr, struct t_call *sndcall ) - -{ - PRMSG(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall); - - if( t_connect(ciptr->fd,sndcall,NULL) < 0 ) - { - extern char *t_errlist[]; - extern int t_errno; - PRMSG(1, "TLIConnect() t_connect() failed\n", 0,0,0 ); - PRMSG(1, "TLIConnect: %s\n", t_errlist[t_errno], 0,0 ); - t_free((char *)sndcall,T_CALL); - if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT) - { - t_rcvdis(ciptr->fd,NULL); - return TRANS_TRY_CONNECT_AGAIN; - } - else - return TRANS_CONNECT_FAILED; - } - - t_free((char *)sndcall,T_CALL); - - /* - * Sync up the address fields of ciptr. - */ - - if( TRANS(TLIGetAddr)(ciptr) < 0 ) - { - PRMSG(1, - "TLIConnect: ...TLIGetAddr() failed: %d\n", - errno, 0,0 ); - return TRANS_CONNECT_FAILED; - } - - if( TRANS(TLIGetPeerAddr)(ciptr) < 0 ) - { - PRMSG(1, - "TLIConnect: ...TLIGetPeerAddr() failed: %d\n", - errno, 0,0 ); - return TRANS_CONNECT_FAILED; - } - - if( ioctl(ciptr->fd, I_POP,"timod") < 0 ) - { - PRMSG(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n", - errno,0,0 ); - return TRANS_CONNECT_FAILED; - } - - if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 ) - { - PRMSG(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n", - errno,0,0 ); - return TRANS_CONNECT_FAILED; - } - - return 0; -} - - -static int -TRANS(TLIINETConnect)(XtransConnInfo ciptr, char *host, char *port) - -{ - char portbuf[PORTBUFSIZE]; - struct t_call *sndcall; - long tmpport; - - PRMSG(2, "TLIINETConnect(%s,%s)\n", host, port, 0); - -#ifdef X11_t - /* - * X has a well known port, that is transport dependant. It is easier - * to handle it here, than try and come up with a transport independent - * representation that can be passed in and resolved the usual way. - * - * The port that is passed here is really a string containing the idisplay - * from ConnectDisplay(). - */ - - if (is_numeric (port)) - { - tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); - sprintf(portbuf,"%u", tmpport ); - port = portbuf; - } -#endif - - if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL ) - { - PRMSG(1, "TLIINETConnect() failed to allocate a t_call\n", 0,0,0 ); - return TRANS_CONNECT_FAILED; - } - - if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, port, &(sndcall->addr) ) < 0 ) - { - PRMSG(1, "TLIINETConnect() unable to resolve name:%s.%s\n", - host, port, 0 ); - t_free((char *)sndcall,T_CALL); - return TRANS_CONNECT_FAILED; - } - - return TRANS(TLIConnect)(ciptr, sndcall ); -} - - -static int -TRANS(TLITLIConnect)(XtransConnInfo ciptr, char *host, char *port) - -{ - struct t_call *sndcall; - struct sockaddr_un *sunaddr; - int ret_value; - - PRMSG(2, "TLITLIConnect(%s,%s)\n", host, port, 0); - - if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL ) - { - PRMSG(1, "TLITLIConnect() failed to allocate a t_call\n", 0,0,0 ); - return TRANS_CONNECT_FAILED; - } - - if( (sunaddr=(struct sockaddr_un *) - malloc(sizeof(struct sockaddr_un))) == NULL ) - { - PRMSG(1, - "TLITLIConnect: failed to allocate a sockaddr_un\n", - 0,0,0 ); - t_free((char *)sndcall,T_CALL); - return TRANS_CONNECT_FAILED; - } - - sunaddr->sun_family=AF_UNIX; - if( *port == '/' || - strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) { - /* Use the port as is */ - (void) strcpy(sunaddr->sun_path, port); - } else { - (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port ); - } - - sndcall->addr.buf=(char *)sunaddr; - sndcall->addr.len=sizeof(*sunaddr); - sndcall->addr.maxlen=sizeof(*sunaddr); - - ret_value = TRANS(TLIConnect)(ciptr, sndcall ); - - free((char *) sunaddr); - - return ret_value; -} - -#endif /* TRANS_CLIENT */ - - -static int -TRANS(TLIBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend) - -{ - int ret; - struct pollfd filedes; - - PRMSG(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend ); - - /* - * This function should detect hangup conditions. Use poll to check - * if no data is present. On SVR4, the M_HANGUP message sits on the - * streams head, and ioctl(N_READ) keeps returning 0 because there is - * no data available. The hangup goes undetected, and the client hangs. - */ - - ret=ioctl(ciptr->fd, I_NREAD, (char *)pend); - - if( ret != 0 ) - return ret; /* Data present or error */ - - - /* Zero data, or POLLHUP message */ - - filedes.fd=ciptr->fd; - filedes.events=POLLIN; - - ret=poll(&filedes, 1, 0); - - if( ret == 0 ) { - *pend=0; - return 0; /* Really, no data */ - } - - if( ret < 0 ) - return -1; /* just pass back the error */ - - if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */ - return -1; - - /* Should only get here if data arrived after the first ioctl() */ - return ioctl(ciptr->fd, I_NREAD, (char *)pend); -} - - -static int -TRANS(TLIRead)(XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return read(ciptr->fd,buf,size); -} - - -static int -TRANS(TLIWrite)(XtransConnInfo ciptr, char *buf, int size) - -{ - PRMSG(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return write(ciptr->fd,buf,size); -} - - -static int -TRANS(TLIReadv)(XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return READV(ciptr,buf,size); -} - - -static int -TRANS(TLIWritev)(XtransConnInfo ciptr, struct iovec *buf, int size) - -{ - PRMSG(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size ); - - return WRITEV(ciptr,buf,size); -} - - -static int -TRANS(TLIDisconnect)(XtransConnInfo ciptr) - -{ - PRMSG(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 ); - - /* - * Restore the TLI modules so that the connection can be properly shutdown. - * This avoids the situation where a connection goes into the TIME_WAIT - * state, and the address remains unavailable for a while. - */ - ioctl(ciptr->fd, I_POP,"tirdwr"); - ioctl(ciptr->fd, I_PUSH,"timod"); - - t_snddis(ciptr->fd,NULL); - - return 0; -} - - -static int -TRANS(TLIClose)(XtransConnInfo ciptr) - -{ - PRMSG(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd, 0 ); - - t_unbind(ciptr->fd); - - return (t_close(ciptr->fd)); -} - - -static int -TRANS(TLICloseForCloning)(XtransConnInfo ciptr) - -{ - /* - * Don't unbind. - */ - - PRMSG(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd, 0 ); - - return (t_close(ciptr->fd)); -} - - -Xtransport TRANS(TLITCPFuncs) = { - /* TLI Interface */ - "tcp", - 0, -#ifdef TRANS_CLIENT - TRANS(TLIOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(TLIOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLIOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(TLIOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(TLIReopenCOTSServer), - TRANS(TLIReopenCLTSServer), -#endif - TRANS(TLISetOption), -#ifdef TRANS_SERVER - TRANS(TLIINETCreateListener), - NULL, /* ResetListener */ - TRANS(TLIAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLIINETConnect), -#endif /* TRANS_CLIENT */ - TRANS(TLIBytesReadable), - TRANS(TLIRead), - TRANS(TLIWrite), - TRANS(TLIReadv), - TRANS(TLIWritev), - TRANS(TLIDisconnect), - TRANS(TLIClose), - TRANS(TLICloseForCloning), -}; - -#ifdef TRANS_SERVER -static char * inet_aliases[] = { "tcp", NULL }; -#endif -Xtransport TRANS(TLIINETFuncs) = { - /* TLI Interface */ - "inet", - TRANS_ALIAS, -#ifdef TRANS_CLIENT - TRANS(TLIOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - inet_aliases, - TRANS(TLIOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLIOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(TLIOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(TLIReopenCOTSServer), - TRANS(TLIReopenCLTSServer), -#endif - TRANS(TLISetOption), -#ifdef TRANS_SERVER - TRANS(TLIINETCreateListener), - NULL, /* ResetListener */ - TRANS(TLIAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLIINETConnect), -#endif /* TRANS_CLIENT */ - TRANS(TLIBytesReadable), - TRANS(TLIRead), - TRANS(TLIWrite), - TRANS(TLIReadv), - TRANS(TLIWritev), - TRANS(TLIDisconnect), - TRANS(TLIClose), - TRANS(TLICloseForCloning), -}; - -Xtransport TRANS(TLITLIFuncs) = { - /* TLI Interface */ - "tli", - 0, -#ifdef TRANS_CLIENT - TRANS(TLIOpenCOTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - NULL, - TRANS(TLIOpenCOTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLIOpenCLTSClient), -#endif /* TRANS_CLIENT */ -#ifdef TRANS_SERVER - TRANS(TLIOpenCLTSServer), -#endif /* TRANS_SERVER */ -#ifdef TRANS_REOPEN - TRANS(TLIReopenCOTSServer), - TRANS(TLIReopenCLTSServer), -#endif - TRANS(TLISetOption), -#ifdef TRANS_SERVER - TRANS(TLITLICreateListener), - NULL, /* ResetListener */ - TRANS(TLIAccept), -#endif /* TRANS_SERVER */ -#ifdef TRANS_CLIENT - TRANS(TLITLIConnect), -#endif /* TRANS_CLIENT */ - TRANS(TLIBytesReadable), - TRANS(TLIRead), - TRANS(TLIWrite), - TRANS(TLIReadv), - TRANS(TLIWritev), - TRANS(TLIDisconnect), - TRANS(TLIClose), - TRANS(TLICloseForCloning), -}; diff --git a/shell/linux-deps/include/X11/Xtrans/Xtransutil.c b/shell/linux-deps/include/X11/Xtrans/Xtransutil.c deleted file mode 100644 index 42f09c4d1..000000000 --- a/shell/linux-deps/include/X11/Xtrans/Xtransutil.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCRS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * These are some utility functions created for convenience or to provide - * an interface that is similar to an existing interface. These are built - * only using the Transport Independant API, and have no knowledge of - * the internal implementation. - */ - -#ifdef XTHREADS -#include -#endif -#ifdef WIN32 -#include -#include -#endif - -#ifdef X11_t - -/* - * These values come from X.h and Xauth.h, and MUST match them. Some - * of these values are also defined by the ChangeHost protocol message. - */ - -#define FamilyInternet 0 /* IPv4 */ -#define FamilyDECnet 1 -#define FamilyChaos 2 -#define FamilyInternet6 6 -#define FamilyAmoeba 33 -#define FamilyLocalHost 252 -#define FamilyKrb5Principal 253 -#define FamilyNetname 254 -#define FamilyLocal 256 -#define FamilyWild 65535 - -/* - * TRANS(ConvertAddress) converts a sockaddr based address to an - * X authorization based address. Some of this is defined as part of - * the ChangeHost protocol. The rest is just done in a consistent manner. - */ - -int -TRANS(ConvertAddress)(int *familyp, int *addrlenp, Xtransaddr **addrp) - -{ - - PRMSG(2,"ConvertAddress(%d,%d,%x)\n",*familyp,*addrlenp,*addrp); - - switch( *familyp ) - { -#if defined(TCPCONN) || defined(STREAMSCONN) - case AF_INET: - { - /* - * Check for the BSD hack localhost address 127.0.0.1. - * In this case, we are really FamilyLocal. - */ - - struct sockaddr_in saddr; - int len = sizeof(saddr.sin_addr.s_addr); - char *cp = (char *) &saddr.sin_addr.s_addr; - - memcpy (&saddr, *addrp, sizeof (struct sockaddr_in)); - - if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) && - (cp[2] == 0) && (cp[3] == 1)) - { - *familyp=FamilyLocal; - } - else - { - *familyp=FamilyInternet; - *addrlenp=len; - memcpy(*addrp,&saddr.sin_addr,len); - } - break; - } - -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 saddr6; - - memcpy (&saddr6, *addrp, sizeof (struct sockaddr_in6)); - - if (IN6_IS_ADDR_LOOPBACK(&saddr6.sin6_addr)) - { - *familyp=FamilyLocal; - } - else if (IN6_IS_ADDR_V4MAPPED(&(saddr6.sin6_addr))) { - char *cp = (char *) &saddr6.sin6_addr.s6_addr[12]; - - if ((cp[0] == 127) && (cp[1] == 0) && - (cp[2] == 0) && (cp[3] == 1)) - { - *familyp=FamilyLocal; - } - else - { - *familyp=FamilyInternet; - *addrlenp = sizeof (struct in_addr); - memcpy(*addrp,cp,*addrlenp); - } - } - else - { - *familyp=FamilyInternet6; - *addrlenp=sizeof(saddr6.sin6_addr); - memcpy(*addrp,&saddr6.sin6_addr,sizeof(saddr6.sin6_addr)); - } - break; - } -#endif /* IPv6 */ -#endif /* defined(TCPCONN) || defined(STREAMSCONN) */ - - -#if defined(UNIXCONN) || defined(LOCALCONN) - case AF_UNIX: - { - *familyp=FamilyLocal; - break; - } -#endif /* defined(UNIXCONN) || defined(LOCALCONN) */ - -#if (defined(__SCO__) || defined(__UNIXWARE__)) && defined(LOCALCONN) - case 0: - { - *familyp=FamilyLocal; - break; - } -#endif - - default: - PRMSG(1,"ConvertAddress: Unknown family type %d\n", - *familyp, 0,0 ); - return -1; - } - - - if (*familyp == FamilyLocal) - { - /* - * In the case of a local connection, we need to get the - * host name for authentication. - */ - - char hostnamebuf[256]; - int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); - - if (len > 0) { - if (*addrp && *addrlenp < (len + 1)) - { - xfree ((char *) *addrp); - *addrp = NULL; - } - if (!*addrp) - *addrp = (Xtransaddr *) xalloc (len + 1); - if (*addrp) { - strcpy ((char *) *addrp, hostnamebuf); - *addrlenp = len; - } else { - *addrlenp = 0; - } - } - else - { - if (*addrp) - xfree ((char *) *addrp); - *addrp = NULL; - *addrlenp = 0; - } - } - - return 0; -} - -#endif /* X11_t */ - -#ifdef ICE_t - -/* Needed for _XGethostbyaddr usage in TRANS(GetPeerNetworkId) */ -# if defined(TCPCONN) || defined(UNIXCONN) -# define X_INCLUDE_NETDB_H -# define XOS_USE_NO_LOCKING -# include -# endif - -#include - -char * -TRANS(GetMyNetworkId) (XtransConnInfo ciptr) - -{ - int family = ciptr->family; - char *addr = ciptr->addr; - char hostnamebuf[256]; - char *networkId = NULL; - char *transName = ciptr->transptr->TransName; - - if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0) - { - return (NULL); - } - - switch (family) - { -#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) - case AF_UNIX: - { - struct sockaddr_un *saddr = (struct sockaddr_un *) addr; - networkId = (char *) xalloc (3 + strlen (transName) + - strlen (hostnamebuf) + strlen (saddr->sun_path)); - sprintf (networkId, "%s/%s:%s", transName, - hostnamebuf, saddr->sun_path); - break; - } -#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */ - -#if defined(TCPCONN) || defined(STREAMSCONN) - case AF_INET: -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: -#endif - { - struct sockaddr_in *saddr = (struct sockaddr_in *) addr; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) addr; -#endif - int portnum; - char portnumbuf[10]; - - -#if defined(IPv6) && defined(AF_INET6) - if (family == AF_INET6) - portnum = ntohs (saddr6->sin6_port); - else -#endif - portnum = ntohs (saddr->sin_port); - - snprintf (portnumbuf, sizeof(portnumbuf), "%d", portnum); - networkId = (char *) xalloc (3 + strlen (transName) + - strlen (hostnamebuf) + strlen (portnumbuf)); - sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf); - break; - } -#endif /* defined(TCPCONN) || defined(STREAMSCONN) */ - - - default: - break; - } - - return (networkId); -} - -#include -static jmp_buf env; - -#ifdef SIGALRM -static volatile int nameserver_timedout = 0; - -static -#ifdef RETSIGTYPE /* set by autoconf AC_TYPE_SIGNAL */ -RETSIGTYPE -#else /* Imake */ -#ifdef SIGNALRETURNSINT -int -#else -void -#endif -#endif -nameserver_lost(int sig) -{ - nameserver_timedout = 1; - longjmp (env, -1); - /* NOTREACHED */ -#ifdef SIGNALRETURNSINT - return -1; /* for picky compilers */ -#endif -} -#endif /* SIGALARM */ - - -char * -TRANS(GetPeerNetworkId) (XtransConnInfo ciptr) - -{ - int family = ciptr->family; - char *peer_addr = ciptr->peeraddr; - char *hostname; - char addrbuf[256]; - const char *addr = NULL; - - switch (family) - { - case AF_UNSPEC: -#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) - case AF_UNIX: - { - if (gethostname (addrbuf, sizeof (addrbuf)) == 0) - addr = addrbuf; - break; - } -#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */ - -#if defined(TCPCONN) || defined(STREAMSCONN) - case AF_INET: -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: -#endif - { - struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) peer_addr; -#endif - char *address; - int addresslen; -#ifdef XTHREADS_NEEDS_BYNAMEPARAMS - _Xgethostbynameparams hparams; -#endif - struct hostent * volatile hostp = NULL; - -#if defined(IPv6) && defined(AF_INET6) - if (family == AF_INET6) - { - address = (char *) &saddr6->sin6_addr; - addresslen = sizeof (saddr6->sin6_addr); - } - else -#endif - { - address = (char *) &saddr->sin_addr; - addresslen = sizeof (saddr->sin_addr); - } - -#ifdef SIGALRM - /* - * gethostbyaddr can take a LONG time if the host does not exist. - * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds - * that something is wrong and do not make the user wait. - * gethostbyaddr will continue after a signal, so we have to - * jump out of it. - */ - - nameserver_timedout = 0; - signal (SIGALRM, nameserver_lost); - alarm (4); - if (setjmp(env) == 0) { -#endif - hostp = _XGethostbyaddr (address, addresslen, family, hparams); -#ifdef SIGALRM - } - alarm (0); -#endif - if (hostp != NULL) - addr = hostp->h_name; - else -#if defined(IPv6) && defined(AF_INET6) - addr = inet_ntop (family, address, addrbuf, sizeof (addrbuf)); -#else - addr = inet_ntoa (saddr->sin_addr); -#endif - break; - } - -#endif /* defined(TCPCONN) || defined(STREAMSCONN) */ - - - default: - return (NULL); - } - - - hostname = (char *) xalloc ( - strlen (ciptr->transptr->TransName) + strlen (addr) + 2); - strcpy (hostname, ciptr->transptr->TransName); - strcat (hostname, "/"); - if (addr) - strcat (hostname, addr); - - return (hostname); -} - -#endif /* ICE_t */ - - -#if defined(WIN32) && defined(TCPCONN) -int -TRANS(WSAStartup) (void) -{ - static WSADATA wsadata; - - PRMSG (2,"WSAStartup()\n", 0, 0, 0); - - if (!wsadata.wVersion && WSAStartup(MAKEWORD(2,2), &wsadata)) - return 1; - return 0; -} -#endif - -#include - -static int -is_numeric (const char *str) -{ - int i; - - for (i = 0; i < (int) strlen (str); i++) - if (!isdigit (str[i])) - return (0); - - return (1); -} - -#ifdef TRANS_SERVER -#include -#include -#include - -#if !defined(S_IFLNK) && !defined(S_ISLNK) -#undef lstat -#define lstat(a,b) stat(a,b) -#endif - -#define FAIL_IF_NOMODE 1 -#define FAIL_IF_NOT_ROOT 2 -#define WARN_NO_ACCESS 4 - -/* - * We make the assumption that when the 'sticky' (t) bit is requested - * it's not save if the directory has non-root ownership or the sticky - * bit cannot be set and fail. - */ -static int -trans_mkdir(const char *path, int mode) -{ - struct stat buf; - - if (lstat(path, &buf) != 0) { - if (errno != ENOENT) { - PRMSG(1, "mkdir: ERROR: (l)stat failed for %s (%d)\n", - path, errno, 0); - return -1; - } - /* Dir doesn't exist. Try to create it */ - -#if !defined(WIN32) && !defined(__CYGWIN__) - /* - * 'sticky' bit requested: assume application makes - * certain security implications. If effective user ID - * is != 0: fail as we may not be able to meet them. - */ - if (geteuid() != 0) { - if (mode & 01000) { - PRMSG(1, "mkdir: ERROR: euid != 0," - "directory %s will not be created.\n", - path, 0, 0); -#ifdef FAIL_HARD - return -1; -#endif - } else { - PRMSG(1, "mkdir: Cannot create %s with root ownership\n", - path, 0, 0); - } - } -#endif - -#ifndef WIN32 - if (mkdir(path, mode) == 0) { - if (chmod(path, mode)) { - PRMSG(1, "mkdir: ERROR: Mode of %s should be set to %04o\n", - path, mode, 0); -#ifdef FAIL_HARD - return -1; -#endif - } -#else - if (mkdir(path) == 0) { -#endif - } else { - PRMSG(1, "mkdir: ERROR: Cannot create %s\n", - path, 0, 0); - return -1; - } - - return 0; - - } else { - if (S_ISDIR(buf.st_mode)) { - int updateOwner = 0; - int updateMode = 0; - int updatedOwner = 0; - int updatedMode = 0; - int status = 0; - /* Check if the directory's ownership is OK. */ - if (buf.st_uid != 0) - updateOwner = 1; - - /* - * Check if the directory's mode is OK. An exact match isn't - * required, just a mode that isn't more permissive than the - * one requested. - */ - if ((~mode) & 0077 & buf.st_mode) - updateMode = 1; - - /* - * If the directory is not writeable not everybody may - * be able to create sockets. Therefore warn if mode - * cannot be fixed. - */ - if ((~buf.st_mode) & 0022 & mode) { - updateMode = 1; - status |= WARN_NO_ACCESS; - } - - /* - * If 'sticky' bit is requested fail if owner isn't root - * as we assume the caller makes certain security implications - */ - if (mode & 01000) { - status |= FAIL_IF_NOT_ROOT; - if (!(buf.st_mode & 01000)) { - status |= FAIL_IF_NOMODE; - updateMode = 1; - } - } - -#ifdef HAS_FCHOWN - /* - * If fchown(2) and fchmod(2) are available, try to correct the - * directory's owner and mode. Otherwise it isn't safe to attempt - * to do this. - */ - if (updateMode || updateOwner) { - int fd = -1; - struct stat fbuf; - if ((fd = open(path, O_RDONLY)) != -1) { - if (fstat(fd, &fbuf) == -1) { - PRMSG(1, "mkdir: ERROR: fstat failed for %s (%d)\n", - path, errno, 0); - return -1; - } - /* - * Verify that we've opened the same directory as was - * checked above. - */ - if (!S_ISDIR(fbuf.st_mode) || - buf.st_dev != fbuf.st_dev || - buf.st_ino != fbuf.st_ino) { - PRMSG(1, "mkdir: ERROR: inode for %s changed\n", - path, 0, 0); - return -1; - } - if (updateOwner && fchown(fd, 0, 0) == 0) - updatedOwner = 1; - if (updateMode && fchmod(fd, mode) == 0) - updatedMode = 1; - close(fd); - } - } -#endif - - if (updateOwner && !updatedOwner) { -#ifdef FAIL_HARD - if (status & FAIL_IF_NOT_ROOT) { - PRMSG(1, "mkdir: ERROR: Owner of %s must be set to root\n", - path, 0, 0); - return -1; - } -#endif -#if !defined(__APPLE_CC__) && !defined(__CYGWIN__) - PRMSG(1, "mkdir: Owner of %s should be set to root\n", - path, 0, 0); -#endif - } - - if (updateMode && !updatedMode) { -#ifdef FAIL_HARD - if (status & FAIL_IF_NOMODE) { - PRMSG(1, "mkdir: ERROR: Mode of %s must be set to %04o\n", - path, mode, 0); - return -1; - } -#endif - PRMSG(1, "mkdir: Mode of %s should be set to %04o\n", - path, mode, 0); - if (status & WARN_NO_ACCESS) { - PRMSG(1, "mkdir: this may cause subsequent errors\n", - 0, 0, 0); - } - } - return 0; - } - return -1; - } - - /* In all other cases, fail */ - return -1; -} - -#endif /* TRANS_SERVER */ diff --git a/shell/linux-deps/include/X11/Xtrans/transport.c b/shell/linux-deps/include/X11/Xtrans/transport.c deleted file mode 100644 index 5131d99e4..000000000 --- a/shell/linux-deps/include/X11/Xtrans/transport.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - -Copyright 1993, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name NCR not be used in advertising - * or publicity pertaining to distribution of the software without specific, - * written prior permission. NCR makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifdef XSERV_t -#include "os.h" -#else -#include -#define xalloc(_size) malloc(_size) -#define xcalloc(_num,_size) calloc(_num,_size) -#define xrealloc(_ptr,_size) realloc(_ptr,_size) -#define xfree(_ptr) free(_ptr) -#endif - -#include "Xtransint.h" - -#ifdef LOCALCONN -#include "Xtranslcl.c" -#endif -#if defined(TCPCONN) || defined(UNIXCONN) -#include "Xtranssock.c" -#endif -#ifdef STREAMSCONN -#include "Xtranstli.c" -#endif -#include "Xtrans.c" -#include "Xtransutil.c" diff --git a/shell/linux-deps/include/X11/Xutil.h b/shell/linux-deps/include/X11/Xutil.h deleted file mode 100644 index 8cab50e7d..000000000 --- a/shell/linux-deps/include/X11/Xutil.h +++ /dev/null @@ -1,826 +0,0 @@ - -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifndef _X11_XUTIL_H_ -#define _X11_XUTIL_H_ - -/* You must include before including this file */ -#include -#include - -/* - * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding - * value (x, y, width, height) was found in the parsed string. - */ -#define NoValue 0x0000 -#define XValue 0x0001 -#define YValue 0x0002 -#define WidthValue 0x0004 -#define HeightValue 0x0008 -#define AllValues 0x000F -#define XNegative 0x0010 -#define YNegative 0x0020 - -/* - * new version containing base_width, base_height, and win_gravity fields; - * used with WM_NORMAL_HINTS. - */ -typedef struct { - long flags; /* marks which fields in this structure are defined */ - int x, y; /* obsolete for new window mgrs, but clients */ - int width, height; /* should set so old wm's don't mess up */ - int min_width, min_height; - int max_width, max_height; - int width_inc, height_inc; - struct { - int x; /* numerator */ - int y; /* denominator */ - } min_aspect, max_aspect; - int base_width, base_height; /* added by ICCCM version 1 */ - int win_gravity; /* added by ICCCM version 1 */ -} XSizeHints; - -/* - * The next block of definitions are for window manager properties that - * clients and applications use for communication. - */ - -/* flags argument in size hints */ -#define USPosition (1L << 0) /* user specified x, y */ -#define USSize (1L << 1) /* user specified width, height */ - -#define PPosition (1L << 2) /* program specified position */ -#define PSize (1L << 3) /* program specified size */ -#define PMinSize (1L << 4) /* program specified minimum size */ -#define PMaxSize (1L << 5) /* program specified maximum size */ -#define PResizeInc (1L << 6) /* program specified resize increments */ -#define PAspect (1L << 7) /* program specified min and max aspect ratios */ -#define PBaseSize (1L << 8) /* program specified base for incrementing */ -#define PWinGravity (1L << 9) /* program specified window gravity */ - -/* obsolete */ -#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) - - - -typedef struct { - long flags; /* marks which fields in this structure are defined */ - Bool input; /* does this application rely on the window manager to - get keyboard input? */ - int initial_state; /* see below */ - Pixmap icon_pixmap; /* pixmap to be used as icon */ - Window icon_window; /* window to be used as icon */ - int icon_x, icon_y; /* initial position of icon */ - Pixmap icon_mask; /* icon mask bitmap */ - XID window_group; /* id of related window group */ - /* this structure may be extended in the future */ -} XWMHints; - -/* definition for flags of XWMHints */ - -#define InputHint (1L << 0) -#define StateHint (1L << 1) -#define IconPixmapHint (1L << 2) -#define IconWindowHint (1L << 3) -#define IconPositionHint (1L << 4) -#define IconMaskHint (1L << 5) -#define WindowGroupHint (1L << 6) -#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \ -IconPositionHint|IconMaskHint|WindowGroupHint) -#define XUrgencyHint (1L << 8) - -/* definitions for initial window state */ -#define WithdrawnState 0 /* for windows that are not mapped */ -#define NormalState 1 /* most applications want to start this way */ -#define IconicState 3 /* application wants to start as an icon */ - -/* - * Obsolete states no longer defined by ICCCM - */ -#define DontCareState 0 /* don't know or care */ -#define ZoomState 2 /* application wants to start zoomed */ -#define InactiveState 4 /* application believes it is seldom used; */ - /* some wm's may put it on inactive menu */ - - -/* - * new structure for manipulating TEXT properties; used with WM_NAME, - * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND. - */ -typedef struct { - unsigned char *value; /* same as Property routines */ - Atom encoding; /* prop type */ - int format; /* prop data format: 8, 16, or 32 */ - unsigned long nitems; /* number of data items in value */ -} XTextProperty; - -#define XNoMemory -1 -#define XLocaleNotSupported -2 -#define XConverterNotFound -3 - -typedef enum { - XStringStyle, /* STRING */ - XCompoundTextStyle, /* COMPOUND_TEXT */ - XTextStyle, /* text in owner's encoding (current locale)*/ - XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */ - /* The following is an XFree86 extension, introduced in November 2000 */ - XUTF8StringStyle /* UTF8_STRING */ -} XICCEncodingStyle; - -typedef struct { - int min_width, min_height; - int max_width, max_height; - int width_inc, height_inc; -} XIconSize; - -typedef struct { - char *res_name; - char *res_class; -} XClassHint; - -#ifdef XUTIL_DEFINE_FUNCTIONS -extern int XDestroyImage( - XImage *ximage); -extern unsigned long XGetPixel( - XImage *ximage, - int x, int y); -extern int XPutPixel( - XImage *ximage, - int x, int y, - unsigned long pixel); -extern XImage *XSubImage( - XImage *ximage, - int x, int y, - unsigned int width, unsigned int height); -extern int XAddPixel( - XImage *ximage, - long value); -#else -/* - * These macros are used to give some sugar to the image routines so that - * naive people are more comfortable with them. - */ -#define XDestroyImage(ximage) \ - ((*((ximage)->f.destroy_image))((ximage))) -#define XGetPixel(ximage, x, y) \ - ((*((ximage)->f.get_pixel))((ximage), (x), (y))) -#define XPutPixel(ximage, x, y, pixel) \ - ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))) -#define XSubImage(ximage, x, y, width, height) \ - ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height))) -#define XAddPixel(ximage, value) \ - ((*((ximage)->f.add_pixel))((ximage), (value))) -#endif - -/* - * Compose sequence status structure, used in calling XLookupString. - */ -typedef struct _XComposeStatus { - XPointer compose_ptr; /* state table pointer */ - int chars_matched; /* match state */ -} XComposeStatus; - -/* - * Keysym macros, used on Keysyms to test for classes of symbols - */ -#define IsKeypadKey(keysym) \ - (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal)) - -#define IsPrivateKeypadKey(keysym) \ - (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) - -#define IsCursorKey(keysym) \ - (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select)) - -#define IsPFKey(keysym) \ - (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4)) - -#define IsFunctionKey(keysym) \ - (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35)) - -#define IsMiscFunctionKey(keysym) \ - (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break)) - -#ifdef XK_XKB_KEYS -#define IsModifierKey(keysym) \ - ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ - || (((KeySym)(keysym) >= XK_ISO_Lock) && \ - ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) \ - || ((KeySym)(keysym) == XK_Mode_switch) \ - || ((KeySym)(keysym) == XK_Num_Lock)) -#else -#define IsModifierKey(keysym) \ - ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ - || ((KeySym)(keysym) == XK_Mode_switch) \ - || ((KeySym)(keysym) == XK_Num_Lock)) -#endif -/* - * opaque reference to Region data type - */ -typedef struct _XRegion *Region; - -/* Return values from XRectInRegion() */ - -#define RectangleOut 0 -#define RectangleIn 1 -#define RectanglePart 2 - - -/* - * Information used by the visual utility routines to find desired visual - * type from the many visuals a display may support. - */ - -typedef struct { - Visual *visual; - VisualID visualid; - int screen; - int depth; -#if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ */ -#else - int class; -#endif - unsigned long red_mask; - unsigned long green_mask; - unsigned long blue_mask; - int colormap_size; - int bits_per_rgb; -} XVisualInfo; - -#define VisualNoMask 0x0 -#define VisualIDMask 0x1 -#define VisualScreenMask 0x2 -#define VisualDepthMask 0x4 -#define VisualClassMask 0x8 -#define VisualRedMaskMask 0x10 -#define VisualGreenMaskMask 0x20 -#define VisualBlueMaskMask 0x40 -#define VisualColormapSizeMask 0x80 -#define VisualBitsPerRGBMask 0x100 -#define VisualAllMask 0x1FF - -/* - * This defines a window manager property that clients may use to - * share standard color maps of type RGB_COLOR_MAP: - */ -typedef struct { - Colormap colormap; - unsigned long red_max; - unsigned long red_mult; - unsigned long green_max; - unsigned long green_mult; - unsigned long blue_max; - unsigned long blue_mult; - unsigned long base_pixel; - VisualID visualid; /* added by ICCCM version 1 */ - XID killid; /* added by ICCCM version 1 */ -} XStandardColormap; - -#define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */ - - -/* - * return codes for XReadBitmapFile and XWriteBitmapFile - */ -#define BitmapSuccess 0 -#define BitmapOpenFailed 1 -#define BitmapFileInvalid 2 -#define BitmapNoMemory 3 - -/**************************************************************** - * - * Context Management - * - ****************************************************************/ - - -/* Associative lookup table return codes */ - -#define XCSUCCESS 0 /* No error. */ -#define XCNOMEM 1 /* Out of memory */ -#define XCNOENT 2 /* No entry in table */ - -typedef int XContext; - -#define XUniqueContext() ((XContext) XrmUniqueQuark()) -#define XStringToContext(string) ((XContext) XrmStringToQuark(string)) - -_XFUNCPROTOBEGIN - -/* The following declarations are alphabetized. */ - -extern XClassHint *XAllocClassHint ( - void -); - -extern XIconSize *XAllocIconSize ( - void -); - -extern XSizeHints *XAllocSizeHints ( - void -); - -extern XStandardColormap *XAllocStandardColormap ( - void -); - -extern XWMHints *XAllocWMHints ( - void -); - -extern int XClipBox( - Region /* r */, - XRectangle* /* rect_return */ -); - -extern Region XCreateRegion( - void -); - -extern const char *XDefaultString (void); - -extern int XDeleteContext( - Display* /* display */, - XID /* rid */, - XContext /* context */ -); - -extern int XDestroyRegion( - Region /* r */ -); - -extern int XEmptyRegion( - Region /* r */ -); - -extern int XEqualRegion( - Region /* r1 */, - Region /* r2 */ -); - -extern int XFindContext( - Display* /* display */, - XID /* rid */, - XContext /* context */, - XPointer* /* data_return */ -); - -extern Status XGetClassHint( - Display* /* display */, - Window /* w */, - XClassHint* /* class_hints_return */ -); - -extern Status XGetIconSizes( - Display* /* display */, - Window /* w */, - XIconSize** /* size_list_return */, - int* /* count_return */ -); - -extern Status XGetNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */ -); - -extern Status XGetRGBColormaps( - Display* /* display */, - Window /* w */, - XStandardColormap** /* stdcmap_return */, - int* /* count_return */, - Atom /* property */ -); - -extern Status XGetSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - Atom /* property */ -); - -extern Status XGetStandardColormap( - Display* /* display */, - Window /* w */, - XStandardColormap* /* colormap_return */, - Atom /* property */ -); - -extern Status XGetTextProperty( - Display* /* display */, - Window /* window */, - XTextProperty* /* text_prop_return */, - Atom /* property */ -); - -extern XVisualInfo *XGetVisualInfo( - Display* /* display */, - long /* vinfo_mask */, - XVisualInfo* /* vinfo_template */, - int* /* nitems_return */ -); - -extern Status XGetWMClientMachine( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ -); - -extern XWMHints *XGetWMHints( - Display* /* display */, - Window /* w */ -); - -extern Status XGetWMIconName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ -); - -extern Status XGetWMName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ -); - -extern Status XGetWMNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - long* /* supplied_return */ -); - -extern Status XGetWMSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - long* /* supplied_return */, - Atom /* property */ -); - -extern Status XGetZoomHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* zhints_return */ -); - -extern int XIntersectRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ -); - -extern void XConvertCase( - KeySym /* sym */, - KeySym* /* lower */, - KeySym* /* upper */ -); - -extern int XLookupString( - XKeyEvent* /* event_struct */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - XComposeStatus* /* status_in_out */ -); - -extern Status XMatchVisualInfo( - Display* /* display */, - int /* screen */, - int /* depth */, - int /* class */, - XVisualInfo* /* vinfo_return */ -); - -extern int XOffsetRegion( - Region /* r */, - int /* dx */, - int /* dy */ -); - -extern Bool XPointInRegion( - Region /* r */, - int /* x */, - int /* y */ -); - -extern Region XPolygonRegion( - XPoint* /* points */, - int /* n */, - int /* fill_rule */ -); - -extern int XRectInRegion( - Region /* r */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ -); - -extern int XSaveContext( - Display* /* display */, - XID /* rid */, - XContext /* context */, - _Xconst char* /* data */ -); - -extern int XSetClassHint( - Display* /* display */, - Window /* w */, - XClassHint* /* class_hints */ -); - -extern int XSetIconSizes( - Display* /* display */, - Window /* w */, - XIconSize* /* size_list */, - int /* count */ -); - -extern int XSetNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */ -); - -extern void XSetRGBColormaps( - Display* /* display */, - Window /* w */, - XStandardColormap* /* stdcmaps */, - int /* count */, - Atom /* property */ -); - -extern int XSetSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */, - Atom /* property */ -); - -extern int XSetStandardProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - Pixmap /* icon_pixmap */, - char** /* argv */, - int /* argc */, - XSizeHints* /* hints */ -); - -extern void XSetTextProperty( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */, - Atom /* property */ -); - -extern void XSetWMClientMachine( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ -); - -extern int XSetWMHints( - Display* /* display */, - Window /* w */, - XWMHints* /* wm_hints */ -); - -extern void XSetWMIconName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ -); - -extern void XSetWMName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ -); - -extern void XSetWMNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */ -); - -extern void XSetWMProperties( - Display* /* display */, - Window /* w */, - XTextProperty* /* window_name */, - XTextProperty* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ -); - -extern void XmbSetWMProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ -); - -extern void Xutf8SetWMProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ -); - -extern void XSetWMSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */, - Atom /* property */ -); - -extern int XSetRegion( - Display* /* display */, - GC /* gc */, - Region /* r */ -); - -extern void XSetStandardColormap( - Display* /* display */, - Window /* w */, - XStandardColormap* /* colormap */, - Atom /* property */ -); - -extern int XSetZoomHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* zhints */ -); - -extern int XShrinkRegion( - Region /* r */, - int /* dx */, - int /* dy */ -); - -extern Status XStringListToTextProperty( - char** /* list */, - int /* count */, - XTextProperty* /* text_prop_return */ -); - -extern int XSubtractRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ -); - -extern int XmbTextListToTextProperty( - Display* display, - char** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); - -extern int XwcTextListToTextProperty( - Display* display, - wchar_t** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); - -extern int Xutf8TextListToTextProperty( - Display* display, - char** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); - -extern void XwcFreeStringList( - wchar_t** list -); - -extern Status XTextPropertyToStringList( - XTextProperty* /* text_prop */, - char*** /* list_return */, - int* /* count_return */ -); - -extern int XmbTextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - char*** list_return, - int* count_return -); - -extern int XwcTextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - wchar_t*** list_return, - int* count_return -); - -extern int Xutf8TextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - char*** list_return, - int* count_return -); - -extern int XUnionRectWithRegion( - XRectangle* /* rectangle */, - Region /* src_region */, - Region /* dest_region_return */ -); - -extern int XUnionRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ -); - -extern int XWMGeometry( - Display* /* display */, - int /* screen_number */, - _Xconst char* /* user_geometry */, - _Xconst char* /* default_geometry */, - unsigned int /* border_width */, - XSizeHints* /* hints */, - int* /* x_return */, - int* /* y_return */, - int* /* width_return */, - int* /* height_return */, - int* /* gravity_return */ -); - -extern int XXorRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ -); - -_XFUNCPROTOEND - -#endif /* _X11_XUTIL_H_ */ diff --git a/shell/linux-deps/include/X11/Xw32defs.h b/shell/linux-deps/include/X11/Xw32defs.h deleted file mode 100644 index b2e4b33ae..000000000 --- a/shell/linux-deps/include/X11/Xw32defs.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _XW32DEFS_H -# define _XW32DEFS_H - -# ifdef __GNUC__ /* mingw is more close to unix than msvc */ -# if !defined(__daddr_t_defined) -typedef char *caddr_t; -# endif -# define lstat stat - -# else -typedef char *caddr_t; - -# define access _access -# define alloca _alloca -# define chdir _chdir -# define chmod _chmod -# define close _close -# define creat _creat -# define dup _dup -# define dup2 _dup2 -# define environ _environ -# define execl _execl -# define execle _execle -# define execlp _execlp -# define execlpe _execlpe -# define execv _execv -# define execve _execve -# define execvp _execvp -# define execvpe _execvpe -# define fdopen _fdopen -# define fileno _fileno -# define fstat _fstat -# define getcwd _getcwd -# define getpid _getpid -# define hypot _hypot -# define isascii __isascii -# define isatty _isatty -# define lseek _lseek -# define mkdir _mkdir -# define mktemp _mktemp -# define open _open -# define putenv _putenv -# define read _read -# define rmdir _rmdir -# define sleep(x) Sleep((x) * 1000) -# define stat _stat -# define sys_errlist _sys_errlist -# define sys_nerr _sys_nerr -# define umask _umask -# define unlink _unlink -# define write _write -# define random rand -# define srandom srand - -# define O_RDONLY _O_RDONLY -# define O_WRONLY _O_WRONLY -# define O_RDWR _O_RDWR -# define O_APPEND _O_APPEND -# define O_CREAT _O_CREAT -# define O_TRUNC _O_TRUNC -# define O_EXCL _O_EXCL -# define O_TEXT _O_TEXT -# define O_BINARY _O_BINARY -# define O_RAW _O_BINARY - -# define S_IFMT _S_IFMT -# define S_IFDIR _S_IFDIR -# define S_IFCHR _S_IFCHR -# define S_IFREG _S_IFREG -# define S_IREAD _S_IREAD -# define S_IWRITE _S_IWRITE -# define S_IEXEC _S_IEXEC - -# define F_OK 0 -# define X_OK 1 -# define W_OK 2 -# define R_OK 4 -# endif /* __GNUC__ */ -#endif diff --git a/shell/linux-deps/include/X11/Xwindows.h b/shell/linux-deps/include/X11/Xwindows.h deleted file mode 100644 index 6318155e1..000000000 --- a/shell/linux-deps/include/X11/Xwindows.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - -Copyright 1996, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- -ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL- -ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization from -The Open Group. - -*/ - -/* - * This header file has the sole purpose of allowing the inclusion of - * windows.h without getting any name conflicts with X headers code, by - * renaming the conflicting definitions from windows.h - * - * Some (non-Microsoft) versions of the Windows API headers actually avoid - * making the conflicting definitions if XFree86Server is defined, so we - * need to remember if that was defined and undefine it during including - * windows.h (so the conflicting definitions get wrapped correctly), and - * then redefine it afterwards... - * - * There doesn't seem to be a good way to wrap the min/max macros from - * windows.h, so we simply avoid defining them completely, allowing any - * pre-existing definition to stand. - * - */ - -#undef _XFree86Server -#ifdef XFree86Server -# define _XFree86Server -# undef XFree86Server -#endif - -#define NOMINMAX -#define BOOL wBOOL -#define INT32 wINT32 -#undef Status -#define Status wStatus -#define ATOM wATOM -#define BYTE wBYTE -#define FreeResource wFreeResource -#include -#undef NOMINMAX -#undef Status -#define Status int -#undef BYTE -#undef BOOL -#undef INT32 -#undef ATOM -#undef FreeResource -#undef CreateWindowA - -#ifdef RESOURCE_H -# undef RT_FONT -# undef RT_CURSOR -# define RT_FONT ((RESTYPE)4) -# define RT_CURSOR ((RESTYPE)5) -#endif - -#ifndef __CYGWIN__ -#define sleep(x) Sleep((x) * 1000) -#endif - -#if defined(WIN32) && (!defined(PATH_MAX) || PATH_MAX < 1024) -# undef PATH_MAX -# define PATH_MAX 1024 -#endif - -#ifdef _XFree86Server -# define XFree86Server -# undef _XFree86Server -#endif - diff --git a/shell/linux-deps/include/X11/Xwinsock.h b/shell/linux-deps/include/X11/Xwinsock.h deleted file mode 100644 index e6ca7b54b..000000000 --- a/shell/linux-deps/include/X11/Xwinsock.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Copyright 1996, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- -ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL- -ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization from -The Open Group. - -*/ - -/* - * This header file has for sole purpose to allow to include winsock.h - * without getting any name conflicts with our code. - * Conflicts come from the fact that including winsock.h actually pulls - * in the whole Windows API... - */ - -#undef _XFree86Server -#ifdef XFree86Server -# define _XFree86Server -# undef XFree86Server -#endif - -#define BOOL wBOOL -#define INT32 wINT32 -#undef Status -#define Status wStatus -#define ATOM wATOM -#define BYTE wBYTE -#define FreeResource wFreeResource -#include -#undef Status -#define Status int -#undef BYTE -#undef BOOL -#undef INT32 -#undef ATOM -#undef FreeResource -#undef CreateWindowA -#undef RT_FONT -#undef RT_CURSOR - -#ifdef _XFree86Server -# define XFree86Server -# undef _XFree86Server -#endif - diff --git a/shell/linux-deps/include/X11/ap_keysym.h b/shell/linux-deps/include/X11/ap_keysym.h deleted file mode 100644 index 9a1197117..000000000 --- a/shell/linux-deps/include/X11/ap_keysym.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************** -Copyright 1987 by Apollo Computer Inc., Chelmsford, Massachusetts. -Copyright 1989 by Hewlett-Packard Company. - - All Rights Reserved - -Permission to use, duplicate, change, and distribute this software and -its documentation for any purpose and without fee is granted, provided -that the above copyright notice appear in such copy and that this -copyright notice appear in all supporting documentation, and that the -names of Apollo Computer Inc., the Hewlett-Packard Company, or the X -Consortium not be used in advertising or publicity pertaining to -distribution of the software without written prior permission. - -HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD -TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. Hewlett-Packard shall not be liable for errors -contained herein or direct, indirect, special, incidental or -consequential damages in connection with the furnishing, -performance, or use of this material. - -This software is not subject to any license of the American -Telephone and Telegraph Company or of the Regents of the -University of California. -******************************************************************/ - -#define apXK_LineDel 0x1000FF00 -#define apXK_CharDel 0x1000FF01 -#define apXK_Copy 0x1000FF02 -#define apXK_Cut 0x1000FF03 -#define apXK_Paste 0x1000FF04 -#define apXK_Move 0x1000FF05 -#define apXK_Grow 0x1000FF06 -#define apXK_Cmd 0x1000FF07 -#define apXK_Shell 0x1000FF08 -#define apXK_LeftBar 0x1000FF09 -#define apXK_RightBar 0x1000FF0A -#define apXK_LeftBox 0x1000FF0B -#define apXK_RightBox 0x1000FF0C -#define apXK_UpBox 0x1000FF0D -#define apXK_DownBox 0x1000FF0E -#define apXK_Pop 0x1000FF0F -#define apXK_Read 0x1000FF10 -#define apXK_Edit 0x1000FF11 -#define apXK_Save 0x1000FF12 -#define apXK_Exit 0x1000FF13 -#define apXK_Repeat 0x1000FF14 - -#define apXK_KP_parenleft 0x1000FFA8 -#define apXK_KP_parenright 0x1000FFA9 diff --git a/shell/linux-deps/include/X11/bitmaps/1x1 b/shell/linux-deps/include/X11/bitmaps/1x1 deleted file mode 100644 index 6d013d4af..000000000 --- a/shell/linux-deps/include/X11/bitmaps/1x1 +++ /dev/null @@ -1,6 +0,0 @@ -#define 1x1_width 16 -#define 1x1_height 16 -static char 1x1_bits[] = { - 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, - 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, - 0xff, 0xff, 0x55, 0x55, 0xff, 0xff, 0x55, 0x55}; diff --git a/shell/linux-deps/include/X11/bitmaps/2x2 b/shell/linux-deps/include/X11/bitmaps/2x2 deleted file mode 100644 index 8490457a1..000000000 --- a/shell/linux-deps/include/X11/bitmaps/2x2 +++ /dev/null @@ -1,6 +0,0 @@ -#define 2x2_width 16 -#define 2x2_height 16 -static char 2x2_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, - 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, - 0xff, 0xff, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33}; diff --git a/shell/linux-deps/include/X11/bitmaps/Dashes b/shell/linux-deps/include/X11/bitmaps/Dashes deleted file mode 100644 index e81aa020d..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Dashes +++ /dev/null @@ -1,4 +0,0 @@ -#define Dashes_width 2 -#define Dashes_height 2 -static char Dashes_bits[] = { - 0x01, 0x02}; diff --git a/shell/linux-deps/include/X11/bitmaps/Down b/shell/linux-deps/include/X11/bitmaps/Down deleted file mode 100644 index 9790e27e0..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Down +++ /dev/null @@ -1,13 +0,0 @@ -#define Down_width 30 -#define Down_height 30 -static char Down_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x18, 0x03, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x58, 0x03, 0x00, 0xf0, 0xb8, 0xe3, 0x01, 0xf0, 0x59, 0xf3, 0x01, - 0xb0, 0xbb, 0xbb, 0x01, 0x70, 0x5f, 0xdf, 0x01, 0xe0, 0xbe, 0xef, 0x00, - 0xc0, 0x5d, 0x77, 0x00, 0x80, 0xab, 0x3a, 0x00, 0x00, 0x57, 0x1d, 0x00, - 0x00, 0xae, 0x0e, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/Excl b/shell/linux-deps/include/X11/bitmaps/Excl deleted file mode 100644 index b17238941..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Excl +++ /dev/null @@ -1,17 +0,0 @@ -#define Excl_width 40 -#define Excl_height 32 -static char Excl_bits[] = { - 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, - 0x00, 0x00, 0x80, 0xc3, 0x01, 0x00, 0x00, 0xc0, 0x99, 0x03, 0x00, 0x00, - 0xc0, 0x34, 0x03, 0x00, 0x00, 0xe0, 0x6a, 0x07, 0x00, 0x00, 0x70, 0x76, - 0x0e, 0x00, 0x00, 0x70, 0x6a, 0x0e, 0x00, 0x00, 0x38, 0x76, 0x1c, 0x00, - 0x00, 0x18, 0x6a, 0x18, 0x00, 0x00, 0x1c, 0x76, 0x38, 0x00, 0x00, 0x0e, - 0x6a, 0x70, 0x00, 0x00, 0x06, 0x76, 0x60, 0x00, 0x00, 0x07, 0x6a, 0xe0, - 0x00, 0x80, 0x03, 0x76, 0xc0, 0x01, 0x80, 0x03, 0x6a, 0xc0, 0x01, 0xc0, - 0x01, 0x76, 0x80, 0x03, 0xc0, 0x00, 0x6a, 0x00, 0x03, 0xe0, 0x00, 0x34, - 0x00, 0x07, 0x70, 0x00, 0x18, 0x00, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x0e, - 0x38, 0x00, 0x3c, 0x00, 0x1c, 0x1c, 0x00, 0x76, 0x00, 0x38, 0x1c, 0x00, - 0x6a, 0x00, 0x38, 0x0e, 0x00, 0x76, 0x00, 0x70, 0x0e, 0x00, 0x3c, 0x00, - 0x70, 0x1e, 0x00, 0x00, 0x00, 0x78, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xfc, - 0xff, 0xff, 0xff, 0x3f}; diff --git a/shell/linux-deps/include/X11/bitmaps/FlipHoriz b/shell/linux-deps/include/X11/bitmaps/FlipHoriz deleted file mode 100644 index a72da3d82..000000000 --- a/shell/linux-deps/include/X11/bitmaps/FlipHoriz +++ /dev/null @@ -1,13 +0,0 @@ -#define FlipHoriz_width 30 -#define FlipHoriz_height 30 -static char FlipHoriz_bits[] = { - 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, - 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, - 0x00, 0x00, 0xdc, 0x01, 0xc0, 0xff, 0xbf, 0x03, 0xe0, 0xff, 0x5f, 0x07, - 0xb0, 0xaa, 0xaa, 0x0e, 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, - 0xfe, 0xff, 0x5f, 0x07, 0xff, 0xff, 0xbf, 0x03, 0x6b, 0x00, 0xdc, 0x01, - 0x77, 0x00, 0xee, 0x00, 0x6b, 0x00, 0x77, 0x00, 0x77, 0x80, 0x3b, 0x00, - 0x6b, 0x80, 0x1d, 0x00, 0x77, 0x80, 0x0f, 0x00, 0x6b, 0x80, 0x07, 0x00, - 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xac, 0x06, 0x00, 0x00, - 0x58, 0x03, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, - 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/FlipVert b/shell/linux-deps/include/X11/bitmaps/FlipVert deleted file mode 100644 index f5df65b28..000000000 --- a/shell/linux-deps/include/X11/bitmaps/FlipVert +++ /dev/null @@ -1,13 +0,0 @@ -#define FlipVert_width 30 -#define FlipVert_height 30 -static char FlipVert_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, - 0x00, 0x1f, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x75, 0x00, 0x00, - 0xe0, 0xea, 0x00, 0x00, 0x70, 0xd5, 0x01, 0x00, 0xb8, 0xaa, 0x03, 0x00, - 0xdc, 0x75, 0x07, 0x00, 0xee, 0xfb, 0x0e, 0x00, 0xf7, 0xf5, 0x1d, 0x00, - 0xbb, 0xbb, 0x1b, 0x00, 0x9f, 0x35, 0x1f, 0x00, 0x8f, 0x3b, 0x1e, 0x00, - 0x80, 0x35, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x35, 0x20, 0x08, - 0x80, 0x3b, 0x60, 0x0c, 0x80, 0x35, 0xe0, 0x0e, 0x80, 0x3b, 0xe0, 0x0f, - 0x80, 0x35, 0x60, 0x0d, 0x80, 0x3b, 0xe0, 0x0e, 0x80, 0xf5, 0x7f, 0x0d, - 0x00, 0xfb, 0xff, 0x06, 0x00, 0xb6, 0x6a, 0x03, 0x00, 0x7c, 0xf5, 0x01, - 0x00, 0xb8, 0xea, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/Fold b/shell/linux-deps/include/X11/bitmaps/Fold deleted file mode 100644 index ea59a19c0..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Fold +++ /dev/null @@ -1,13 +0,0 @@ -#define Fold_width 30 -#define Fold_height 30 -static char Fold_bits[] = { - 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x57, 0xf5, 0xab, 0x3a, - 0xab, 0xff, 0x7f, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0x03, 0x70, 0x35, - 0x57, 0x07, 0xb8, 0x3a, 0xbb, 0x0e, 0x5c, 0x37, 0x7f, 0x1d, 0xae, 0x3f, - 0xfb, 0x3a, 0xd7, 0x37, 0xdf, 0xf5, 0xeb, 0x3e, 0x9b, 0xeb, 0x75, 0x36, - 0x1f, 0xd7, 0x3a, 0x3e, 0x1f, 0xae, 0x1d, 0x3e, 0x0e, 0xfc, 0x0e, 0x1c, - 0x0e, 0xdc, 0x0f, 0x1c, 0x1f, 0x6e, 0x1d, 0x3e, 0x1f, 0xd7, 0x3a, 0x3e, - 0x9b, 0xeb, 0x75, 0x36, 0xdf, 0xf5, 0xeb, 0x3e, 0xfb, 0x3a, 0xd7, 0x37, - 0x7f, 0x1d, 0xae, 0x3f, 0xbb, 0x0e, 0x5c, 0x37, 0x57, 0x07, 0xb8, 0x3a, - 0xab, 0x03, 0x70, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0xff, 0x7f, 0x35, - 0x57, 0xf5, 0xab, 0x3a, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f}; diff --git a/shell/linux-deps/include/X11/bitmaps/Left b/shell/linux-deps/include/X11/bitmaps/Left deleted file mode 100644 index 5c7f14190..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Left +++ /dev/null @@ -1,13 +0,0 @@ -#define Left_width 30 -#define Left_height 30 -static char Left_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, - 0x00, 0x37, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, - 0xe0, 0x0e, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb8, 0xff, 0xff, 0x1f, - 0x5c, 0xff, 0xff, 0x0f, 0xae, 0xaa, 0xaa, 0x06, 0x57, 0x55, 0x55, 0x03, - 0xae, 0xaa, 0xaa, 0x06, 0x5c, 0xff, 0xff, 0x0f, 0xb8, 0xff, 0xff, 0x1f, - 0x70, 0x07, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, - 0x80, 0x3b, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, - 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/Right b/shell/linux-deps/include/X11/bitmaps/Right deleted file mode 100644 index d751a5f2d..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Right +++ /dev/null @@ -1,13 +0,0 @@ -#define Right_width 30 -#define Right_height 30 -static char Right_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, - 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, - 0xff, 0xff, 0xbf, 0x03, 0xfe, 0xff, 0x5f, 0x07, 0xac, 0xaa, 0xaa, 0x0e, - 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, 0xfe, 0xff, 0x5f, 0x07, - 0xff, 0xff, 0xbf, 0x03, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00, 0xee, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x1d, 0x00, - 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/RotateLeft b/shell/linux-deps/include/X11/bitmaps/RotateLeft deleted file mode 100644 index c4d4b1440..000000000 --- a/shell/linux-deps/include/X11/bitmaps/RotateLeft +++ /dev/null @@ -1,13 +0,0 @@ -#define RotateLeft_width 30 -#define RotateLeft_height 30 -static char RotateLeft_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, - 0x00, 0x6e, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, - 0xc0, 0x1d, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0x70, 0xff, 0x0f, 0x00, - 0xb8, 0xfe, 0x1f, 0x00, 0x5c, 0x55, 0x35, 0x00, 0xae, 0xaa, 0x6a, 0x00, - 0x5c, 0x55, 0xd5, 0x00, 0xb8, 0xfe, 0xff, 0x01, 0x70, 0xff, 0xff, 0x03, - 0xe0, 0x0e, 0x58, 0x03, 0xc0, 0x1d, 0xb8, 0x03, 0x80, 0x3b, 0x58, 0x03, - 0x00, 0x77, 0xb8, 0x03, 0x00, 0x6e, 0x58, 0x03, 0x00, 0x7c, 0xb8, 0x03, - 0x00, 0x78, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, - 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x18, 0x03, - 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/RotateRight b/shell/linux-deps/include/X11/bitmaps/RotateRight deleted file mode 100644 index d54f3c78c..000000000 --- a/shell/linux-deps/include/X11/bitmaps/RotateRight +++ /dev/null @@ -1,13 +0,0 @@ -#define RotateRight_width 30 -#define RotateRight_height 30 -static char RotateRight_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, - 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0xfc, 0xbf, 0x03, - 0x00, 0xfe, 0x5f, 0x07, 0x00, 0xab, 0xaa, 0x0e, 0x80, 0x55, 0x55, 0x1d, - 0xc0, 0xaa, 0xaa, 0x0e, 0xe0, 0xff, 0x5f, 0x07, 0xf0, 0xff, 0xbf, 0x03, - 0xb0, 0x06, 0xdc, 0x01, 0x70, 0x07, 0xee, 0x00, 0xb0, 0x06, 0x77, 0x00, - 0x70, 0x87, 0x3b, 0x00, 0xb0, 0x86, 0x1d, 0x00, 0x70, 0x87, 0x0f, 0x00, - 0xb0, 0x86, 0x07, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, - 0xf0, 0x07, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, - 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/Term b/shell/linux-deps/include/X11/bitmaps/Term deleted file mode 100644 index 19ec39979..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Term +++ /dev/null @@ -1,14 +0,0 @@ -#define Term_width 32 -#define Term_height 32 -static char Term_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x04, 0x00, 0x00, 0x20, - 0xe4, 0xff, 0xff, 0x27, 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x01, 0x28, - 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, - 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x00, 0x28, - 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, - 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x00, 0x00, 0x28, - 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xf8, 0xff, 0xff, 0x1f, - 0xfe, 0xff, 0xff, 0x7f, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0xc0, 0x5f, 0x02, 0x00, 0x00, 0x40, 0xfa, 0xff, 0xff, 0x5f, - 0xae, 0xaa, 0xaa, 0x6a, 0x56, 0x55, 0x55, 0x55, 0xab, 0xaa, 0xaa, 0xea, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/Up b/shell/linux-deps/include/X11/bitmaps/Up deleted file mode 100644 index 423103f98..000000000 --- a/shell/linux-deps/include/X11/bitmaps/Up +++ /dev/null @@ -1,13 +0,0 @@ -#define Up_width 30 -#define Up_height 30 -static char Up_bits[] = { - 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xae, 0x0e, 0x00, - 0x00, 0x57, 0x1d, 0x00, 0x80, 0xab, 0x3a, 0x00, 0xc0, 0x5d, 0x77, 0x00, - 0xe0, 0xbe, 0xef, 0x00, 0x70, 0x5f, 0xdf, 0x01, 0xb0, 0xbb, 0xbb, 0x01, - 0xf0, 0x59, 0xf3, 0x01, 0xf0, 0xb8, 0xe3, 0x01, 0x00, 0x58, 0x03, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, - 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x58, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, - 0x00, 0x18, 0x03, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/black b/shell/linux-deps/include/X11/bitmaps/black deleted file mode 100644 index 3a1ec90a3..000000000 --- a/shell/linux-deps/include/X11/bitmaps/black +++ /dev/null @@ -1,6 +0,0 @@ -#define black_width 16 -#define black_height 16 -static char black_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/shell/linux-deps/include/X11/bitmaps/black6 b/shell/linux-deps/include/X11/bitmaps/black6 deleted file mode 100644 index 4e5384e44..000000000 --- a/shell/linux-deps/include/X11/bitmaps/black6 +++ /dev/null @@ -1,4 +0,0 @@ -#define black6_width 6 -#define black6_height 6 -static char black6_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; diff --git a/shell/linux-deps/include/X11/bitmaps/box6 b/shell/linux-deps/include/X11/bitmaps/box6 deleted file mode 100644 index 83ac4a791..000000000 --- a/shell/linux-deps/include/X11/bitmaps/box6 +++ /dev/null @@ -1,4 +0,0 @@ -#define box6_width 6 -#define box6_height 6 -static char box6_bits[] = { - 0x3f, 0x21, 0x21, 0x21, 0x21, 0x3f}; diff --git a/shell/linux-deps/include/X11/bitmaps/boxes b/shell/linux-deps/include/X11/bitmaps/boxes deleted file mode 100644 index 0deb80130..000000000 --- a/shell/linux-deps/include/X11/bitmaps/boxes +++ /dev/null @@ -1,6 +0,0 @@ -#define boxes_width 16 -#define boxes_height 16 -static char boxes_bits[] = { - 0x0f, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x0f, 0x0f, 0xf0, 0xf0, 0x90, 0x90, - 0x90, 0x90, 0xf0, 0xf0, 0x0f, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x0f, 0x0f, - 0xf0, 0xf0, 0x90, 0x90, 0x90, 0x90, 0xf0, 0xf0}; diff --git a/shell/linux-deps/include/X11/bitmaps/calculator b/shell/linux-deps/include/X11/bitmaps/calculator deleted file mode 100644 index 2be3b9d5a..000000000 --- a/shell/linux-deps/include/X11/bitmaps/calculator +++ /dev/null @@ -1,19 +0,0 @@ -#define icon_width 28 -#define icon_height 48 -static char icon_bits[] = { - 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x0f, 0x03, 0x00, 0x00, 0x0c, - 0xd3, 0x5d, 0x5d, 0x0c, 0x13, 0x51, 0x45, 0x0c, 0xd3, 0xdd, 0xdd, 0x0d, - 0x53, 0x10, 0x51, 0x0d, 0xd3, 0x1d, 0xdd, 0x0d, 0x03, 0x00, 0x00, 0x0c, - 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x00, 0x08, - 0xbd, 0xf7, 0xde, 0x0b, 0xbd, 0xf7, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, - 0xbd, 0xf7, 0xde, 0x0b, 0xa5, 0x94, 0x52, 0x0a, 0xbd, 0xf7, 0xde, 0x0b, - 0x01, 0x00, 0x00, 0x08, 0xbd, 0xf7, 0xde, 0x0b, 0xbd, 0xf7, 0xde, 0x0b, - 0xbd, 0xf7, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, 0xbd, 0xf7, 0xde, 0x0b, - 0xbd, 0xf7, 0xde, 0x0b, 0xbd, 0xf7, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, - 0xbd, 0xf7, 0xde, 0x0b, 0xbd, 0x94, 0xd2, 0x0b, 0xbd, 0x94, 0xd2, 0x0b, - 0xbd, 0xf7, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, 0xbd, 0xf7, 0xde, 0x0b, - 0xbd, 0x94, 0xd2, 0x0b, 0xbd, 0x94, 0xd2, 0x0b, 0xbd, 0xf7, 0xde, 0x0b, - 0x01, 0x00, 0x00, 0x08, 0xbd, 0xf7, 0xde, 0x0b, 0xbd, 0x94, 0xd2, 0x0b, - 0xbd, 0x94, 0xd2, 0x0b, 0xbd, 0xf7, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, - 0xbd, 0xff, 0xde, 0x0b, 0xbd, 0x80, 0xd2, 0x0b, 0xbd, 0x80, 0xd2, 0x0b, - 0xbd, 0xff, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0x0f}; diff --git a/shell/linux-deps/include/X11/bitmaps/cntr_ptr b/shell/linux-deps/include/X11/bitmaps/cntr_ptr deleted file mode 100644 index eddb25f1e..000000000 --- a/shell/linux-deps/include/X11/bitmaps/cntr_ptr +++ /dev/null @@ -1,8 +0,0 @@ -#define cntr_ptr_width 16 -#define cntr_ptr_height 16 -#define cntr_ptr_x_hot 7 -#define cntr_ptr_y_hot 1 -static char cntr_ptr_bits[] = { - 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, - 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0x98, 0x19, 0x88, 0x11, 0x80, 0x01, - 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/cntr_ptrmsk b/shell/linux-deps/include/X11/bitmaps/cntr_ptrmsk deleted file mode 100644 index d3607a4ba..000000000 --- a/shell/linux-deps/include/X11/bitmaps/cntr_ptrmsk +++ /dev/null @@ -1,6 +0,0 @@ -#define cntr_ptrmsk_width 16 -#define cntr_ptrmsk_height 16 -static char cntr_ptrmsk_bits[] = { - 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, - 0xf8, 0x1f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xdc, 0x3b, - 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03}; diff --git a/shell/linux-deps/include/X11/bitmaps/cross_weave b/shell/linux-deps/include/X11/bitmaps/cross_weave deleted file mode 100644 index 40de9e426..000000000 --- a/shell/linux-deps/include/X11/bitmaps/cross_weave +++ /dev/null @@ -1,6 +0,0 @@ -#define cross_weave_width 16 -#define cross_weave_height 16 -static char cross_weave_bits[] = { - 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88, - 0x55, 0x55, 0x22, 0x22, 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22, - 0x55, 0x55, 0x88, 0x88, 0x55, 0x55, 0x22, 0x22}; diff --git a/shell/linux-deps/include/X11/bitmaps/dimple1 b/shell/linux-deps/include/X11/bitmaps/dimple1 deleted file mode 100644 index 9144605a8..000000000 --- a/shell/linux-deps/include/X11/bitmaps/dimple1 +++ /dev/null @@ -1,6 +0,0 @@ -#define dimple1_width 16 -#define dimple1_height 16 -static char dimple1_bits[] = { - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/dimple3 b/shell/linux-deps/include/X11/bitmaps/dimple3 deleted file mode 100644 index 209b4e8b2..000000000 --- a/shell/linux-deps/include/X11/bitmaps/dimple3 +++ /dev/null @@ -1,6 +0,0 @@ -#define dimple3_width 16 -#define dimple3_height 16 -static char dimple3_bits[] = { - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/dot b/shell/linux-deps/include/X11/bitmaps/dot deleted file mode 100644 index e403eebe9..000000000 --- a/shell/linux-deps/include/X11/bitmaps/dot +++ /dev/null @@ -1,6 +0,0 @@ -#define dot_width 16 -#define dot_height 16 -static char dot_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xf0, 0x0f, 0xf0, 0x0f, - 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xf0, 0x0f, - 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/dropbar7 b/shell/linux-deps/include/X11/bitmaps/dropbar7 deleted file mode 100644 index 26893009b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/dropbar7 +++ /dev/null @@ -1,4 +0,0 @@ -#define bar7_width 7 -#define bar7_height 7 -static char bar7_bits[] = { - 0x00, 0x3f, 0x61, 0x61, 0x7f, 0x7e, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/dropbar8 b/shell/linux-deps/include/X11/bitmaps/dropbar8 deleted file mode 100644 index d7cfdeb9a..000000000 --- a/shell/linux-deps/include/X11/bitmaps/dropbar8 +++ /dev/null @@ -1,4 +0,0 @@ -#define dropbar8_width 8 -#define dropbar8_height 8 -static char dropbar8_bits[] = { - 0x00, 0x7f, 0xc1, 0xc1, 0xc1, 0xff, 0xfe, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/escherknot b/shell/linux-deps/include/X11/bitmaps/escherknot deleted file mode 100644 index 80bc471b2..000000000 --- a/shell/linux-deps/include/X11/bitmaps/escherknot +++ /dev/null @@ -1,473 +0,0 @@ -#define escherknot_width 216 -#define escherknot_height 208 - -static char escherknot_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x5f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x6f, 0xf6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xff, 0x3a, 0x13, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, 0x02, 0x51, 0x71, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2f, 0x20, 0xd9, 0x88, - 0x9b, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, - 0xac, 0x44, 0x4e, 0x1c, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1e, 0x40, 0x02, 0x44, 0x60, 0xe2, 0xfc, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x25, 0x09, 0x90, 0x22, 0x13, 0xb7, 0x9a, 0x1e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x40, 0x10, 0x89, - 0x18, 0xe3, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x08, - 0x01, 0x10, 0xc8, 0xa8, 0xd5, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x80, 0x20, 0x40, 0x82, 0x00, 0x66, 0x9c, 0xec, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x08, 0x24, 0x12, 0x93, 0x5b, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x12, 0x80, 0x04, 0x01, 0x00, 0x80, - 0x19, 0x33, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x80, 0x80, 0x00, - 0x20, 0x08, 0x12, 0xc4, 0x68, 0x26, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x02, 0x04, 0x24, 0x00, 0x01, 0x40, 0x24, 0x8c, 0xcd, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x80, 0x49, 0x10, 0x90, 0x00, 0x21, 0x20, 0x08, 0x11, 0x43, 0xd9, - 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, - 0xff, 0xff, 0x0b, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x30, 0xb9, 0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x97, 0x04, 0x08, 0xfe, 0x05, 0x30, 0x10, 0x12, 0x20, 0x20, - 0x04, 0x00, 0x80, 0x48, 0x0c, 0xa3, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3e, 0x92, 0x20, 0x49, 0x40, 0x3e, 0x0e, 0x82, - 0x00, 0x84, 0x25, 0x01, 0x80, 0x00, 0x80, 0xc8, 0x34, 0xed, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x01, 0x04, 0x01, 0x08, - 0xd0, 0x17, 0x00, 0x80, 0x25, 0x01, 0xad, 0x04, 0x12, 0x20, 0x23, 0x4c, - 0x6a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x48, - 0x92, 0x20, 0x41, 0x92, 0x9e, 0x80, 0x24, 0x24, 0x29, 0x00, 0x04, 0x00, - 0x10, 0x98, 0xcc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x4f, 0x10, 0x01, 0x90, 0x24, 0x40, 0x12, 0xf0, 0x00, 0x24, 0x41, 0x0b, - 0xa9, 0x10, 0x00, 0x00, 0x04, 0xd9, 0x96, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x00, 0x92, 0x48, 0x02, 0x04, 0x09, 0xc0, 0x84, 0x8f, - 0x29, 0x2d, 0xf8, 0xa9, 0x02, 0x00, 0x00, 0x20, 0x90, 0xf4, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x24, 0x91, 0x04, 0x50, 0x22, 0x24, - 0x1b, 0x12, 0x7a, 0x48, 0xca, 0x03, 0x21, 0x10, 0x00, 0x00, 0x48, 0x93, - 0xff, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x24, 0x92, 0x20, - 0x81, 0xda, 0x24, 0xc8, 0x16, 0xd0, 0xe7, 0x50, 0xd2, 0xbf, 0x03, 0x00, - 0x80, 0x00, 0x30, 0x29, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, - 0x20, 0x80, 0x24, 0x41, 0x12, 0x2a, 0x41, 0xb2, 0x80, 0x33, 0x0e, 0x7e, - 0x88, 0x1c, 0x01, 0x00, 0xa0, 0x24, 0x69, 0x75, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x82, 0x44, 0x11, 0x24, 0x09, 0x90, 0xa4, 0x4d, 0xd2, 0x92, - 0x9e, 0xd3, 0x83, 0x6b, 0x62, 0x00, 0x00, 0x10, 0x22, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x42, 0x04, 0x92, 0x24, 0x6b, 0x53, 0x32, - 0x59, 0x90, 0x16, 0xfa, 0xb4, 0xf4, 0xff, 0x0f, 0x01, 0x00, 0x90, 0x68, - 0x4a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x90, 0x24, 0x11, 0x24, - 0x49, 0xda, 0x82, 0xc5, 0x92, 0xd2, 0xd0, 0x9e, 0x1e, 0x00, 0x78, 0x0a, - 0x00, 0x00, 0x05, 0xd2, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x02, - 0x44, 0xb2, 0x65, 0xea, 0x49, 0x9e, 0x2c, 0x4b, 0x1a, 0xd2, 0xeb, 0xe3, - 0xff, 0xc7, 0x09, 0x00, 0x20, 0x68, 0xff, 0xd6, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x0b, 0x90, 0x40, 0x92, 0x24, 0x09, 0x5f, 0xd2, 0x64, 0x59, 0x72, - 0x56, 0x7f, 0xfd, 0xdf, 0x1f, 0x12, 0x00, 0x20, 0x49, 0x92, 0xde, 0x01, - 0x00, 0x00, 0x00, 0x80, 0x41, 0x92, 0x4c, 0x92, 0x24, 0x25, 0xc9, 0x8b, - 0x2e, 0xcb, 0x92, 0x4b, 0x5a, 0x2f, 0x75, 0xf4, 0x04, 0x00, 0x00, 0x41, - 0xf6, 0x74, 0x01, 0x00, 0x00, 0x00, 0x40, 0x49, 0x02, 0x00, 0xba, 0xb6, - 0xfd, 0x49, 0xf8, 0x74, 0x6d, 0x4b, 0x72, 0xed, 0xdb, 0xff, 0xcf, 0x53, - 0x00, 0x00, 0x48, 0xb6, 0xd7, 0x03, 0x00, 0x00, 0x00, 0x60, 0x48, 0x10, - 0xc9, 0x93, 0x24, 0x00, 0x7b, 0xc3, 0xa6, 0x69, 0x58, 0x5a, 0xfb, 0xfa, - 0xa5, 0xbe, 0x16, 0x00, 0x00, 0x92, 0xa4, 0xfd, 0x03, 0x00, 0x00, 0x00, - 0x30, 0x01, 0x20, 0x5d, 0xa2, 0xfe, 0x7f, 0x01, 0x4f, 0x1a, 0xcd, 0x6b, - 0x6a, 0xa9, 0x5f, 0xff, 0xf3, 0x24, 0x01, 0x40, 0xc0, 0xb4, 0xf4, 0x03, - 0x00, 0x00, 0x00, 0x2c, 0x88, 0x84, 0x89, 0xb6, 0x00, 0x24, 0x7d, 0x69, - 0xf2, 0x34, 0xad, 0x99, 0x2d, 0xf7, 0xff, 0x9f, 0x4b, 0x00, 0x00, 0x92, - 0xa6, 0xad, 0x07, 0x00, 0x00, 0x00, 0x06, 0x91, 0x24, 0xe9, 0xa4, 0xfd, - 0xa5, 0xa9, 0x4b, 0x93, 0xe7, 0x34, 0x63, 0xf9, 0xfc, 0xd5, 0xef, 0x16, - 0x00, 0x40, 0x90, 0xb4, 0xbd, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x80, 0x4c, - 0x96, 0xbe, 0x2d, 0xfd, 0x2f, 0x7c, 0x5e, 0x9c, 0x67, 0xad, 0xa5, 0xfd, - 0xff, 0xbf, 0x29, 0x00, 0x00, 0x92, 0x76, 0xed, 0x06, 0x00, 0x00, 0x00, - 0x05, 0x12, 0x48, 0x53, 0x25, 0x65, 0x25, 0xf4, 0xe5, 0xd3, 0x72, 0x9c, - 0x35, 0xdf, 0xf6, 0x7f, 0xf5, 0x56, 0x00, 0x00, 0x92, 0xa4, 0xed, 0x0f, - 0x00, 0x00, 0x80, 0x49, 0x20, 0x59, 0x38, 0xec, 0xff, 0xff, 0xad, 0x2f, - 0x5d, 0xd3, 0x33, 0xe6, 0x24, 0xed, 0xff, 0xdf, 0x2d, 0x01, 0x40, 0x80, - 0x24, 0xbd, 0x07, 0x00, 0x00, 0xc0, 0x48, 0x24, 0x49, 0x87, 0x37, 0x21, - 0xa0, 0xbd, 0xf4, 0x79, 0x4f, 0xc7, 0x9c, 0xde, 0xf6, 0xff, 0xff, 0x5b, - 0x08, 0x00, 0x92, 0xfc, 0xe9, 0x0e, 0x00, 0x00, 0x20, 0x89, 0x40, 0xd3, - 0xf4, 0x49, 0xff, 0xff, 0xe7, 0x2f, 0xcf, 0x79, 0x9c, 0x53, 0xb2, 0x35, - 0xff, 0xff, 0x37, 0x00, 0x40, 0x90, 0x24, 0xef, 0x0e, 0x00, 0x00, 0x30, - 0x91, 0x49, 0x32, 0x2d, 0xff, 0x6b, 0xb7, 0xbd, 0xbc, 0x3c, 0xef, 0x79, - 0xce, 0xde, 0xd6, 0xfd, 0xff, 0x9f, 0x00, 0x00, 0x92, 0xa6, 0xad, 0x0b, - 0x00, 0x00, 0x30, 0x11, 0x89, 0x8c, 0xcb, 0x5b, 0xba, 0xaf, 0xf6, 0xd7, - 0xe7, 0x35, 0xe7, 0x59, 0xb3, 0xfb, 0xff, 0xff, 0x7f, 0x04, 0x40, 0x80, - 0xe4, 0xb9, 0x1f, 0x00, 0x00, 0x48, 0x22, 0x91, 0x66, 0x79, 0xeb, 0xff, - 0xff, 0xdf, 0xbe, 0xbe, 0xe7, 0x8c, 0x75, 0x6b, 0x4a, 0xfa, 0xbf, 0x7f, - 0x00, 0x00, 0x82, 0x24, 0xef, 0x0e, 0x00, 0x00, 0x4c, 0x22, 0xb2, 0x79, - 0x5e, 0xfa, 0x5b, 0xa9, 0xfd, 0xeb, 0xf5, 0x9c, 0x3d, 0xc6, 0xcc, 0xee, - 0xed, 0x01, 0xf8, 0x00, 0x40, 0x82, 0xb6, 0xa9, 0x1b, 0x00, 0x00, 0x94, - 0x64, 0x66, 0x8e, 0xd3, 0x97, 0xfe, 0xff, 0xd7, 0xdf, 0x9f, 0x7b, 0xf3, - 0x3c, 0x35, 0x59, 0x6b, 0x00, 0x70, 0x00, 0x00, 0x40, 0xe4, 0xed, 0x1e, - 0x00, 0x00, 0x92, 0xc4, 0x34, 0xf3, 0xfc, 0xfd, 0x5f, 0xad, 0x7d, 0xfa, - 0x7a, 0xce, 0x8e, 0xb3, 0x76, 0x2f, 0xfd, 0x00, 0xe0, 0x04, 0x00, 0x9a, - 0x26, 0xaf, 0x1e, 0x00, 0x00, 0x13, 0x88, 0xcc, 0xb5, 0x3f, 0xbf, 0xff, - 0xff, 0xd7, 0xef, 0xef, 0xbd, 0x79, 0x6a, 0xde, 0xec, 0xab, 0x01, 0xc0, - 0x00, 0x00, 0x40, 0xb6, 0xbd, 0x1b, 0x00, 0x00, 0x05, 0x91, 0xeb, 0x5c, - 0xeb, 0xeb, 0xff, 0xff, 0xff, 0x7e, 0xef, 0x6b, 0xef, 0xcd, 0x99, 0xb3, - 0xe4, 0x07, 0x80, 0x00, 0x40, 0x49, 0xb2, 0xe5, 0x1a, 0x00, 0x80, 0x20, - 0x32, 0xb1, 0xe7, 0x79, 0x7f, 0xf7, 0xff, 0xfd, 0xeb, 0xbd, 0xfe, 0x2c, - 0x3d, 0x6b, 0xb6, 0xaf, 0x06, 0x80, 0x00, 0x00, 0x41, 0x96, 0xfe, 0x1e, - 0x00, 0x80, 0x44, 0xb2, 0x9b, 0xf9, 0xde, 0xff, 0xff, 0xff, 0x7f, 0xbf, - 0xf7, 0xbb, 0xb3, 0x77, 0xce, 0xce, 0xb6, 0x0d, 0x80, 0x01, 0x00, 0x49, - 0xf2, 0x94, 0x1f, 0x00, 0x40, 0x49, 0x44, 0xe6, 0x9e, 0x77, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xbf, 0xf7, 0x7e, 0xd6, 0xbc, 0xd9, 0xba, 0x3b, 0x80, - 0x00, 0x00, 0x64, 0x93, 0xf7, 0x1b, 0x00, 0x40, 0x89, 0xec, 0x7e, 0x67, - 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xdb, 0x99, 0x33, 0x37, - 0xd3, 0x36, 0x80, 0x01, 0x80, 0x24, 0xda, 0xd6, 0x1e, 0x00, 0x20, 0x90, - 0x99, 0x99, 0x7b, 0xef, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xef, 0xbd, 0x37, - 0x63, 0xf3, 0x66, 0xdb, 0x7a, 0x80, 0x00, 0x00, 0x24, 0x59, 0xde, 0x1f, - 0x00, 0x60, 0x12, 0xb3, 0xf7, 0xdd, 0xfb, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xbf, 0xf7, 0xfe, 0x6e, 0xce, 0xdd, 0x6d, 0xd7, 0x80, 0x00, 0x80, 0x20, - 0xcb, 0xfb, 0x1f, 0x00, 0x10, 0x20, 0x6e, 0x66, 0x76, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xef, 0xde, 0xdb, 0x9b, 0x99, 0xb3, 0x5d, 0x6b, 0x81, - 0x00, 0x40, 0x96, 0x59, 0x6a, 0x1f, 0x00, 0x98, 0xc4, 0xe4, 0xdf, 0xff, - 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x6f, 0x7b, 0x37, 0x7f, - 0xb3, 0xdd, 0x83, 0x00, 0x00, 0xb0, 0xed, 0xef, 0x1d, 0x00, 0x10, 0x88, - 0x9e, 0xdd, 0xcd, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xed, - 0x6c, 0xe6, 0xcc, 0x76, 0x6d, 0xc1, 0x00, 0x40, 0x91, 0x24, 0x7b, 0x1f, - 0x00, 0x08, 0xd1, 0xf1, 0x66, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xdf, 0xbd, 0xbf, 0xd9, 0xdd, 0xdd, 0xb6, 0x47, 0x00, 0x00, 0xd8, - 0xb4, 0xad, 0x1f, 0x00, 0x24, 0x24, 0x6f, 0xf6, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xb7, 0x9d, 0x33, 0xd9, 0x96, 0x4e, - 0x00, 0x20, 0x49, 0xf7, 0xfd, 0x1e, 0x00, 0x48, 0xe4, 0xac, 0xb9, 0xdd, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xdd, 0x76, 0xb6, - 0xb7, 0xfd, 0x7a, 0x00, 0x00, 0x44, 0x96, 0xb7, 0x1f, 0x00, 0x02, 0x9a, - 0xbe, 0x6f, 0x77, 0xff, 0xff, 0x7f, 0x61, 0xd9, 0xff, 0xff, 0xff, 0xfd, - 0xdd, 0x66, 0xed, 0x66, 0x5b, 0x37, 0x00, 0x90, 0x64, 0xb9, 0xf6, 0x1f, - 0x00, 0x02, 0xc9, 0xf3, 0xee, 0xfd, 0xff, 0xff, 0x2f, 0x24, 0x4f, 0xfe, - 0xff, 0xff, 0x7f, 0x37, 0xdb, 0xcd, 0x7c, 0xff, 0x3a, 0x00, 0x88, 0x24, - 0xdb, 0xde, 0x1a, 0x00, 0x13, 0x31, 0x6f, 0xbb, 0xdf, 0xff, 0xff, 0x21, - 0xa0, 0x64, 0xf3, 0xff, 0xff, 0xe7, 0xff, 0x96, 0xbb, 0x9b, 0xa5, 0x1d, - 0x00, 0x60, 0x32, 0xe9, 0xdb, 0x0f, 0x00, 0x65, 0xe6, 0x3c, 0xfb, 0xf6, - 0xff, 0x7f, 0x10, 0xa4, 0xb5, 0x9d, 0xfe, 0xdf, 0xdf, 0xdd, 0x6d, 0x32, - 0xb3, 0x7d, 0x0d, 0x00, 0x0b, 0x93, 0x7c, 0x7b, 0x0f, 0x00, 0x89, 0xdc, - 0xb3, 0xed, 0xfb, 0xff, 0x1f, 0x10, 0x90, 0x92, 0xd9, 0xfe, 0x7f, 0xff, - 0x77, 0xdb, 0xee, 0x6e, 0xdb, 0x0e, 0x00, 0x20, 0xdd, 0x66, 0x6f, 0x0f, - 0x80, 0x91, 0x5a, 0xfb, 0xbe, 0xef, 0xff, 0x0f, 0x10, 0xda, 0x92, 0xee, - 0xff, 0xff, 0xff, 0xf7, 0xb7, 0xcd, 0xee, 0xde, 0x07, 0x00, 0x24, 0x49, - 0xb6, 0xed, 0x0f, 0x00, 0x12, 0x6b, 0xcd, 0xf3, 0xbe, 0xff, 0x07, 0x08, - 0x48, 0xda, 0x76, 0xb7, 0xff, 0xff, 0xdd, 0x6e, 0xba, 0x99, 0x65, 0x03, - 0x40, 0x92, 0xe4, 0xba, 0xbd, 0x0e, 0x80, 0x62, 0xed, 0x7d, 0x5f, 0xf7, - 0xff, 0x01, 0x08, 0x28, 0xc9, 0x26, 0xbb, 0xff, 0xff, 0xff, 0x99, 0xb7, - 0xbb, 0x7d, 0x03, 0x00, 0x89, 0x64, 0xdb, 0xf6, 0x07, 0x40, 0x0c, 0x35, - 0xe7, 0x79, 0xdd, 0xff, 0x01, 0x84, 0xa5, 0x7d, 0xba, 0xdd, 0xfe, 0x7f, - 0xbf, 0xbf, 0x6d, 0x76, 0xdb, 0x01, 0x00, 0x48, 0x36, 0xdb, 0xd6, 0x07, - 0xc0, 0x88, 0xb4, 0xb6, 0xbf, 0xff, 0x7f, 0x00, 0x0c, 0x24, 0x44, 0xdb, - 0xed, 0xff, 0xdf, 0xef, 0x6e, 0xdb, 0x6e, 0xb7, 0x00, 0x80, 0x44, 0x93, - 0xed, 0x5b, 0x07, 0x40, 0x91, 0xd2, 0xfa, 0xfc, 0xf6, 0x7f, 0x00, 0x02, - 0xb4, 0x35, 0xd9, 0xef, 0xff, 0xff, 0xfb, 0xef, 0xb6, 0xc9, 0xe4, 0x00, - 0x10, 0x24, 0xd9, 0x6d, 0xfb, 0x03, 0x00, 0x27, 0xfe, 0xd3, 0xd6, 0xdb, - 0x3f, 0x00, 0xa2, 0x94, 0xb4, 0xdb, 0x7c, 0xff, 0xff, 0xbf, 0xd9, 0xad, - 0xdb, 0x7d, 0x00, 0x40, 0x32, 0xd9, 0xb6, 0xef, 0x03, 0x60, 0xe4, 0x5a, - 0x5f, 0x5f, 0xff, 0x1f, 0x00, 0x02, 0x52, 0x92, 0xec, 0xb6, 0xff, 0xff, - 0xef, 0xff, 0x6d, 0xb6, 0x3b, 0x00, 0x28, 0x90, 0xcc, 0xbe, 0xfd, 0x03, - 0xa0, 0x88, 0xeb, 0xf9, 0xfd, 0xf5, 0x1f, 0x00, 0x82, 0x53, 0xbb, 0x6d, - 0xf7, 0xff, 0xf9, 0xff, 0x6f, 0xdb, 0x6d, 0x1b, 0x00, 0x04, 0xc9, 0x66, - 0xdb, 0x57, 0x03, 0xa0, 0x52, 0xaf, 0xa7, 0x97, 0xff, 0x0f, 0x00, 0x51, - 0x48, 0xda, 0x66, 0xdb, 0xff, 0xf8, 0xdf, 0xed, 0xbe, 0xed, 0x0e, 0x00, - 0x92, 0x64, 0x32, 0xeb, 0xf6, 0x01, 0x20, 0x63, 0xbd, 0xbc, 0xfc, 0xfa, - 0x0f, 0x00, 0x09, 0x20, 0x89, 0x3e, 0xff, 0xff, 0xe0, 0x7f, 0xdf, 0x6f, - 0xdb, 0x07, 0x00, 0x01, 0x24, 0xbb, 0xed, 0xfe, 0x01, 0xa0, 0xce, 0xf5, - 0xf6, 0xdb, 0xdf, 0x07, 0x00, 0x41, 0xad, 0x5f, 0xf2, 0xed, 0xff, 0xc0, - 0xff, 0xbf, 0xdd, 0x92, 0x03, 0x00, 0x44, 0xb2, 0xd9, 0x7d, 0xfb, 0x01, - 0xe0, 0xaa, 0xdf, 0x9b, 0x7f, 0xfb, 0x07, 0x80, 0x28, 0x21, 0x64, 0xbb, - 0x7f, 0x7f, 0x80, 0xff, 0xf6, 0xbb, 0xee, 0x03, 0x80, 0x22, 0x99, 0xed, - 0xb6, 0xff, 0x00, 0x90, 0xb8, 0x5e, 0x5b, 0x6b, 0xed, 0x03, 0x00, 0x01, - 0xa6, 0x6d, 0xdb, 0xf6, 0x7f, 0x00, 0xff, 0xff, 0xf6, 0xcd, 0x00, 0x40, - 0x10, 0xc9, 0x6c, 0xff, 0xf7, 0x00, 0xa0, 0xe3, 0x72, 0xeb, 0xef, 0xff, - 0x03, 0x80, 0xe0, 0x90, 0x24, 0xdb, 0xbd, 0x3f, 0x00, 0xfe, 0xdb, 0x6f, - 0xfb, 0x00, 0x00, 0x89, 0x4c, 0xb6, 0xd9, 0x7e, 0x00, 0x70, 0xaf, 0xaf, - 0x6f, 0xb5, 0xde, 0x03, 0x80, 0x94, 0x92, 0xb6, 0xf9, 0xf6, 0x3f, 0x00, - 0xfc, 0xbf, 0xdd, 0x7b, 0x00, 0x10, 0x48, 0x26, 0xb3, 0xdf, 0x7f, 0x00, - 0x70, 0xd8, 0xae, 0xfd, 0xff, 0xf7, 0x03, 0x80, 0x00, 0xd2, 0x36, 0xcf, - 0xdf, 0x3f, 0x00, 0xb8, 0x6d, 0xdf, 0x16, 0x00, 0x48, 0x44, 0xb2, 0xfb, - 0x6c, 0x3f, 0x00, 0x50, 0x75, 0xfd, 0xa5, 0xd5, 0xfe, 0x01, 0x40, 0xd1, - 0x12, 0xa2, 0x7d, 0xfb, 0x1f, 0x00, 0xf0, 0xff, 0xbf, 0x0d, 0x00, 0x20, - 0x12, 0x9b, 0xcd, 0xf6, 0x3f, 0x00, 0x90, 0xd5, 0xa7, 0xfd, 0x77, 0xab, - 0x03, 0x40, 0x1c, 0xc8, 0xbe, 0x6d, 0xfb, 0x1f, 0x00, 0xe0, 0xff, 0xee, - 0x07, 0x00, 0x04, 0x91, 0xc9, 0x7e, 0xbf, 0x1f, 0x00, 0x30, 0x57, 0xbf, - 0xa6, 0xde, 0xfd, 0x01, 0x40, 0x40, 0x6b, 0xd3, 0x6e, 0xef, 0x0f, 0x00, - 0xc0, 0xeb, 0x7d, 0x03, 0x00, 0x90, 0xc8, 0x6c, 0x76, 0xfb, 0x0f, 0x00, - 0x70, 0x5c, 0xe5, 0xf7, 0xfa, 0xeb, 0x01, 0x40, 0x50, 0x49, 0x92, 0xf4, - 0xfd, 0x0f, 0x00, 0xc0, 0xff, 0xdb, 0x01, 0x80, 0x44, 0x44, 0x66, 0xbb, - 0x6f, 0x0f, 0x00, 0xd0, 0xf1, 0x95, 0xf6, 0x6f, 0xad, 0x01, 0x40, 0x08, - 0x78, 0xdb, 0xb6, 0xef, 0x0f, 0x00, 0x00, 0xdf, 0xd6, 0x00, 0x00, 0x20, - 0x32, 0xb3, 0xdb, 0xfd, 0x0f, 0x00, 0x10, 0xd7, 0xf7, 0xb6, 0xd8, 0xeb, - 0x03, 0x20, 0x43, 0x27, 0xd9, 0xb6, 0xfd, 0x0f, 0x00, 0x00, 0xff, 0x7e, - 0x00, 0x40, 0x12, 0x93, 0xd9, 0xec, 0xb6, 0x07, 0x00, 0x70, 0x55, 0xdd, - 0xf6, 0x6f, 0xbb, 0x01, 0x40, 0x28, 0xa1, 0x6f, 0xb6, 0xb7, 0x0f, 0x00, - 0x00, 0xde, 0x1f, 0x00, 0x80, 0x88, 0xd8, 0xcc, 0x66, 0xff, 0x03, 0x00, - 0x70, 0xf4, 0xf5, 0xdb, 0xaa, 0xee, 0x01, 0x60, 0x28, 0x2d, 0x49, 0xf7, - 0xf6, 0x07, 0x00, 0x00, 0x7c, 0x0f, 0x00, 0x08, 0x48, 0x66, 0x6e, 0xfb, - 0xef, 0x03, 0x00, 0xd0, 0xd5, 0xdf, 0x52, 0xff, 0xda, 0x03, 0x20, 0xa3, - 0xa5, 0xd9, 0xb2, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x20, 0x22, - 0x33, 0x37, 0xbf, 0xfd, 0x01, 0x00, 0x70, 0x5f, 0xf7, 0xfe, 0xab, 0x6b, - 0x02, 0xa0, 0xa8, 0xb4, 0x6d, 0xdf, 0xf6, 0x07, 0x00, 0x00, 0xf8, 0x01, - 0x00, 0x12, 0x33, 0x11, 0xd9, 0xdd, 0xff, 0x01, 0x00, 0x70, 0x75, 0xd5, - 0x52, 0xea, 0x8a, 0x03, 0x20, 0x84, 0x36, 0x69, 0xba, 0xdb, 0x07, 0x00, - 0x00, 0xf0, 0x01, 0x00, 0x81, 0xc8, 0xcc, 0xdd, 0xed, 0xff, 0x00, 0x00, - 0x60, 0xd5, 0xdf, 0xf6, 0xae, 0x6b, 0x03, 0x00, 0xa1, 0xa4, 0x6d, 0xdf, - 0xfe, 0x07, 0x00, 0x00, 0x60, 0x00, 0x40, 0x44, 0xc6, 0xcc, 0x64, 0xb7, - 0xfd, 0x00, 0x00, 0xe0, 0x55, 0xf7, 0xd6, 0xea, 0xba, 0x07, 0x20, 0x94, - 0x94, 0x6d, 0xfb, 0xdb, 0x07, 0x00, 0x00, 0x20, 0x00, 0x20, 0x20, 0x32, - 0x76, 0x77, 0xff, 0x7f, 0x00, 0x00, 0x60, 0x7d, 0xd5, 0xb6, 0x3f, 0xaf, - 0x06, 0xa0, 0xa4, 0x95, 0x6c, 0x9b, 0xee, 0x07, 0x00, 0x00, 0x18, 0x00, - 0x10, 0x92, 0x15, 0x73, 0xbb, 0xd9, 0x3f, 0x00, 0x00, 0xe0, 0xf5, 0xff, - 0xf7, 0x6a, 0xa9, 0x06, 0x80, 0xa2, 0xb4, 0x6d, 0xfb, 0xfb, 0x07, 0x00, - 0x00, 0x04, 0x00, 0x84, 0x88, 0xc8, 0x99, 0xdd, 0xff, 0x3f, 0x00, 0x00, - 0xe0, 0x8b, 0xff, 0x96, 0x6a, 0xb6, 0x0a, 0xa0, 0x94, 0x96, 0x64, 0xdb, - 0xee, 0x07, 0x00, 0x00, 0x03, 0x08, 0x20, 0x60, 0x66, 0xec, 0xee, 0xb6, - 0x1d, 0x00, 0x00, 0xc0, 0x7e, 0xa5, 0xf4, 0xab, 0x55, 0x0d, 0x20, 0xe7, - 0xd4, 0x6d, 0xdb, 0xfb, 0x07, 0x00, 0x80, 0x00, 0x00, 0x09, 0x12, 0x33, - 0x67, 0x77, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xfa, 0xff, 0xb7, 0x7a, 0x55, - 0x19, 0x90, 0x91, 0xd4, 0x64, 0xdb, 0xee, 0x07, 0x00, 0x40, 0x00, 0x81, - 0x04, 0x88, 0x91, 0x3b, 0xbb, 0xfd, 0x0f, 0x00, 0x00, 0xc0, 0xab, 0xbf, - 0xed, 0x4e, 0xbb, 0x32, 0x20, 0x94, 0x96, 0x6c, 0xff, 0xfa, 0x03, 0x00, - 0x30, 0x40, 0x20, 0x20, 0x64, 0xcc, 0xdc, 0xdd, 0xff, 0x07, 0x00, 0x00, - 0xc0, 0xeb, 0xea, 0xfd, 0xd5, 0xaa, 0x2a, 0x20, 0xd7, 0xb0, 0x6d, 0x93, - 0xef, 0x07, 0x00, 0x08, 0x00, 0x08, 0x01, 0x23, 0xee, 0xee, 0xee, 0xfb, - 0x03, 0x00, 0x00, 0xc0, 0xfe, 0xff, 0x2d, 0xdd, 0x6a, 0x49, 0xd0, 0x90, - 0x9a, 0x64, 0xdf, 0xea, 0x07, 0x00, 0x03, 0x80, 0x40, 0x8c, 0x98, 0x33, - 0xb3, 0xbb, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xa5, 0x7b, 0x6d, 0xa7, 0x56, - 0xc5, 0xa0, 0x94, 0x94, 0x6f, 0xd3, 0xbb, 0x07, 0x80, 0x10, 0x0c, 0x12, - 0x40, 0xc6, 0xb9, 0xdb, 0xfb, 0xfd, 0x01, 0x00, 0x00, 0x80, 0x97, 0xee, - 0xdf, 0xba, 0x54, 0x1a, 0xa1, 0xe5, 0xd2, 0x64, 0x7e, 0xee, 0x07, 0x60, - 0x02, 0x80, 0x00, 0x31, 0x62, 0xcc, 0xdc, 0xee, 0x7f, 0x00, 0x00, 0x00, - 0x80, 0xff, 0xff, 0xdb, 0xaa, 0xb5, 0x8a, 0x86, 0x98, 0x96, 0x6d, 0x9b, - 0xea, 0x07, 0x98, 0x00, 0x22, 0x44, 0x88, 0x39, 0x77, 0x77, 0xff, 0x7f, - 0x00, 0x00, 0x00, 0x80, 0x7d, 0x77, 0xba, 0x7b, 0x2d, 0x55, 0x3c, 0xa6, - 0xb4, 0x6c, 0xf6, 0xaf, 0x07, 0x07, 0x90, 0x88, 0x20, 0x42, 0x9c, 0xbb, - 0xbb, 0xbb, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xbd, 0xbf, 0x55, 0x53, - 0xa5, 0xb2, 0xa1, 0xb4, 0xc9, 0x9f, 0xda, 0xcf, 0x28, 0x24, 0x42, 0x08, - 0x31, 0xe6, 0xcc, 0xdd, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, - 0xb7, 0xbd, 0xde, 0x12, 0xd1, 0xac, 0x95, 0x4d, 0xf2, 0x56, 0x9f, 0x88, - 0x80, 0x10, 0xc2, 0x9c, 0x73, 0x77, 0xef, 0xfe, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0xbf, 0xfb, 0xed, 0xeb, 0x35, 0x95, 0x72, 0xa2, 0x35, 0xcd, 0xb6, - 0xd6, 0x2f, 0x21, 0x24, 0x04, 0x31, 0xc6, 0x98, 0x33, 0xf7, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xd6, 0x6a, 0x7f, 0x5b, 0xab, 0x2d, 0x28, 0x23, - 0x65, 0xd9, 0xb6, 0x55, 0x5f, 0x88, 0x08, 0x43, 0x0c, 0x61, 0xde, 0xdd, - 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0x4d, 0xd7, 0x4d, - 0x4a, 0xa5, 0x29, 0x2d, 0xdb, 0xbe, 0x55, 0x1f, 0x22, 0x42, 0x28, 0xc2, - 0x39, 0xe7, 0xee, 0xee, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x7f, - 0xfb, 0xb6, 0xb6, 0x95, 0x70, 0x2e, 0xa5, 0xd9, 0x24, 0x5d, 0x5f, 0x8a, - 0x28, 0x88, 0x31, 0x9e, 0x39, 0x73, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0xec, 0xb7, 0xdf, 0x6c, 0xb5, 0x65, 0x26, 0xa3, 0x39, 0x9b, 0xfc, - 0x85, 0x5d, 0x21, 0x04, 0x63, 0x1c, 0xe6, 0xdd, 0xbd, 0xfb, 0xff, 0xff, - 0x01, 0x00, 0x00, 0x00, 0xb8, 0xfa, 0xb6, 0x6f, 0x4d, 0x9a, 0x28, 0x59, - 0x4d, 0xd3, 0x2f, 0xf5, 0x3f, 0x8c, 0xd1, 0x18, 0xc6, 0x31, 0xf6, 0xdd, - 0xfe, 0xff, 0xfe, 0x01, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xef, 0xb9, 0xb6, - 0x25, 0xe1, 0x4d, 0x69, 0xba, 0x6c, 0xad, 0x3c, 0x41, 0x14, 0x84, 0xe9, - 0x9e, 0x37, 0xf7, 0xff, 0xff, 0xfb, 0x03, 0x00, 0x00, 0x00, 0x70, 0x5d, - 0x3d, 0x9f, 0x3d, 0x6d, 0x26, 0x52, 0x59, 0xb6, 0x6d, 0xab, 0x7f, 0x14, - 0x82, 0xe1, 0x39, 0xe6, 0xdd, 0xfb, 0xff, 0xbf, 0xff, 0x01, 0x00, 0x00, - 0x00, 0xf0, 0xf6, 0x6f, 0x77, 0xcd, 0x92, 0xd0, 0x52, 0x4b, 0xb3, 0x49, - 0x0b, 0x3a, 0x41, 0x61, 0x38, 0x9e, 0x73, 0xee, 0xdc, 0xff, 0xff, 0xfd, - 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xd7, 0x65, 0xda, 0x66, 0x63, 0x9d, - 0xf2, 0x36, 0x7b, 0x6a, 0x7f, 0x14, 0x18, 0x8e, 0xe7, 0xd9, 0x7b, 0xff, - 0xff, 0xef, 0xff, 0x03, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xdd, 0xb6, - 0xc9, 0x4c, 0x46, 0x9a, 0x64, 0xcb, 0x5b, 0xed, 0x06, 0xc6, 0xe3, 0x71, - 0xde, 0xbd, 0xff, 0xff, 0x7f, 0xff, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x7f, - 0x7f, 0xff, 0x59, 0x37, 0x75, 0xbb, 0x96, 0x66, 0xdb, 0x56, 0xf7, 0xe0, - 0xf2, 0x74, 0x9e, 0x77, 0xef, 0xfd, 0xff, 0xeb, 0xed, 0x03, 0x00, 0x00, - 0x00, 0xc0, 0xea, 0xdf, 0xb3, 0xdb, 0xde, 0xc6, 0x81, 0xb0, 0x6c, 0xba, - 0xb4, 0xf6, 0x38, 0x18, 0x3c, 0xe7, 0x9c, 0xfb, 0xff, 0x7f, 0xff, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xf7, 0x6e, 0x66, 0xd9, 0x99, 0xac, - 0xa4, 0xcd, 0x96, 0xa5, 0xea, 0x03, 0xa7, 0xcf, 0x79, 0xef, 0xfd, 0xff, - 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0xef, 0xdf, - 0x6f, 0xef, 0x72, 0x65, 0xd9, 0xb6, 0xad, 0xe8, 0xc1, 0xe1, 0xf1, 0xbe, - 0x7b, 0xef, 0xff, 0xdf, 0x7a, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x5f, 0xdd, 0x9d, 0xac, 0x99, 0x84, 0x29, 0xcd, 0x3c, 0x4f, 0x9d, 0x7d, - 0x3c, 0x9e, 0xe7, 0xbe, 0xff, 0xff, 0xff, 0xff, 0xef, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xff, 0x77, 0x7b, 0x33, 0xe7, 0x5a, 0x49, 0x9b, 0x65, - 0x59, 0x75, 0x07, 0x97, 0xf7, 0xbb, 0xef, 0xff, 0xff, 0xdb, 0xfe, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf7, 0x3f, 0xe7, 0xcf, 0x9c, 0x51, - 0x4d, 0xb0, 0x6d, 0x4b, 0xc9, 0xd3, 0xf5, 0x79, 0xfe, 0xfb, 0xff, 0xff, - 0xdb, 0xda, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xef, 0xde, - 0xdd, 0xf3, 0x4d, 0x52, 0x36, 0xcb, 0xd2, 0x3a, 0x7e, 0x3c, 0xde, 0xe7, - 0xbe, 0xff, 0x7f, 0xda, 0xff, 0xdf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, - 0xff, 0xfb, 0xdd, 0x73, 0x8f, 0xa5, 0x9a, 0xe6, 0xd9, 0xb6, 0xe2, 0x4e, - 0xc7, 0xf7, 0xfd, 0xff, 0xff, 0xff, 0xf7, 0xf6, 0xff, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x7f, 0xee, 0x79, 0xb2, 0xb2, 0x2c, 0x9f, - 0xb6, 0x54, 0xfe, 0xfb, 0x79, 0xbf, 0xff, 0xff, 0x5f, 0xda, 0xff, 0xfa, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xf7, 0xbf, 0xe7, 0x4b, - 0xb4, 0x69, 0xd3, 0x2c, 0x25, 0xbd, 0xbc, 0xcf, 0xf7, 0xfd, 0xff, 0xd7, - 0xf6, 0xfe, 0xdf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xbf, 0x9d, - 0xf1, 0x3e, 0x57, 0x25, 0xcb, 0xb6, 0x6d, 0xa9, 0xb5, 0xef, 0xfb, 0xff, - 0xff, 0xff, 0xd5, 0xda, 0xd6, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xff, 0xfb, 0xcf, 0xf5, 0x25, 0x65, 0xd9, 0x66, 0x5b, 0x4a, 0xfa, - 0xf9, 0x7e, 0xff, 0xff, 0xff, 0xf6, 0xd6, 0xdf, 0xfa, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xff, 0xef, 0x3e, 0xf7, 0x9f, 0x5b, 0x92, 0x6c, - 0xdb, 0x52, 0xe5, 0xbe, 0xdf, 0xff, 0xff, 0xbf, 0x51, 0xda, 0xfa, 0x7f, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7b, 0x9f, 0xe7, - 0x4c, 0xb3, 0x4d, 0xd3, 0x54, 0xd9, 0xe7, 0xfb, 0xff, 0xff, 0x5f, 0xdc, - 0xfa, 0xdf, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, - 0xe7, 0xf9, 0x3a, 0xd3, 0xa6, 0xe9, 0xb6, 0xa5, 0xca, 0xf9, 0xfd, 0xff, - 0xff, 0x83, 0x42, 0xd2, 0xff, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0xff, 0xfd, 0xbf, 0xef, 0x4f, 0xd5, 0x64, 0xdb, 0x26, 0x4d, 0x30, - 0x7f, 0xff, 0xff, 0xff, 0x91, 0xda, 0xdb, 0xda, 0xdf, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbf, 0xff, 0x7d, 0xbe, 0xb5, 0x6d, 0x97, - 0x6d, 0x93, 0x56, 0xdf, 0xff, 0xff, 0x7f, 0x81, 0x4a, 0xda, 0x7f, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xef, 0xeb, 0xbb, - 0xa6, 0x4d, 0x73, 0xcd, 0x92, 0xaa, 0xfe, 0xff, 0xff, 0x1f, 0x01, 0x6a, - 0x5b, 0xfb, 0xfb, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xfd, 0xbf, 0x5f, 0x3b, 0xdb, 0x36, 0xbb, 0x26, 0x4c, 0xf9, 0xff, 0xff, - 0x0f, 0xa3, 0x2a, 0xe9, 0x7f, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xee, 0xff, 0xff, 0xfe, 0xfe, 0xcc, 0x91, 0xec, 0x93, 0x6d, 0x93, - 0xf2, 0xff, 0xff, 0x03, 0x00, 0x6a, 0x6d, 0x6f, 0xff, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xf7, 0x6f, 0x76, 0xb6, 0xcd, - 0x76, 0xc9, 0x2a, 0xe9, 0xff, 0xff, 0x00, 0x02, 0x24, 0xed, 0xf9, 0xed, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xdf, 0xff, - 0xd9, 0x66, 0x9b, 0x6c, 0x93, 0x54, 0xc5, 0xff, 0x3f, 0x00, 0x01, 0x95, - 0xb5, 0xaf, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, - 0xff, 0xff, 0xfd, 0xae, 0x7d, 0xde, 0x6d, 0xf6, 0xa1, 0x8a, 0xff, 0x0f, - 0x00, 0x81, 0x90, 0xb4, 0xfd, 0xfd, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xcd, 0xb2, 0xdb, 0x2c, 0xcb, - 0x54, 0xfe, 0x01, 0x00, 0x01, 0xd2, 0xb6, 0xb7, 0xff, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x39, 0xdb, 0x76, - 0xb3, 0x4b, 0xb6, 0x0a, 0xfe, 0x00, 0x00, 0x01, 0x48, 0xda, 0xfe, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, - 0xcf, 0xb9, 0x6d, 0xb6, 0xd9, 0xa5, 0x75, 0x1c, 0x00, 0x80, 0x80, 0x20, - 0xdb, 0xda, 0xbe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, - 0xff, 0xff, 0xff, 0x77, 0x96, 0xd9, 0x26, 0xb3, 0x4d, 0x82, 0x11, 0x00, - 0x80, 0x80, 0x24, 0x6d, 0xff, 0xf7, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xbb, 0x67, 0xdb, 0xdd, 0x36, 0xd9, - 0x54, 0x60, 0x00, 0xc0, 0x00, 0x92, 0x65, 0x6b, 0xff, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x4f, 0x7d, 0x96, - 0xd9, 0x6c, 0x36, 0xad, 0xc2, 0x00, 0x60, 0x00, 0xc8, 0xb6, 0x6d, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, - 0xff, 0xc8, 0x76, 0xbb, 0xcb, 0x64, 0x52, 0x02, 0x03, 0x10, 0x00, 0x64, - 0xda, 0xff, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0xff, 0xff, 0x5f, 0xd7, 0x4d, 0x33, 0x99, 0xdd, 0x96, 0x04, 0x2c, - 0x1c, 0x40, 0x22, 0xdb, 0xb6, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xdf, 0xb5, 0xed, 0xe6, 0x36, 0x9b, - 0x6c, 0x29, 0xf0, 0x03, 0x00, 0x99, 0x6c, 0xfb, 0xfd, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x35, 0xbb, - 0xec, 0x76, 0x33, 0x91, 0x02, 0x00, 0x00, 0x00, 0x64, 0x67, 0xdf, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, - 0xbf, 0x6f, 0x9b, 0x9d, 0xc9, 0xce, 0x36, 0x49, 0x00, 0x00, 0x00, 0x93, - 0xb1, 0xdd, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xff, 0x6a, 0x76, 0xbb, 0xdd, 0xd9, 0x64, 0x12, 0x01, - 0x00, 0x40, 0x98, 0xdd, 0x6d, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x66, 0x73, 0x33, 0xbb, - 0x9d, 0x4d, 0x00, 0x00, 0x00, 0x63, 0xe6, 0xf6, 0xff, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xed, 0xfd, - 0xee, 0xee, 0x36, 0x73, 0x2b, 0x04, 0x00, 0xa0, 0x38, 0x75, 0xbf, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0xd9, 0xec, 0xce, 0x66, 0x66, 0x66, 0x22, 0x04, 0x00, 0xc6, - 0x99, 0xbb, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5e, 0xb3, 0xdb, 0xb9, 0xcd, 0xc9, 0x88, 0x89, - 0x00, 0x68, 0x31, 0xee, 0xdd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xbe, 0xbb, 0x9b, 0x3f, - 0xbb, 0x33, 0x23, 0x04, 0x00, 0x8c, 0xf3, 0xee, 0xff, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x67, - 0x76, 0x77, 0xb2, 0x66, 0xce, 0x0c, 0xd1, 0xd6, 0xe3, 0x79, 0xf7, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xfd, 0xef, 0xe6, 0xee, 0xce, 0x9c, 0x31, 0x16, 0x00, 0x3c, - 0x9e, 0xfb, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x9f, 0xdb, 0xdc, 0x9d, 0x99, 0x33, 0xc6, - 0xc1, 0xff, 0x8f, 0xe7, 0xbb, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf7, 0xbd, 0xbb, 0x33, - 0x7b, 0xee, 0x18, 0x1e, 0x50, 0xf0, 0xf9, 0xfe, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7b, - 0xf7, 0x77, 0xf7, 0xe6, 0x9c, 0xe3, 0xf0, 0x4d, 0xff, 0x7c, 0xef, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xdf, 0x76, 0x7f, 0xcf, 0x9e, 0x73, 0x8f, 0x07, 0xff, 0x0b, - 0xdf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0xee, 0xcd, 0xdd, 0x9d, 0x7b, 0xf7, 0x7c, - 0x7a, 0x00, 0xf0, 0xe7, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xbf, 0xdd, 0x7b, - 0x6b, 0x9e, 0xf3, 0xe1, 0xff, 0xff, 0x7d, 0xff, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, - 0xb7, 0xbb, 0x7b, 0xee, 0x79, 0x8f, 0x0f, 0xfa, 0x2f, 0xff, 0xf7, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0x77, 0xef, 0xdd, 0x77, 0x7c, 0xfe, 0x02, 0xe8, - 0xcf, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0xee, 0xdd, 0xb3, 0xcf, 0xf3, - 0xf1, 0xff, 0xff, 0xf9, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfb, 0xff, 0xbf, - 0xef, 0xbe, 0xcf, 0x8f, 0xfe, 0x5f, 0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, - 0xbf, 0xbb, 0xf7, 0xde, 0x79, 0x3e, 0xff, 0x52, 0xd2, 0xdf, 0xff, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0xef, 0xef, 0xef, 0x3c, 0xef, 0xf9, 0xf8, 0xff, 0xff, - 0xf7, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xee, 0xdc, 0xf7, 0xfe, 0xe7, - 0x97, 0xfe, 0xff, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, - 0xef, 0xbf, 0x3e, 0xff, 0xda, 0xf6, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0xbf, 0xf7, 0xfe, 0xf7, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xff, 0xde, 0xbd, 0xef, 0xfb, 0xd7, 0xff, 0xbf, - 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xf7, 0x7d, 0xbf, - 0xff, 0xd2, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbf, - 0xef, 0xfb, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xef, 0xbe, 0xf7, 0xef, 0xef, 0xff, 0xff, 0xff, 0x3f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xdf, 0xbf, 0xff, 0xff, 0xff, - 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, - 0xfe, 0xff, 0xfb, 0xf7, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xfd, 0xff, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; diff --git a/shell/linux-deps/include/X11/bitmaps/flagdown b/shell/linux-deps/include/X11/bitmaps/flagdown deleted file mode 100644 index 55abc5182..000000000 --- a/shell/linux-deps/include/X11/bitmaps/flagdown +++ /dev/null @@ -1,27 +0,0 @@ -#define flagdown_width 48 -#define flagdown_height 48 -static char flagdown_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x80, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, - 0x00, 0x00, 0x03, 0x00, 0x06, 0x06, 0x00, 0x80, 0x01, 0x00, 0x06, 0x07, - 0x00, 0xc0, 0x1f, 0x00, 0x87, 0x07, 0x00, 0xe0, 0x7f, 0x80, 0xc7, 0x07, - 0x00, 0x70, 0xe0, 0xc0, 0xe5, 0x07, 0x00, 0x38, 0x80, 0xe1, 0x74, 0x07, - 0x00, 0x18, 0x80, 0x71, 0x3c, 0x07, 0x00, 0x0c, 0x00, 0x3b, 0x1e, 0x03, - 0x00, 0x0c, 0x00, 0x1f, 0x0f, 0x00, 0x00, 0x86, 0x1f, 0x8e, 0x07, 0x00, - 0x00, 0x06, 0x06, 0xc6, 0x05, 0x00, 0x00, 0x06, 0x00, 0xc6, 0x05, 0x00, - 0x00, 0x06, 0x00, 0xc6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, - 0x7f, 0x06, 0x00, 0x06, 0xe4, 0xff, 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, - 0x00, 0x06, 0x00, 0x06, 0x04, 0x00, 0x00, 0x06, 0x00, 0x06, 0x06, 0x00, - 0x00, 0x06, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00, - 0x00, 0x06, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3e, 0x00, 0x00, - 0x00, 0xfe, 0xff, 0x2f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x27, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, - 0xf7, 0xbf, 0x8e, 0xfc, 0xdf, 0xf8, 0x9d, 0xeb, 0x9b, 0x76, 0xd2, 0x7a, - 0x46, 0x30, 0xe2, 0x0f, 0xe1, 0x47, 0x55, 0x84, 0x48, 0x11, 0x84, 0x19}; diff --git a/shell/linux-deps/include/X11/bitmaps/flagup b/shell/linux-deps/include/X11/bitmaps/flagup deleted file mode 100644 index 6eb0d846a..000000000 --- a/shell/linux-deps/include/X11/bitmaps/flagup +++ /dev/null @@ -1,27 +0,0 @@ -#define flagup_width 48 -#define flagup_height 48 -static char flagup_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xef, 0x6a, 0x00, - 0x00, 0x00, 0xc0, 0x7b, 0x75, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x6a, 0x00, - 0x00, 0x00, 0x30, 0x60, 0x75, 0x00, 0x00, 0x00, 0x18, 0xe0, 0x7f, 0x00, - 0x00, 0x00, 0x0c, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x06, 0xe0, 0x04, 0x00, - 0x00, 0x00, 0x03, 0xe0, 0x04, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00, - 0x00, 0xc0, 0x1f, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x7f, 0xe0, 0x07, 0x00, - 0x00, 0x70, 0xe0, 0xe0, 0x05, 0x00, 0x00, 0x38, 0x80, 0xe1, 0x04, 0x00, - 0x00, 0x18, 0x80, 0xf1, 0x04, 0x00, 0x00, 0x0c, 0x00, 0xfb, 0x04, 0x00, - 0x00, 0x0c, 0x00, 0xff, 0x04, 0x00, 0x00, 0x86, 0x1f, 0xee, 0x04, 0x00, - 0x00, 0x06, 0x06, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, - 0x00, 0x06, 0x00, 0xe6, 0x04, 0x00, 0x00, 0x06, 0x00, 0x66, 0x04, 0x00, - 0x7f, 0x56, 0x52, 0x06, 0xe4, 0xff, 0x00, 0x76, 0x55, 0x06, 0x04, 0x00, - 0x00, 0x56, 0x57, 0x06, 0x04, 0x00, 0x00, 0x56, 0x55, 0x06, 0x06, 0x00, - 0x00, 0x56, 0xd5, 0x06, 0x03, 0x00, 0x00, 0x06, 0x00, 0x86, 0x01, 0x00, - 0x54, 0x06, 0x00, 0xc6, 0x54, 0x55, 0xaa, 0x06, 0x00, 0x66, 0xaa, 0x2a, - 0x54, 0x06, 0x00, 0x36, 0x55, 0x55, 0xaa, 0x06, 0x00, 0xbe, 0xaa, 0x2a, - 0x54, 0xfe, 0xff, 0x6f, 0x55, 0x55, 0xaa, 0xfc, 0xff, 0xa7, 0xaa, 0x2a, - 0x54, 0x01, 0x88, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x60, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa0, 0xaa, 0x2a, - 0x54, 0x55, 0x8d, 0x50, 0x55, 0x55, 0xaa, 0xaa, 0x8a, 0xa8, 0xaa, 0x2a, - 0x54, 0x55, 0x95, 0x54, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a, - 0x54, 0x55, 0x55, 0x55, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/flipped_gray b/shell/linux-deps/include/X11/bitmaps/flipped_gray deleted file mode 100644 index b75cacd7b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/flipped_gray +++ /dev/null @@ -1,4 +0,0 @@ -#define flipped_gray_width 4 -#define flipped_gray_height 2 -static char flipped_gray_bits[] = { - 0x07, 0x0d}; diff --git a/shell/linux-deps/include/X11/bitmaps/gray b/shell/linux-deps/include/X11/bitmaps/gray deleted file mode 100644 index dc7327e5c..000000000 --- a/shell/linux-deps/include/X11/bitmaps/gray +++ /dev/null @@ -1,4 +0,0 @@ -#define gray_width 2 -#define gray_height 2 -static char gray_bits[] = { - 0x01, 0x02}; diff --git a/shell/linux-deps/include/X11/bitmaps/gray1 b/shell/linux-deps/include/X11/bitmaps/gray1 deleted file mode 100644 index 476d93055..000000000 --- a/shell/linux-deps/include/X11/bitmaps/gray1 +++ /dev/null @@ -1,4 +0,0 @@ -#define gray1_width 2 -#define gray1_height 2 -static char gray1_bits[] = { - 0x01, 0x02}; diff --git a/shell/linux-deps/include/X11/bitmaps/gray3 b/shell/linux-deps/include/X11/bitmaps/gray3 deleted file mode 100644 index 230288478..000000000 --- a/shell/linux-deps/include/X11/bitmaps/gray3 +++ /dev/null @@ -1,4 +0,0 @@ -#define gray3_width 4 -#define gray3_height 4 -static char gray3_bits[] = { - 0x01, 0x00, 0x04, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/grid16 b/shell/linux-deps/include/X11/bitmaps/grid16 deleted file mode 100644 index edc7c735b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/grid16 +++ /dev/null @@ -1,6 +0,0 @@ -#define grid16_width 16 -#define grid16_height 16 -static char grid16_bits[] = { - 0x55, 0x55, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/grid2 b/shell/linux-deps/include/X11/bitmaps/grid2 deleted file mode 100644 index 7a021673e..000000000 --- a/shell/linux-deps/include/X11/bitmaps/grid2 +++ /dev/null @@ -1,4 +0,0 @@ -#define grid2_width 2 -#define grid2_height 2 -static char grid2_bits[] = { - 0x01, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/grid4 b/shell/linux-deps/include/X11/bitmaps/grid4 deleted file mode 100644 index 8062f40f1..000000000 --- a/shell/linux-deps/include/X11/bitmaps/grid4 +++ /dev/null @@ -1,4 +0,0 @@ -#define grid4_width 4 -#define grid4_height 4 -static char grid4_bits[] = { - 0x05, 0x00, 0x01, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/grid8 b/shell/linux-deps/include/X11/bitmaps/grid8 deleted file mode 100644 index 02ce50e5b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/grid8 +++ /dev/null @@ -1,4 +0,0 @@ -#define grid8_width 8 -#define grid8_height 8 -static char grid8_bits[] = { - 0x55, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/hlines2 b/shell/linux-deps/include/X11/bitmaps/hlines2 deleted file mode 100644 index 5c1a396f9..000000000 --- a/shell/linux-deps/include/X11/bitmaps/hlines2 +++ /dev/null @@ -1,4 +0,0 @@ -#define hlines2_width 1 -#define hlines2_height 2 -static char hlines2_bits[] = { - 0x01, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/hlines3 b/shell/linux-deps/include/X11/bitmaps/hlines3 deleted file mode 100644 index ed4943319..000000000 --- a/shell/linux-deps/include/X11/bitmaps/hlines3 +++ /dev/null @@ -1,4 +0,0 @@ -#define hlines3_width 1 -#define hlines3_height 3 -static char hlines3_bits[] = { - 0x00, 0x01, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/icon b/shell/linux-deps/include/X11/bitmaps/icon deleted file mode 100644 index 9a75a57c4..000000000 --- a/shell/linux-deps/include/X11/bitmaps/icon +++ /dev/null @@ -1,6 +0,0 @@ -#define icon_width 16 -#define icon_height 16 -static char icon_bits[] = { - 0xff, 0xff, 0xab, 0xaa, 0x55, 0xd5, 0xab, 0xaa, 0x05, 0xd0, 0x0b, 0xa0, - 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, 0x05, 0xd0, 0x0b, 0xa0, - 0x55, 0xd5, 0xab, 0xaa, 0x55, 0xd5, 0xff, 0xff}; diff --git a/shell/linux-deps/include/X11/bitmaps/keyboard16 b/shell/linux-deps/include/X11/bitmaps/keyboard16 deleted file mode 100644 index c4ead326b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/keyboard16 +++ /dev/null @@ -1,6 +0,0 @@ -#define keyboard16_width 16 -#define keyboard16_height 16 -static char keyboard16_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, - 0x08, 0x10, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0xa8, 0x1a, - 0x54, 0x35, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/ldblarrow b/shell/linux-deps/include/X11/bitmaps/ldblarrow deleted file mode 100644 index 48bbeb0eb..000000000 --- a/shell/linux-deps/include/X11/bitmaps/ldblarrow +++ /dev/null @@ -1,5 +0,0 @@ -#define previous_width 11 -#define previous_height 11 -static char previous_bits[] = { - 0x20, 0x04, 0x10, 0x02, 0x08, 0x01, 0x84, 0x00, 0x42, 0x00, 0x21, 0x00, - 0x42, 0x00, 0x84, 0x00, 0x08, 0x01, 0x10, 0x02, 0x20, 0x04}; diff --git a/shell/linux-deps/include/X11/bitmaps/left_ptr b/shell/linux-deps/include/X11/bitmaps/left_ptr deleted file mode 100644 index 8a6abb13a..000000000 --- a/shell/linux-deps/include/X11/bitmaps/left_ptr +++ /dev/null @@ -1,8 +0,0 @@ -#define left_ptr_width 16 -#define left_ptr_height 16 -#define left_ptr_x_hot 3 -#define left_ptr_y_hot 1 -static char left_ptr_bits[] = { - 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, - 0xf8, 0x01, 0xf8, 0x03, 0xf8, 0x07, 0xf8, 0x00, 0xd8, 0x00, 0x88, 0x01, - 0x80, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/left_ptrmsk b/shell/linux-deps/include/X11/bitmaps/left_ptrmsk deleted file mode 100644 index 851911d3d..000000000 --- a/shell/linux-deps/include/X11/bitmaps/left_ptrmsk +++ /dev/null @@ -1,6 +0,0 @@ -#define left_ptrmsk_width 16 -#define left_ptrmsk_height 16 -static char left_ptrmsk_bits[] = { - 0x0c, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0xfc, 0x01, - 0xfc, 0x03, 0xfc, 0x07, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x01, 0xdc, 0x03, - 0xcc, 0x03, 0x80, 0x07, 0x80, 0x07, 0x00, 0x03}; diff --git a/shell/linux-deps/include/X11/bitmaps/letters b/shell/linux-deps/include/X11/bitmaps/letters deleted file mode 100644 index 0f12568d1..000000000 --- a/shell/linux-deps/include/X11/bitmaps/letters +++ /dev/null @@ -1,27 +0,0 @@ -#define letters_width 48 -#define letters_height 48 -static char letters_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, - 0x00, 0xfa, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, - 0x00, 0x3a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2e, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0x21, - 0xa0, 0x03, 0x00, 0x00, 0x70, 0x21, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, - 0xa0, 0x1f, 0x00, 0x00, 0x50, 0x21, 0x20, 0x00, 0x00, 0x00, 0x70, 0x21, - 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21, - 0xfa, 0x01, 0x00, 0x80, 0x0b, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0a, 0x21, - 0xba, 0x01, 0x00, 0x80, 0x0a, 0x21, 0x02, 0x00, 0x00, 0x80, 0x0b, 0x21, - 0x3a, 0x00, 0x00, 0x00, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x21, - 0x02, 0xc0, 0xfb, 0x03, 0x08, 0x21, 0x02, 0x00, 0x00, 0x00, 0x08, 0x3f, - 0x02, 0xc0, 0xbd, 0x0f, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01, - 0x02, 0xc0, 0x7f, 0x7b, 0x08, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x01, - 0x02, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, - 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/light_gray b/shell/linux-deps/include/X11/bitmaps/light_gray deleted file mode 100644 index ea62e17dc..000000000 --- a/shell/linux-deps/include/X11/bitmaps/light_gray +++ /dev/null @@ -1,4 +0,0 @@ -#define light_gray_width 4 -#define light_gray_height 2 -static char light_gray_bits[] = { - 0x08, 0x02}; diff --git a/shell/linux-deps/include/X11/bitmaps/mailempty b/shell/linux-deps/include/X11/bitmaps/mailempty deleted file mode 100644 index 064252534..000000000 --- a/shell/linux-deps/include/X11/bitmaps/mailempty +++ /dev/null @@ -1,27 +0,0 @@ -#define mailempty_width 48 -#define mailempty_height 48 -static unsigned char mailempty_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x80, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0xc0, 0xaf, 0xaa, 0xaa, 0xaa, 0x7a, 0xe0, 0x57, 0x55, 0x55, 0x55, 0x7d, - 0xf0, 0xaf, 0xaa, 0xaa, 0xaa, 0x7e, 0xf8, 0x57, 0x55, 0x55, 0x55, 0x7f, - 0xfc, 0xaf, 0xaa, 0xaa, 0xaa, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xab, 0xaa, 0xaa, 0xea, 0x7f, - 0xfe, 0x55, 0x55, 0x55, 0xf5, 0x6f, 0xfe, 0xaa, 0xaa, 0xaa, 0xea, 0x67, - 0x7e, 0x55, 0x55, 0x55, 0xf5, 0x63, 0xbe, 0xaa, 0xaa, 0xaa, 0xea, 0x61, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x60, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0xfe, 0xff, 0xff, 0xff, 0x7f, - 0x06, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x86, 0xaf, 0xaa, 0xaa, 0xea, 0x7a, - 0xc6, 0x57, 0x55, 0x55, 0x75, 0x7d, 0xe6, 0xaf, 0xaa, 0xaa, 0xea, 0x7e, - 0xf6, 0x57, 0x55, 0x55, 0x75, 0x7f, 0xfe, 0xaf, 0xaa, 0xaa, 0xea, 0x7f, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0xfe, 0xab, 0xaa, 0xaa, 0xea, 0x7f, 0xfe, 0x55, 0x55, 0x55, 0xf5, 0x6f, - 0xfe, 0xaa, 0xaa, 0xaa, 0xea, 0x67, 0x7e, 0x55, 0x55, 0x55, 0xf5, 0x63, - 0xbe, 0xaa, 0xaa, 0xaa, 0xea, 0x61, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x60, - 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/mailemptymsk b/shell/linux-deps/include/X11/bitmaps/mailemptymsk deleted file mode 100644 index f1204b233..000000000 --- a/shell/linux-deps/include/X11/bitmaps/mailemptymsk +++ /dev/null @@ -1,27 +0,0 @@ -#define mailemask_width 48 -#define mailemask_height 48 -static char mailemask_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, - 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/mailfull b/shell/linux-deps/include/X11/bitmaps/mailfull deleted file mode 100644 index cc2f6f8b6..000000000 --- a/shell/linux-deps/include/X11/bitmaps/mailfull +++ /dev/null @@ -1,27 +0,0 @@ -#define mailfull_width 48 -#define mailfull_height 48 -static unsigned char mailfull_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x07, - 0xc0, 0xff, 0xff, 0xff, 0x1f, 0x04, 0x40, 0x00, 0x00, 0x00, 0xd0, 0x05, - 0x40, 0x00, 0x00, 0x00, 0x57, 0x7d, 0x40, 0x1e, 0x00, 0x00, 0x55, 0x7d, - 0x40, 0x00, 0x00, 0x00, 0xd5, 0x7d, 0x60, 0x02, 0x00, 0x00, 0x17, 0x7c, - 0x70, 0x00, 0x7e, 0x00, 0x10, 0x7c, 0x78, 0x00, 0x00, 0x00, 0x10, 0x7e, - 0x7c, 0x00, 0x1e, 0x00, 0x10, 0x7f, 0x7e, 0x00, 0x00, 0x00, 0x90, 0x7f, - 0x7e, 0x00, 0x3e, 0x07, 0xd0, 0x7f, 0x7e, 0x00, 0x00, 0x00, 0xf0, 0x7f, - 0x7e, 0x00, 0x00, 0x00, 0xf0, 0x6f, 0x7e, 0x00, 0x00, 0x00, 0xf0, 0x67, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x63, 0xbe, 0xaa, 0xaa, 0xaa, 0xea, 0x61, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x60, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, - 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, 0x06, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x86, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xc6, 0xaf, 0xaa, 0xaa, 0xea, 0x7a, - 0xe6, 0x57, 0x55, 0x55, 0x75, 0x7d, 0xf6, 0xaf, 0xaa, 0xaa, 0xea, 0x7e, - 0xfe, 0x57, 0x55, 0x55, 0x75, 0x7f, 0xfe, 0xaf, 0xaa, 0xaa, 0xea, 0x7f, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0xfe, 0xab, 0xaa, 0xaa, 0xea, 0x7f, 0xfe, 0x55, 0x55, 0x55, 0xf5, 0x6f, - 0xfe, 0xaa, 0xaa, 0xaa, 0xea, 0x67, 0x7e, 0x55, 0x55, 0x55, 0xf5, 0x63, - 0xbe, 0xaa, 0xaa, 0xaa, 0xea, 0x61, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x60, - 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x60, 0x06, 0x06, 0x00, 0x00, 0x60, 0x60, - 0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0xee, 0x9c, 0x37, 0x60, 0x00, - 0x06, 0xfe, 0x36, 0x33, 0x60, 0x00, 0x06, 0xd6, 0x3e, 0x33, 0x60, 0x00, - 0x06, 0xc6, 0xb6, 0xf7, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/mailfullmsk b/shell/linux-deps/include/X11/bitmaps/mailfullmsk deleted file mode 100644 index 6dfc942eb..000000000 --- a/shell/linux-deps/include/X11/bitmaps/mailfullmsk +++ /dev/null @@ -1,27 +0,0 @@ -#define mailfullmsk_width 48 -#define mailfullmsk_height 48 -static char mailfullmsk_bits[] = { - 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, - 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, - 0x0f, 0xff, 0xff, 0xff, 0xf1, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xf1, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf1, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/mensetmanus b/shell/linux-deps/include/X11/bitmaps/mensetmanus deleted file mode 100644 index 095b8ec48..000000000 --- a/shell/linux-deps/include/X11/bitmaps/mensetmanus +++ /dev/null @@ -1,258 +0,0 @@ -#define mensetmanus_width 161 -#define mensetmanus_height 145 - -static char mensetmanus_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, - 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xdb, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x07, - 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf7, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x61, 0x00, 0x00, 0xc6, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc3, 0xff, - 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xe1, 0xff, 0xff, 0x87, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc3, 0xf6, 0x1f, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xff, 0xff, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x9f, 0x65, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0x00, - 0x07, 0x80, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x9f, 0x6d, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xff, 0xff, 0xc7, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x6d, - 0x1b, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x81, 0x6d, 0x1b, 0x00, 0x00, - 0x00, 0xc0, 0xe1, 0x5b, 0xdb, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x81, 0x6d, 0x1b, 0x00, 0x00, 0x00, 0x80, 0x83, - 0x5b, 0xdb, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x81, 0x6d, 0x1b, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x5b, 0x1b, 0x0c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x6d, - 0x1b, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x5b, 0x1b, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x80, 0x6d, 0x1b, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x5b, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x83, 0x6d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x5b, 0x0b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x83, 0x6d, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5b, 0x0f, 0x0e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x6d, - 0x1b, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x0f, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x79, 0x1b, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x6b, 0xbf, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xfb, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x6d, 0xb7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xed, 0xf7, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xfe, - 0x7f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xed, 0xd7, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0xf8, 0xff, 0x07, 0x00, - 0x00, 0x00, 0xe0, 0xfe, 0xd7, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xff, 0x7f, 0xe0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xf0, - 0xff, 0xd6, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0xbf, 0x73, 0x80, 0x3b, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0xe7, 0xd6, 0xef, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb9, 0x73, 0xc0, - 0x3b, 0xf0, 0x01, 0x00, 0x00, 0xff, 0xc3, 0xbf, 0xe7, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb8, 0x7f, 0xe0, 0x3b, 0xc0, 0x03, - 0x00, 0xc0, 0xbf, 0xc7, 0xbf, 0xe7, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0xb8, 0xff, 0xf8, 0x3b, 0x80, 0x07, 0x00, 0xe0, 0x61, - 0x87, 0xfd, 0xe7, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, - 0xb8, 0xf3, 0xff, 0x3b, 0x00, 0x0f, 0x00, 0x78, 0x60, 0x8e, 0xf1, 0x67, - 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xb8, 0xc3, 0x8f, - 0x7b, 0x00, 0x0e, 0x00, 0x38, 0xe0, 0x8c, 0x03, 0x66, 0x87, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xb8, 0x03, 0x83, 0x7b, 0x00, 0x1e, - 0x00, 0x1c, 0xe0, 0x1d, 0x03, 0x76, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x07, 0xb8, 0xe3, 0x8f, 0xbb, 0x01, 0x39, 0x00, 0x1e, 0xe0, - 0x3b, 0x03, 0xf6, 0x87, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, - 0xb8, 0xe3, 0x8f, 0x3b, 0xc6, 0x38, 0x00, 0x17, 0xe0, 0x73, 0x07, 0xfe, - 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0b, 0xb8, 0xe7, 0x8e, - 0x3b, 0x38, 0x78, 0x00, 0x13, 0xe0, 0x77, 0x06, 0xfe, 0xff, 0xff, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0xe0, 0x12, 0x3c, 0xff, 0xce, 0x3b, 0x00, 0x78, - 0x80, 0x13, 0x60, 0xef, 0x0e, 0xfe, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, - 0x00, 0x70, 0x22, 0x3e, 0xfc, 0xfe, 0x39, 0x00, 0xe8, 0x80, 0x61, 0x60, - 0xce, 0x0f, 0xfe, 0x00, 0x00, 0x60, 0xf8, 0x00, 0x00, 0x00, 0x70, 0xc2, - 0x39, 0xf8, 0x7e, 0x38, 0x00, 0xc8, 0xc0, 0x81, 0x71, 0xde, 0x0f, 0xfe, - 0x00, 0x00, 0x60, 0x88, 0x00, 0x00, 0x00, 0x70, 0x04, 0x38, 0xe0, 0x0e, - 0x38, 0x00, 0xc4, 0xc0, 0x01, 0x7e, 0xbc, 0x1f, 0xfe, 0x00, 0x00, 0x60, - 0x88, 0x00, 0x00, 0x00, 0x78, 0x04, 0x38, 0xe0, 0x0e, 0x38, 0x00, 0xc4, - 0xc1, 0x01, 0x60, 0x3c, 0x1f, 0xfe, 0x00, 0x00, 0x60, 0x84, 0x0f, 0x00, - 0x00, 0x78, 0x08, 0x38, 0xe0, 0x0f, 0x38, 0x00, 0x82, 0xe1, 0x01, 0x60, - 0x74, 0x3e, 0xfe, 0x00, 0x00, 0x60, 0x44, 0x08, 0x00, 0x00, 0xb8, 0x10, - 0x38, 0xe0, 0x0f, 0x38, 0x00, 0x81, 0xe1, 0x00, 0x60, 0xe4, 0x3e, 0xfe, - 0x00, 0x00, 0x60, 0x44, 0x08, 0x00, 0x00, 0x98, 0x20, 0x38, 0xf8, 0x3f, - 0x38, 0x80, 0x80, 0xe1, 0x01, 0x60, 0xc4, 0x3c, 0xfe, 0x00, 0x00, 0x60, - 0x24, 0x0c, 0x00, 0x00, 0x1c, 0xc1, 0x39, 0x3c, 0x78, 0x38, 0x40, 0x80, - 0x61, 0x01, 0x60, 0xc4, 0x79, 0xfe, 0x00, 0x00, 0x60, 0x22, 0x32, 0x00, - 0x00, 0x1c, 0x01, 0x3e, 0x1c, 0xf0, 0x38, 0xf0, 0x9f, 0x61, 0x01, 0x60, - 0x84, 0x7b, 0xee, 0x00, 0x00, 0x60, 0x12, 0x21, 0x00, 0x00, 0x1c, 0x02, - 0x38, 0x0e, 0xe7, 0xf8, 0x3f, 0xe0, 0x61, 0x00, 0x60, 0x04, 0xf7, 0xce, - 0x00, 0x00, 0x60, 0x92, 0x10, 0x00, 0x00, 0x1c, 0x04, 0x38, 0x06, 0xff, - 0x38, 0x40, 0x80, 0x61, 0x02, 0x60, 0x04, 0xe7, 0xcf, 0x00, 0x00, 0x60, - 0x8a, 0x18, 0x00, 0x00, 0x1c, 0x18, 0x38, 0x07, 0xf0, 0x38, 0x00, 0x81, - 0x61, 0x02, 0x60, 0x04, 0xee, 0xcf, 0xff, 0x03, 0x60, 0x49, 0xe4, 0x00, - 0x00, 0x1c, 0x70, 0x38, 0x07, 0xe7, 0x38, 0x00, 0x82, 0x61, 0x04, 0x60, - 0x04, 0xdc, 0xcf, 0x01, 0x04, 0x60, 0x25, 0x42, 0x00, 0x00, 0x1c, 0xfe, - 0x3f, 0x03, 0xff, 0x38, 0x00, 0x84, 0x61, 0x08, 0x60, 0x04, 0xfc, 0xcf, - 0xf8, 0xff, 0x60, 0x95, 0x31, 0x00, 0x00, 0xfc, 0x01, 0xff, 0x03, 0xf0, - 0xf8, 0x1f, 0x88, 0x61, 0x10, 0xe0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xe1, - 0x53, 0x0c, 0x00, 0x00, 0x38, 0xf0, 0xff, 0x03, 0xef, 0xf8, 0x7f, 0x90, - 0x61, 0x40, 0xe0, 0xff, 0xff, 0xff, 0x00, 0xff, 0xe3, 0x2b, 0xfe, 0x00, - 0x00, 0x18, 0xf8, 0xff, 0x03, 0xff, 0x7c, 0xf0, 0x90, 0x61, 0x00, 0x3e, - 0x36, 0xe3, 0xe1, 0x00, 0x00, 0xe3, 0x9f, 0x60, 0x00, 0x00, 0x38, 0x3c, - 0x00, 0x03, 0xf0, 0x1f, 0xe0, 0xa0, 0xe1, 0x00, 0x30, 0x22, 0xe2, 0xc0, - 0x00, 0xff, 0xe3, 0x7f, 0x18, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x07, 0xe7, - 0x07, 0xc0, 0xe1, 0xc1, 0x00, 0x18, 0x22, 0xe2, 0xc0, 0x00, 0x00, 0xe1, - 0x1f, 0x07, 0x00, 0x00, 0x38, 0x06, 0x00, 0x07, 0xef, 0x01, 0xc0, 0xc1, - 0xc1, 0x01, 0x16, 0x24, 0xe2, 0xc0, 0x01, 0xff, 0xe1, 0xff, 0x00, 0x00, - 0x00, 0x70, 0x07, 0x00, 0x0e, 0xf8, 0x00, 0x80, 0xc3, 0xc0, 0xf1, 0x11, - 0x24, 0xe4, 0xc0, 0x03, 0xe0, 0xe1, 0x7f, 0x00, 0x00, 0x00, 0x70, 0x07, - 0x00, 0x1e, 0x3c, 0x00, 0x80, 0xe3, 0x80, 0x0f, 0x10, 0x24, 0xe4, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xe0, 0x03, 0x00, 0xfc, 0x0f, - 0x00, 0x00, 0x63, 0x80, 0x01, 0x08, 0x44, 0xe4, 0xc0, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x01, 0x00, 0xe0, 0x03, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x73, - 0x80, 0x03, 0x08, 0x44, 0xe4, 0xc0, 0xfc, 0x00, 0x07, 0x0e, 0x00, 0x00, - 0x00, 0xc0, 0x03, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x33, 0x00, 0x03, 0x08, - 0x44, 0xe4, 0xe0, 0xcc, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x00, 0xc0, 0x03, - 0x00, 0x78, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x07, 0x04, 0x44, 0xe8, 0x70, - 0xcc, 0x01, 0x87, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x3e, 0x00, - 0x00, 0x80, 0x1f, 0x00, 0x0e, 0x04, 0x44, 0xe8, 0x38, 0xcc, 0x81, 0xe7, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x00, 0x80, 0x0f, - 0x00, 0x1c, 0x02, 0x44, 0xf8, 0x1e, 0xcc, 0xe1, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xc0, 0x23, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x38, 0x01, - 0x42, 0xfc, 0x0f, 0xcc, 0xf1, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, - 0xf0, 0x39, 0x00, 0x00, 0xe0, 0x03, 0x00, 0xf0, 0x00, 0xc2, 0xff, 0x07, - 0xcc, 0x7f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x0e, 0x00, - 0x00, 0xf0, 0x01, 0x00, 0xe0, 0x03, 0xe2, 0xe7, 0x07, 0xcc, 0x1f, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf, 0x23, 0xe0, 0xff, 0xff, 0x00, - 0x00, 0xc0, 0x1f, 0xff, 0x64, 0x06, 0xcc, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0xff, 0x3c, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xff, - 0x7f, 0x64, 0x06, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0xf8, 0x1f, 0x78, 0x7c, 0x7f, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x64, 0x06, - 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xf8, 0x33, 0x1c, - 0x38, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x6c, 0x06, 0xcc, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x3e, 0x0e, 0x38, 0x76, 0x00, - 0x00, 0x00, 0x0c, 0x20, 0x68, 0x06, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0xf8, 0x87, 0x0f, 0x38, 0x76, 0x00, 0x00, 0x00, 0x0c, - 0x20, 0x68, 0x06, 0xcc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x78, 0xf8, 0x0f, 0x38, 0x76, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x68, 0x06, - 0xcc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf8, 0xff, 0x0f, - 0x38, 0x76, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x68, 0x06, 0xcc, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf8, 0xff, 0x0e, 0x38, 0x76, 0x00, - 0x00, 0x00, 0x0c, 0x10, 0x68, 0x06, 0xcc, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0xf8, 0xe1, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x0c, - 0x08, 0x68, 0x06, 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, - 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x68, 0x06, - 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x0e, - 0x38, 0x3e, 0x00, 0x00, 0x00, 0x0c, 0x04, 0x68, 0x06, 0xcc, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, - 0x00, 0x00, 0x1c, 0x04, 0x68, 0x06, 0xcc, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x1c, - 0x02, 0x68, 0x06, 0xcc, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x1c, 0x02, 0x68, 0x06, - 0xcc, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x38, 0xe0, 0x0e, - 0x38, 0x3e, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x68, 0x06, 0xcc, 0x1c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, - 0x00, 0x00, 0x18, 0x01, 0x68, 0x06, 0xcc, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x98, - 0x00, 0x68, 0x06, 0xcc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, - 0x38, 0xe0, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x98, 0x00, 0x68, 0x06, - 0xcc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x38, 0xe0, 0x0e, - 0x38, 0x1e, 0x00, 0x00, 0x00, 0x58, 0x00, 0x6c, 0x0e, 0xcc, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x30, 0xe0, 0x0e, 0x38, 0x1e, 0x00, - 0x00, 0x00, 0x38, 0x00, 0x64, 0x0e, 0xcc, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x01, 0x70, 0xe0, 0x0e, 0x1c, 0x1e, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x64, 0x1e, 0xcc, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, - 0xe0, 0xe1, 0x0e, 0x0f, 0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x64, 0x3e, - 0xcc, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0xef, 0xce, - 0x07, 0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x64, 0x3e, 0xcc, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xff, 0xfe, 0x03, 0x1e, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x64, 0x7e, 0xcc, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x00, 0xfc, 0xfe, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x64, 0x66, 0xcc, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x00, 0xe0, 0x1e, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x66, 0xe6, - 0xcc, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x0e, - 0x00, 0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x62, 0xc6, 0xcd, 0x70, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0x1e, 0x00, - 0x00, 0x00, 0x18, 0x00, 0x62, 0xc6, 0xcd, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x0e, 0x00, 0x00, 0x00, 0x38, - 0x00, 0x62, 0x86, 0xcf, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, - 0xf0, 0xff, 0xff, 0x0f, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x61, 0x86, - 0xcf, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xfc, 0x00, 0x00, - 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x61, 0x8e, 0xcf, 0xe0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x78, 0x00, 0x00, 0x0e, 0x0e, 0x00, - 0x00, 0x00, 0xf8, 0xff, 0x7f, 0xfe, 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x00, 0xf0, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0xf0, - 0xff, 0x3f, 0xff, 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, - 0xe0, 0x01, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x8f, 0x07, - 0x9e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xe0, 0x07, 0x00, - 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x00, 0xc0, 0xff, 0x3f, 0xc0, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x00, - 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0xf0, - 0xff, 0xff, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, - 0x3f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x00, - 0x38, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x38, 0x00, 0x38, 0xe0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x18, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x18, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0xdc, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1c, 0x00, - 0x38, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x9c, 0x03, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1c, 0x00, 0x18, 0x70, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x07, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x0c, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x1c, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x0c, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x1c, 0xfc, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x00, - 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x1c, 0x00, - 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x18, 0x70, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x0e, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x1c, 0x1c, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, - 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x1c, 0x00, - 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x18, 0x38, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x0e, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, - 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x18, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x0e, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x0e, 0x00, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x00, - 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1c, 0x00, 0x38, 0x70, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x1c, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x18, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x00, - 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x1e, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x00, 0x30, 0xe0, 0x01, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x3c, 0x00, 0x30, 0xf0, 0x01, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0x03, 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x7e, 0x00, 0x70, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0f, - 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xe7, 0x00, - 0x70, 0xbc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1f, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xe3, 0x00, 0x60, 0x1e, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0xc1, 0x01, 0xe0, 0x0f, 0x0f, 0x00, 0x00, 0x00, - 0x80, 0x07, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0x80, 0x03, 0xe0, 0x03, 0x1e, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe0, - 0x1b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x78, 0x80, 0x07, - 0xe0, 0x01, 0x1c, 0x00, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0x1b, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0f, 0xe0, 0x01, 0x38, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0xc0, 0x19, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x0e, 0x1e, 0xc0, 0x71, 0xf8, 0x00, 0x00, 0x00, - 0x78, 0x00, 0xdc, 0x19, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x1f, 0x1e, 0xc0, 0xf9, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/shell/linux-deps/include/X11/bitmaps/menu10 b/shell/linux-deps/include/X11/bitmaps/menu10 deleted file mode 100644 index 6250e8e3c..000000000 --- a/shell/linux-deps/include/X11/bitmaps/menu10 +++ /dev/null @@ -1,5 +0,0 @@ -#define menu10_width 10 -#define menu10_height 10 -static char menu10_bits[] = { - 0xfe, 0x01, 0x02, 0x01, 0x02, 0x03, 0x32, 0x03, 0x02, 0x03, 0x32, 0x03, - 0x02, 0x03, 0x02, 0x03, 0xfe, 0x03, 0xf8, 0x03}; diff --git a/shell/linux-deps/include/X11/bitmaps/menu12 b/shell/linux-deps/include/X11/bitmaps/menu12 deleted file mode 100644 index e88ca688b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/menu12 +++ /dev/null @@ -1,5 +0,0 @@ -#define menu12_width 12 -#define menu12_height 12 -static unsigned char menu12_bits[] = { - 0xfe, 0x03, 0x02, 0x02, 0x02, 0x06, 0x72, 0x06, 0x02, 0x06, 0x72, 0x06, - 0x02, 0x06, 0x72, 0x06, 0x02, 0x06, 0x02, 0x06, 0xfe, 0x07, 0xf8, 0x07}; diff --git a/shell/linux-deps/include/X11/bitmaps/menu16 b/shell/linux-deps/include/X11/bitmaps/menu16 deleted file mode 100644 index 770deeea5..000000000 --- a/shell/linux-deps/include/X11/bitmaps/menu16 +++ /dev/null @@ -1,6 +0,0 @@ -#define menu16_width 16 -#define menu16_height 16 -static char menu16_bits[] = { - 0xfc, 0x1f, 0x04, 0x10, 0x04, 0x30, 0x04, 0x30, 0xe4, 0x33, 0x04, 0x30, - 0xe4, 0x33, 0x04, 0x30, 0xe4, 0x33, 0x04, 0x30, 0xe4, 0x33, 0x04, 0x30, - 0x04, 0x30, 0x04, 0x30, 0xfc, 0x3f, 0xf0, 0x3f}; diff --git a/shell/linux-deps/include/X11/bitmaps/menu6 b/shell/linux-deps/include/X11/bitmaps/menu6 deleted file mode 100644 index 780b028b5..000000000 --- a/shell/linux-deps/include/X11/bitmaps/menu6 +++ /dev/null @@ -1,4 +0,0 @@ -#define menu6_width 6 -#define menu6_height 7 -static char menu6_bits[] = { - 0x1f, 0x31, 0x35, 0x35, 0x31, 0x3f, 0x1e}; diff --git a/shell/linux-deps/include/X11/bitmaps/menu8 b/shell/linux-deps/include/X11/bitmaps/menu8 deleted file mode 100644 index 955c1e92b..000000000 --- a/shell/linux-deps/include/X11/bitmaps/menu8 +++ /dev/null @@ -1,4 +0,0 @@ -#define menu8_width 8 -#define menu8_height 8 -static char menu8_bits[] = { - 0x7f, 0x41, 0xdd, 0xc1, 0xdd, 0xc1, 0xff, 0xfc}; diff --git a/shell/linux-deps/include/X11/bitmaps/noletters b/shell/linux-deps/include/X11/bitmaps/noletters deleted file mode 100644 index 5774124ef..000000000 --- a/shell/linux-deps/include/X11/bitmaps/noletters +++ /dev/null @@ -1,27 +0,0 @@ -#define noletters_width 48 -#define noletters_height 48 -static char noletters_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, - 0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00, - 0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01, - 0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0xe0, 0x07, - 0xe0, 0x01, 0x00, 0x00, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x0e, - 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x70, 0x00, 0x00, 0x00, 0x1e, 0x1c, - 0x38, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x38, 0x00, 0x00, 0x80, 0x07, 0x38, - 0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x1c, 0x04, 0x00, 0xe0, 0x41, 0x70, - 0x1c, 0x04, 0x00, 0xf0, 0x40, 0x70, 0x1c, 0x74, 0x00, 0x78, 0x4e, 0x70, - 0x0e, 0x04, 0x00, 0x3c, 0x4a, 0xe0, 0x0e, 0x74, 0x03, 0x1e, 0x4a, 0xe0, - 0x0e, 0x04, 0x00, 0x0f, 0x4e, 0xe0, 0x0e, 0x04, 0x80, 0x07, 0x40, 0xe0, - 0x0e, 0x04, 0xf8, 0x0f, 0x40, 0xe0, 0x0e, 0x04, 0xe0, 0x01, 0x40, 0xe0, - 0x0e, 0x04, 0xf8, 0x00, 0x40, 0xe0, 0x0e, 0x04, 0x78, 0x00, 0x40, 0xe0, - 0x0e, 0x04, 0xfc, 0xf3, 0x40, 0xe0, 0x1c, 0x04, 0x1e, 0x00, 0x40, 0x70, - 0x1c, 0x04, 0x0f, 0x00, 0x40, 0x70, 0x1c, 0x84, 0x07, 0x00, 0x40, 0x70, - 0x3c, 0xfc, 0xff, 0xff, 0x7f, 0x78, 0x38, 0xe0, 0x01, 0x00, 0x00, 0x38, - 0x38, 0xf0, 0x00, 0x00, 0x00, 0x38, 0x70, 0x78, 0x00, 0x00, 0x00, 0x1c, - 0xf0, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x1e, 0x00, 0x00, 0x00, 0x0e, - 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x07, - 0x80, 0x07, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x01, - 0x00, 0x3e, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x7f, 0x00, - 0x00, 0xf0, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/opendot b/shell/linux-deps/include/X11/bitmaps/opendot deleted file mode 100644 index a8ec421df..000000000 --- a/shell/linux-deps/include/X11/bitmaps/opendot +++ /dev/null @@ -1,8 +0,0 @@ -#define opendot_width 16 -#define opendot_height 16 -#define opendot_x_hot 7 -#define opendot_y_hot 7 -static char opendot_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, - 0x60, 0x03, 0x20, 0x02, 0x60, 0x03, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/opendotMask b/shell/linux-deps/include/X11/bitmaps/opendotMask deleted file mode 100644 index 0f83c64de..000000000 --- a/shell/linux-deps/include/X11/bitmaps/opendotMask +++ /dev/null @@ -1,8 +0,0 @@ -#define opendotMask_width 16 -#define opendotMask_height 16 -#define opendotMask_x_hot 7 -#define opendotMask_y_hot 7 -static char opendotMask_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xf0, 0x07, - 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/plaid b/shell/linux-deps/include/X11/bitmaps/plaid deleted file mode 100644 index 578e464db..000000000 --- a/shell/linux-deps/include/X11/bitmaps/plaid +++ /dev/null @@ -1,11 +0,0 @@ -#define plaid_width 22 -#define plaid_height 22 -#define plaid_x_hot -1 -#define plaid_y_hot -1 -static char plaid_bits[] = { - 0x75, 0xfd, 0x3f, 0xaa, 0xfa, 0x3e, 0x75, 0xfd, 0x3f, 0xaa, 0xfa, 0x3e, - 0x75, 0xfd, 0x3f, 0xff, 0x57, 0x15, 0x75, 0xfd, 0x3f, 0xaa, 0xfa, 0x3e, - 0x75, 0xfd, 0x3f, 0xaa, 0xfa, 0x3e, 0x75, 0xfd, 0x3f, 0x20, 0xa8, 0x2b, - 0x20, 0x50, 0x15, 0x20, 0xa8, 0x2b, 0x20, 0x50, 0x15, 0x20, 0xa8, 0x2b, - 0xff, 0xff, 0x3f, 0x20, 0xa8, 0x2b, 0x20, 0x50, 0x15, 0x20, 0xa8, 0x2b, - 0x20, 0x50, 0x15, 0x20, 0xa8, 0x2b}; diff --git a/shell/linux-deps/include/X11/bitmaps/rdblarrow b/shell/linux-deps/include/X11/bitmaps/rdblarrow deleted file mode 100644 index 19140c764..000000000 --- a/shell/linux-deps/include/X11/bitmaps/rdblarrow +++ /dev/null @@ -1,5 +0,0 @@ -#define next_width 11 -#define next_height 11 -static char next_bits[] = { - 0x21, 0x00, 0x42, 0x00, 0x84, 0x00, 0x08, 0x01, 0x10, 0x02, 0x20, 0x04, - 0x10, 0x02, 0x08, 0x01, 0x84, 0x00, 0x42, 0x00, 0x21, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/right_ptr b/shell/linux-deps/include/X11/bitmaps/right_ptr deleted file mode 100644 index 3922aa562..000000000 --- a/shell/linux-deps/include/X11/bitmaps/right_ptr +++ /dev/null @@ -1,8 +0,0 @@ -#define right_ptr_width 16 -#define right_ptr_height 16 -#define right_ptr_x_hot 12 -#define right_ptr_y_hot 1 -static char right_ptr_bits[] = { - 0x00, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x1f, - 0x80, 0x1f, 0xc0, 0x1f, 0xe0, 0x1f, 0x00, 0x1f, 0x00, 0x1b, 0x80, 0x11, - 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/right_ptrmsk b/shell/linux-deps/include/X11/bitmaps/right_ptrmsk deleted file mode 100644 index 96f532488..000000000 --- a/shell/linux-deps/include/X11/bitmaps/right_ptrmsk +++ /dev/null @@ -1,6 +0,0 @@ -#define right_ptrmsk_width 16 -#define right_ptrmsk_height 16 -static char right_ptrmsk_bits[] = { - 0x00, 0x30, 0x00, 0x38, 0x00, 0x3c, 0x00, 0x3e, 0x00, 0x3f, 0x80, 0x3f, - 0xc0, 0x3f, 0xe0, 0x3f, 0xf0, 0x3f, 0xf0, 0x3f, 0x80, 0x3f, 0xc0, 0x3b, - 0xc0, 0x33, 0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/root_weave b/shell/linux-deps/include/X11/bitmaps/root_weave deleted file mode 100644 index ec41e436f..000000000 --- a/shell/linux-deps/include/X11/bitmaps/root_weave +++ /dev/null @@ -1,4 +0,0 @@ -#define root_weave_width 4 -#define root_weave_height 4 -static char root_weave_bits[] = { - 0x07, 0x0d, 0x0b, 0x0e}; diff --git a/shell/linux-deps/include/X11/bitmaps/scales b/shell/linux-deps/include/X11/bitmaps/scales deleted file mode 100644 index e5aac6acb..000000000 --- a/shell/linux-deps/include/X11/bitmaps/scales +++ /dev/null @@ -1,6 +0,0 @@ -#define scales_width 16 -#define scales_height 16 -static char scales_bits[] = { - 0x10, 0x10, 0x10, 0x10, 0x28, 0x28, 0xc7, 0xc7, 0x01, 0x01, 0x01, 0x01, - 0x82, 0x82, 0x7c, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x28, 0x28, 0xc7, 0xc7, - 0x01, 0x01, 0x01, 0x01, 0x82, 0x82, 0x7c, 0x7c}; diff --git a/shell/linux-deps/include/X11/bitmaps/sipb b/shell/linux-deps/include/X11/bitmaps/sipb deleted file mode 100644 index 7f3b7c1a6..000000000 --- a/shell/linux-deps/include/X11/bitmaps/sipb +++ /dev/null @@ -1,16 +0,0 @@ -#define sipb_width 32 -#define sipb_height 32 -#define sipb_x_hot 12 -#define sipb_y_hot 16 -static char sipb_bits[] = { - 0xbe, 0xdf, 0x03, 0x00, 0x22, 0x49, 0x04, 0x00, 0x04, 0x49, 0x04, 0x00, - 0x08, 0x49, 0x04, 0x00, 0x10, 0xc9, 0x03, 0x00, 0x08, 0x49, 0x04, 0x00, - 0x04, 0x49, 0x04, 0x00, 0x22, 0x49, 0x04, 0x00, 0x3e, 0xc9, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xfd, 0x1e, 0x00, 0x10, 0x49, 0x22, - 0x00, 0x20, 0x48, 0x22, 0x00, 0x40, 0x48, 0x22, 0x00, 0x80, 0x48, 0x1e, - 0x00, 0x40, 0x48, 0x22, 0x00, 0x20, 0x48, 0x22, 0x00, 0x10, 0x49, 0x22, - 0x00, 0xf0, 0x49, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/star b/shell/linux-deps/include/X11/bitmaps/star deleted file mode 100644 index c98f1a4ab..000000000 --- a/shell/linux-deps/include/X11/bitmaps/star +++ /dev/null @@ -1,8 +0,0 @@ -#define star_width 16 -#define star_height 16 -#define star_x_hot 7 -#define star_y_hot 7 -static char star_bits[] = { - 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x88, 0x08, 0x90, 0x04, 0xa0, 0x02, - 0x40, 0x01, 0x3e, 0x3e, 0x40, 0x01, 0xa0, 0x02, 0x90, 0x04, 0x88, 0x08, - 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/starMask b/shell/linux-deps/include/X11/bitmaps/starMask deleted file mode 100644 index c220bb6ff..000000000 --- a/shell/linux-deps/include/X11/bitmaps/starMask +++ /dev/null @@ -1,8 +0,0 @@ -#define starMask_width 16 -#define starMask_height 16 -#define starMask_x_hot 7 -#define starMask_y_hot 7 -static char starMask_bits[] = { - 0xc0, 0x01, 0xc0, 0x01, 0xdc, 0x1d, 0xfc, 0x1f, 0xfc, 0x1f, 0xf8, 0x0f, - 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xf8, 0x0f, 0xfc, 0x1f, 0xfc, 0x1f, - 0xdc, 0x1d, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/stipple b/shell/linux-deps/include/X11/bitmaps/stipple deleted file mode 100644 index 63558d026..000000000 --- a/shell/linux-deps/include/X11/bitmaps/stipple +++ /dev/null @@ -1,4 +0,0 @@ -#define stipple_width 16 -#define stipple_height 4 -static char stipple_bits[] = { - 0x55, 0x55, 0xee, 0xee, 0x55, 0x55, 0xba, 0xbb}; diff --git a/shell/linux-deps/include/X11/bitmaps/target b/shell/linux-deps/include/X11/bitmaps/target deleted file mode 100644 index 6d23ecada..000000000 --- a/shell/linux-deps/include/X11/bitmaps/target +++ /dev/null @@ -1,6 +0,0 @@ -#define target_width 16 -#define target_height 16 -static char target_bits[] = { - 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0xe0, 0x07, 0x90, 0x09, 0x88, 0x11, - 0xc8, 0x13, 0x7e, 0x7e, 0x7e, 0x7e, 0xc8, 0x13, 0x88, 0x11, 0x90, 0x09, - 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/terminal b/shell/linux-deps/include/X11/bitmaps/terminal deleted file mode 100644 index b8d9204bd..000000000 --- a/shell/linux-deps/include/X11/bitmaps/terminal +++ /dev/null @@ -1,52 +0,0 @@ -/*****************************************************************************/ -/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ -/** Salt Lake City, Utah **/ -/** **/ -/** All Rights Reserved **/ -/** **/ -/** Permission to use, copy, modify, and distribute this software and **/ -/** its documentation for any purpose and without fee is hereby **/ -/** granted, provided that the above copyright notice appear in all **/ -/** copies and that both that copyright notice and this permis- **/ -/** sion notice appear in supporting documentation, and that the **/ -/** name of Evans & Sutherland not be used in advertising or publi- **/ -/** city pertaining to distribution of the software without specif- **/ -/** ic, written prior permission. **/ -/** **/ -/** EVANS & SUTHERLAND DISCLAIMS ALL WARRANTIES WITH REGARD TO **/ -/** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI- **/ -/** TY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND BE LIABLE **/ -/** FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAM- **/ -/** AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, **/ -/** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS **/ -/** ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER- **/ -/** FORMANCE OF THIS SOFTWARE. **/ -/*****************************************************************************/ - -#define xterm_width 48 -#define xterm_height 48 -static char xterm_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xfe, 0xff, 0xff, 0x1f, 0x05, - 0x20, 0x01, 0x00, 0x00, 0x20, 0x09, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xa0, 0xfc, 0xff, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0xfc, 0x01, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0xfc, 0xff, 0x3f, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0xfc, 0x03, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0xfc, 0xff, 0x01, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0xfc, 0x00, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x21, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x11, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x09, - 0xa0, 0x00, 0x00, 0x00, 0x40, 0x09, 0xa0, 0x00, 0x00, 0x00, 0x40, 0x05, - 0x20, 0x01, 0x00, 0x00, 0x20, 0x05, 0x20, 0xfe, 0xff, 0xff, 0x1f, 0x03, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, - 0xa0, 0xaa, 0xaa, 0xaa, 0x2a, 0x03, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, - 0x50, 0x55, 0x55, 0x55, 0x95, 0x02, 0x08, 0x00, 0x00, 0x00, 0x40, 0x02, - 0xa8, 0xaa, 0xaa, 0xaa, 0x4a, 0x02, 0x04, 0x00, 0x00, 0x00, 0x20, 0x01, - 0xb4, 0xff, 0xff, 0xff, 0xad, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, - 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/tie_fighter b/shell/linux-deps/include/X11/bitmaps/tie_fighter deleted file mode 100644 index 0513db646..000000000 --- a/shell/linux-deps/include/X11/bitmaps/tie_fighter +++ /dev/null @@ -1,6 +0,0 @@ -#define tie_fighter_width 16 -#define tie_fighter_height 16 -static char tie_fighter_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x02, 0x40, - 0xe2, 0x47, 0x3e, 0x7c, 0x12, 0x48, 0x3e, 0x7c, 0xe2, 0x47, 0x02, 0x40, - 0x42, 0x42, 0x64, 0x26, 0x28, 0x14, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/vlines2 b/shell/linux-deps/include/X11/bitmaps/vlines2 deleted file mode 100644 index f42ae583f..000000000 --- a/shell/linux-deps/include/X11/bitmaps/vlines2 +++ /dev/null @@ -1,4 +0,0 @@ -#define vlines2_width 2 -#define vlines2_height 1 -static char vlines2_bits[] = { - 0x01}; diff --git a/shell/linux-deps/include/X11/bitmaps/vlines3 b/shell/linux-deps/include/X11/bitmaps/vlines3 deleted file mode 100644 index 55c224654..000000000 --- a/shell/linux-deps/include/X11/bitmaps/vlines3 +++ /dev/null @@ -1,4 +0,0 @@ -#define vlines3_width 3 -#define vlines3_height 1 -static char vlines3_bits[] = { - 0x02}; diff --git a/shell/linux-deps/include/X11/bitmaps/weird_size b/shell/linux-deps/include/X11/bitmaps/weird_size deleted file mode 100644 index e6f45d506..000000000 --- a/shell/linux-deps/include/X11/bitmaps/weird_size +++ /dev/null @@ -1,5 +0,0 @@ -#define weird_size_width 7 -#define weird_size_height 13 -static char weird_size_bits[] = { - 0x07, 0x05, 0x07, 0x01, 0x75, 0x45, 0x74, 0x44, 0x74, 0x00, 0x10, 0x38, - 0x10}; diff --git a/shell/linux-deps/include/X11/bitmaps/wide_weave b/shell/linux-deps/include/X11/bitmaps/wide_weave deleted file mode 100644 index 27ba6397f..000000000 --- a/shell/linux-deps/include/X11/bitmaps/wide_weave +++ /dev/null @@ -1,6 +0,0 @@ -#define wide_weave_width 16 -#define wide_weave_height 16 -static char wide_weave_bits[] = { - 0x11, 0x11, 0xb8, 0xb8, 0x7c, 0x7c, 0x3a, 0x3a, 0x11, 0x11, 0xa3, 0xa3, - 0xc7, 0xc7, 0x8b, 0x8b, 0x11, 0x11, 0xb8, 0xb8, 0x7c, 0x7c, 0x3a, 0x3a, - 0x11, 0x11, 0xa3, 0xa3, 0xc7, 0xc7, 0x8b, 0x8b}; diff --git a/shell/linux-deps/include/X11/bitmaps/wingdogs b/shell/linux-deps/include/X11/bitmaps/wingdogs deleted file mode 100644 index 1a4befc44..000000000 --- a/shell/linux-deps/include/X11/bitmaps/wingdogs +++ /dev/null @@ -1,14 +0,0 @@ -#define wingdogs_width 32 -#define wingdogs_height 32 -static char wingdogs_bits[] = { - 0x60, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, - 0x20, 0x0f, 0x00, 0x00, 0x40, 0x3e, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x80, - 0x84, 0xff, 0x00, 0xc0, 0x86, 0xff, 0x00, 0xc0, 0x07, 0xff, 0x21, 0xe0, - 0x0f, 0xfe, 0x23, 0xf0, 0x0f, 0xfe, 0x23, 0xfc, 0x1d, 0xfe, 0x13, 0xfe, - 0x39, 0xfc, 0x13, 0xff, 0x3f, 0xfc, 0x83, 0xff, 0x9f, 0xfc, 0xc1, 0xff, - 0x0f, 0xfe, 0xe0, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, - 0xfc, 0xff, 0xff, 0x7f, 0xf6, 0xff, 0xff, 0x1f, 0xfb, 0xff, 0xff, 0x07, - 0xf8, 0xfd, 0xff, 0x03, 0xbc, 0xf9, 0xff, 0x01, 0x3c, 0xf9, 0xff, 0x01, - 0x3e, 0xf0, 0xf7, 0x00, 0x1f, 0xe0, 0x77, 0x00, 0x1f, 0x80, 0x77, 0x00, - 0x8f, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x6e, 0x80, 0x07, 0x00, 0x7c, 0x80, - 0x0d, 0x00, 0xf8, 0x80, 0x1f, 0x00, 0xf0, 0x01}; diff --git a/shell/linux-deps/include/X11/bitmaps/woman b/shell/linux-deps/include/X11/bitmaps/woman deleted file mode 100644 index 92e604186..000000000 --- a/shell/linux-deps/include/X11/bitmaps/woman +++ /dev/null @@ -1,66 +0,0 @@ -#define sorceress_width 75 -#define sorceress_height 75 -static char sorceress_bits[] = { - 0xfc, 0x7e, 0x40, 0x20, 0x90, 0x00, 0x07, 0x80, 0x23, 0x00, 0x00, 0xc6, - 0xc1, 0x41, 0x98, 0xb8, 0x01, 0x07, 0x66, 0x00, 0x15, 0x9f, 0x03, 0x47, - 0x8c, 0xc6, 0xdc, 0x7b, 0xcc, 0x00, 0xb0, 0x71, 0x0e, 0x4d, 0x06, 0x66, - 0x73, 0x8e, 0x8f, 0x01, 0x18, 0xc4, 0x39, 0x4b, 0x02, 0x23, 0x0c, 0x04, - 0x1e, 0x03, 0x0c, 0x08, 0xc7, 0xef, 0x08, 0x30, 0x06, 0x07, 0x1c, 0x02, - 0x06, 0x30, 0x18, 0xae, 0xc8, 0x98, 0x3f, 0x78, 0x20, 0x06, 0x02, 0x20, - 0x60, 0xa0, 0xc4, 0x1d, 0xc0, 0xff, 0x41, 0x04, 0xfa, 0x63, 0x80, 0xa1, - 0xa4, 0x3d, 0x00, 0x84, 0xbf, 0x04, 0x0f, 0x06, 0xfc, 0xa1, 0x34, 0x6b, - 0x01, 0x1c, 0xc9, 0x05, 0x06, 0xc7, 0x06, 0xbe, 0x11, 0x1e, 0x43, 0x30, - 0x91, 0x05, 0xc3, 0x61, 0x02, 0x30, 0x1b, 0x30, 0xcc, 0x20, 0x11, 0x00, - 0xc1, 0x3c, 0x03, 0x20, 0x0a, 0x00, 0xe8, 0x60, 0x21, 0x00, 0x61, 0x1b, - 0xc1, 0x63, 0x08, 0xf0, 0xc6, 0xc7, 0x21, 0x03, 0xf8, 0x08, 0xe1, 0xcf, - 0x0a, 0xfc, 0x4d, 0x99, 0x43, 0x07, 0x3c, 0x0c, 0xf1, 0x9f, 0x0b, 0xfc, - 0x5b, 0x81, 0x47, 0x02, 0x16, 0x04, 0x31, 0x1c, 0x0b, 0x1f, 0x17, 0x89, - 0x4d, 0x06, 0x1a, 0x04, 0x31, 0x38, 0x02, 0x07, 0x56, 0x89, 0x49, 0x04, - 0x0b, 0x04, 0xb1, 0x72, 0x82, 0xa1, 0x54, 0x9a, 0x49, 0x04, 0x1d, 0x66, - 0x50, 0xe7, 0xc2, 0xf0, 0x54, 0x9a, 0x58, 0x04, 0x0d, 0x62, 0xc1, 0x1f, - 0x44, 0xfc, 0x51, 0x90, 0x90, 0x04, 0x86, 0x63, 0xe0, 0x74, 0x04, 0xef, - 0x31, 0x1a, 0x91, 0x00, 0x02, 0xe2, 0xc1, 0xfd, 0x84, 0xf9, 0x30, 0x0a, - 0x91, 0x00, 0x82, 0xa9, 0xc0, 0xb9, 0x84, 0xf9, 0x31, 0x16, 0x81, 0x00, - 0x42, 0xa9, 0xdb, 0x7f, 0x0c, 0xff, 0x1c, 0x16, 0x11, 0x00, 0x02, 0x28, - 0x0b, 0x07, 0x08, 0x60, 0x1c, 0x02, 0x91, 0x00, 0x46, 0x29, 0x0e, 0x00, - 0x00, 0x00, 0x10, 0x16, 0x11, 0x02, 0x06, 0x29, 0x04, 0x00, 0x00, 0x00, - 0x10, 0x16, 0x91, 0x06, 0xa6, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x24, - 0x91, 0x04, 0x86, 0x2a, 0x04, 0x00, 0x00, 0x00, 0x18, 0x27, 0x93, 0x04, - 0x96, 0x4a, 0x04, 0x00, 0x00, 0x00, 0x04, 0x02, 0x91, 0x04, 0x86, 0x4a, - 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x23, 0x93, 0x04, 0x56, 0x88, 0x08, 0x00, - 0x00, 0x00, 0x90, 0x21, 0x93, 0x04, 0x52, 0x0a, 0x09, 0x80, 0x01, 0x00, - 0xd0, 0x21, 0x95, 0x04, 0x57, 0x0a, 0x0f, 0x80, 0x27, 0x00, 0xd8, 0x20, - 0x9d, 0x04, 0x5d, 0x08, 0x1c, 0x80, 0x67, 0x00, 0xe4, 0x01, 0x85, 0x04, - 0x79, 0x8a, 0x3f, 0x00, 0x00, 0x00, 0xf4, 0x11, 0x85, 0x06, 0x39, 0x08, - 0x7d, 0x00, 0x00, 0x18, 0xb7, 0x10, 0x81, 0x03, 0x29, 0x12, 0xcb, 0x00, - 0x7e, 0x30, 0x28, 0x00, 0x85, 0x03, 0x29, 0x10, 0xbe, 0x81, 0xff, 0x27, - 0x0c, 0x10, 0x85, 0x03, 0x29, 0x32, 0xfa, 0xc1, 0xff, 0x27, 0x94, 0x11, - 0x85, 0x03, 0x28, 0x20, 0x6c, 0xe1, 0xff, 0x07, 0x0c, 0x01, 0x85, 0x01, - 0x28, 0x62, 0x5c, 0xe3, 0x8f, 0x03, 0x4e, 0x91, 0x80, 0x05, 0x39, 0x40, - 0xf4, 0xc2, 0xff, 0x00, 0x9f, 0x91, 0x84, 0x05, 0x31, 0xc6, 0xe8, 0x07, - 0x7f, 0x80, 0xcd, 0x00, 0xc4, 0x04, 0x31, 0x06, 0xc9, 0x0e, 0x00, 0xc0, - 0x48, 0x88, 0xe0, 0x04, 0x79, 0x04, 0xdb, 0x12, 0x00, 0x30, 0x0c, 0xc8, - 0xe4, 0x04, 0x6d, 0x06, 0xb6, 0x23, 0x00, 0x18, 0x1c, 0xc0, 0x84, 0x04, - 0x25, 0x0c, 0xff, 0xc2, 0x00, 0x4e, 0x06, 0xb0, 0x80, 0x04, 0x3f, 0x8a, - 0xb3, 0x83, 0xff, 0xc3, 0x03, 0x91, 0x84, 0x04, 0x2e, 0xd8, 0x0f, 0x3f, - 0x00, 0x00, 0x5f, 0x83, 0x84, 0x04, 0x2a, 0x70, 0xfd, 0x7f, 0x00, 0x00, - 0xc8, 0xc0, 0x84, 0x04, 0x4b, 0xe2, 0x2f, 0x01, 0x00, 0x08, 0x58, 0x60, - 0x80, 0x04, 0x5b, 0x82, 0xff, 0x01, 0x00, 0x08, 0xd0, 0xa0, 0x84, 0x04, - 0x72, 0x80, 0xe5, 0x00, 0x00, 0x08, 0xd2, 0x20, 0x44, 0x04, 0xca, 0x02, - 0xff, 0x00, 0x00, 0x08, 0xde, 0xa0, 0x44, 0x04, 0x82, 0x02, 0x6d, 0x00, - 0x00, 0x08, 0xf6, 0xb0, 0x40, 0x02, 0x82, 0x07, 0x3f, 0x00, 0x00, 0x08, - 0x44, 0x58, 0x44, 0x02, 0x93, 0x3f, 0x1f, 0x00, 0x00, 0x30, 0x88, 0x4f, - 0x44, 0x03, 0x83, 0x23, 0x3e, 0x00, 0x00, 0x00, 0x18, 0x60, 0xe0, 0x07, - 0xe3, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x70, 0x70, 0xe4, 0x07, 0xc7, 0x1b, - 0xfe, 0x01, 0x00, 0x00, 0xe0, 0x3c, 0xe4, 0x07, 0xc7, 0xe3, 0xfe, 0x1f, - 0x00, 0x00, 0xff, 0x1f, 0xfc, 0x07, 0xc7, 0x03, 0xf8, 0x33, 0x00, 0xc0, - 0xf0, 0x07, 0xff, 0x07, 0x87, 0x02, 0xfc, 0x43, 0x00, 0x60, 0xf0, 0xff, - 0xff, 0x07, 0x8f, 0x06, 0xbe, 0x87, 0x00, 0x30, 0xf8, 0xff, 0xff, 0x07, - 0x8f, 0x14, 0x9c, 0x8f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x07, 0x9f, 0x8d, - 0x8a, 0x0f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xbf, 0x0b, 0x80, 0x1f, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x7f, 0x3a, 0x80, 0x3f, 0x00, 0x80, - 0xff, 0xff, 0xff, 0x07, 0xff, 0x20, 0xc0, 0x3f, 0x00, 0x80, 0xff, 0xff, - 0xff, 0x07, 0xff, 0x01, 0xe0, 0x7f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x07, - 0xff, 0x0f, 0xf8, 0xff, 0x40, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, - 0xff, 0xff, 0x40, 0xf0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, - 0x41, 0xf0, 0xff, 0xff, 0xff, 0x07}; diff --git a/shell/linux-deps/include/X11/bitmaps/xfd_icon b/shell/linux-deps/include/X11/bitmaps/xfd_icon deleted file mode 100644 index 383334cf9..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xfd_icon +++ /dev/null @@ -1,27 +0,0 @@ -#define xfd_icon_width 48 -#define xfd_icon_height 48 -static char xfd_icon_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x01, 0x81, 0x40, 0x20, 0x10, 0x08, - 0x11, 0x9d, 0x5c, 0xa7, 0xd7, 0x0b, 0x29, 0xa5, 0x42, 0xa9, 0x50, 0x08, - 0x45, 0xa5, 0x42, 0xa9, 0x50, 0x08, 0x7d, 0x9d, 0x42, 0xa9, 0xd7, 0x09, - 0x45, 0xa5, 0x42, 0xa9, 0x50, 0x08, 0x45, 0xa5, 0x42, 0xa9, 0x50, 0x08, - 0x45, 0x9d, 0x5c, 0xa7, 0x57, 0x08, 0x01, 0x81, 0x40, 0x20, 0x10, 0x08, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/bitmaps/xlogo11 b/shell/linux-deps/include/X11/bitmaps/xlogo11 deleted file mode 100644 index 5efd2c20e..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xlogo11 +++ /dev/null @@ -1,6 +0,0 @@ -#define xlogo11_width 11 -#define xlogo11_height 11 - -static char xlogo11_bits[] = { - 0x0f, 0x04, 0x0f, 0x02, 0x1e, 0x01, 0x3c, 0x01, 0xb8, 0x00, 0x58, 0x00, - 0xe8, 0x00, 0xe4, 0x01, 0xc4, 0x03, 0xc2, 0x03, 0x81, 0x07 }; diff --git a/shell/linux-deps/include/X11/bitmaps/xlogo16 b/shell/linux-deps/include/X11/bitmaps/xlogo16 deleted file mode 100644 index 5c2302734..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xlogo16 +++ /dev/null @@ -1,6 +0,0 @@ -#define xlogo16_width 16 -#define xlogo16_height 16 -static unsigned char xlogo16_bits[] = { - 0x0f, 0x80, 0x1e, 0x80, 0x3c, 0x40, 0x78, 0x20, 0x78, 0x10, 0xf0, 0x08, - 0xe0, 0x09, 0xc0, 0x05, 0xc0, 0x02, 0x40, 0x07, 0x20, 0x0f, 0x20, 0x1e, - 0x10, 0x1e, 0x08, 0x3c, 0x04, 0x78, 0x02, 0xf0}; diff --git a/shell/linux-deps/include/X11/bitmaps/xlogo32 b/shell/linux-deps/include/X11/bitmaps/xlogo32 deleted file mode 100644 index 1ecb6acaa..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xlogo32 +++ /dev/null @@ -1,14 +0,0 @@ -#define xlogo32_width 32 -#define xlogo32_height 32 -static char xlogo32_bits[] = { - 0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x00, 0xc0, 0xfc, 0x03, 0x00, 0x60, - 0xf8, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x00, 0x18, 0xf0, 0x0f, 0x00, 0x0c, - 0xe0, 0x1f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x03, - 0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00, - 0x00, 0xfe, 0x31, 0x00, 0x00, 0xfc, 0x33, 0x00, 0x00, 0xf8, 0x1b, 0x00, - 0x00, 0xf0, 0x0d, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x60, 0x1f, 0x00, - 0x00, 0xb0, 0x3f, 0x00, 0x00, 0x98, 0x7f, 0x00, 0x00, 0x98, 0x7f, 0x00, - 0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x03, 0xfc, 0x03, - 0x80, 0x01, 0xfc, 0x03, 0xc0, 0x00, 0xf8, 0x07, 0xc0, 0x00, 0xf0, 0x0f, - 0x60, 0x00, 0xe0, 0x1f, 0x30, 0x00, 0xe0, 0x1f, 0x18, 0x00, 0xc0, 0x3f, - 0x0c, 0x00, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff}; diff --git a/shell/linux-deps/include/X11/bitmaps/xlogo64 b/shell/linux-deps/include/X11/bitmaps/xlogo64 deleted file mode 100644 index ad3b0dbbf..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xlogo64 +++ /dev/null @@ -1,46 +0,0 @@ -#define xlogo64_width 64 -#define xlogo64_height 64 -static unsigned char xlogo64_bits[] = { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfe, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x7c, - 0xf8, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x3e, 0xf8, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x0f, - 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xc0, 0xff, 0x3f, 0x00, - 0x00, 0x00, 0xc0, 0x07, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xe0, 0x03, - 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0xf8, 0x00, - 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00, 0xfc, 0xff, 0x03, - 0x00, 0x00, 0x3e, 0x00, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x1f, 0x00, - 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0x0f, - 0x00, 0xc0, 0x07, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xc0, 0x07, 0x00, - 0x00, 0xc0, 0xff, 0x3f, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x80, 0xff, 0x7f, - 0x00, 0xf0, 0x01, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0xf8, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, - 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0xff, 0x03, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, - 0x87, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xcf, 0x07, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xcf, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, - 0xe7, 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xf3, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xff, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, - 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xcf, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe7, - 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe7, 0xff, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0xc3, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc1, - 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xff, 0x7f, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, - 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xfe, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x1f, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x80, 0x0f, 0x00, - 0xf8, 0xff, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0xf0, 0xff, 0x0f, 0x00, - 0x00, 0xe0, 0x03, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0x03, 0x00, - 0xe0, 0xff, 0x1f, 0x00, 0x00, 0xf0, 0x01, 0x00, 0xc0, 0xff, 0x3f, 0x00, - 0x00, 0xf8, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x7c, 0x00, 0x00, - 0x80, 0xff, 0x7f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x3e, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x1f, 0x00, 0x00, - 0x00, 0xfc, 0xff, 0x03, 0x80, 0x0f, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, - 0xc0, 0x07, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x07, 0xe0, 0x03, 0x00, 0x00, - 0x00, 0xf0, 0xff, 0x0f, 0xe0, 0x03, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, - 0xf0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x1f, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xff, 0x3f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, - 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff}; diff --git a/shell/linux-deps/include/X11/bitmaps/xsnow b/shell/linux-deps/include/X11/bitmaps/xsnow deleted file mode 100644 index 2c1bd8b65..000000000 --- a/shell/linux-deps/include/X11/bitmaps/xsnow +++ /dev/null @@ -1,1112 +0,0 @@ -#define xsnow_width 300 -#define xsnow_height 350 -static char xsnow_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, - 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x01, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x99, 0x39, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9e, 0x1f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x98, - 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x09, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x0f, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfe, 0x03, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x47, 0x00, - 0x00, 0x90, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xce, - 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x6c, 0x0f, 0xef, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6a, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0xcf, 0x07, 0x7c, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0xf7, 0x03, 0x1e, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x70, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc, 0x07, 0x7e, 0x5b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x60, 0x30, 0xf0, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x07, 0xef, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x71, - 0xf0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xfe, - 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x77, 0xf0, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xb0, 0x33, 0xf0, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0xf0, 0xe1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0xe0, 0xe1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0c, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0xe0, 0x81, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x9c, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x30, - 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x19, 0xe0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x99, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x1f, 0xe0, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xf0, 0x7b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xfc, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0x68, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0xdf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x33, 0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0xf6, 0xff, 0x03, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0xfe, 0xff, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x1e, 0xce, 0x03, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x1f, 0x80, 0x07, 0x7c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, - 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x90, 0xc3, 0x1f, 0x80, 0x1f, - 0x7e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3f, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1c, 0xef, 0x0f, - 0x80, 0xbf, 0xff, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x1e, - 0xfc, 0x07, 0x80, 0xff, 0x8f, 0x7b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0xf8, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x40, - 0xdb, 0x0f, 0xf8, 0x03, 0x00, 0xf7, 0x07, 0xff, 0x16, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb8, 0x0f, 0x03, 0x00, 0x00, - 0x00, 0xe0, 0x8d, 0x07, 0xfe, 0x01, 0x00, 0xfc, 0x03, 0x8e, 0x3d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x3d, 0xdc, 0x23, - 0x00, 0x00, 0x00, 0x60, 0xef, 0x03, 0x7f, 0x07, 0x00, 0xfe, 0x80, 0xcf, - 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3e, 0x1f, - 0xfc, 0xbd, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x8e, 0x7f, 0x0f, 0x00, 0xff, - 0xc1, 0xfb, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, - 0x1d, 0x0f, 0x58, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x30, 0xfc, 0xef, 0x0f, - 0x80, 0xbf, 0xc3, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xde, 0x1f, 0x7c, 0xbe, 0x01, 0x00, 0x00, 0x00, 0x10, 0xf0, - 0xc3, 0x0f, 0xc0, 0x1f, 0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe2, 0x1d, 0xde, 0x27, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x01, 0x0f, 0xc0, 0x07, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x78, 0x0e, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x9e, 0xc3, 0x03, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf8, 0x0f, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xfe, 0xdf, 0x03, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfe, 0x7f, 0x03, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3f, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, - 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x39, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xff, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x7e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0xe0, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x33, - 0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1e, 0xe0, 0xfe, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1e, - 0x60, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x1c, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x1c, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3c, 0x70, 0x62, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3f, 0x70, 0x6f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x39, - 0x70, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7e, 0x20, 0x30, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x33, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x50, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xf0, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0b, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x67, 0x00, - 0x00, 0x90, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xcf, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfc, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xdc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xd8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x98, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x1f, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x3e, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x7b, 0x78, - 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7d, - 0x3e, 0xf8, 0xd3, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x33, 0x1a, 0xf0, 0xb0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xad, 0x3f, 0xf0, 0xf9, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x3b, 0x78, 0x9f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x39, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x1f, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x73, 0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x88, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xac, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfc, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xcf, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x33, 0x60, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xe0, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xe0, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x13, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x1f, 0xc0, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xcf, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xc1, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x00, 0x86, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb6, 0x07, 0x00, 0xec, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe7, 0x03, 0x00, - 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf3, - 0x00, 0x00, 0x3c, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0xfe, 0x01, 0x00, 0x7e, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xbc, 0x03, 0x00, 0xef, 0x11, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x87, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x80, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, - 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x19, 0x40, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, - 0x11, 0x00, 0x00, 0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1b, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3b, 0x60, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x1a, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x08, 0x00, 0x00, 0x4c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x33, 0x20, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0b, 0x00, 0x00, 0xcc, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x08, - 0x04, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, - 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x0c, 0x9c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x0d, 0xfc, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x23, 0x60, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x0c, 0x7c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x3c, 0x1c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0xe0, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x38, 0x1c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, - 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x17, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x1f, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x7f, 0x06, 0x78, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xff, 0x07, 0x78, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xdf, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x7c, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc5, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0xff, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0xc0, 0xfd, 0x7f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x87, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0xc0, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbc, 0x07, 0x00, 0xee, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xc0, 0x87, 0xf9, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf6, 0x03, 0x00, - 0xfc, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xe0, 0x07, 0xf0, 0x80, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xe3, - 0x01, 0x00, 0x78, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf4, 0xf0, 0x07, - 0xf0, 0xc3, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd8, 0xfb, 0x00, 0x00, 0x3e, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc7, - 0xfb, 0x03, 0xf0, 0xf7, 0x3f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0xbe, 0x03, 0x00, 0xef, 0x13, 0x00, 0x00, 0x00, 0x40, - 0xbc, 0x87, 0xff, 0x00, 0xf0, 0xff, 0x73, 0x8f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x07, 0x00, 0x87, 0x01, 0x00, 0x00, - 0x00, 0xd0, 0xf6, 0x03, 0xff, 0x00, 0xc0, 0xff, 0xe0, 0xdf, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x01, 0x01, - 0x00, 0x00, 0x00, 0xf8, 0xe3, 0x81, 0x3f, 0x00, 0x00, 0x7f, 0xc0, 0x33, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xfb, 0xc0, 0xef, 0x00, 0xc0, 0x3f, - 0xf0, 0xf9, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbe, 0xf3, 0xff, 0x03, - 0xe0, 0x3f, 0x78, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, - 0xfb, 0x03, 0xf0, 0x77, 0x38, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x80, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x98, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0xfc, 0xf0, 0x03, 0xf8, 0xc3, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xe0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf8, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xe0, 0x03, 0xf8, 0x80, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x05, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xc0, 0x67, 0xf8, 0x00, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x67, 0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x19, 0xc0, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0xff, 0xff, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x19, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0xff, - 0x6f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3b, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xf7, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0xcc, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x33, 0x60, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0xfc, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9f, 0x07, 0xf8, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0xf8, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x87, 0x07, - 0x98, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x38, 0x1f, 0x06, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x81, 0x07, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x3d, 0xbc, 0x47, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x07, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3e, 0x1f, 0xfc, - 0x69, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x19, - 0x0d, 0x78, 0xd8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x0c, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0xd6, 0x1f, 0xf8, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0xcc, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe2, 0x1d, 0xbc, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x0f, - 0xec, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xf8, 0x1c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x0e, 0x8c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf8, 0x0f, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0x1f, 0x08, 0x04, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x39, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1c, 0x00, 0x00, 0x56, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1e, 0x00, - 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x56, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, - 0x19, 0x00, 0x00, 0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x67, 0xe6, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x07, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x80, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, - 0x98, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x0e, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x08, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x09, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0xf0, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xf8, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf6, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x42, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x40, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x03, - 0x80, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0xdb, 0x03, 0x00, 0xfb, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0xf3, 0x01, 0x00, 0xbc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0x79, 0x00, 0x00, 0x8f, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x23, 0x00, 0x00, - 0x00, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0x00, 0x80, 0xdf, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xde, 0x01, 0xc0, 0x7b, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x03, - 0xc0, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x10, 0x00, 0x20, 0xf0, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x18, 0x00, - 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x67, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, - 0x1b, 0x00, 0xe0, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x19, 0x00, 0xe0, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0xe0, 0xe1, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x0f, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x00, 0xc0, 0xe1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x0e, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x00, 0xc0, 0x81, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0c, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x08, 0x00, - 0xc0, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x58, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, - 0x0c, 0x00, 0xc0, 0xc3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0xf8, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfe, 0x0f, 0x00, 0xc0, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x09, - 0x88, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0xf8, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x01, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0xfe, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x87, - 0xcf, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf3, 0xff, 0xc3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc3, 0xcf, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, - 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x3c, - 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, - 0x00, 0x78, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x1e, 0xfe, - 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe1, - 0x78, 0x7f, 0x00, 0x00, 0x00, 0xc0, 0xfb, 0x1f, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x88, 0xf7, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xb9, 0x47, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xda, 0x7e, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf0, - 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0x3c, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x80, - 0x3f, 0xe0, 0xb9, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x1f, 0xf8, 0x01, 0x00, 0x00, - 0x00, 0xc0, 0x1f, 0xf8, 0x7c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x77, 0xfe, 0x03, - 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xbc, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe1, - 0x7f, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x7b, 0x1c, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x1f, 0x0e, 0x00, 0x00, 0x00, 0xfc, 0xe1, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x0f, 0x38, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x70, 0x00, 0x00, 0x00, 0x3c, - 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x00, 0x00, - 0x00, 0x1c, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x80, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xec, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, - 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x3f, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x23, - 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xc7, 0xff, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x3f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x01, 0xff, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x35, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7f, 0x00, - 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, - 0x1f, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x17, 0x00, 0x00, 0x98, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3e, 0x0f, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x10, 0x08, - 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x0f, 0x0f, 0x00, 0xc0, 0xfc, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x18, 0x38, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x00, 0x60, 0xf0, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x1b, 0xf8, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x00, 0x60, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xcc, 0x19, 0xf8, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, - 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x18, 0x78, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x1e, 0x00, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x70, 0x38, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x1e, 0x00, 0x60, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x70, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x98, 0x1f, 0x00, 0x70, 0x7f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x00, 0x70, 0xfc, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0x0c, 0xf0, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x10, 0x00, 0x30, 0xf0, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x0f, 0xf0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x19, 0x00, 0x00, - 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0xf8, 0x3e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, - 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xfe, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3b, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x33, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x80, 0xfb, 0xff, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x80, 0x0f, 0xf3, 0x01, 0x1e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc0, 0x0f, 0xe0, 0x01, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0xe1, 0x0f, 0xe0, - 0x87, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x8e, 0xf7, - 0x07, 0xe0, 0xef, 0x7f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x78, - 0x0f, 0xff, 0x01, 0xe0, 0xff, 0xe7, 0x1e, 0x01, 0x00, 0x00, 0x00, 0xf0, - 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa0, 0xed, 0x07, 0xfe, 0x01, 0x80, 0xff, 0xc1, 0xbf, 0x05, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0xc7, 0x03, 0x7f, 0x00, 0x00, 0xfe, 0x80, 0x67, 0x0e, - 0x00, 0x00, 0x00, 0xe0, 0x06, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xb0, 0xf7, 0x81, 0xdf, 0x01, 0x80, 0x7f, 0xe0, - 0xf3, 0x0d, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x1f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7c, 0xe7, 0xff, 0x07, 0xc0, - 0x7f, 0xf0, 0x3e, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x1b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xfe, 0xf7, - 0x07, 0xe0, 0xef, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0xf8, 0xe1, 0x07, 0xf0, 0x87, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x8f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0xc0, 0x07, 0xf0, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x80, 0xcf, 0xf0, 0x01, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x19, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0xff, 0xff, 0x01, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0xff, 0xdf, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x04, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xef, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x01, 0xdc, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, - 0x01, 0xf8, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x73, 0x00, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0xf8, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xa0, 0x7f, 0x00, 0x78, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x0f, 0xf0, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0xde, 0x00, 0xdc, 0x0b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x0f, 0x30, - 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x04, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x0f, 0x30, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x0e, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf3, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1e, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xdf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1e, 0x98, 0x31, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x3f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xd8, - 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x1b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, - 0x1c, 0x18, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x41, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x3f, 0x10, 0x08, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x07, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xc1, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xc1, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x19, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xc1, 0x0d, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0xac, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, - 0xc1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3d, 0x00, 0x00, - 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xf7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x33, - 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x03, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x41, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x77, - 0x00, 0xf6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0x3d, 0x00, 0xbc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x1e, 0x00, 0xde, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x37, 0x00, 0xf7, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x63, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x41, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xb4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe3, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xc1, 0x0f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xc1, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, - 0xc1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0xc1, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; diff --git a/shell/linux-deps/include/X11/cursorfont.h b/shell/linux-deps/include/X11/cursorfont.h deleted file mode 100644 index c69d508f4..000000000 --- a/shell/linux-deps/include/X11/cursorfont.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -*/ - -#ifndef _X11_CURSORFONT_H_ -#define _X11_CURSORFONT_H_ - -#define XC_num_glyphs 154 -#define XC_X_cursor 0 -#define XC_arrow 2 -#define XC_based_arrow_down 4 -#define XC_based_arrow_up 6 -#define XC_boat 8 -#define XC_bogosity 10 -#define XC_bottom_left_corner 12 -#define XC_bottom_right_corner 14 -#define XC_bottom_side 16 -#define XC_bottom_tee 18 -#define XC_box_spiral 20 -#define XC_center_ptr 22 -#define XC_circle 24 -#define XC_clock 26 -#define XC_coffee_mug 28 -#define XC_cross 30 -#define XC_cross_reverse 32 -#define XC_crosshair 34 -#define XC_diamond_cross 36 -#define XC_dot 38 -#define XC_dotbox 40 -#define XC_double_arrow 42 -#define XC_draft_large 44 -#define XC_draft_small 46 -#define XC_draped_box 48 -#define XC_exchange 50 -#define XC_fleur 52 -#define XC_gobbler 54 -#define XC_gumby 56 -#define XC_hand1 58 -#define XC_hand2 60 -#define XC_heart 62 -#define XC_icon 64 -#define XC_iron_cross 66 -#define XC_left_ptr 68 -#define XC_left_side 70 -#define XC_left_tee 72 -#define XC_leftbutton 74 -#define XC_ll_angle 76 -#define XC_lr_angle 78 -#define XC_man 80 -#define XC_middlebutton 82 -#define XC_mouse 84 -#define XC_pencil 86 -#define XC_pirate 88 -#define XC_plus 90 -#define XC_question_arrow 92 -#define XC_right_ptr 94 -#define XC_right_side 96 -#define XC_right_tee 98 -#define XC_rightbutton 100 -#define XC_rtl_logo 102 -#define XC_sailboat 104 -#define XC_sb_down_arrow 106 -#define XC_sb_h_double_arrow 108 -#define XC_sb_left_arrow 110 -#define XC_sb_right_arrow 112 -#define XC_sb_up_arrow 114 -#define XC_sb_v_double_arrow 116 -#define XC_shuttle 118 -#define XC_sizing 120 -#define XC_spider 122 -#define XC_spraycan 124 -#define XC_star 126 -#define XC_target 128 -#define XC_tcross 130 -#define XC_top_left_arrow 132 -#define XC_top_left_corner 134 -#define XC_top_right_corner 136 -#define XC_top_side 138 -#define XC_top_tee 140 -#define XC_trek 142 -#define XC_ul_angle 144 -#define XC_umbrella 146 -#define XC_ur_angle 148 -#define XC_watch 150 -#define XC_xterm 152 - -#endif /* _X11_CURSORFONT_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XI.h b/shell/linux-deps/include/X11/extensions/XI.h deleted file mode 100644 index 7b443997c..000000000 --- a/shell/linux-deps/include/X11/extensions/XI.h +++ /dev/null @@ -1,308 +0,0 @@ -/************************************************************ - -Copyright 1989, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -********************************************************/ - -/* Definitions used by the server, library and client */ - -#ifndef _XI_H_ -#define _XI_H_ - -#define sz_xGetExtensionVersionReq 8 -#define sz_xGetExtensionVersionReply 32 -#define sz_xListInputDevicesReq 4 -#define sz_xListInputDevicesReply 32 -#define sz_xOpenDeviceReq 8 -#define sz_xOpenDeviceReply 32 -#define sz_xCloseDeviceReq 8 -#define sz_xSetDeviceModeReq 8 -#define sz_xSetDeviceModeReply 32 -#define sz_xSelectExtensionEventReq 12 -#define sz_xGetSelectedExtensionEventsReq 8 -#define sz_xGetSelectedExtensionEventsReply 32 -#define sz_xChangeDeviceDontPropagateListReq 12 -#define sz_xGetDeviceDontPropagateListReq 8 -#define sz_xGetDeviceDontPropagateListReply 32 -#define sz_xGetDeviceMotionEventsReq 16 -#define sz_xGetDeviceMotionEventsReply 32 -#define sz_xChangeKeyboardDeviceReq 8 -#define sz_xChangeKeyboardDeviceReply 32 -#define sz_xChangePointerDeviceReq 8 -#define sz_xChangePointerDeviceReply 32 -#define sz_xGrabDeviceReq 20 -#define sz_xGrabDeviceReply 32 -#define sz_xUngrabDeviceReq 12 -#define sz_xGrabDeviceKeyReq 20 -#define sz_xGrabDeviceKeyReply 32 -#define sz_xUngrabDeviceKeyReq 16 -#define sz_xGrabDeviceButtonReq 20 -#define sz_xGrabDeviceButtonReply 32 -#define sz_xUngrabDeviceButtonReq 16 -#define sz_xAllowDeviceEventsReq 12 -#define sz_xGetDeviceFocusReq 8 -#define sz_xGetDeviceFocusReply 32 -#define sz_xSetDeviceFocusReq 16 -#define sz_xGetFeedbackControlReq 8 -#define sz_xGetFeedbackControlReply 32 -#define sz_xChangeFeedbackControlReq 12 -#define sz_xGetDeviceKeyMappingReq 8 -#define sz_xGetDeviceKeyMappingReply 32 -#define sz_xChangeDeviceKeyMappingReq 8 -#define sz_xGetDeviceModifierMappingReq 8 -#define sz_xSetDeviceModifierMappingReq 8 -#define sz_xSetDeviceModifierMappingReply 32 -#define sz_xGetDeviceButtonMappingReq 8 -#define sz_xGetDeviceButtonMappingReply 32 -#define sz_xSetDeviceButtonMappingReq 8 -#define sz_xSetDeviceButtonMappingReply 32 -#define sz_xQueryDeviceStateReq 8 -#define sz_xQueryDeviceStateReply 32 -#define sz_xSendExtensionEventReq 16 -#define sz_xDeviceBellReq 8 -#define sz_xSetDeviceValuatorsReq 8 -#define sz_xSetDeviceValuatorsReply 32 -#define sz_xGetDeviceControlReq 8 -#define sz_xGetDeviceControlReply 32 -#define sz_xChangeDeviceControlReq 8 -#define sz_xChangeDeviceControlReply 32 -#define sz_xListDevicePropertiesReq 8 -#define sz_xListDevicePropertiesReply 32 -#define sz_xChangeDevicePropertyReq 20 -#define sz_xDeleteDevicePropertyReq 12 -#define sz_xGetDevicePropertyReq 24 -#define sz_xGetDevicePropertyReply 32 - -#define INAME "XInputExtension" - -#define XI_KEYBOARD "KEYBOARD" -#define XI_MOUSE "MOUSE" -#define XI_TABLET "TABLET" -#define XI_TOUCHSCREEN "TOUCHSCREEN" -#define XI_TOUCHPAD "TOUCHPAD" -#define XI_BARCODE "BARCODE" -#define XI_BUTTONBOX "BUTTONBOX" -#define XI_KNOB_BOX "KNOB_BOX" -#define XI_ONE_KNOB "ONE_KNOB" -#define XI_NINE_KNOB "NINE_KNOB" -#define XI_TRACKBALL "TRACKBALL" -#define XI_QUADRATURE "QUADRATURE" -#define XI_ID_MODULE "ID_MODULE" -#define XI_SPACEBALL "SPACEBALL" -#define XI_DATAGLOVE "DATAGLOVE" -#define XI_EYETRACKER "EYETRACKER" -#define XI_CURSORKEYS "CURSORKEYS" -#define XI_FOOTMOUSE "FOOTMOUSE" -#define XI_JOYSTICK "JOYSTICK" - -/* Indices into the versions[] array (XExtInt.c). Used as a index to - * retrieve the minimum version of XI from _XiCheckExtInit */ -#define Dont_Check 0 -#define XInput_Initial_Release 1 -#define XInput_Add_XDeviceBell 2 -#define XInput_Add_XSetDeviceValuators 3 -#define XInput_Add_XChangeDeviceControl 4 -#define XInput_Add_DevicePresenceNotify 5 -#define XInput_Add_DeviceProperties 6 -/* DO NOT ADD TO HERE -> XI2 */ - -#define XI_Absent 0 -#define XI_Present 1 - -#define XI_Initial_Release_Major 1 -#define XI_Initial_Release_Minor 0 - -#define XI_Add_XDeviceBell_Major 1 -#define XI_Add_XDeviceBell_Minor 1 - -#define XI_Add_XSetDeviceValuators_Major 1 -#define XI_Add_XSetDeviceValuators_Minor 2 - -#define XI_Add_XChangeDeviceControl_Major 1 -#define XI_Add_XChangeDeviceControl_Minor 3 - -#define XI_Add_DevicePresenceNotify_Major 1 -#define XI_Add_DevicePresenceNotify_Minor 4 - -#define XI_Add_DeviceProperties_Major 1 -#define XI_Add_DeviceProperties_Minor 5 - -#define DEVICE_RESOLUTION 1 -#define DEVICE_ABS_CALIB 2 -#define DEVICE_CORE 3 -#define DEVICE_ENABLE 4 -#define DEVICE_ABS_AREA 5 - -#define NoSuchExtension 1 - -#define COUNT 0 -#define CREATE 1 - -#define NewPointer 0 -#define NewKeyboard 1 - -#define XPOINTER 0 -#define XKEYBOARD 1 - -#define UseXKeyboard 0xFF - -#define IsXPointer 0 -#define IsXKeyboard 1 -#define IsXExtensionDevice 2 -#define IsXExtensionKeyboard 3 -#define IsXExtensionPointer 4 - -#define AsyncThisDevice 0 -#define SyncThisDevice 1 -#define ReplayThisDevice 2 -#define AsyncOtherDevices 3 -#define AsyncAll 4 -#define SyncAll 5 - -#define FollowKeyboard 3 -#ifndef RevertToFollowKeyboard -#define RevertToFollowKeyboard 3 -#endif - -#define DvAccelNum (1L << 0) -#define DvAccelDenom (1L << 1) -#define DvThreshold (1L << 2) - -#define DvKeyClickPercent (1L<<0) -#define DvPercent (1L<<1) -#define DvPitch (1L<<2) -#define DvDuration (1L<<3) -#define DvLed (1L<<4) -#define DvLedMode (1L<<5) -#define DvKey (1L<<6) -#define DvAutoRepeatMode (1L<<7) - -#define DvString (1L << 0) - -#define DvInteger (1L << 0) - -#define DeviceMode (1L << 0) -#define Relative 0 -#define Absolute 1 - -#define ProximityState (1L << 1) -#define InProximity (0L << 1) -#define OutOfProximity (1L << 1) - -#define AddToList 0 -#define DeleteFromList 1 - -#define KeyClass 0 -#define ButtonClass 1 -#define ValuatorClass 2 -#define FeedbackClass 3 -#define ProximityClass 4 -#define FocusClass 5 -#define OtherClass 6 -#define AttachClass 7 - -#define KbdFeedbackClass 0 -#define PtrFeedbackClass 1 -#define StringFeedbackClass 2 -#define IntegerFeedbackClass 3 -#define LedFeedbackClass 4 -#define BellFeedbackClass 5 - -#define _devicePointerMotionHint 0 -#define _deviceButton1Motion 1 -#define _deviceButton2Motion 2 -#define _deviceButton3Motion 3 -#define _deviceButton4Motion 4 -#define _deviceButton5Motion 5 -#define _deviceButtonMotion 6 -#define _deviceButtonGrab 7 -#define _deviceOwnerGrabButton 8 -#define _noExtensionEvent 9 - -#define _devicePresence 0 - -#define _deviceEnter 0 -#define _deviceLeave 1 - -/* Device presence notify states */ -#define DeviceAdded 0 -#define DeviceRemoved 1 -#define DeviceEnabled 2 -#define DeviceDisabled 3 -#define DeviceUnrecoverable 4 -#define DeviceControlChanged 5 - -/* XI Errors */ -#define XI_BadDevice 0 -#define XI_BadEvent 1 -#define XI_BadMode 2 -#define XI_DeviceBusy 3 -#define XI_BadClass 4 - -/* - * Make XEventClass be a CARD32 for 64 bit servers. Don't affect client - * definition of XEventClass since that would be a library interface change. - * See the top of X.h for more _XSERVER64 magic. - * - * But, don't actually use the CARD32 type. We can't get it defined here - * without polluting the namespace. - */ -#ifdef _XSERVER64 -typedef unsigned int XEventClass; -#else -typedef unsigned long XEventClass; -#endif - -/******************************************************************* - * - * Extension version structure. - * - */ - -typedef struct { - int present; - short major_version; - short minor_version; -} XExtensionVersion; - -#endif /* _XI_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XI2.h b/shell/linux-deps/include/X11/extensions/XI2.h deleted file mode 100644 index e864b0635..000000000 --- a/shell/linux-deps/include/X11/extensions/XI2.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _XI2_H_ -#define _XI2_H_ - -#define XInput_2_0 7 -/* DO NOT ADD TO THIS LIST. These are libXi-specific defines. - See commit libXi-1.4.2-21-ge8531dd */ - -#define XI_2_Major 2 -#define XI_2_Minor 2 - -/* Property event flags */ -#define XIPropertyDeleted 0 -#define XIPropertyCreated 1 -#define XIPropertyModified 2 - -/* Property modes */ -#define XIPropModeReplace 0 -#define XIPropModePrepend 1 -#define XIPropModeAppend 2 - -/* Special property type used for XIGetProperty */ -#define XIAnyPropertyType 0L - -/* Enter/Leave and Focus In/Out modes */ -#define XINotifyNormal 0 -#define XINotifyGrab 1 -#define XINotifyUngrab 2 -#define XINotifyWhileGrabbed 3 -#define XINotifyPassiveGrab 4 -#define XINotifyPassiveUngrab 5 - -/* Enter/Leave and focus In/out detail */ -#define XINotifyAncestor 0 -#define XINotifyVirtual 1 -#define XINotifyInferior 2 -#define XINotifyNonlinear 3 -#define XINotifyNonlinearVirtual 4 -#define XINotifyPointer 5 -#define XINotifyPointerRoot 6 -#define XINotifyDetailNone 7 - -/* Grab modes */ -#define XIGrabModeSync 0 -#define XIGrabModeAsync 1 -#define XIGrabModeTouch 2 - -/* Grab reply status codes */ -#define XIGrabSuccess 0 -#define XIAlreadyGrabbed 1 -#define XIGrabInvalidTime 2 -#define XIGrabNotViewable 3 -#define XIGrabFrozen 4 - -/* Grab owner events values */ -#define XIOwnerEvents True -#define XINoOwnerEvents False - -/* Passive grab types */ -#define XIGrabtypeButton 0 -#define XIGrabtypeKeycode 1 -#define XIGrabtypeEnter 2 -#define XIGrabtypeFocusIn 3 -#define XIGrabtypeTouchBegin 4 - -/* Passive grab modifier */ -#define XIAnyModifier (1U << 31) -#define XIAnyButton 0 -#define XIAnyKeycode 0 - -/* XIAllowEvents event-modes */ -#define XIAsyncDevice 0 -#define XISyncDevice 1 -#define XIReplayDevice 2 -#define XIAsyncPairedDevice 3 -#define XIAsyncPair 4 -#define XISyncPair 5 -#define XIAcceptTouch 6 -#define XIRejectTouch 7 - -/* DeviceChangedEvent change reasons */ -#define XISlaveSwitch 1 -#define XIDeviceChange 2 - -/* Hierarchy flags */ -#define XIMasterAdded (1 << 0) -#define XIMasterRemoved (1 << 1) -#define XISlaveAdded (1 << 2) -#define XISlaveRemoved (1 << 3) -#define XISlaveAttached (1 << 4) -#define XISlaveDetached (1 << 5) -#define XIDeviceEnabled (1 << 6) -#define XIDeviceDisabled (1 << 7) - -/* ChangeHierarchy constants */ -#define XIAddMaster 1 -#define XIRemoveMaster 2 -#define XIAttachSlave 3 -#define XIDetachSlave 4 - -#define XIAttachToMaster 1 -#define XIFloating 2 - -/* Valuator modes */ -#define XIModeRelative 0 -#define XIModeAbsolute 1 - -/* Device types */ -#define XIMasterPointer 1 -#define XIMasterKeyboard 2 -#define XISlavePointer 3 -#define XISlaveKeyboard 4 -#define XIFloatingSlave 5 - -/* Device classes: classes that are not identical to Xi 1.x classes must be - * numbered starting from 8. */ -#define XIKeyClass 0 -#define XIButtonClass 1 -#define XIValuatorClass 2 -#define XIScrollClass 3 -#define XITouchClass 8 - -/* Scroll class types */ -#define XIScrollTypeVertical 1 -#define XIScrollTypeHorizontal 2 - -/* Scroll class flags */ -#define XIScrollFlagNoEmulation (1 << 0) -#define XIScrollFlagPreferred (1 << 1) - -/* Device event flags (common) */ -/* Device event flags (key events only) */ -#define XIKeyRepeat (1 << 16) -/* Device event flags (pointer events only) */ -#define XIPointerEmulated (1 << 16) -/* Device event flags (touch events only) */ -#define XITouchPendingEnd (1 << 16) -#define XITouchEmulatingPointer (1 << 17) - -/* Touch modes */ -#define XIDirectTouch 1 -#define XIDependentTouch 2 - -/* XI2 event mask macros */ -#define XISetMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] |= (1 << ((event) & 7))) -#define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7))) -#define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7))) -#define XIMaskLen(event) (((event) >> 3) + 1) - -/* Fake device ID's for event selection */ -#define XIAllDevices 0 -#define XIAllMasterDevices 1 - -/* Event types */ -#define XI_DeviceChanged 1 -#define XI_KeyPress 2 -#define XI_KeyRelease 3 -#define XI_ButtonPress 4 -#define XI_ButtonRelease 5 -#define XI_Motion 6 -#define XI_Enter 7 -#define XI_Leave 8 -#define XI_FocusIn 9 -#define XI_FocusOut 10 -#define XI_HierarchyChanged 11 -#define XI_PropertyEvent 12 -#define XI_RawKeyPress 13 -#define XI_RawKeyRelease 14 -#define XI_RawButtonPress 15 -#define XI_RawButtonRelease 16 -#define XI_RawMotion 17 -#define XI_TouchBegin 18 /* XI 2.2 */ -#define XI_TouchUpdate 19 -#define XI_TouchEnd 20 -#define XI_TouchOwnership 21 -#define XI_RawTouchBegin 22 -#define XI_RawTouchUpdate 23 -#define XI_RawTouchEnd 24 -#define XI_LASTEVENT XI_RawTouchEnd -/* NOTE: XI2LASTEVENT in xserver/include/inputstr.h must be the same value - * as XI_LASTEVENT if the server is supposed to handle masks etc. for this - * type of event. */ - -/* Event masks. - * Note: the protocol spec defines a mask to be of (1 << type). Clients are - * free to create masks by bitshifting instead of using these defines. - */ -#define XI_DeviceChangedMask (1 << XI_DeviceChanged) -#define XI_KeyPressMask (1 << XI_KeyPress) -#define XI_KeyReleaseMask (1 << XI_KeyRelease) -#define XI_ButtonPressMask (1 << XI_ButtonPress) -#define XI_ButtonReleaseMask (1 << XI_ButtonRelease) -#define XI_MotionMask (1 << XI_Motion) -#define XI_EnterMask (1 << XI_Enter) -#define XI_LeaveMask (1 << XI_Leave) -#define XI_FocusInMask (1 << XI_FocusIn) -#define XI_FocusOutMask (1 << XI_FocusOut) -#define XI_HierarchyChangedMask (1 << XI_HierarchyChanged) -#define XI_PropertyEventMask (1 << XI_PropertyEvent) -#define XI_RawKeyPressMask (1 << XI_RawKeyPress) -#define XI_RawKeyReleaseMask (1 << XI_RawKeyRelease) -#define XI_RawButtonPressMask (1 << XI_RawButtonPress) -#define XI_RawButtonReleaseMask (1 << XI_RawButtonRelease) -#define XI_RawMotionMask (1 << XI_RawMotion) -#define XI_TouchBeginMask (1 << XI_TouchBegin) -#define XI_TouchEndMask (1 << XI_TouchEnd) -#define XI_TouchOwnershipChangedMask (1 << XI_TouchOwnershipChanged) -#define XI_TouchUpdateMask (1 << XI_TouchUpdate) -#define XI_RawTouchBeginMask (1 << XI_RawTouchBegin) -#define XI_RawTouchEndMask (1 << XI_RawTouchEnd) -#define XI_RawTouchUpdateMask (1 << XI_RawTouchUpdate) - -#endif /* _XI2_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XI2proto.h b/shell/linux-deps/include/X11/extensions/XI2proto.h deleted file mode 100644 index 733f923b7..000000000 --- a/shell/linux-deps/include/X11/extensions/XI2proto.h +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -/* Conventions for this file: - * Names: - * structs: always typedef'd, prefixed with xXI, CamelCase - * struct members: lower_case_with_underscores - * Exceptions: reqType, ReqType, repType, RepType, sequenceNumber are - * named as such for historical reasons. - * request opcodes: X_XIRequestName as CamelCase - * defines: defines used in client applications must go in XI2.h - * defines used only in protocol handling: XISOMENAME - * - * Data types: unless there is a historical name for a datatype (e.g. - * Window), use stdint types specifying the size of the datatype. - * historical data type names must be defined and undefined at the top and - * end of the file. - * - * General: - * spaces, not tabs. - * structs specific to a request or reply added before the request - * definition. structs used in more than one request, reply or event - * appended to the common structs section before the definition of the - * first request. - * members of structs vertically aligned on column 16 if datatypes permit. - * otherwise alingned on next available 8n column. - */ - -/** - * Protocol definitions for the XI2 protocol. - * This file should not be included by clients that merely use XI2, but do not - * need the wire protocol. Such clients should include XI2.h, or the matching - * header from the library. - * - */ -#ifndef _XI2PROTO_H_ -#define _XI2PROTO_H_ - -#include -#include -#include -#include - -/* make sure types have right sizes for protocol structures. */ -#define Window uint32_t -#define Time uint32_t -#define Atom uint32_t -#define Cursor uint32_t - -/** - * XI2 Request opcodes - */ -#define X_XIQueryPointer 40 -#define X_XIWarpPointer 41 -#define X_XIChangeCursor 42 -#define X_XIChangeHierarchy 43 -#define X_XISetClientPointer 44 -#define X_XIGetClientPointer 45 -#define X_XISelectEvents 46 -#define X_XIQueryVersion 47 -#define X_XIQueryDevice 48 -#define X_XISetFocus 49 -#define X_XIGetFocus 50 -#define X_XIGrabDevice 51 -#define X_XIUngrabDevice 52 -#define X_XIAllowEvents 53 -#define X_XIPassiveGrabDevice 54 -#define X_XIPassiveUngrabDevice 55 -#define X_XIListProperties 56 -#define X_XIChangeProperty 57 -#define X_XIDeleteProperty 58 -#define X_XIGetProperty 59 -#define X_XIGetSelectedEvents 60 - -/** Number of XI requests */ -#define XI2REQUESTS (X_XIGetSelectedEvents - X_XIQueryPointer + 1) -/** Number of XI2 events */ -#define XI2EVENTS (XI_LASTEVENT + 1) - -/************************************************************************************* - * * - * COMMON STRUCTS * - * * - *************************************************************************************/ -/** Fixed point 16.16 */ -typedef int32_t FP1616; - -/** Fixed point 32.32 */ -typedef struct { - int32_t integral; - uint32_t frac; -} FP3232; - -/** - * Struct to describe a device. - * - * For a MasterPointer or a MasterKeyboard, 'attachment' specifies the - * paired master device. - * For a SlaveKeyboard or SlavePointer, 'attachment' specifies the master - * device this device is attached to. - * For a FloatingSlave, 'attachment' is undefined. - */ -typedef struct { - uint16_t deviceid; - uint16_t use; /**< ::XIMasterPointer, ::XIMasterKeyboard, - ::XISlavePointer, ::XISlaveKeyboard, - ::XIFloatingSlave */ - uint16_t attachment; /**< Current attachment or pairing.*/ - uint16_t num_classes; /**< Number of classes following this struct. */ - uint16_t name_len; /**< Length of name in bytes. */ - uint8_t enabled; /**< TRUE if device is enabled. */ - uint8_t pad; -} xXIDeviceInfo; - -/** - * Default template for a device class. - * A device class is equivalent to a device's capabilities. Multiple classes - * are supported per device. - */ -typedef struct { - uint16_t type; /**< One of *class */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint16_t pad; -} xXIAnyInfo; - -/** - * Denotes button capability on a device. - * Struct is followed by num_buttons * Atom that names the buttons in the - * device-native setup (i.e. ignoring button mappings). - */ -typedef struct { - uint16_t type; /**< Always ButtonClass */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint16_t num_buttons; /**< Number of buttons provide */ -} xXIButtonInfo; - -/** - * Denotes key capability on a device. - * Struct is followed by num_keys * CARD32 that lists the keycodes available - * on the device. - */ -typedef struct { - uint16_t type; /**< Always KeyClass */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint16_t num_keycodes; /**< Number of keys provided */ -} xXIKeyInfo; - -/** - * Denotes an valuator capability on a device. - * One XIValuatorInfo describes exactly one valuator (axis) on the device. - */ -typedef struct { - uint16_t type; /**< Always ValuatorClass */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint16_t number; /**< Valuator number */ - Atom label; /**< Axis label */ - FP3232 min; /**< Min value */ - FP3232 max; /**< Max value */ - FP3232 value; /**< Last published value */ - uint32_t resolution; /**< Resolutions in units/m */ - uint8_t mode; /**< ModeRelative or ModeAbsolute */ - uint8_t pad1; - uint16_t pad2; -} xXIValuatorInfo; - -/*** - * Denotes a scroll valuator on a device. - * One XIScrollInfo describes exactly one scroll valuator that must have a - * XIValuatorInfo struct. - */ -typedef struct { - uint16_t type; /**< Always ValuatorClass */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint16_t number; /**< Valuator number */ - uint16_t scroll_type; /**< ::XIScrollTypeVertical, ::XIScrollTypeHorizontal */ - uint16_t pad0; - uint32_t flags; /**< ::XIScrollFlagEmulate, ::XIScrollFlagPreferred */ - FP3232 increment; /**< Increment for one unit of scrolling */ -} xXIScrollInfo; - -/** - * Denotes multitouch capability on a device. - */ -typedef struct { - uint16_t type; /**< Always TouchClass */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t sourceid; /**< source device for this class */ - uint8_t mode; /**< DirectTouch or DependentTouch */ - uint8_t num_touches; /**< Maximum number of touches (0==unlimited) */ -} xXITouchInfo; - -/** - * Used to select for events on a given window. - * Struct is followed by (mask_len * CARD8), with each bit set representing - * the event mask for the given type. A mask bit represents an event type if - * (mask == (1 << type)). - */ -typedef struct { - uint16_t deviceid; /**< Device id to select for */ - uint16_t mask_len; /**< Length of mask in 4 byte units */ -} xXIEventMask; - -/** - * XKB modifier information. - * The effective modifier is a binary mask of base, latched, and locked - * modifiers. - */ -typedef struct -{ - uint32_t base_mods; /**< Logically pressed modifiers */ - uint32_t latched_mods; /**< Logically latched modifiers */ - uint32_t locked_mods; /**< Logically locked modifiers */ - uint32_t effective_mods; /**< Effective modifiers */ -} xXIModifierInfo; - -/** - * XKB group information. - * The effective group is the mathematical sum of base, latched, and locked - * group after group wrapping is taken into account. - */ -typedef struct -{ - uint8_t base_group; /**< Logically "pressed" group */ - uint8_t latched_group; /**< Logically latched group */ - uint8_t locked_group; /**< Logically locked group */ - uint8_t effective_group; /**< Effective group */ -} xXIGroupInfo; - - -/************************************************************************************* - * * - * REQUESTS * - * * - *************************************************************************************/ - -/** - * Query the server for the supported X Input extension version. - */ - -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIQueryVersion */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t major_version; - uint16_t minor_version; -} xXIQueryVersionReq; -#define sz_xXIQueryVersionReq 8 - -typedef struct { - uint8_t repType; /**< ::X_Reply */ - uint8_t RepType; /**< Always ::X_XIQueryVersion */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t major_version; - uint16_t minor_version; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIQueryVersionReply; -#define sz_xXIQueryVersionReply 32 - -/** - * Query the server for information about a specific device or all input - * devices. - */ -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIQueryDevice */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; - uint16_t pad; -} xXIQueryDeviceReq; -#define sz_xXIQueryDeviceReq 8 - -typedef struct { - uint8_t repType; /**< ::X_Reply */ - uint8_t RepType; /**< Always ::X_XIQueryDevice */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t num_devices; - uint16_t pad0; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIQueryDeviceReply; -#define sz_xXIQueryDeviceReply 32 - -/** - * Select for events on a given window. - */ -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XISelectEvents */ - uint16_t length; /**< Length in 4 byte units */ - Window win; - uint16_t num_masks; - uint16_t pad; -} xXISelectEventsReq; -#define sz_xXISelectEventsReq 12 - -/** - * Query for selected events on a given window. - */ -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIGetSelectedEvents */ - uint16_t length; /**< Length in 4 byte units */ - Window win; -} xXIGetSelectedEventsReq; -#define sz_xXIGetSelectedEventsReq 8 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIGetSelectedEvents */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t num_masks; /**< Number of xXIEventMask structs - trailing the reply */ - uint16_t pad0; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIGetSelectedEventsReply; -#define sz_xXIGetSelectedEventsReply 32 - -/** - * Query the given device's screen/window coordinates. - */ - -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIQueryPointer */ - uint16_t length; /**< Length in 4 byte units */ - Window win; - uint16_t deviceid; - uint16_t pad1; -} xXIQueryPointerReq; -#define sz_xXIQueryPointerReq 12 - - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIQueryPointer */ - uint16_t sequenceNumber; - uint32_t length; - Window root; - Window child; - FP1616 root_x; - FP1616 root_y; - FP1616 win_x; - FP1616 win_y; - uint8_t same_screen; - uint8_t pad0; - uint16_t buttons_len; - xXIModifierInfo mods; - xXIGroupInfo group; -} xXIQueryPointerReply; -#define sz_xXIQueryPointerReply 56 - -/** - * Warp the given device's pointer to the specified position. - */ - -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIWarpPointer */ - uint16_t length; /**< Length in 4 byte units */ - Window src_win; - Window dst_win; - FP1616 src_x; - FP1616 src_y; - uint16_t src_width; - uint16_t src_height; - FP1616 dst_x; - FP1616 dst_y; - uint16_t deviceid; - uint16_t pad1; -} xXIWarpPointerReq; -#define sz_xXIWarpPointerReq 36 - -/** - * Change the given device's sprite to the given cursor. - */ - -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIChangeCursor */ - uint16_t length; /**< Length in 4 byte units */ - Window win; - Cursor cursor; - uint16_t deviceid; - uint16_t pad1; -} xXIChangeCursorReq; -#define sz_xXIChangeCursorReq 16 - -/** - * Modify the device hierarchy. - */ - -typedef struct { - uint8_t reqType; /**< Input extension major code */ - uint8_t ReqType; /**< Always ::X_XIChangeHierarchy */ - uint16_t length; /**< Length in 4 byte units */ - uint8_t num_changes; - uint8_t pad0; - uint16_t pad1; -} xXIChangeHierarchyReq; -#define sz_xXIChangeHierarchyReq 8 - -/** - * Generic header for any hierarchy change. - */ -typedef struct { - uint16_t type; - uint16_t length; /**< Length in 4 byte units */ -} xXIAnyHierarchyChangeInfo; - -/** - * Create a new master device. - * Name of new master follows struct (4-byte padded) - */ -typedef struct { - uint16_t type; /**< Always ::XIAddMaster */ - uint16_t length; /**< 2 + (namelen + padding)/4 */ - uint16_t name_len; - uint8_t send_core; - uint8_t enable; -} xXIAddMasterInfo; - -/** - * Delete a master device. Will automatically delete the master device paired - * with the given master device. - */ -typedef struct { - uint16_t type; /**< Always ::XIRemoveMaster */ - uint16_t length; /**< 3 */ - uint16_t deviceid; - uint8_t return_mode; /**< ::XIAttachToMaster, ::XIFloating */ - uint8_t pad; - uint16_t return_pointer; /**< Pointer to attach slave ptr devices to */ - uint16_t return_keyboard; /**< keyboard to attach slave keybd devices to*/ -} xXIRemoveMasterInfo; - -/** - * Attach an SD to a new device. - * NewMaster has to be of same type (pointer->pointer, keyboard->keyboard); - */ -typedef struct { - uint16_t type; /**< Always ::XIAttachSlave */ - uint16_t length; /**< 2 */ - uint16_t deviceid; - uint16_t new_master; /**< id of new master device */ -} xXIAttachSlaveInfo; - -/** - * Detach an SD from its current master device. - */ -typedef struct { - uint16_t type; /**< Always ::XIDetachSlave */ - uint16_t length; /**< 2 */ - uint16_t deviceid; - uint16_t pad; -} xXIDetachSlaveInfo; - - -/** - * Set the window/client's ClientPointer. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XISetClientPointer */ - uint16_t length; /**< Length in 4 byte units */ - Window win; - uint16_t deviceid; - uint16_t pad1; -} xXISetClientPointerReq; -#define sz_xXISetClientPointerReq 12 - -/** - * Query the given window/client's ClientPointer setting. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_GetClientPointer */ - uint16_t length; /**< Length in 4 byte units */ - Window win; -} xXIGetClientPointerReq; -#define sz_xXIGetClientPointerReq 8 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_GetClientPointer */ - uint16_t sequenceNumber; - uint32_t length; - BOOL set; /**< client pointer is set? */ - uint8_t pad0; - uint16_t deviceid; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIGetClientPointerReply; -#define sz_xXIGetClientPointerReply 32 - -/** - * Set the input focus to the specified window. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XISetFocus */ - uint16_t length; /**< Length in 4 byte units */ - Window focus; - Time time; - uint16_t deviceid; - uint16_t pad0; -} xXISetFocusReq; -#define sz_xXISetFocusReq 16 - -/** - * Query the current input focus. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIGetDeviceFocus */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; - uint16_t pad0; -} xXIGetFocusReq; -#define sz_xXIGetFocusReq 8 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIGetFocus */ - uint16_t sequenceNumber; - uint32_t length; - Window focus; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIGetFocusReply; -#define sz_xXIGetFocusReply 32 - - -/** - * Grab the given device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIGrabDevice */ - uint16_t length; /**< Length in 4 byte units */ - Window grab_window; - Time time; - Cursor cursor; - uint16_t deviceid; - uint8_t grab_mode; - uint8_t paired_device_mode; - uint8_t owner_events; - uint8_t pad; - uint16_t mask_len; -} xXIGrabDeviceReq; -#define sz_xXIGrabDeviceReq 24 - -/** - * Return codes from a XIPassiveGrabDevice request. - */ -typedef struct { - uint32_t modifiers; /**< Modifier state */ - uint8_t status; /**< Grab status code */ - uint8_t pad0; - uint16_t pad1; -} xXIGrabModifierInfo; - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIGrabDevice */ - uint16_t sequenceNumber; - uint32_t length; - uint8_t status; - uint8_t pad0; - uint16_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; - uint32_t pad6; -} xXIGrabDeviceReply; -#define sz_xXIGrabDeviceReply 32 - -/** - * Ungrab the specified device. - * - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIUngrabDevice */ - uint16_t length; /**< Length in 4 byte units */ - Time time; - uint16_t deviceid; - uint16_t pad; -} xXIUngrabDeviceReq; -#define sz_xXIUngrabDeviceReq 12 - - -/** - * Allow or replay events on the specified grabbed device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIAllowEvents */ - uint16_t length; /**< Length in 4 byte units */ - Time time; - uint16_t deviceid; - uint8_t mode; - uint8_t pad; -} xXIAllowEventsReq; -#define sz_xXIAllowEventsReq 12 - -/** - * Allow or replay events on the specified grabbed device. - * Since XI 2.2 - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIAllowEvents */ - uint16_t length; /**< Length in 4 byte units */ - Time time; - uint16_t deviceid; - uint8_t mode; - uint8_t pad; - uint32_t touchid; /**< Since XI 2.2 */ - Window grab_window; /**< Since XI 2.2 */ -} xXI2_2AllowEventsReq; -#define sz_xXI2_2AllowEventsReq 20 - - -/** - * Passively grab the device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIPassiveGrabDevice */ - uint16_t length; /**< Length in 4 byte units */ - Time time; - Window grab_window; - Cursor cursor; - uint32_t detail; - uint16_t deviceid; - uint16_t num_modifiers; - uint16_t mask_len; - uint8_t grab_type; - uint8_t grab_mode; - uint8_t paired_device_mode; - uint8_t owner_events; - uint16_t pad1; -} xXIPassiveGrabDeviceReq; -#define sz_xXIPassiveGrabDeviceReq 32 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIPassiveGrabDevice */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t num_modifiers; - uint16_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; - uint32_t pad6; -} xXIPassiveGrabDeviceReply; -#define sz_xXIPassiveGrabDeviceReply 32 - -/** - * Delete a passive grab for the given device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIPassiveUngrabDevice */ - uint16_t length; /**< Length in 4 byte units */ - Window grab_window; - uint32_t detail; - uint16_t deviceid; - uint16_t num_modifiers; - uint8_t grab_type; - uint8_t pad0; - uint16_t pad1; -} xXIPassiveUngrabDeviceReq; -#define sz_xXIPassiveUngrabDeviceReq 20 - -/** - * List all device properties on the specified device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIListProperties */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; - uint16_t pad; -} xXIListPropertiesReq; -#define sz_xXIListPropertiesReq 8 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always ::X_XIListProperties */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t num_properties; - uint16_t pad0; - uint32_t pad1; - uint32_t pad2; - uint32_t pad3; - uint32_t pad4; - uint32_t pad5; -} xXIListPropertiesReply; -#define sz_xXIListPropertiesReply 32 - -/** - * Change a property on the specified device. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always ::X_XIChangeProperty */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; - uint8_t mode; - uint8_t format; - Atom property; - Atom type; - uint32_t num_items; -} xXIChangePropertyReq; -#define sz_xXIChangePropertyReq 20 - -/** - * Delete the specified property. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always X_XIDeleteProperty */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; - uint16_t pad0; - Atom property; -} xXIDeletePropertyReq; -#define sz_xXIDeletePropertyReq 12 - -/** - * Query the specified property's values. - */ -typedef struct { - uint8_t reqType; - uint8_t ReqType; /**< Always X_XIGetProperty */ - uint16_t length; /**< Length in 4 byte units */ - uint16_t deviceid; -#if defined(__cplusplus) || defined(c_plusplus) - uint8_t c_delete; -#else - uint8_t delete; -#endif - uint8_t pad0; - Atom property; - Atom type; - uint32_t offset; - uint32_t len; -} xXIGetPropertyReq; -#define sz_xXIGetPropertyReq 24 - -typedef struct { - uint8_t repType; /**< Input extension major opcode */ - uint8_t RepType; /**< Always X_XIGetProperty */ - uint16_t sequenceNumber; - uint32_t length; - Atom type; - uint32_t bytes_after; - uint32_t num_items; - uint8_t format; - uint8_t pad0; - uint16_t pad1; - uint32_t pad2; - uint32_t pad3; -} xXIGetPropertyReply; -#define sz_xXIGetPropertyReply 32 - -/************************************************************************************* - * * - * EVENTS * - * * - *************************************************************************************/ - -/** - * Generic XI2 event header. All XI2 events use the same header. - */ -typedef struct -{ - uint8_t type; - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; - uint16_t evtype; - uint16_t deviceid; - Time time; -} xXIGenericDeviceEvent; - -/** - * Device hierarchy information. - */ -typedef struct -{ - uint16_t deviceid; - uint16_t attachment; /**< ID of master or paired device */ - uint8_t use; /**< ::XIMasterKeyboard, - ::XIMasterPointer, - ::XISlaveKeyboard, - ::XISlavePointer, - ::XIFloatingSlave */ - BOOL enabled; /**< TRUE if the device is enabled */ - uint16_t pad; - uint32_t flags; /**< ::XIMasterAdded, ::XIMasterRemoved, - ::XISlaveAttached, ::XISlaveDetached, - ::XISlaveAdded, ::XISlaveRemoved, - ::XIDeviceEnabled, ::XIDeviceDisabled */ -} xXIHierarchyInfo; - -/** - * The device hierarchy has been modified. This event includes the device - * hierarchy after the modification has been applied. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte units */ - uint16_t evtype; /**< ::XI_Hierarchy */ - uint16_t deviceid; - Time time; - uint32_t flags; /**< ::XIMasterAdded, ::XIMasterDeleted, - ::XISlaveAttached, ::XISlaveDetached, - ::XISlaveAdded, ::XISlaveRemoved, - ::XIDeviceEnabled, ::XIDeviceDisabled */ - uint16_t num_info; - uint16_t pad0; - uint32_t pad1; - uint32_t pad2; -} xXIHierarchyEvent; - -/** - * A device has changed capabilities. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte units */ - uint16_t evtype; /**< XI_DeviceChanged */ - uint16_t deviceid; /**< Device that has changed */ - Time time; - uint16_t num_classes; /**< Number of classes that have changed */ - uint16_t sourceid; /**< Source of the new classes */ - uint8_t reason; /**< ::XISlaveSwitch, ::XIDeviceChange */ - uint8_t pad0; - uint16_t pad1; - uint32_t pad2; - uint32_t pad3; -} xXIDeviceChangedEvent; - -/** - * The owner of a touch stream has passed on ownership to another client. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte units */ - uint16_t evtype; /**< XI_TouchOwnership */ - uint16_t deviceid; /**< Device that has changed */ - Time time; - uint32_t touchid; - Window root; - Window event; - Window child; -/* └──────── 32 byte boundary ────────┘ */ - uint16_t sourceid; - uint16_t pad0; - uint32_t flags; - uint32_t pad1; - uint32_t pad2; -} xXITouchOwnershipEvent; - -/** - * Default input event for pointer, keyboard or touch input. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte uints */ - uint16_t evtype; - uint16_t deviceid; - Time time; - uint32_t detail; /**< Keycode or button */ - Window root; - Window event; - Window child; -/* └──────── 32 byte boundary ────────┘ */ - FP1616 root_x; /**< Always screen coords, 16.16 fixed point */ - FP1616 root_y; - FP1616 event_x; /**< Always screen coords, 16.16 fixed point */ - FP1616 event_y; - uint16_t buttons_len; /**< Len of button flags in 4 b units */ - uint16_t valuators_len; /**< Len of val. flags in 4 b units */ - uint16_t sourceid; /**< The source device */ - uint16_t pad0; - uint32_t flags; /**< ::XIKeyRepeat */ - xXIModifierInfo mods; - xXIGroupInfo group; -} xXIDeviceEvent; - - -/** - * Sent when an input event is generated. RawEvents include valuator - * information in both device-specific data (i.e. unaccelerated) and - * processed data (i.e. accelerated, if applicable). - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte uints */ - uint16_t evtype; /**< ::XI_RawEvent */ - uint16_t deviceid; - Time time; - uint32_t detail; - uint16_t sourceid; /**< The source device (XI 2.1) */ - uint16_t valuators_len; /**< Length of trailing valuator - mask in 4 byte units */ - uint32_t flags; /**< ::XIKeyRepeat */ - uint32_t pad2; -} xXIRawEvent; - -/** - * Note that the layout of root, event, child, root_x, root_y, event_x, - * event_y must be identical to the xXIDeviceEvent. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte uints */ - uint16_t evtype; /**< ::XI_Enter */ - uint16_t deviceid; - Time time; - uint16_t sourceid; - uint8_t mode; - uint8_t detail; - Window root; - Window event; - Window child; -/* └──────── 32 byte boundary ────────┘ */ - FP1616 root_x; - FP1616 root_y; - FP1616 event_x; - FP1616 event_y; - BOOL same_screen; - BOOL focus; - uint16_t buttons_len; /**< Length of trailing button mask - in 4 byte units */ - xXIModifierInfo mods; - xXIGroupInfo group; -} xXIEnterEvent; - -typedef xXIEnterEvent xXILeaveEvent; -typedef xXIEnterEvent xXIFocusInEvent; -typedef xXIEnterEvent xXIFocusOutEvent; - -/** - * Sent when a device property is created, modified or deleted. Does not - * include property data, the client is required to query the data. - */ -typedef struct -{ - uint8_t type; /**< Always GenericEvent */ - uint8_t extension; /**< XI extension offset */ - uint16_t sequenceNumber; - uint32_t length; /**< Length in 4 byte uints */ - uint16_t evtype; /**< ::XI_PropertyEvent */ - uint16_t deviceid; - Time time; - Atom property; - uint8_t what; /**< ::XIPropertyDeleted, - ::XIPropertyCreated, - ::XIPropertyMotified */ - uint8_t pad0; - uint16_t pad1; - uint32_t pad2; - uint32_t pad3; -} xXIPropertyEvent; - - -#undef Window -#undef Time -#undef Atom -#undef Cursor - -#endif /* _XI2PROTO_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XIproto.h b/shell/linux-deps/include/X11/extensions/XIproto.h deleted file mode 100644 index e00ab61dc..000000000 --- a/shell/linux-deps/include/X11/extensions/XIproto.h +++ /dev/null @@ -1,1756 +0,0 @@ -/************************************************************ - -Copyright 1989, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -********************************************************/ - -#ifndef _XIPROTO_H -#define _XIPROTO_H - -#include -#include - -/* make sure types have right sizes for protocol structures. */ -#define Window CARD32 -#define Time CARD32 -#define KeyCode CARD8 -#define Mask CARD32 -#define Atom CARD32 -#define Cursor CARD32 - -/********************************************************* - * - * number of events, errors, and extension name. - * - */ - -#define MORE_EVENTS 0x80 -#define DEVICE_BITS 0x7F - -#define InputClassBits 0x3F /* bits in mode field for input classes */ -#define ModeBitsShift 6 /* amount to shift the remaining bits */ - -#define numInputClasses 7 - -#define IEVENTS 17 /* does NOT include generic events */ -#define IERRORS 5 -#define IREQUESTS 39 - -#define CLIENT_REQ 1 - -typedef struct _XExtEventInfo - { - Mask mask; - BYTE type; - BYTE word; - } XExtEventInfo; - -typedef unsigned char *Pointer; - -struct tmask - { - Mask mask; - Pointer dev; - }; - -/********************************************************* - * - * Event constants used by library. - * - */ - -#define XI_DeviceValuator 0 -#define XI_DeviceKeyPress 1 -#define XI_DeviceKeyRelease 2 -#define XI_DeviceButtonPress 3 -#define XI_DeviceButtonRelease 4 -#define XI_DeviceMotionNotify 5 -#define XI_DeviceFocusIn 6 -#define XI_DeviceFocusOut 7 -#define XI_ProximityIn 8 -#define XI_ProximityOut 9 -#define XI_DeviceStateNotify 10 -#define XI_DeviceMappingNotify 11 -#define XI_ChangeDeviceNotify 12 -#define XI_DeviceKeystateNotify 13 -#define XI_DeviceButtonstateNotify 14 -#define XI_DevicePresenceNotify 15 -#define XI_DevicePropertyNotify 16 - -/********************************************************* - * - * Protocol request constants - * - */ - -#define X_GetExtensionVersion 1 -#define X_ListInputDevices 2 -#define X_OpenDevice 3 -#define X_CloseDevice 4 -#define X_SetDeviceMode 5 -#define X_SelectExtensionEvent 6 -#define X_GetSelectedExtensionEvents 7 -#define X_ChangeDeviceDontPropagateList 8 -#define X_GetDeviceDontPropagateList 9 -#define X_GetDeviceMotionEvents 10 -#define X_ChangeKeyboardDevice 11 -#define X_ChangePointerDevice 12 -#define X_GrabDevice 13 -#define X_UngrabDevice 14 -#define X_GrabDeviceKey 15 -#define X_UngrabDeviceKey 16 -#define X_GrabDeviceButton 17 -#define X_UngrabDeviceButton 18 -#define X_AllowDeviceEvents 19 -#define X_GetDeviceFocus 20 -#define X_SetDeviceFocus 21 -#define X_GetFeedbackControl 22 -#define X_ChangeFeedbackControl 23 -#define X_GetDeviceKeyMapping 24 -#define X_ChangeDeviceKeyMapping 25 -#define X_GetDeviceModifierMapping 26 -#define X_SetDeviceModifierMapping 27 -#define X_GetDeviceButtonMapping 28 -#define X_SetDeviceButtonMapping 29 -#define X_QueryDeviceState 30 -#define X_SendExtensionEvent 31 -#define X_DeviceBell 32 -#define X_SetDeviceValuators 33 -#define X_GetDeviceControl 34 -#define X_ChangeDeviceControl 35 -/* XI 1.5 */ -#define X_ListDeviceProperties 36 -#define X_ChangeDeviceProperty 37 -#define X_DeleteDeviceProperty 38 -#define X_GetDeviceProperty 39 - -/********************************************************* - * - * Protocol request and reply structures. - * - * GetExtensionVersion. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetExtensionVersion */ - CARD16 length B16; - CARD16 nbytes B16; - CARD8 pad1, pad2; -} xGetExtensionVersionReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetExtensionVersion */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 major_version B16; - CARD16 minor_version B16; - BOOL present; - CARD8 pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; -} xGetExtensionVersionReply; - -/********************************************************* - * - * ListInputDevices. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_ListInputDevices */ - CARD16 length B16; -} xListInputDevicesReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_ListInputDevices */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 ndevices; - CARD8 pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xListInputDevicesReply; - -typedef struct _xDeviceInfo *xDeviceInfoPtr; - -typedef struct _xAnyClassinfo *xAnyClassPtr; - -typedef struct _xAnyClassinfo { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - } xAnyClassInfo; - -typedef struct _xDeviceInfo { - CARD32 type B32; - CARD8 id; - CARD8 num_classes; - CARD8 use; /* IsXPointer | IsXKeyboard | IsXExtension... */ - CARD8 attached; /* id of master dev (if IsXExtension..) */ - } xDeviceInfo; - -typedef struct _xKeyInfo *xKeyInfoPtr; - -typedef struct _xKeyInfo { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - KeyCode min_keycode; - KeyCode max_keycode; - CARD16 num_keys B16; - CARD8 pad1,pad2; - } xKeyInfo; - -typedef struct _xButtonInfo *xButtonInfoPtr; - -typedef struct _xButtonInfo { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - CARD16 num_buttons B16; - } xButtonInfo; - -typedef struct _xValuatorInfo *xValuatorInfoPtr; - -typedef struct _xValuatorInfo { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - CARD8 num_axes; - CARD8 mode; - CARD32 motion_buffer_size B32; - } xValuatorInfo; - -typedef struct _xAxisInfo *xAxisInfoPtr; - -typedef struct _xAxisInfo { - CARD32 resolution B32; - CARD32 min_value B32; - CARD32 max_value B32; - } xAxisInfo; - -/********************************************************* - * - * OpenDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_OpenDevice */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xOpenDeviceReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_OpenDevice */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 num_classes; - BYTE pad1, pad2, pad3; - CARD32 pad00 B32; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - } xOpenDeviceReply; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 event_type_base; - } xInputClassInfo; - -/********************************************************* - * - * CloseDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_CloseDevice */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xCloseDeviceReq; - -/********************************************************* - * - * SetDeviceMode. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_SetDeviceMode */ - CARD16 length B16; - CARD8 deviceid; - CARD8 mode; - BYTE pad1, pad2; -} xSetDeviceModeReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_SetDeviceMode */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xSetDeviceModeReply; - -/********************************************************* - * - * SelectExtensionEvent. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_SelectExtensionEvent */ - CARD16 length B16; - Window window B32; - CARD16 count B16; - CARD16 pad00 B16; -} xSelectExtensionEventReq; - -/********************************************************* - * - * GetSelectedExtensionEvent. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_GetSelectedExtensionEvents */ - CARD16 length B16; - Window window B32; -} xGetSelectedExtensionEventsReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* GetSelectedExtensionEvents */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 this_client_count B16; - CARD16 all_clients_count B16; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xGetSelectedExtensionEventsReply; - -/********************************************************* - * - * ChangeDeviceDontPropagateList. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_ChangeDeviceDontPropagateList */ - CARD16 length B16; - Window window B32; - CARD16 count B16; - CARD8 mode; - BYTE pad; -} xChangeDeviceDontPropagateListReq; - -/********************************************************* - * - * GetDeviceDontPropagateList. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_GetDeviceDontPropagateList */ - CARD16 length B16; - Window window B32; -} xGetDeviceDontPropagateListReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* GetDeviceDontPropagateList */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 count B16; - CARD16 pad00 B16; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - } xGetDeviceDontPropagateListReply; - -/********************************************************* - * - * GetDeviceMotionEvents. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetDeviceMotionEvents*/ - CARD16 length B16; - Time start B32; - Time stop B32; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xGetDeviceMotionEventsReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceMotionEvents */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 nEvents B32; - CARD8 axes; - CARD8 mode; - BYTE pad1, pad2; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; -} xGetDeviceMotionEventsReply; - -/********************************************************* - * - * ChangeKeyboardDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_ChangeKeyboardDevice */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xChangeKeyboardDeviceReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_ChangeKeyboardDevice*/ - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - } xChangeKeyboardDeviceReply; - -/********************************************************* - * - * ChangePointerDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_ChangePointerDevice */ - CARD16 length B16; - CARD8 xaxis; - CARD8 yaxis; - CARD8 deviceid; - BYTE pad1; -} xChangePointerDeviceReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_ChangePointerDevice */ - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - } xChangePointerDeviceReply; - -/********************************************************* - * - * GrabDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GrabDevice */ - CARD16 length B16; - Window grabWindow B32; - Time time B32; - CARD16 event_count B16; - CARD8 this_device_mode; - CARD8 other_devices_mode; - BOOL ownerEvents; - CARD8 deviceid; - CARD16 pad01 B16; -} xGrabDeviceReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GrabDevice */ - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - } xGrabDeviceReply; - -/********************************************************* - * - * UngrabDevice. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_UnGrabDevice */ - CARD16 length B16; - Time time B32; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xUngrabDeviceReq; - -/********************************************************* - * - * GrabDeviceKey. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GrabDeviceKey */ - CARD16 length B16; - Window grabWindow B32; - CARD16 event_count B16; - CARD16 modifiers B16; - CARD8 modifier_device; - CARD8 grabbed_device; - CARD8 key; - BYTE this_device_mode; - BYTE other_devices_mode; - BOOL ownerEvents; - BYTE pad1, pad2; -} xGrabDeviceKeyReq; - -/********************************************************* - * - * UngrabDeviceKey. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_UngrabDeviceKey */ - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD8 modifier_device; - CARD8 key; - CARD8 grabbed_device; - BYTE pad1, pad2, pad3; -} xUngrabDeviceKeyReq; - -/********************************************************* - * - * GrabDeviceButton. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GrabDeviceButton */ - CARD16 length B16; - Window grabWindow B32; - CARD8 grabbed_device; - CARD8 modifier_device; - CARD16 event_count B16; - CARD16 modifiers B16; - BYTE this_device_mode; - BYTE other_devices_mode; - CARD8 button; - BOOL ownerEvents; - BYTE pad1, pad2; -} xGrabDeviceButtonReq; - -/********************************************************* - * - * UngrabDeviceButton. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_UngrabDeviceButton */ - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD8 modifier_device; - CARD8 button; - CARD8 grabbed_device; - BYTE pad1, pad2, pad3; -} xUngrabDeviceButtonReq; - -/********************************************************* - * - * AllowDeviceEvents. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_AllowDeviceEvents */ - CARD16 length B16; - Time time B32; - CARD8 mode; - CARD8 deviceid; - BYTE pad1, pad2; -} xAllowDeviceEventsReq; - -/********************************************************* - * - * GetDeviceFocus. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetDeviceFocus */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xGetDeviceFocusReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceFocus */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 focus B32; - Time time B32; - CARD8 revertTo; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - } xGetDeviceFocusReply; - -/********************************************************* - * - * SetDeviceFocus. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_SetDeviceFocus */ - CARD16 length B16; - Window focus B32; - Time time B32; - CARD8 revertTo; - CARD8 device; - CARD16 pad01 B16; -} xSetDeviceFocusReq; - -/********************************************************* - * - * GetFeedbackControl. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_GetFeedbackControl */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xGetFeedbackControlReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetFeedbackControl */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 num_feedbacks B16; - CARD16 pad01 B16; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - CARD32 pad06 B32; -} xGetFeedbackControlReply; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class */ -#else - CARD8 class; /* feedback class */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ -} xFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 id; - CARD16 length B16; - CARD16 pitch B16; - CARD16 duration B16; - CARD32 led_mask B32; - CARD32 led_values B32; - BOOL global_auto_repeat; - CARD8 click; - CARD8 percent; - BYTE pad; - BYTE auto_repeats[32]; -} xKbdFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 id; - CARD16 length B16; - CARD8 pad1,pad2; - CARD16 accelNum B16; - CARD16 accelDenom B16; - CARD16 threshold B16; -} xPtrFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; - CARD16 length B16; /* feedback length */ - CARD32 resolution B32; - INT32 min_value B32; - INT32 max_value B32; -} xIntegerFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; - CARD16 length B16; /* feedback length */ - CARD16 max_symbols B16; - CARD16 num_syms_supported B16; -} xStringFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; - CARD16 length B16; /* feedback length */ - CARD8 percent; - BYTE pad1, pad2, pad3; - CARD16 pitch B16; - CARD16 duration B16; -} xBellFeedbackState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; - CARD16 length B16; /* feedback length */ - CARD32 led_mask B32; - CARD32 led_values B32; -} xLedFeedbackState; - -/********************************************************* - * - * ChangeFeedbackControl. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_ChangeFeedbackControl */ - CARD16 length B16; - CARD32 mask B32; - CARD8 deviceid; - CARD8 feedbackid; - BYTE pad1, pad2; -} xChangeFeedbackControlReq; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ -} xFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback length */ - CARD16 length B16; /* feedback length */ - KeyCode key; - CARD8 auto_repeat_mode; - INT8 click; - INT8 percent; - INT16 pitch B16; - INT16 duration B16; - CARD32 led_mask B32; - CARD32 led_values B32; -} xKbdFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ - CARD8 pad1,pad2; - INT16 num B16; - INT16 denom B16; - INT16 thresh B16; -} xPtrFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ - INT32 int_to_display B32; -} xIntegerFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ - CARD8 pad1,pad2; - CARD16 num_keysyms B16; -} xStringFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ - INT8 percent; - BYTE pad1, pad2, pad3; - INT16 pitch B16; - INT16 duration B16; -} xBellFeedbackCtl; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; /* feedback class id */ -#else - CARD8 class; /* feedback class id */ -#endif - CARD8 id; /* feedback id */ - CARD16 length B16; /* feedback length */ - CARD32 led_mask B32; - CARD32 led_values B32; -} xLedFeedbackCtl; - -/********************************************************* - * - * GetDeviceKeyMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetDeviceKeyMapping */ - CARD16 length B16; - CARD8 deviceid; - KeyCode firstKeyCode; - CARD8 count; - BYTE pad1; -} xGetDeviceKeyMappingReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceKeyMapping */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 keySymsPerKeyCode; - CARD8 pad0; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xGetDeviceKeyMappingReply; - -/********************************************************* - * - * ChangeDeviceKeyMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_ChangeDeviceKeyMapping */ - CARD16 length B16; - CARD8 deviceid; - KeyCode firstKeyCode; - CARD8 keySymsPerKeyCode; - CARD8 keyCodes; -} xChangeDeviceKeyMappingReq; - -/********************************************************* - * - * GetDeviceModifierMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetDeviceModifierMapping */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xGetDeviceModifierMappingReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceModifierMapping */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 numKeyPerModifier; - CARD8 pad0; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xGetDeviceModifierMappingReply; - -/********************************************************* - * - * SetDeviceModifierMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_SetDeviceModifierMapping */ - CARD16 length B16; - CARD8 deviceid; - CARD8 numKeyPerModifier; - CARD16 pad1 B16; -} xSetDeviceModifierMappingReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_SetDeviceModifierMapping */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 success; - CARD8 pad0; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xSetDeviceModifierMappingReply; - -/********************************************************* - * - * GetDeviceButtonMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_GetDeviceButtonMapping */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xGetDeviceButtonMappingReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceButtonMapping */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 nElts; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xGetDeviceButtonMappingReply; - -/********************************************************* - * - * SetDeviceButtonMapping. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* X_SetDeviceButtonMapping */ - CARD16 length B16; - CARD8 deviceid; - CARD8 map_length; - BYTE pad1, pad2; -} xSetDeviceButtonMappingReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_SetDeviceButtonMapping */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 status; - BYTE pad0; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xSetDeviceButtonMappingReply; - -/********************************************************* - * - * QueryDeviceState. - * - */ - -typedef struct { - CARD8 reqType; - CARD8 ReqType; /* always X_QueryDeviceState */ - CARD16 length B16; - CARD8 deviceid; - BYTE pad1, pad2, pad3; -} xQueryDeviceStateReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_QueryDeviceState */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 num_classes; - BYTE pad0; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xQueryDeviceStateReply; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - CARD8 num_keys; - BYTE pad1; - CARD8 keys[32]; -} xKeyState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - CARD8 num_buttons; - BYTE pad1; - CARD8 buttons[32]; -} xButtonState; - -typedef struct { -#if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; -#else - CARD8 class; -#endif - CARD8 length; - CARD8 num_valuators; - CARD8 mode; -} xValuatorState; - -/********************************************************* - * - * SendExtensionEvent. - * THIS REQUEST MUST BE KEPT A MULTIPLE OF 8 BYTES IN LENGTH! - * MORE EVENTS MAY FOLLOW AND THEY MUST BE QUAD-ALIGNED! - * - */ - -typedef struct { - CARD8 reqType; - CARD8 ReqType; /* always X_SendExtensionEvent */ - CARD16 length B16; - Window destination B32; - CARD8 deviceid; - BOOL propagate; - CARD16 count B16; - CARD8 num_events; - BYTE pad1,pad2,pad3; -} xSendExtensionEventReq; - -/********************************************************* - * - * DeviceBell. - * - */ - -typedef struct { - CARD8 reqType; - CARD8 ReqType; /* always X_DeviceBell */ - CARD16 length B16; - CARD8 deviceid; - CARD8 feedbackid; - CARD8 feedbackclass; - INT8 percent; -} xDeviceBellReq; - -/********************************************************* - * - * SetDeviceValuators. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_SetDeviceValuators */ - CARD16 length B16; - CARD8 deviceid; - CARD8 first_valuator; - CARD8 num_valuators; - BYTE pad1; -} xSetDeviceValuatorsReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_SetDeviceValuators */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xSetDeviceValuatorsReply; - -/********************************************************* - * - * GetDeviceControl. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_GetDeviceControl */ - CARD16 length B16; - CARD16 control B16; - CARD8 deviceid; - BYTE pad2; -} xGetDeviceControlReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceControl */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xGetDeviceControlReply; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ -} xDeviceState; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ - CARD32 num_valuators B32; /* number of valuators */ -} xDeviceResolutionState; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - INT32 min_x B32; - INT32 max_x B32; - INT32 min_y B32; - INT32 max_y B32; - CARD32 flip_x B32; - CARD32 flip_y B32; - CARD32 rotation B32; - CARD32 button_threshold B32; -} xDeviceAbsCalibState; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - CARD32 offset_x B32; - CARD32 offset_y B32; - CARD32 width B32; - CARD32 height B32; - CARD32 screen B32; - CARD32 following B32; -} xDeviceAbsAreaState; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ - CARD8 status; - CARD8 iscore; - CARD16 pad1 B16; -} xDeviceCoreState; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ - CARD8 enable; - CARD8 pad0; - CARD16 pad1 B16; -} xDeviceEnableState; - -/********************************************************* - * - * ChangeDeviceControl. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major code */ - CARD8 ReqType; /* always X_ChangeDeviceControl */ - CARD16 length B16; - CARD16 control B16; - CARD8 deviceid; - BYTE pad0; -} xChangeDeviceControlReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_ChangeDeviceControl */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 status; - BYTE pad1, pad2, pad3; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; -} xChangeDeviceControlReply; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ -} xDeviceCtl; - -typedef struct { - CARD16 control B16; /* control type */ - CARD16 length B16; /* control length */ - CARD8 first_valuator; /* first valuator to change */ - CARD8 num_valuators; /* number of valuators to change*/ - CARD8 pad1,pad2; -} xDeviceResolutionCtl; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - INT32 min_x; - INT32 max_x; - INT32 min_y; - INT32 max_y; - CARD32 flip_x; - CARD32 flip_y; - CARD32 rotation; - CARD32 button_threshold; -} xDeviceAbsCalibCtl; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - CARD32 offset_x; - CARD32 offset_y; - INT32 width; - INT32 height; - INT32 screen; - CARD32 following; -} xDeviceAbsAreaCtl; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - CARD8 status; - CARD8 pad0; - CARD16 pad1 B16; -} xDeviceCoreCtl; - -typedef struct { - CARD16 control B16; - CARD16 length B16; - CARD8 enable; - CARD8 pad0; - CARD16 pad1 B16; -} xDeviceEnableCtl; - -/* XI 1.5 */ - -/********************************************************* - * - * ListDeviceProperties. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major opcode */ - CARD8 ReqType; /* always X_ListDeviceProperties */ - CARD16 length B16; - CARD8 deviceid; - CARD8 pad0; - CARD16 pad1 B16; -} xListDevicePropertiesReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_ListDeviceProperties */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nAtoms B16; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xListDevicePropertiesReply; - -/********************************************************* - * - * ChangeDeviceProperty. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major opcode */ - CARD8 ReqType; /* always X_ChangeDeviceProperty */ - CARD16 length B16; - Atom property B32; - Atom type B32; - CARD8 deviceid; - CARD8 format; - CARD8 mode; - CARD8 pad; - CARD32 nUnits B32; -} xChangeDevicePropertyReq; - -/********************************************************* - * - * DeleteDeviceProperty. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major opcode */ - CARD8 ReqType; /* always X_DeleteDeviceProperty */ - CARD16 length B16; - Atom property B32; - CARD8 deviceid; - CARD8 pad0; - CARD16 pad1 B16; -} xDeleteDevicePropertyReq; - -/********************************************************* - * - * GetDeviceProperty. - * - */ - -typedef struct { - CARD8 reqType; /* input extension major opcode */ - CARD8 ReqType; /* always X_GetDeviceProperty */ - CARD16 length B16; - Atom property B32; - Atom type B32; - CARD32 longOffset B32; - CARD32 longLength B32; - CARD8 deviceid; -#if defined(__cplusplus) || defined(c_plusplus) - BOOL c_delete; -#else - BOOL delete; -#endif - CARD16 pad; -} xGetDevicePropertyReq; - -typedef struct { - CARD8 repType; /* X_Reply */ - CARD8 RepType; /* always X_GetDeviceProperty */ - CARD16 sequenceNumber B16; - CARD32 length B32; - Atom propertyType B32; - CARD32 bytesAfter B32; - CARD32 nItems B32; - CARD8 format; - CARD8 deviceid; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; -} xGetDevicePropertyReply; - - -/********************************************************** - * - * Input extension events. - * - * DeviceValuator - * - */ - -typedef struct - { - BYTE type; - CARD8 deviceid; - CARD16 sequenceNumber B16; - KeyButMask device_state B16; - CARD8 num_valuators; - CARD8 first_valuator; - INT32 valuator0 B32; - INT32 valuator1 B32; - INT32 valuator2 B32; - INT32 valuator3 B32; - INT32 valuator4 B32; - INT32 valuator5 B32; - } deviceValuator; - -/********************************************************** - * - * DeviceKeyButtonPointer. - * - * Used for: DeviceKeyPress, DeviceKeyRelease, - * DeviceButtonPress, DeviceButtonRelease, - * ProximityIn, ProximityOut - * DeviceMotionNotify, - * - */ - -typedef struct - { - BYTE type; - BYTE detail; - CARD16 sequenceNumber B16; - Time time B32; - Window root B32; - Window event B32; - Window child B32; - INT16 root_x B16; - INT16 root_y B16; - INT16 event_x B16; - INT16 event_y B16; - KeyButMask state B16; - BOOL same_screen; - CARD8 deviceid; - } deviceKeyButtonPointer; - -/********************************************************** - * - * DeviceFocus. - * - */ - -typedef struct - { - BYTE type; - BYTE detail; - CARD16 sequenceNumber B16; - Time time B32; - Window window B32; - BYTE mode; - CARD8 deviceid; - BYTE pad1, pad2; - CARD32 pad00 B32; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - } deviceFocus; - -/********************************************************** - * - * DeviceStateNotify. - * - * Note that the two high-order bits in the classes_reported - * field are the proximity state (InProximity or OutOfProximity), - * and the device mode (Absolute or Relative), respectively. - * - */ - -typedef struct - { - BYTE type; - BYTE deviceid; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 num_keys; - CARD8 num_buttons; - CARD8 num_valuators; - CARD8 classes_reported; - CARD8 buttons[4]; - CARD8 keys[4]; - INT32 valuator0 B32; - INT32 valuator1 B32; - INT32 valuator2 B32; - } deviceStateNotify; - -/********************************************************** - * - * DeviceKeyStateNotify. - * - */ - -typedef struct - { - BYTE type; - BYTE deviceid; - CARD16 sequenceNumber B16; - CARD8 keys[28]; - } deviceKeyStateNotify; - -/********************************************************** - * - * DeviceButtonStateNotify. - * - */ - -typedef struct - { - BYTE type; - BYTE deviceid; - CARD16 sequenceNumber B16; - CARD8 buttons[28]; - } deviceButtonStateNotify; - -/********************************************************** - * - * DeviceMappingNotify. - * Fields must be kept in sync with core mappingnotify event. - * - */ - -typedef struct - { - BYTE type; - BYTE deviceid; - CARD16 sequenceNumber B16; - CARD8 request; - KeyCode firstKeyCode; - CARD8 count; - BYTE pad1; - Time time B32; - CARD32 pad00 B32; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - } deviceMappingNotify; - -/********************************************************** - * - * ChangeDeviceNotify. - * - */ - -typedef struct - { - BYTE type; - BYTE deviceid; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 request; - BYTE pad1, pad2, pad3; - CARD32 pad00 B32; - CARD32 pad01 B32; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - } changeDeviceNotify; - -/********************************************************** - * - * devicePresenceNotify. - * - */ - -typedef struct - { - BYTE type; - BYTE pad00; - CARD16 sequenceNumber B16; - Time time B32; - BYTE devchange; /* Device{Added|Removed|Enabled|Disabled|ControlChanged} */ - BYTE deviceid; - CARD16 control B16; - CARD32 pad02 B32; - CARD32 pad03 B32; - CARD32 pad04 B32; - CARD32 pad05 B32; - CARD32 pad06 B32; - } devicePresenceNotify; - - -/********************************************************* - * DevicePropertyNotifyEvent - * - * Sent whenever a device's property changes. - * - */ - -typedef struct - { - BYTE type; - BYTE state; /* NewValue or Deleted */ - CARD16 sequenceNumber B16; - CARD32 time B32; - Atom atom B32; /* affected property */ - CARD32 pad0 B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD16 pad5 B16; - CARD8 pad4; - CARD8 deviceid; /* id of device */ - } devicePropertyNotify; - -#undef Window -#undef Time -#undef KeyCode -#undef Mask -#undef Atom -#undef Cursor - -#endif diff --git a/shell/linux-deps/include/X11/extensions/XKB.h b/shell/linux-deps/include/X11/extensions/XKB.h deleted file mode 100644 index a3b3bc0ec..000000000 --- a/shell/linux-deps/include/X11/extensions/XKB.h +++ /dev/null @@ -1,788 +0,0 @@ -/* $Xorg: XKB.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ */ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ -/* $XFree86: xc/include/extensions/XKB.h,v 1.5tsi Exp $ */ - -#ifndef _XKB_H_ -#define _XKB_H_ - - /* - * XKB request codes, used in: - * - xkbReqType field of all requests - * - requestMinor field of some events - */ -#define X_kbUseExtension 0 -#define X_kbSelectEvents 1 -#define X_kbBell 3 -#define X_kbGetState 4 -#define X_kbLatchLockState 5 -#define X_kbGetControls 6 -#define X_kbSetControls 7 -#define X_kbGetMap 8 -#define X_kbSetMap 9 -#define X_kbGetCompatMap 10 -#define X_kbSetCompatMap 11 -#define X_kbGetIndicatorState 12 -#define X_kbGetIndicatorMap 13 -#define X_kbSetIndicatorMap 14 -#define X_kbGetNamedIndicator 15 -#define X_kbSetNamedIndicator 16 -#define X_kbGetNames 17 -#define X_kbSetNames 18 -#define X_kbGetGeometry 19 -#define X_kbSetGeometry 20 -#define X_kbPerClientFlags 21 -#define X_kbListComponents 22 -#define X_kbGetKbdByName 23 -#define X_kbGetDeviceInfo 24 -#define X_kbSetDeviceInfo 25 -#define X_kbSetDebuggingFlags 101 - - /* - * In the X sense, XKB reports only one event. - * The type field of all XKB events is XkbEventCode - */ -#define XkbEventCode 0 -#define XkbNumberEvents (XkbEventCode+1) - - /* - * XKB has a minor event code so it can use one X event code for - * multiple purposes. - * - reported in the xkbType field of all XKB events. - * - XkbSelectEventDetails: Indicates the event for which event details - * are being changed - */ -#define XkbNewKeyboardNotify 0 -#define XkbMapNotify 1 -#define XkbStateNotify 2 -#define XkbControlsNotify 3 -#define XkbIndicatorStateNotify 4 -#define XkbIndicatorMapNotify 5 -#define XkbNamesNotify 6 -#define XkbCompatMapNotify 7 -#define XkbBellNotify 8 -#define XkbActionMessage 9 -#define XkbAccessXNotify 10 -#define XkbExtensionDeviceNotify 11 - - /* - * Event Mask: - * - XkbSelectEvents: Specifies event interest. - */ -#define XkbNewKeyboardNotifyMask (1L << 0) -#define XkbMapNotifyMask (1L << 1) -#define XkbStateNotifyMask (1L << 2) -#define XkbControlsNotifyMask (1L << 3) -#define XkbIndicatorStateNotifyMask (1L << 4) -#define XkbIndicatorMapNotifyMask (1L << 5) -#define XkbNamesNotifyMask (1L << 6) -#define XkbCompatMapNotifyMask (1L << 7) -#define XkbBellNotifyMask (1L << 8) -#define XkbActionMessageMask (1L << 9) -#define XkbAccessXNotifyMask (1L << 10) -#define XkbExtensionDeviceNotifyMask (1L << 11) -#define XkbAllEventsMask (0xFFF) - - /* - * NewKeyboardNotify event details: - */ -#define XkbNKN_KeycodesMask (1L << 0) -#define XkbNKN_GeometryMask (1L << 1) -#define XkbNKN_DeviceIDMask (1L << 2) -#define XkbAllNewKeyboardEventsMask (0x7) - - /* - * AccessXNotify event types: - * - The 'what' field of AccessXNotify events reports the - * reason that the event was generated. - */ -#define XkbAXN_SKPress 0 -#define XkbAXN_SKAccept 1 -#define XkbAXN_SKReject 2 -#define XkbAXN_SKRelease 3 -#define XkbAXN_BKAccept 4 -#define XkbAXN_BKReject 5 -#define XkbAXN_AXKWarning 6 - - /* - * AccessXNotify details: - * - Used as an event detail mask to limit the conditions under which - * AccessXNotify events are reported - */ -#define XkbAXN_SKPressMask (1L << 0) -#define XkbAXN_SKAcceptMask (1L << 1) -#define XkbAXN_SKRejectMask (1L << 2) -#define XkbAXN_SKReleaseMask (1L << 3) -#define XkbAXN_BKAcceptMask (1L << 4) -#define XkbAXN_BKRejectMask (1L << 5) -#define XkbAXN_AXKWarningMask (1L << 6) -#define XkbAllAccessXEventsMask (0x7f) - - /* - * Miscellaneous event details: - * - event detail masks for assorted events that don't reall - * have any details. - */ -#define XkbAllStateEventsMask XkbAllStateComponentsMask -#define XkbAllMapEventsMask XkbAllMapComponentsMask -#define XkbAllControlEventsMask XkbAllControlsMask -#define XkbAllIndicatorEventsMask XkbAllIndicatorsMask -#define XkbAllNameEventsMask XkbAllNamesMask -#define XkbAllCompatMapEventsMask XkbAllCompatMask -#define XkbAllBellEventsMask (1L << 0) -#define XkbAllActionMessagesMask (1L << 0) - - /* - * XKB reports one error: BadKeyboard - * A further reason for the error is encoded into to most significant - * byte of the resourceID for the error: - * XkbErr_BadDevice - the device in question was not found - * XkbErr_BadClass - the device was found but it doesn't belong to - * the appropriate class. - * XkbErr_BadId - the device was found and belongs to the right - * class, but not feedback with a matching id was - * found. - * The low byte of the resourceID for this error contains the device - * id, class specifier or feedback id that failed. - */ -#define XkbKeyboard 0 -#define XkbNumberErrors 1 - -#define XkbErr_BadDevice 0xff -#define XkbErr_BadClass 0xfe -#define XkbErr_BadId 0xfd - - /* - * Keyboard Components Mask: - * - Specifies the components that follow a GetKeyboardByNameReply - */ -#define XkbClientMapMask (1L << 0) -#define XkbServerMapMask (1L << 1) -#define XkbCompatMapMask (1L << 2) -#define XkbIndicatorMapMask (1L << 3) -#define XkbNamesMask (1L << 4) -#define XkbGeometryMask (1L << 5) -#define XkbControlsMask (1L << 6) -#define XkbAllComponentsMask (0x7f) - - /* - * State detail mask: - * - The 'changed' field of StateNotify events reports which of - * the keyboard state components have changed. - * - Used as an event detail mask to limit the conditions under - * which StateNotify events are reported. - */ -#define XkbModifierStateMask (1L << 0) -#define XkbModifierBaseMask (1L << 1) -#define XkbModifierLatchMask (1L << 2) -#define XkbModifierLockMask (1L << 3) -#define XkbGroupStateMask (1L << 4) -#define XkbGroupBaseMask (1L << 5) -#define XkbGroupLatchMask (1L << 6) -#define XkbGroupLockMask (1L << 7) -#define XkbCompatStateMask (1L << 8) -#define XkbGrabModsMask (1L << 9) -#define XkbCompatGrabModsMask (1L << 10) -#define XkbLookupModsMask (1L << 11) -#define XkbCompatLookupModsMask (1L << 12) -#define XkbPointerButtonMask (1L << 13) -#define XkbAllStateComponentsMask (0x3fff) - - /* - * Controls detail masks: - * The controls specified in XkbAllControlsMask: - * - The 'changed' field of ControlsNotify events reports which of - * the keyboard controls have changed. - * - The 'changeControls' field of the SetControls request specifies - * the controls for which values are to be changed. - * - Used as an event detail mask to limit the conditions under - * which ControlsNotify events are reported. - * - * The controls specified in the XkbAllBooleanCtrlsMask: - * - The 'enabledControls' field of ControlsNotify events reports the - * current status of the boolean controls. - * - The 'enabledControlsChanges' field of ControlsNotify events reports - * any boolean controls that have been turned on or off. - * - The 'affectEnabledControls' and 'enabledControls' fields of the - * kbSetControls request change the set of enabled controls. - * - The 'accessXTimeoutMask' and 'accessXTimeoutValues' fields of - * an XkbControlsRec specify the controls to be changed if the keyboard - * times out and the values to which they should be changed. - * - The 'autoCtrls' and 'autoCtrlsValues' fields of the PerClientFlags - * request specifies the specify the controls to be reset when the - * client exits and the values to which they should be reset. - * - The 'ctrls' field of an indicator map specifies the controls - * that drive the indicator. - * - Specifies the boolean controls affected by the SetControls and - * LockControls key actions. - */ -#define XkbRepeatKeysMask (1L << 0) -#define XkbSlowKeysMask (1L << 1) -#define XkbBounceKeysMask (1L << 2) -#define XkbStickyKeysMask (1L << 3) -#define XkbMouseKeysMask (1L << 4) -#define XkbMouseKeysAccelMask (1L << 5) -#define XkbAccessXKeysMask (1L << 6) -#define XkbAccessXTimeoutMask (1L << 7) -#define XkbAccessXFeedbackMask (1L << 8) -#define XkbAudibleBellMask (1L << 9) -#define XkbOverlay1Mask (1L << 10) -#define XkbOverlay2Mask (1L << 11) -#define XkbIgnoreGroupLockMask (1L << 12) -#define XkbGroupsWrapMask (1L << 27) -#define XkbInternalModsMask (1L << 28) -#define XkbIgnoreLockModsMask (1L << 29) -#define XkbPerKeyRepeatMask (1L << 30) -#define XkbControlsEnabledMask (1L << 31) - -#define XkbAccessXOptionsMask (XkbStickyKeysMask|XkbAccessXFeedbackMask) - -#define XkbAllBooleanCtrlsMask (0x00001FFF) -#define XkbAllControlsMask (0xF8001FFF) -#define XkbAllControlEventsMask XkbAllControlsMask - - /* - * AccessX Options Mask - * - The 'accessXOptions' field of an XkbControlsRec specifies the - * AccessX options that are currently in effect. - * - The 'accessXTimeoutOptionsMask' and 'accessXTimeoutOptionsValues' - * fields of an XkbControlsRec specify the Access X options to be - * changed if the keyboard times out and the values to which they - * should be changed. - */ -#define XkbAX_SKPressFBMask (1L << 0) -#define XkbAX_SKAcceptFBMask (1L << 1) -#define XkbAX_FeatureFBMask (1L << 2) -#define XkbAX_SlowWarnFBMask (1L << 3) -#define XkbAX_IndicatorFBMask (1L << 4) -#define XkbAX_StickyKeysFBMask (1L << 5) -#define XkbAX_TwoKeysMask (1L << 6) -#define XkbAX_LatchToLockMask (1L << 7) -#define XkbAX_SKReleaseFBMask (1L << 8) -#define XkbAX_SKRejectFBMask (1L << 9) -#define XkbAX_BKRejectFBMask (1L << 10) -#define XkbAX_DumbBellFBMask (1L << 11) -#define XkbAX_FBOptionsMask (0xF3F) -#define XkbAX_SKOptionsMask (0x0C0) -#define XkbAX_AllOptionsMask (0xFFF) - - /* - * XkbUseCoreKbd is used to specify the core keyboard without having - * to look up its X input extension identifier. - * XkbUseCorePtr is used to specify the core pointer without having - * to look up its X input extension identifier. - * XkbDfltXIClass is used to specify "don't care" any place that the - * XKB protocol is looking for an X Input Extension - * device class. - * XkbDfltXIId is used to specify "don't care" any place that the - * XKB protocol is looking for an X Input Extension - * feedback identifier. - * XkbAllXIClasses is used to get information about all device indicators, - * whether they're part of the indicator feedback class - * or the keyboard feedback class. - * XkbAllXIIds is used to get information about all device indicator - * feedbacks without having to list them. - * XkbXINone is used to indicate that no class or id has been specified. - * XkbLegalXILedClass(c) True if 'c' specifies a legal class with LEDs - * XkbLegalXIBellClass(c) True if 'c' specifies a legal class with bells - * XkbExplicitXIDevice(d) True if 'd' explicitly specifies a device - * XkbExplicitXIClass(c) True if 'c' explicitly specifies a device class - * XkbExplicitXIId(c) True if 'i' explicitly specifies a device id - * XkbSingleXIClass(c) True if 'c' specifies exactly one device class, - * including the default. - * XkbSingleXIId(i) True if 'i' specifies exactly one device - * identifier, including the default. - */ -#define XkbUseCoreKbd 0x0100 -#define XkbUseCorePtr 0x0200 -#define XkbDfltXIClass 0x0300 -#define XkbDfltXIId 0x0400 -#define XkbAllXIClasses 0x0500 -#define XkbAllXIIds 0x0600 -#define XkbXINone 0xff00 - -#define XkbLegalXILedClass(c) (((c)==KbdFeedbackClass)||\ - ((c)==LedFeedbackClass)||\ - ((c)==XkbDfltXIClass)||\ - ((c)==XkbAllXIClasses)) -#define XkbLegalXIBellClass(c) (((c)==KbdFeedbackClass)||\ - ((c)==BellFeedbackClass)||\ - ((c)==XkbDfltXIClass)||\ - ((c)==XkbAllXIClasses)) -#define XkbExplicitXIDevice(c) (((c)&(~0xff))==0) -#define XkbExplicitXIClass(c) (((c)&(~0xff))==0) -#define XkbExplicitXIId(c) (((c)&(~0xff))==0) -#define XkbSingleXIClass(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIClass)) -#define XkbSingleXIId(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIId)) - -#define XkbNoModifier 0xff -#define XkbNoShiftLevel 0xff -#define XkbNoShape 0xff -#define XkbNoIndicator 0xff - -#define XkbNoModifierMask 0 -#define XkbAllModifiersMask 0xff -#define XkbAllVirtualModsMask 0xffff - -#define XkbNumKbdGroups 4 -#define XkbMaxKbdGroup (XkbNumKbdGroups-1) - -#define XkbMaxMouseKeysBtn 4 - - /* - * Group Index and Mask: - * - Indices into the kt_index array of a key type. - * - Mask specifies types to be changed for XkbChangeTypesOfKey - */ -#define XkbGroup1Index 0 -#define XkbGroup2Index 1 -#define XkbGroup3Index 2 -#define XkbGroup4Index 3 -#define XkbAnyGroup 254 -#define XkbAllGroups 255 - -#define XkbGroup1Mask (1<<0) -#define XkbGroup2Mask (1<<1) -#define XkbGroup3Mask (1<<2) -#define XkbGroup4Mask (1<<3) -#define XkbAnyGroupMask (1<<7) -#define XkbAllGroupsMask (0xf) - - /* - * BuildCoreState: Given a keyboard group and a modifier state, - * construct the value to be reported an event. - * GroupForCoreState: Given the state reported in an event, - * determine the keyboard group. - * IsLegalGroup: Returns TRUE if 'g' is a valid group index. - */ -#define XkbBuildCoreState(m,g) ((((g)&0x3)<<13)|((m)&0xff)) -#define XkbGroupForCoreState(s) (((s)>>13)&0x3) -#define XkbIsLegalGroup(g) (((g)>=0)&&((g)type>=Xkb_SASetMods)&&((a)->type<=XkbSA_LockMods)) -#define XkbIsGroupAction(a) (((a)->type>=XkbSA_SetGroup)&&((a)->type<=XkbSA_LockGroup)) -#define XkbIsPtrAction(a) (((a)->type>=XkbSA_MovePtr)&&((a)->type<=XkbSA_SetPtrDflt)) - - - /* - * Key Behavior Qualifier: - * KB_Permanent indicates that the behavior describes an unalterable - * characteristic of the keyboard, not an XKB software-simulation of - * the listed behavior. - * Key Behavior Types: - * Specifies the behavior of the underlying key. - */ -#define XkbKB_Permanent 0x80 -#define XkbKB_OpMask 0x7f - -#define XkbKB_Default 0x00 -#define XkbKB_Lock 0x01 -#define XkbKB_RadioGroup 0x02 -#define XkbKB_Overlay1 0x03 -#define XkbKB_Overlay2 0x04 - -#define XkbKB_RGAllowNone 0x80 - - /* - * Various macros which describe the range of legal keycodes. - */ -#define XkbMinLegalKeyCode 8 -#define XkbMaxLegalKeyCode 255 -#define XkbMaxKeyCount (XkbMaxLegalKeyCode-XkbMinLegalKeyCode+1) -#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8) -/* Seems kinda silly to check that an unsigned char is <= 255... */ -#define XkbIsLegalKeycode(k) ((k)>=XkbMinLegalKeyCode) - - /* - * Assorted constants and limits. - */ -#define XkbNumModifiers 8 -#define XkbNumVirtualMods 16 -#define XkbNumIndicators 32 -#define XkbAllIndicatorsMask (0xffffffff) -#define XkbMaxRadioGroups 32 -#define XkbAllRadioGroupsMask (0xffffffff) -#define XkbMaxShiftLevel 63 -#define XkbMaxSymsPerKey (XkbMaxShiftLevel*XkbNumKbdGroups) -#define XkbRGMaxMembers 12 -#define XkbActionMessageLength 6 -#define XkbKeyNameLength 4 -#define XkbMaxRedirectCount 8 - -#define XkbGeomPtsPerMM 10 -#define XkbGeomMaxColors 32 -#define XkbGeomMaxLabelColors 3 -#define XkbGeomMaxPriority 255 - - /* - * Key Type index and mask for the four standard key types. - */ -#define XkbOneLevelIndex 0 -#define XkbTwoLevelIndex 1 -#define XkbAlphabeticIndex 2 -#define XkbKeypadIndex 3 -#define XkbLastRequiredType XkbKeypadIndex -#define XkbNumRequiredTypes (XkbLastRequiredType+1) -#define XkbMaxKeyTypes 255 - -#define XkbOneLevelMask (1<<0) -#define XkbTwoLevelMask (1<<1) -#define XkbAlphabeticMask (1<<2) -#define XkbKeypadMask (1<<3) -#define XkbAllRequiredTypes (0xf) - -#define XkbShiftLevel(n) ((n)-1) -#define XkbShiftLevelMask(n) (1<<((n)-1)) - - /* - * Extension name and version information - */ -#define XkbName "XKEYBOARD" -#define XkbMajorVersion 1 -#define XkbMinorVersion 0 - - /* - * Explicit map components: - * - Used in the 'explicit' field of an XkbServerMap. Specifies - * the keyboard components that should _not_ be updated automatically - * in response to core protocol keyboard mapping requests. - */ -#define XkbExplicitKeyTypesMask (0x0f) -#define XkbExplicitKeyType1Mask (1<<0) -#define XkbExplicitKeyType2Mask (1<<1) -#define XkbExplicitKeyType3Mask (1<<2) -#define XkbExplicitKeyType4Mask (1<<3) -#define XkbExplicitInterpretMask (1<<4) -#define XkbExplicitAutoRepeatMask (1<<5) -#define XkbExplicitBehaviorMask (1<<6) -#define XkbExplicitVModMapMask (1<<7) -#define XkbAllExplicitMask (0xff) - - /* - * Map components masks: - * Those in AllMapComponentsMask: - * - Specifies the individual fields to be loaded or changed for the - * GetMap and SetMap requests. - * Those in ClientInfoMask: - * - Specifies the components to be allocated by XkbAllocClientMap. - * Those in ServerInfoMask: - * - Specifies the components to be allocated by XkbAllocServerMap. - */ -#define XkbKeyTypesMask (1<<0) -#define XkbKeySymsMask (1<<1) -#define XkbModifierMapMask (1<<2) -#define XkbExplicitComponentsMask (1<<3) -#define XkbKeyActionsMask (1<<4) -#define XkbKeyBehaviorsMask (1<<5) -#define XkbVirtualModsMask (1<<6) -#define XkbVirtualModMapMask (1<<7) - -#define XkbAllClientInfoMask (XkbKeyTypesMask|XkbKeySymsMask|XkbModifierMapMask) -#define XkbAllServerInfoMask (XkbExplicitComponentsMask|XkbKeyActionsMask|XkbKeyBehaviorsMask|XkbVirtualModsMask|XkbVirtualModMapMask) -#define XkbAllMapComponentsMask (XkbAllClientInfoMask|XkbAllServerInfoMask) - - /* - * Symbol interpretations flags: - * - Used in the flags field of a symbol interpretation - */ -#define XkbSI_AutoRepeat (1<<0) -#define XkbSI_LockingKey (1<<1) - - /* - * Symbol interpretations match specification: - * - Used in the match field of a symbol interpretation to specify - * the conditions under which an interpretation is used. - */ -#define XkbSI_LevelOneOnly (0x80) -#define XkbSI_OpMask (0x7f) -#define XkbSI_NoneOf (0) -#define XkbSI_AnyOfOrNone (1) -#define XkbSI_AnyOf (2) -#define XkbSI_AllOf (3) -#define XkbSI_Exactly (4) - - /* - * Indicator map flags: - * - Used in the flags field of an indicator map to indicate the - * conditions under which and indicator can be changed and the - * effects of changing the indicator. - */ -#define XkbIM_NoExplicit (1L << 7) -#define XkbIM_NoAutomatic (1L << 6) -#define XkbIM_LEDDrivesKB (1L << 5) - - /* - * Indicator map component specifications: - * - Used by the 'which_groups' and 'which_mods' fields of an indicator - * map to specify which keyboard components should be used to drive - * the indicator. - */ -#define XkbIM_UseBase (1L << 0) -#define XkbIM_UseLatched (1L << 1) -#define XkbIM_UseLocked (1L << 2) -#define XkbIM_UseEffective (1L << 3) -#define XkbIM_UseCompat (1L << 4) - -#define XkbIM_UseNone 0 -#define XkbIM_UseAnyGroup (XkbIM_UseBase|XkbIM_UseLatched|XkbIM_UseLocked\ - |XkbIM_UseEffective) -#define XkbIM_UseAnyMods (XkbIM_UseAnyGroup|XkbIM_UseCompat) - - /* - * Compatibility Map Compontents: - * - Specifies the components to be allocated in XkbAllocCompatMap. - */ -#define XkbSymInterpMask (1<<0) -#define XkbGroupCompatMask (1<<1) -#define XkbAllCompatMask (0x3) - - /* - * Names component mask: - * - Specifies the names to be loaded or changed for the GetNames and - * SetNames requests. - * - Specifies the names that have changed in a NamesNotify event. - * - Specifies the names components to be allocated by XkbAllocNames. - */ -#define XkbKeycodesNameMask (1<<0) -#define XkbGeometryNameMask (1<<1) -#define XkbSymbolsNameMask (1<<2) -#define XkbPhysSymbolsNameMask (1<<3) -#define XkbTypesNameMask (1<<4) -#define XkbCompatNameMask (1<<5) -#define XkbKeyTypeNamesMask (1<<6) -#define XkbKTLevelNamesMask (1<<7) -#define XkbIndicatorNamesMask (1<<8) -#define XkbKeyNamesMask (1<<9) -#define XkbKeyAliasesMask (1<<10) -#define XkbVirtualModNamesMask (1<<11) -#define XkbGroupNamesMask (1<<12) -#define XkbRGNamesMask (1<<13) -#define XkbComponentNamesMask (0x3f) -#define XkbAllNamesMask (0x3fff) - - /* - * GetByName components: - * - Specifies desired or necessary components to GetKbdByName request. - * - Reports the components that were found in a GetKbdByNameReply - */ -#define XkbGBN_TypesMask (1L << 0) -#define XkbGBN_CompatMapMask (1L << 1) -#define XkbGBN_ClientSymbolsMask (1L << 2) -#define XkbGBN_ServerSymbolsMask (1L << 3) -#define XkbGBN_SymbolsMask (XkbGBN_ClientSymbolsMask|XkbGBN_ServerSymbolsMask) -#define XkbGBN_IndicatorMapMask (1L << 4) -#define XkbGBN_KeyNamesMask (1L << 5) -#define XkbGBN_GeometryMask (1L << 6) -#define XkbGBN_OtherNamesMask (1L << 7) -#define XkbGBN_AllComponentsMask (0xff) - - /* - * ListComponents flags - */ -#define XkbLC_Hidden (1L << 0) -#define XkbLC_Default (1L << 1) -#define XkbLC_Partial (1L << 2) - -#define XkbLC_AlphanumericKeys (1L << 8) -#define XkbLC_ModifierKeys (1L << 9) -#define XkbLC_KeypadKeys (1L << 10) -#define XkbLC_FunctionKeys (1L << 11) -#define XkbLC_AlternateGroup (1L << 12) - - /* - * X Input Extension Interactions - * - Specifies the possible interactions between XKB and the X input - * extension - * - Used to request (XkbGetDeviceInfo) or change (XKbSetDeviceInfo) - * XKB information about an extension device. - * - Reports the list of supported optional features in the reply to - * XkbGetDeviceInfo or in an XkbExtensionDeviceNotify event. - * XkbXI_UnsupportedFeature is reported in XkbExtensionDeviceNotify - * events to indicate an attempt to use an unsupported feature. - */ -#define XkbXI_KeyboardsMask (1L << 0) -#define XkbXI_ButtonActionsMask (1L << 1) -#define XkbXI_IndicatorNamesMask (1L << 2) -#define XkbXI_IndicatorMapsMask (1L << 3) -#define XkbXI_IndicatorStateMask (1L << 4) -#define XkbXI_UnsupportedFeatureMask (1L << 15) -#define XkbXI_AllFeaturesMask (0x001f) -#define XkbXI_AllDeviceFeaturesMask (0x001e) - -#define XkbXI_IndicatorsMask (0x001c) -#define XkbAllExtensionDeviceEventsMask (0x801f) - - /* - * Per-Client Flags: - * - Specifies flags to be changed by the PerClientFlags request. - */ -#define XkbPCF_DetectableAutoRepeatMask (1L << 0) -#define XkbPCF_GrabsUseXKBStateMask (1L << 1) -#define XkbPCF_AutoResetControlsMask (1L << 2) -#define XkbPCF_LookupStateWhenGrabbed (1L << 3) -#define XkbPCF_SendEventUsesXKBState (1L << 4) -#define XkbPCF_AllFlagsMask (0x1F) - - /* - * Debugging flags and controls - */ -#define XkbDF_DisableLocks (1<<0) - -#endif /* _XKB_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XKBgeom.h b/shell/linux-deps/include/X11/extensions/XKBgeom.h deleted file mode 100644 index 89f902fba..000000000 --- a/shell/linux-deps/include/X11/extensions/XKBgeom.h +++ /dev/null @@ -1,659 +0,0 @@ -/* $Xorg: XKBgeom.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ */ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ -/* $XFree86: xc/include/extensions/XKBgeom.h,v 3.9 2002/09/18 17:11:40 tsi Exp $ */ - -#ifndef _XKBGEOM_H_ -#define _XKBGEOM_H_ - -#include - -#ifdef XKB_IN_SERVER -#define XkbAddGeomKeyAlias SrvXkbAddGeomKeyAlias -#define XkbAddGeomColor SrvXkbAddGeomColor -#define XkbAddGeomDoodad SrvXkbAddGeomDoodad -#define XkbAddGeomKey SrvXkbAddGeomKey -#define XkbAddGeomOutline SrvXkbAddGeomOutline -#define XkbAddGeomOverlay SrvXkbAddGeomOverlay -#define XkbAddGeomOverlayRow SrvXkbAddGeomOverlayRow -#define XkbAddGeomOverlayKey SrvXkbAddGeomOverlayKey -#define XkbAddGeomProperty SrvXkbAddGeomProperty -#define XkbAddGeomRow SrvXkbAddGeomRow -#define XkbAddGeomSection SrvXkbAddGeomSection -#define XkbAddGeomShape SrvXkbAddGeomShape -#define XkbAllocGeomKeyAliases SrvXkbAllocGeomKeyAliases -#define XkbAllocGeomColors SrvXkbAllocGeomColors -#define XkbAllocGeomDoodads SrvXkbAllocGeomDoodads -#define XkbAllocGeomKeys SrvXkbAllocGeomKeys -#define XkbAllocGeomOutlines SrvXkbAllocGeomOutlines -#define XkbAllocGeomPoints SrvXkbAllocGeomPoints -#define XkbAllocGeomProps SrvXkbAllocGeomProps -#define XkbAllocGeomRows SrvXkbAllocGeomRows -#define XkbAllocGeomSectionDoodads SrvXkbAllocGeomSectionDoodads -#define XkbAllocGeomSections SrvXkbAllocGeomSections -#define XkbAllocGeomOverlays SrvXkbAllocGeomOverlays -#define XkbAllocGeomOverlayRows SrvXkbAllocGeomOverlayRows -#define XkbAllocGeomOverlayKeys SrvXkbAllocGeomOverlayKeys -#define XkbAllocGeomShapes SrvXkbAllocGeomShapes -#define XkbAllocGeometry SrvXkbAllocGeometry -#define XkbFreeGeomKeyAliases SrvXkbFreeGeomKeyAliases -#define XkbFreeGeomColors SrvXkbFreeGeomColors -#define XkbFreeGeomDoodads SrvXkbFreeGeomDoodads -#define XkbFreeGeomProperties SrvXkbFreeGeomProperties -#define XkbFreeGeomOverlayKeys SrvXkbFreeGeomOverlayKeys -#define XkbFreeGeomOverlayRows SrvXkbFreeGeomOverlayRows -#define XkbFreeGeomOverlays SrvXkbFreeGeomOverlays -#define XkbFreeGeomKeys SrvXkbFreeGeomKeys -#define XkbFreeGeomRows SrvXkbFreeGeomRows -#define XkbFreeGeomSections SrvXkbFreeGeomSections -#define XkbFreeGeomPoints SrvXkbFreeGeomPoints -#define XkbFreeGeomOutlines SrvXkbFreeGeomOutlines -#define XkbFreeGeomShapes SrvXkbFreeGeomShapes -#define XkbFreeGeometry SrvXkbFreeGeometry -#endif - -typedef struct _XkbProperty { - char *name; - char *value; -} XkbPropertyRec,*XkbPropertyPtr; - -typedef struct _XkbColor { - unsigned int pixel; - char * spec; -} XkbColorRec,*XkbColorPtr; - -typedef struct _XkbPoint { - short x; - short y; -} XkbPointRec, *XkbPointPtr; - -typedef struct _XkbBounds { - short x1,y1; - short x2,y2; -} XkbBoundsRec, *XkbBoundsPtr; -#define XkbBoundsWidth(b) (((b)->x2)-((b)->x1)) -#define XkbBoundsHeight(b) (((b)->y2)-((b)->y1)) - -typedef struct _XkbOutline { - unsigned short num_points; - unsigned short sz_points; - unsigned short corner_radius; - XkbPointPtr points; -} XkbOutlineRec, *XkbOutlinePtr; - -typedef struct _XkbShape { - Atom name; - unsigned short num_outlines; - unsigned short sz_outlines; - XkbOutlinePtr outlines; - XkbOutlinePtr approx; - XkbOutlinePtr primary; - XkbBoundsRec bounds; -} XkbShapeRec, *XkbShapePtr; -#define XkbOutlineIndex(s,o) ((int)((o)-&(s)->outlines[0])) - -typedef struct _XkbShapeDoodad { - Atom name; - unsigned char type; - unsigned char priority; - short top; - short left; - short angle; - unsigned short color_ndx; - unsigned short shape_ndx; -} XkbShapeDoodadRec, *XkbShapeDoodadPtr; -#define XkbShapeDoodadColor(g,d) (&(g)->colors[(d)->color_ndx]) -#define XkbShapeDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx]) -#define XkbSetShapeDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0]) -#define XkbSetShapeDoodadShape(g,d,s) ((d)->shape_ndx= (s)-&(g)->shapes[0]) - -typedef struct _XkbTextDoodad { - Atom name; - unsigned char type; - unsigned char priority; - short top; - short left; - short angle; - short width; - short height; - unsigned short color_ndx; - char * text; - char * font; -} XkbTextDoodadRec, *XkbTextDoodadPtr; -#define XkbTextDoodadColor(g,d) (&(g)->colors[(d)->color_ndx]) -#define XkbSetTextDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0]) - -typedef struct _XkbIndicatorDoodad { - Atom name; - unsigned char type; - unsigned char priority; - short top; - short left; - short angle; - unsigned short shape_ndx; - unsigned short on_color_ndx; - unsigned short off_color_ndx; -} XkbIndicatorDoodadRec, *XkbIndicatorDoodadPtr; -#define XkbIndicatorDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx]) -#define XkbIndicatorDoodadOnColor(g,d) (&(g)->colors[(d)->on_color_ndx]) -#define XkbIndicatorDoodadOffColor(g,d) (&(g)->colors[(d)->off_color_ndx]) -#define XkbSetIndicatorDoodadOnColor(g,d,c) \ - ((d)->on_color_ndx= (c)-&(g)->colors[0]) -#define XkbSetIndicatorDoodadOffColor(g,d,c) \ - ((d)->off_color_ndx= (c)-&(g)->colors[0]) -#define XkbSetIndicatorDoodadShape(g,d,s) \ - ((d)->shape_ndx= (s)-&(g)->shapes[0]) - -typedef struct _XkbLogoDoodad { - Atom name; - unsigned char type; - unsigned char priority; - short top; - short left; - short angle; - unsigned short color_ndx; - unsigned short shape_ndx; - char * logo_name; -} XkbLogoDoodadRec, *XkbLogoDoodadPtr; -#define XkbLogoDoodadColor(g,d) (&(g)->colors[(d)->color_ndx]) -#define XkbLogoDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx]) -#define XkbSetLogoDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0]) -#define XkbSetLogoDoodadShape(g,d,s) ((d)->shape_ndx= (s)-&(g)->shapes[0]) - -typedef struct _XkbAnyDoodad { - Atom name; - unsigned char type; - unsigned char priority; - short top; - short left; - short angle; -} XkbAnyDoodadRec, *XkbAnyDoodadPtr; - -typedef union _XkbDoodad { - XkbAnyDoodadRec any; - XkbShapeDoodadRec shape; - XkbTextDoodadRec text; - XkbIndicatorDoodadRec indicator; - XkbLogoDoodadRec logo; -} XkbDoodadRec, *XkbDoodadPtr; - -#define XkbUnknownDoodad 0 -#define XkbOutlineDoodad 1 -#define XkbSolidDoodad 2 -#define XkbTextDoodad 3 -#define XkbIndicatorDoodad 4 -#define XkbLogoDoodad 5 - -typedef struct _XkbKey { - XkbKeyNameRec name; - short gap; - unsigned char shape_ndx; - unsigned char color_ndx; -} XkbKeyRec, *XkbKeyPtr; -#define XkbKeyShape(g,k) (&(g)->shapes[(k)->shape_ndx]) -#define XkbKeyColor(g,k) (&(g)->colors[(k)->color_ndx]) -#define XkbSetKeyShape(g,k,s) ((k)->shape_ndx= (s)-&(g)->shapes[0]) -#define XkbSetKeyColor(g,k,c) ((k)->color_ndx= (c)-&(g)->colors[0]) - -typedef struct _XkbRow { - short top; - short left; - unsigned short num_keys; - unsigned short sz_keys; - int vertical; - XkbKeyPtr keys; - XkbBoundsRec bounds; -} XkbRowRec, *XkbRowPtr; - -typedef struct _XkbSection { - Atom name; - unsigned char priority; - short top; - short left; - unsigned short width; - unsigned short height; - short angle; - unsigned short num_rows; - unsigned short num_doodads; - unsigned short num_overlays; - unsigned short sz_rows; - unsigned short sz_doodads; - unsigned short sz_overlays; - XkbRowPtr rows; - XkbDoodadPtr doodads; - XkbBoundsRec bounds; - struct _XkbOverlay *overlays; -} XkbSectionRec, *XkbSectionPtr; - -typedef struct _XkbOverlayKey { - XkbKeyNameRec over; - XkbKeyNameRec under; -} XkbOverlayKeyRec,*XkbOverlayKeyPtr; - -typedef struct _XkbOverlayRow { - unsigned short row_under; - unsigned short num_keys; - unsigned short sz_keys; - XkbOverlayKeyPtr keys; -} XkbOverlayRowRec,*XkbOverlayRowPtr; - -typedef struct _XkbOverlay { - Atom name; - XkbSectionPtr section_under; - unsigned short num_rows; - unsigned short sz_rows; - XkbOverlayRowPtr rows; - XkbBoundsPtr bounds; -} XkbOverlayRec,*XkbOverlayPtr; - -typedef struct _XkbGeometry { - Atom name; - unsigned short width_mm; - unsigned short height_mm; - char * label_font; - XkbColorPtr label_color; - XkbColorPtr base_color; - unsigned short sz_properties; - unsigned short sz_colors; - unsigned short sz_shapes; - unsigned short sz_sections; - unsigned short sz_doodads; - unsigned short sz_key_aliases; - unsigned short num_properties; - unsigned short num_colors; - unsigned short num_shapes; - unsigned short num_sections; - unsigned short num_doodads; - unsigned short num_key_aliases; - XkbPropertyPtr properties; - XkbColorPtr colors; - XkbShapePtr shapes; - XkbSectionPtr sections; - XkbDoodadPtr doodads; - XkbKeyAliasPtr key_aliases; -} XkbGeometryRec; -#define XkbGeomColorIndex(g,c) ((int)((c)-&(g)->colors[0])) - -#define XkbGeomPropertiesMask (1<<0) -#define XkbGeomColorsMask (1<<1) -#define XkbGeomShapesMask (1<<2) -#define XkbGeomSectionsMask (1<<3) -#define XkbGeomDoodadsMask (1<<4) -#define XkbGeomKeyAliasesMask (1<<5) -#define XkbGeomAllMask (0x3f) - -typedef struct _XkbGeometrySizes { - unsigned int which; - unsigned short num_properties; - unsigned short num_colors; - unsigned short num_shapes; - unsigned short num_sections; - unsigned short num_doodads; - unsigned short num_key_aliases; -} XkbGeometrySizesRec,*XkbGeometrySizesPtr; - -_XFUNCPROTOBEGIN - -extern XkbPropertyPtr -XkbAddGeomProperty( - XkbGeometryPtr /* geom */, - char * /* name */, - char * /* value */ -); - -extern XkbKeyAliasPtr -XkbAddGeomKeyAlias( - XkbGeometryPtr /* geom */, - char * /* alias */, - char * /* real */ -); - -extern XkbColorPtr -XkbAddGeomColor( - XkbGeometryPtr /* geom */, - char * /* spec */, - unsigned int /* pixel */ -); - -extern XkbOutlinePtr -XkbAddGeomOutline( - XkbShapePtr /* shape */, - int /* sz_points */ -); - -extern XkbShapePtr -XkbAddGeomShape( - XkbGeometryPtr /* geom */, - Atom /* name */, - int /* sz_outlines */ -); - -extern XkbKeyPtr -XkbAddGeomKey( - XkbRowPtr /* row */ -); - -extern XkbRowPtr -XkbAddGeomRow( - XkbSectionPtr /* section */, - int /* sz_keys */ -); - -extern XkbSectionPtr -XkbAddGeomSection( - XkbGeometryPtr /* geom */, - Atom /* name */, - int /* sz_rows */, - int /* sz_doodads */, - int /* sz_overlays */ -); - -extern XkbOverlayPtr -XkbAddGeomOverlay( - XkbSectionPtr /* section */, - Atom /* name */, - int /* sz_rows */ -); - -extern XkbOverlayRowPtr -XkbAddGeomOverlayRow( - XkbOverlayPtr /* overlay */, - int /* row_under */, - int /* sz_keys */ -); - -extern XkbOverlayKeyPtr -XkbAddGeomOverlayKey( - XkbOverlayPtr /* overlay */, - XkbOverlayRowPtr /* row */, - char * /* over */, - char * /* under */ -); - -extern XkbDoodadPtr -XkbAddGeomDoodad( - XkbGeometryPtr /* geom */, - XkbSectionPtr /* section */, - Atom /* name */ -); - - -extern void -XkbFreeGeomKeyAliases( - XkbGeometryPtr /* geom */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomColors( - XkbGeometryPtr /* geom */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomDoodads( - XkbDoodadPtr /* doodads */, - int /* nDoodads */, - Bool /* freeAll */ -); - - -extern void -XkbFreeGeomProperties( - XkbGeometryPtr /* geom */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomOverlayKeys( - XkbOverlayRowPtr /* row */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomOverlayRows( - XkbOverlayPtr /* overlay */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomOverlays( - XkbSectionPtr /* section */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomKeys( - XkbRowPtr /* row */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomRows( - XkbSectionPtr /* section */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomSections( - XkbGeometryPtr /* geom */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - - -extern void -XkbFreeGeomPoints( - XkbOutlinePtr /* outline */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomOutlines( - XkbShapePtr /* shape */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeomShapes( - XkbGeometryPtr /* geom */, - int /* first */, - int /* count */, - Bool /* freeAll */ -); - -extern void -XkbFreeGeometry( - XkbGeometryPtr /* geom */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern Status -XkbAllocGeomProps( - XkbGeometryPtr /* geom */, - int /* nProps */ -); - -extern Status -XkbAllocGeomKeyAliases( - XkbGeometryPtr /* geom */, - int /* nAliases */ -); - -extern Status -XkbAllocGeomColors( - XkbGeometryPtr /* geom */, - int /* nColors */ -); - -extern Status -XkbAllocGeomShapes( - XkbGeometryPtr /* geom */, - int /* nShapes */ -); - -extern Status -XkbAllocGeomSections( - XkbGeometryPtr /* geom */, - int /* nSections */ -); - -extern Status -XkbAllocGeomOverlays( - XkbSectionPtr /* section */, - int /* num_needed */ -); - -extern Status -XkbAllocGeomOverlayRows( - XkbOverlayPtr /* overlay */, - int /* num_needed */ -); - -extern Status -XkbAllocGeomOverlayKeys( - XkbOverlayRowPtr /* row */, - int /* num_needed */ -); - -extern Status -XkbAllocGeomDoodads( - XkbGeometryPtr /* geom */, - int /* nDoodads */ -); - -extern Status -XkbAllocGeomSectionDoodads( - XkbSectionPtr /* section */, - int /* nDoodads */ -); - -extern Status -XkbAllocGeomOutlines( - XkbShapePtr /* shape */, - int /* nOL */ -); - -extern Status -XkbAllocGeomRows( - XkbSectionPtr /* section */, - int /* nRows */ -); - -extern Status -XkbAllocGeomPoints( - XkbOutlinePtr /* ol */, - int /* nPts */ -); - -extern Status -XkbAllocGeomKeys( - XkbRowPtr /* row */, - int /* nKeys */ -); - -extern Status -XkbAllocGeometry( - XkbDescPtr /* xkb */, - XkbGeometrySizesPtr /* sizes */ -); - -extern Status -XkbSetGeometry( - Display * /* dpy */, - unsigned /* deviceSpec */, - XkbGeometryPtr /* geom */ -); - -extern Bool -XkbComputeShapeTop( - XkbShapePtr /* shape */, - XkbBoundsPtr /* bounds */ -); - -extern Bool -XkbComputeShapeBounds( - XkbShapePtr /* shape */ -); - -extern Bool -XkbComputeRowBounds( - XkbGeometryPtr /* geom */, - XkbSectionPtr /* section */, - XkbRowPtr /* row */ -); - -extern Bool -XkbComputeSectionBounds( - XkbGeometryPtr /* geom */, - XkbSectionPtr /* section */ -); - -extern char * -XkbFindOverlayForKey( - XkbGeometryPtr /* geom */, - XkbSectionPtr /* wanted */, - char * /* under */ -); - -extern Status -XkbGetGeometry( - Display * /* dpy */, - XkbDescPtr /* xkb */ -); - -extern Status -XkbGetNamedGeometry( - Display * /* dpy */, - XkbDescPtr /* xkb */, - Atom /* name */ -); - -_XFUNCPROTOEND - -#endif /* _XKBSTR_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XKBproto.h b/shell/linux-deps/include/X11/extensions/XKBproto.h deleted file mode 100644 index 97dd4d262..000000000 --- a/shell/linux-deps/include/X11/extensions/XKBproto.h +++ /dev/null @@ -1,1282 +0,0 @@ -/* $Xorg: XKBproto.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ */ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ - -#ifndef _XKBPROTO_H_ -#define _XKBPROTO_H_ - -#include -#include - -#define Window CARD32 -#define Atom CARD32 -#define Time CARD32 -#define KeyCode CARD8 -#define KeySym CARD32 - -#define XkbPaddedSize(n) ((((unsigned int)(n)+3) >> 2) << 2) - -typedef struct _xkbUseExtension { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBUseExtension */ - CARD16 length B16; - CARD16 wantedMajor B16; - CARD16 wantedMinor B16; -} xkbUseExtensionReq; -#define sz_xkbUseExtensionReq 8 - -typedef struct _xkbUseExtensionReply { - BYTE type; /* X_Reply */ - BOOL supported; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 serverMajor B16; - CARD16 serverMinor B16; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xkbUseExtensionReply; -#define sz_xkbUseExtensionReply 32 - -typedef struct _xkbSelectEvents { - CARD8 reqType; - CARD8 xkbReqType; /* X_KBSelectEvents */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 affectWhich B16; - CARD16 clear B16; - CARD16 selectAll B16; - CARD16 affectMap B16; - CARD16 map B16; -} xkbSelectEventsReq; -#define sz_xkbSelectEventsReq 16 - -typedef struct _xkbBell { - CARD8 reqType; - CARD8 xkbReqType; /* X_KBBell */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 bellClass B16; - CARD16 bellID B16; - INT8 percent; - BOOL forceSound; - BOOL eventOnly; - CARD8 pad1; - INT16 pitch B16; - INT16 duration B16; - CARD16 pad2 B16; - Atom name B32; - Window window B32; -} xkbBellReq; -#define sz_xkbBellReq 28 - -typedef struct _xkbGetState { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetState */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad B16; -} xkbGetStateReq; -#define sz_xkbGetStateReq 8 - -typedef struct _xkbGetStateReply { - BYTE type; - BYTE deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 mods; - CARD8 baseMods; - CARD8 latchedMods; - CARD8 lockedMods; - CARD8 group; - CARD8 lockedGroup; - INT16 baseGroup B16; - INT16 latchedGroup B16; - CARD8 compatState; - CARD8 grabMods; - CARD8 compatGrabMods; - CARD8 lookupMods; - CARD8 compatLookupMods; - CARD8 pad1; - CARD16 ptrBtnState B16; - CARD16 pad2 B16; - CARD32 pad3 B32; -} xkbGetStateReply; -#define sz_xkbGetStateReply 32 - -typedef struct _xkbLatchLockState { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBLatchLockState */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 affectModLocks; - CARD8 modLocks; - BOOL lockGroup; - CARD8 groupLock; - CARD8 affectModLatches; - CARD8 modLatches; - CARD8 pad; - BOOL latchGroup; - INT16 groupLatch B16; -} xkbLatchLockStateReq; -#define sz_xkbLatchLockStateReq 16 - -typedef struct _xkbGetControls { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetControls */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad B16; -} xkbGetControlsReq; -#define sz_xkbGetControlsReq 8 - -typedef struct _xkbGetControlsReply { - BYTE type; /* X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 mkDfltBtn; - CARD8 numGroups; - CARD8 groupsWrap; - CARD8 internalMods; - CARD8 ignoreLockMods; - CARD8 internalRealMods; - CARD8 ignoreLockRealMods; - CARD8 pad1; - CARD16 internalVMods B16; - CARD16 ignoreLockVMods B16; - CARD16 repeatDelay B16; - CARD16 repeatInterval B16; - CARD16 slowKeysDelay B16; - CARD16 debounceDelay B16; - CARD16 mkDelay B16; - CARD16 mkInterval B16; - CARD16 mkTimeToMax B16; - CARD16 mkMaxSpeed B16; - INT16 mkCurve B16; - CARD16 axOptions B16; - CARD16 axTimeout B16; - CARD16 axtOptsMask B16; - CARD16 axtOptsValues B16; - CARD16 pad2 B16; - CARD32 axtCtrlsMask B32; - CARD32 axtCtrlsValues B32; - CARD32 enabledCtrls B32; - BYTE perKeyRepeat[XkbPerKeyBitArraySize]; -} xkbGetControlsReply; -#define sz_xkbGetControlsReply 92 - -typedef struct _xkbSetControls { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetControls */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 affectInternalMods; - CARD8 internalMods; - CARD8 affectIgnoreLockMods; - CARD8 ignoreLockMods; - CARD16 affectInternalVMods B16; - CARD16 internalVMods B16; - CARD16 affectIgnoreLockVMods B16; - CARD16 ignoreLockVMods B16; - CARD8 mkDfltBtn; - CARD8 groupsWrap; - CARD16 axOptions B16; - CARD16 pad1 B16; - CARD32 affectEnabledCtrls B32; - CARD32 enabledCtrls B32; - CARD32 changeCtrls B32; - CARD16 repeatDelay B16; - CARD16 repeatInterval B16; - CARD16 slowKeysDelay B16; - CARD16 debounceDelay B16; - CARD16 mkDelay B16; - CARD16 mkInterval B16; - CARD16 mkTimeToMax B16; - CARD16 mkMaxSpeed B16; - INT16 mkCurve B16; - CARD16 axTimeout B16; - CARD32 axtCtrlsMask B32; - CARD32 axtCtrlsValues B32; - CARD16 axtOptsMask B16; - CARD16 axtOptsValues B16; - BYTE perKeyRepeat[XkbPerKeyBitArraySize]; -} xkbSetControlsReq; -#define sz_xkbSetControlsReq 100 - -typedef struct _xkbKTMapEntryWireDesc { - BOOL active; - CARD8 mask; - CARD8 level; - CARD8 realMods; - CARD16 virtualMods B16; - CARD16 pad B16; -} xkbKTMapEntryWireDesc; -#define sz_xkbKTMapEntryWireDesc 8 - -typedef struct _xkbKTSetMapEntryWireDesc { - CARD8 level; - CARD8 realMods; - CARD16 virtualMods B16; -} xkbKTSetMapEntryWireDesc; -#define sz_xkbKTSetMapEntryWireDesc 4 - -typedef struct _xkbModsWireDesc { - CARD8 mask; /* GetMap only */ - CARD8 realMods; - CARD16 virtualMods B16; -} xkbModsWireDesc; -#define sz_xkbModsWireDesc 4 - -typedef struct _xkbKeyTypeWireDesc { - CARD8 mask; - CARD8 realMods; - CARD16 virtualMods B16; - CARD8 numLevels; - CARD8 nMapEntries; - BOOL preserve; - CARD8 pad; -} xkbKeyTypeWireDesc; -#define sz_xkbKeyTypeWireDesc 8 - -typedef struct _xkbSymMapWireDesc { - CARD8 ktIndex[XkbNumKbdGroups]; - CARD8 groupInfo; - CARD8 width; - CARD16 nSyms B16; -} xkbSymMapWireDesc; -#define sz_xkbSymMapWireDesc 8 - -typedef struct _xkbVModMapWireDesc { - KeyCode key; - CARD8 pad; - CARD16 vmods B16; -} xkbVModMapWireDesc; -#define sz_xkbVModMapWireDesc 4 - -typedef struct _xkbBehaviorWireDesc { - CARD8 key; - CARD8 type; - CARD8 data; - CARD8 pad; -} xkbBehaviorWireDesc; -#define sz_xkbBehaviorWireDesc 4 - -typedef struct _xkbActionWireDesc { - CARD8 type; - CARD8 data[7]; -} xkbActionWireDesc; -#define sz_xkbActionWireDesc 8 - -typedef struct _xkbGetMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 full B16; - CARD16 partial B16; - CARD8 firstType; - CARD8 nTypes; - KeyCode firstKeySym; - CARD8 nKeySyms; - KeyCode firstKeyAct; - CARD8 nKeyActs; - KeyCode firstKeyBehavior; - CARD8 nKeyBehaviors; - CARD16 virtualMods B16; - KeyCode firstKeyExplicit; - CARD8 nKeyExplicit; - KeyCode firstModMapKey; - CARD8 nModMapKeys; - KeyCode firstVModMapKey; - CARD8 nVModMapKeys; - CARD16 pad1 B16; -} xkbGetMapReq; -#define sz_xkbGetMapReq 28 - -typedef struct _xkbGetMapReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 pad1 B16; - KeyCode minKeyCode; - KeyCode maxKeyCode; - CARD16 present B16; - CARD8 firstType; - CARD8 nTypes; - CARD8 totalTypes; - KeyCode firstKeySym; - CARD16 totalSyms B16; - CARD8 nKeySyms; - KeyCode firstKeyAct; - CARD16 totalActs B16; - CARD8 nKeyActs; - KeyCode firstKeyBehavior; - CARD8 nKeyBehaviors; - CARD8 totalKeyBehaviors; - KeyCode firstKeyExplicit; - CARD8 nKeyExplicit; - CARD8 totalKeyExplicit; - KeyCode firstModMapKey; - CARD8 nModMapKeys; - CARD8 totalModMapKeys; - KeyCode firstVModMapKey; - CARD8 nVModMapKeys; - CARD8 totalVModMapKeys; - CARD8 pad2; - CARD16 virtualMods B16; -} xkbGetMapReply; -#define sz_xkbGetMapReply 40 - -#define XkbSetMapResizeTypes (1L<<0) -#define XkbSetMapRecomputeActions (1L<<1) -#define XkbSetMapAllFlags (0x3) - -typedef struct _xkbSetMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 present B16; - CARD16 flags B16; - KeyCode minKeyCode; - KeyCode maxKeyCode; - CARD8 firstType; - CARD8 nTypes; - KeyCode firstKeySym; - CARD8 nKeySyms; - CARD16 totalSyms B16; - KeyCode firstKeyAct; - CARD8 nKeyActs; - CARD16 totalActs B16; - KeyCode firstKeyBehavior; - CARD8 nKeyBehaviors; - CARD8 totalKeyBehaviors; - KeyCode firstKeyExplicit; - CARD8 nKeyExplicit; - CARD8 totalKeyExplicit; - KeyCode firstModMapKey; - CARD8 nModMapKeys; - CARD8 totalModMapKeys; - KeyCode firstVModMapKey; - CARD8 nVModMapKeys; - CARD8 totalVModMapKeys; - CARD16 virtualMods B16; -} xkbSetMapReq; -#define sz_xkbSetMapReq 36 - -typedef struct _xkbSymInterpretWireDesc { - CARD32 sym B32; - CARD8 mods; - CARD8 match; - CARD8 virtualMod; - CARD8 flags; - xkbActionWireDesc act; -} xkbSymInterpretWireDesc; -#define sz_xkbSymInterpretWireDesc 16 - -typedef struct _xkbGetCompatMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetCompatMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 groups; - BOOL getAllSI; - CARD16 firstSI B16; - CARD16 nSI B16; -} xkbGetCompatMapReq; -#define sz_xkbGetCompatMapReq 12 - -typedef struct _xkbGetCompatMapReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD8 groups; - CARD8 pad1; - CARD16 firstSI B16; - CARD16 nSI B16; - CARD16 nTotalSI B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xkbGetCompatMapReply; -#define sz_xkbGetCompatMapReply 32 - -typedef struct _xkbSetCompatMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetCompatMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 pad1; - BOOL recomputeActions; - BOOL truncateSI; - CARD8 groups; - CARD16 firstSI B16; - CARD16 nSI B16; - CARD16 pad2 B16; -} xkbSetCompatMapReq; -#define sz_xkbSetCompatMapReq 16 - -typedef struct _xkbGetIndicatorState { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetIndicatorState */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad1 B16; -} xkbGetIndicatorStateReq; -#define sz_xkbGetIndicatorStateReq 8 - -typedef struct _xkbGetIndicatorStateReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 state B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xkbGetIndicatorStateReply; -#define sz_xkbGetIndicatorStateReply 32 - -typedef struct _xkbGetIndicatorMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetIndicatorMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad B16; - CARD32 which B32; -} xkbGetIndicatorMapReq; -#define sz_xkbGetIndicatorMapReq 12 - -typedef struct _xkbGetIndicatorMapReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 which B32; - CARD32 realIndicators B32; - CARD8 nIndicators; - CARD8 pad1; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xkbGetIndicatorMapReply; -#define sz_xkbGetIndicatorMapReply 32 - -typedef struct _xkbIndicatorMapWireDesc { - CARD8 flags; - CARD8 whichGroups; - CARD8 groups; - CARD8 whichMods; - CARD8 mods; - CARD8 realMods; - CARD16 virtualMods B16; - CARD32 ctrls B32; -} xkbIndicatorMapWireDesc; -#define sz_xkbIndicatorMapWireDesc 12 - -typedef struct _xkbSetIndicatorMap { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetIndicatorMap */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad1 B16; - CARD32 which B32; -} xkbSetIndicatorMapReq; -#define sz_xkbSetIndicatorMapReq 12 - -typedef struct _xkbGetNamedIndicator { - CARD8 reqType; - CARD8 xkbReqType; /* X_KBGetNamedIndicator */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 ledClass B16; - CARD16 ledID B16; - CARD16 pad1 B16; - Atom indicator B32; -} xkbGetNamedIndicatorReq; -#define sz_xkbGetNamedIndicatorReq 16 - -typedef struct _xkbGetNamedIndicatorReply { - BYTE type; - BYTE deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - Atom indicator B32; - BOOL found; - BOOL on; - BOOL realIndicator; - CARD8 ndx; - CARD8 flags; - CARD8 whichGroups; - CARD8 groups; - CARD8 whichMods; - CARD8 mods; - CARD8 realMods; - CARD16 virtualMods B16; - CARD32 ctrls B32; - BOOL supported; - CARD8 pad1; - CARD16 pad2 B16; -} xkbGetNamedIndicatorReply; -#define sz_xkbGetNamedIndicatorReply 32 - -typedef struct _xkbSetNamedIndicator { - CARD8 reqType; - CARD8 xkbReqType; /* X_KBSetNamedIndicator */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 ledClass B16; - CARD16 ledID B16; - CARD16 pad1 B16; - Atom indicator B32; - BOOL setState; - BOOL on; - BOOL setMap; - BOOL createMap; - CARD8 pad2; - CARD8 flags; - CARD8 whichGroups; - CARD8 groups; - CARD8 whichMods; - CARD8 realMods; - CARD16 virtualMods B16; - CARD32 ctrls B32; -} xkbSetNamedIndicatorReq; -#define sz_xkbSetNamedIndicatorReq 32 - -typedef struct _xkbGetNames { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetNames */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad B16; - CARD32 which B32; -} xkbGetNamesReq; -#define sz_xkbGetNamesReq 12 - -typedef struct _xkbGetNamesReply { - BYTE type; - BYTE deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 which B32; - KeyCode minKeyCode; - KeyCode maxKeyCode; - CARD8 nTypes; - CARD8 groupNames; - CARD16 virtualMods B16; - KeyCode firstKey; - CARD8 nKeys; - CARD32 indicators B32; - CARD8 nRadioGroups; - CARD8 nKeyAliases; - CARD16 nKTLevels B16; - CARD32 pad3 B32; -} xkbGetNamesReply; -#define sz_xkbGetNamesReply 32 - -typedef struct _xkbSetNames { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetNames */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 virtualMods B16; - CARD32 which B32; - CARD8 firstType; - CARD8 nTypes; - CARD8 firstKTLevel; - CARD8 nKTLevels; - CARD32 indicators B32; - CARD8 groupNames; - CARD8 nRadioGroups; - KeyCode firstKey; - CARD8 nKeys; - CARD8 nKeyAliases; - CARD8 pad1; - CARD16 totalKTLevelNames B16; -} xkbSetNamesReq; -#define sz_xkbSetNamesReq 28 - -typedef struct _xkbPointWireDesc { - INT16 x B16; - INT16 y B16; -} xkbPointWireDesc; -#define sz_xkbPointWireDesc 4 - -typedef struct _xkbOutlineWireDesc { - CARD8 nPoints; - CARD8 cornerRadius; - CARD16 pad B16; -} xkbOutlineWireDesc; -#define sz_xkbOutlineWireDesc 4 - -typedef struct _xkbShapeWireDesc { - Atom name B32; - CARD8 nOutlines; - CARD8 primaryNdx; - CARD8 approxNdx; - CARD8 pad; -} xkbShapeWireDesc; -#define sz_xkbShapeWireDesc 8 - -typedef struct _xkbSectionWireDesc { - Atom name B32; - INT16 top B16; - INT16 left B16; - CARD16 width B16; - CARD16 height B16; - INT16 angle B16; - CARD8 priority; - CARD8 nRows; - CARD8 nDoodads; - CARD8 nOverlays; - CARD16 pad B16; -} xkbSectionWireDesc; -#define sz_xkbSectionWireDesc 20 - -typedef struct _xkbRowWireDesc { - INT16 top B16; - INT16 left B16; - CARD8 nKeys; - BOOL vertical; - CARD16 pad B16; -} xkbRowWireDesc; -#define sz_xkbRowWireDesc 8 - -typedef struct _xkbKeyWireDesc { - CARD8 name[XkbKeyNameLength]; - INT16 gap B16; - CARD8 shapeNdx; - CARD8 colorNdx; -} xkbKeyWireDesc; -#define sz_xkbKeyWireDesc 8 - -typedef struct _xkbOverlayWireDesc { - Atom name B32; - CARD8 nRows; - CARD8 pad1; - CARD16 pad2 B16; -} xkbOverlayWireDesc; -#define sz_xkbOverlayWireDesc 8 - -typedef struct _xkbOverlayRowWireDesc { - CARD8 rowUnder; - CARD8 nKeys; - CARD16 pad1 B16; -} xkbOverlayRowWireDesc; -#define sz_xkbOverlayRowWireDesc 4 - -typedef struct _xkbOverlayKeyWireDesc { - CARD8 over[XkbKeyNameLength]; - CARD8 under[XkbKeyNameLength]; -} xkbOverlayKeyWireDesc; -#define sz_xkbOverlayKeyWireDesc 8 - -typedef struct _xkbShapeDoodadWireDesc { - Atom name B32; - CARD8 type; - CARD8 priority; - INT16 top B16; - INT16 left B16; - INT16 angle B16; - CARD8 colorNdx; - CARD8 shapeNdx; - CARD16 pad1 B16; - CARD32 pad2 B32; -} xkbShapeDoodadWireDesc; -#define sz_xkbShapeDoodadWireDesc 20 - -typedef struct _xkbTextDoodadWireDesc { - Atom name B32; - CARD8 type; - CARD8 priority; - INT16 top B16; - INT16 left B16; - INT16 angle B16; - CARD16 width B16; - CARD16 height B16; - CARD8 colorNdx; - CARD8 pad1; - CARD16 pad2 B16; -} xkbTextDoodadWireDesc; -#define sz_xkbTextDoodadWireDesc 20 - -typedef struct _xkbIndicatorDoodadWireDesc { - Atom name B32; - CARD8 type; - CARD8 priority; - INT16 top B16; - INT16 left B16; - INT16 angle B16; - CARD8 shapeNdx; - CARD8 onColorNdx; - CARD8 offColorNdx; - CARD8 pad1; - CARD32 pad2 B32; -} xkbIndicatorDoodadWireDesc; -#define sz_xkbIndicatorDoodadWireDesc 20 - -typedef struct _xkbLogoDoodadWireDesc { - Atom name B32; - CARD8 type; - CARD8 priority; - INT16 top B16; - INT16 left B16; - INT16 angle B16; - CARD8 colorNdx; - CARD8 shapeNdx; - CARD16 pad1 B16; - CARD32 pad2 B32; -} xkbLogoDoodadWireDesc; -#define sz_xkbLogoDoodadWireDesc 20 - -typedef struct _xkbAnyDoodadWireDesc { - Atom name B32; - CARD8 type; - CARD8 priority; - INT16 top B16; - INT16 left B16; - INT16 angle B16; - CARD32 pad2 B32; - CARD32 pad3 B32; -} xkbAnyDoodadWireDesc; -#define sz_xkbAnyDoodadWireDesc 20 - -typedef union _xkbDoodadWireDesc { - xkbAnyDoodadWireDesc any; - xkbShapeDoodadWireDesc shape; - xkbTextDoodadWireDesc text; - xkbIndicatorDoodadWireDesc indicator; - xkbLogoDoodadWireDesc logo; -} xkbDoodadWireDesc; -#define sz_xkbDoodadWireDesc 20 - -typedef struct _xkbGetGeometry { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetGeometry */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad B16; - Atom name B32; -} xkbGetGeometryReq; -#define sz_xkbGetGeometryReq 12 - -typedef struct _xkbGetGeometryReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - Atom name B32; - BOOL found; - CARD8 pad; - CARD16 widthMM B16; - CARD16 heightMM B16; - CARD16 nProperties B16; - CARD16 nColors B16; - CARD16 nShapes B16; - CARD16 nSections B16; - CARD16 nDoodads B16; - CARD16 nKeyAliases B16; - CARD8 baseColorNdx; - CARD8 labelColorNdx; -} xkbGetGeometryReply; -#define sz_xkbGetGeometryReply 32 - -typedef struct _xkbSetGeometry { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetGeometry */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 nShapes; - CARD8 nSections; - Atom name B32; - CARD16 widthMM B16; - CARD16 heightMM B16; - CARD16 nProperties B16; - CARD16 nColors B16; - CARD16 nDoodads B16; - CARD16 nKeyAliases B16; - CARD8 baseColorNdx; - CARD8 labelColorNdx; - CARD16 pad B16; -} xkbSetGeometryReq; -#define sz_xkbSetGeometryReq 28 - -typedef struct _xkbPerClientFlags { - CARD8 reqType; - CARD8 xkbReqType;/* always X_KBPerClientFlags */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 pad1 B16; - CARD32 change B32; - CARD32 value B32; - CARD32 ctrlsToChange B32; - CARD32 autoCtrls B32; - CARD32 autoCtrlValues B32; -} xkbPerClientFlagsReq; -#define sz_xkbPerClientFlagsReq 28 - -typedef struct _xkbPerClientFlagsReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 supported B32; - CARD32 value B32; - CARD32 autoCtrls B32; - CARD32 autoCtrlValues B32; - CARD32 pad1 B32; - CARD32 pad2 B32; -} xkbPerClientFlagsReply; -#define sz_xkbPerClientFlagsReply 32 - -typedef struct _xkbListComponents { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBListComponents */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 maxNames B16; -} xkbListComponentsReq; -#define sz_xkbListComponentsReq 8 - -typedef struct _xkbListComponentsReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nKeymaps B16; - CARD16 nKeycodes B16; - CARD16 nTypes B16; - CARD16 nCompatMaps B16; - CARD16 nSymbols B16; - CARD16 nGeometries B16; - CARD16 extra B16; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; -} xkbListComponentsReply; -#define sz_xkbListComponentsReply 32 - -typedef struct _xkbGetKbdByName { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetKbdByName */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 need B16; /* combination of XkbGBN_* */ - CARD16 want B16; /* combination of XkbGBN_* */ - BOOL load; - CARD8 pad; -} xkbGetKbdByNameReq; -#define sz_xkbGetKbdByNameReq 12 - -typedef struct _xkbGetKbdByNameReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - KeyCode minKeyCode; - KeyCode maxKeyCode; - BOOL loaded; - BOOL newKeyboard; - CARD16 found B16; /* combination of XkbGBN_* */ - CARD16 reported B16; /* combination of XkbAllComponents */ - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; -} xkbGetKbdByNameReply; -#define sz_xkbGetKbdByNameReply 32 - -typedef struct _xkbDeviceLedsWireDesc { - CARD16 ledClass B16; - CARD16 ledID B16; - CARD32 namesPresent B32; - CARD32 mapsPresent B32; - CARD32 physIndicators B32; - CARD32 state B32; -} xkbDeviceLedsWireDesc; -#define sz_xkbDeviceLedsWireDesc 20 - -typedef struct _xkbGetDeviceInfo { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBGetDeviceInfo */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD16 wanted B16; - BOOL allBtns; - CARD8 firstBtn; - CARD8 nBtns; - CARD8 pad; - CARD16 ledClass B16; - CARD16 ledID B16; -} xkbGetDeviceInfoReq; -#define sz_xkbGetDeviceInfoReq 16 - -typedef struct _xkbGetDeviceInfoReply { - CARD8 type; /* always X_Reply */ - CARD8 deviceID; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 present B16; - CARD16 supported B16; - CARD16 unsupported B16; - CARD16 nDeviceLedFBs B16; - CARD8 firstBtnWanted; - CARD8 nBtnsWanted; - CARD8 firstBtnRtrn; - CARD8 nBtnsRtrn; - CARD8 totalBtns; - BOOL hasOwnState; - CARD16 dfltKbdFB B16; - CARD16 dfltLedFB B16; - CARD16 pad B16; - Atom devType B32; -} xkbGetDeviceInfoReply; -#define sz_xkbGetDeviceInfoReply 32 - -typedef struct _xkbSetDeviceInfo { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetDeviceInfo */ - CARD16 length B16; - CARD16 deviceSpec B16; - CARD8 firstBtn; - CARD8 nBtns; - CARD16 change B16; - CARD16 nDeviceLedFBs B16; -} xkbSetDeviceInfoReq; -#define sz_xkbSetDeviceInfoReq 12 - -typedef struct _xkbSetDebuggingFlags { - CARD8 reqType; - CARD8 xkbReqType; /* always X_KBSetDebuggingFlags */ - CARD16 length B16; - CARD16 msgLength B16; - CARD16 pad B16; - CARD32 affectFlags B32; - CARD32 flags B32; - CARD32 affectCtrls B32; - CARD32 ctrls B32; -} xkbSetDebuggingFlagsReq; -#define sz_xkbSetDebuggingFlagsReq 24 - -typedef struct _xkbSetDebuggingFlagsReply { - BYTE type; /* X_Reply */ - CARD8 pad0; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 currentFlags B32; - CARD32 currentCtrls B32; - CARD32 supportedFlags B32; - CARD32 supportedCtrls B32; - CARD32 pad1 B32; - CARD32 pad2 B32; -} xkbSetDebuggingFlagsReply; -#define sz_xkbSetDebuggingFlagsReply 32 - - /* - * X KEYBOARD EXTENSION EVENT STRUCTURES - */ - -typedef struct _xkbAnyEvent { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 pad1; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xkbAnyEvent; -#define sz_xkbAnyEvent 32 - -typedef struct _xkbNewKeyboardNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 oldDeviceID; - KeyCode minKeyCode; - KeyCode maxKeyCode; - KeyCode oldMinKeyCode; - KeyCode oldMaxKeyCode; - CARD8 requestMajor; - CARD8 requestMinor; - CARD16 changed B16; - CARD8 detail; - CARD8 pad1; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; -} xkbNewKeyboardNotify; -#define sz_xkbNewKeyboardNotify 32 - -typedef struct _xkbMapNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 ptrBtnActions; - CARD16 changed B16; - KeyCode minKeyCode; - KeyCode maxKeyCode; - CARD8 firstType; - CARD8 nTypes; - KeyCode firstKeySym; - CARD8 nKeySyms; - KeyCode firstKeyAct; - CARD8 nKeyActs; - KeyCode firstKeyBehavior; - CARD8 nKeyBehaviors; - KeyCode firstKeyExplicit; - CARD8 nKeyExplicit; - KeyCode firstModMapKey; - CARD8 nModMapKeys; - KeyCode firstVModMapKey; - CARD8 nVModMapKeys; - CARD16 virtualMods B16; - CARD16 pad1 B16; -} xkbMapNotify; -#define sz_xkbMapNotify 32 - -typedef struct _xkbStateNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 mods; - CARD8 baseMods; - CARD8 latchedMods; - CARD8 lockedMods; - CARD8 group; - INT16 baseGroup B16; - INT16 latchedGroup B16; - CARD8 lockedGroup; - CARD8 compatState; - CARD8 grabMods; - CARD8 compatGrabMods; - CARD8 lookupMods; - CARD8 compatLookupMods; - CARD16 ptrBtnState B16; - CARD16 changed B16; - KeyCode keycode; - CARD8 eventType; - CARD8 requestMajor; - CARD8 requestMinor; -} xkbStateNotify; -#define sz_xkbStateNotify 32 - -typedef struct _xkbControlsNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 numGroups; - CARD16 pad1 B16; - CARD32 changedControls B32; - CARD32 enabledControls B32; - CARD32 enabledControlChanges B32; - KeyCode keycode; - CARD8 eventType; - CARD8 requestMajor; - CARD8 requestMinor; - CARD32 pad2 B32; -} xkbControlsNotify; -#define sz_xkbControlsNotify 32 - -typedef struct _xkbIndicatorNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 pad1; - CARD16 pad2 B16; - CARD32 state B32; - CARD32 changed B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xkbIndicatorNotify; -#define sz_xkbIndicatorNotify 32 - -typedef struct _xkbNamesNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 pad1; - CARD16 changed B16; - CARD8 firstType; - CARD8 nTypes; - CARD8 firstLevelName; - CARD8 nLevelNames; - CARD8 pad2; - CARD8 nRadioGroups; - CARD8 nAliases; - CARD8 changedGroupNames; - CARD16 changedVirtualMods B16; - CARD8 firstKey; - CARD8 nKeys; - CARD32 changedIndicators B32; - CARD32 pad3 B32; -} xkbNamesNotify; -#define sz_xkbNamesNotify 32 - -typedef struct _xkbCompatMapNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 changedGroups; - CARD16 firstSI B16; - CARD16 nSI B16; - CARD16 nTotalSI B16; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; -} xkbCompatMapNotify; -#define sz_xkbCompatMapNotify 32 - -typedef struct _xkbBellNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 bellClass; - CARD8 bellID; - CARD8 percent; - CARD16 pitch B16; - CARD16 duration B16; - Atom name B32; - Window window B32; - BOOL eventOnly; - CARD8 pad1; - CARD16 pad2 B16; - CARD32 pad3 B32; -} xkbBellNotify; -#define sz_xkbBellNotify 32 - -typedef struct _xkbActionMessage { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - KeyCode keycode; - BOOL press; - BOOL keyEventFollows; - CARD8 mods; - CARD8 group; - CARD8 message[8]; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; -} xkbActionMessage; -#define sz_xkbActionMessage 32 - -typedef struct _xkbAccessXNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - KeyCode keycode; - CARD16 detail B16; - CARD16 slowKeysDelay B16; - CARD16 debounceDelay B16; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; -} xkbAccessXNotify; -#define sz_xkbAccessXNotify 32 - -typedef struct _xkbExtensionDeviceNotify { - BYTE type; - BYTE xkbType; - CARD16 sequenceNumber B16; - Time time B32; - CARD8 deviceID; - CARD8 pad1; - CARD16 reason B16; - CARD16 ledClass B16; - CARD16 ledID B16; - CARD32 ledsDefined B32; - CARD32 ledState B32; - CARD8 firstBtn; - CARD8 nBtns; - CARD16 supported B16; - CARD16 unsupported B16; - CARD16 pad3 B16; -} xkbExtensionDeviceNotify; -#define sz_xkbExtensionDeviceNotify 32 - -typedef struct _xkbEvent { - union { - xkbAnyEvent any; - xkbNewKeyboardNotify new_kbd; - xkbMapNotify map; - xkbStateNotify state; - xkbControlsNotify ctrls; - xkbIndicatorNotify indicators; - xkbNamesNotify names; - xkbCompatMapNotify compat; - xkbBellNotify bell; - xkbActionMessage message; - xkbAccessXNotify accessx; - xkbExtensionDeviceNotify device; - } u; -} xkbEvent; -#define sz_xkbEvent 32 - -#undef Window -#undef Atom -#undef Time -#undef KeyCode -#undef KeySym - -#endif /* _XKBPROTO_H_ */ diff --git a/shell/linux-deps/include/X11/extensions/XKBsrv.h b/shell/linux-deps/include/X11/extensions/XKBsrv.h deleted file mode 100644 index 26a4ed8cc..000000000 --- a/shell/linux-deps/include/X11/extensions/XKBsrv.h +++ /dev/null @@ -1,1187 +0,0 @@ -/* $Xorg: XKBsrv.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ */ -/* $XdotOrg: $ */ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ -/* $XFree86: xc/include/extensions/XKBsrv.h,v 3.22 2002/11/20 04:49:01 dawes Exp $ */ - -#ifndef _XKBSRV_H_ -#define _XKBSRV_H_ - -#ifdef XKB_IN_SERVER -#define XkbAllocClientMap SrvXkbAllocClientMap -#define XkbAllocServerMap SrvXkbAllocServerMap -#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey -#define XkbAddKeyType SrvXkbAddKeyType -#define XkbCopyKeyType SrvXkbCopyKeyType -#define XkbCopyKeyTypes SrvXkbCopyKeyTypes -#define XkbFreeClientMap SrvXkbFreeClientMap -#define XkbFreeServerMap SrvXkbFreeServerMap -#define XkbInitCanonicalKeyTypes SrvXkbInitCanonicalKeyTypes -#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols -#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey -#define XkbUpdateMapFromCore SrvXkbUpdateMapFromCore -#define XkbResizeKeyActions SrvXkbResizeKeyActions -#define XkbResizeKeySyms SrvXkbResizeKeySyms -#define XkbResizeKeyType SrvXkbResizeKeyType -#define XkbAllocCompatMap SrvXkbAllocCompatMap -#define XkbAllocControls SrvXkbAllocControls -#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps -#define XkbAllocKeyboard SrvXkbAllocKeyboard -#define XkbAllocNames SrvXkbAllocNames -#define XkbFreeCompatMap SrvXkbFreeCompatMap -#define XkbFreeControls SrvXkbFreeControls -#define XkbFreeIndicatorMaps SrvXkbFreeIndicatorMaps -#define XkbFreeKeyboard SrvXkbFreeKeyboard -#define XkbFreeNames SrvXkbFreeNames -#define XkbAddDeviceLedInfo SrvXkbAddDeviceLedInfo -#define XkbAllocDeviceInfo SrvXkbAllocDeviceInfo -#define XkbFreeDeviceInfo SrvXkbFreeDeviceInfo -#define XkbResizeDeviceButtonActions SrvXkbResizeDeviceButtonActions -#define XkbLatchModifiers SrvXkbLatchModifiers -#define XkbLatchGroup SrvXkbLatchGroup -#define XkbVirtualModsToReal SrvXkbVirtualModsToReal -#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange -#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges -#define XkbUpdateActionVirtualMods SrvXkbUpdateActionVirtualMods -#define XkbUpdateKeyTypeVirtualMods SrvXkbUpdateKeyTypeVirtualMods -#endif - -#include -#include -#include "inputstr.h" - -typedef struct _XkbInterest { - DeviceIntPtr dev; - ClientPtr client; - XID resource; - struct _XkbInterest * next; - CARD16 extDevNotifyMask; - CARD16 stateNotifyMask; - CARD16 namesNotifyMask; - CARD32 ctrlsNotifyMask; - CARD8 compatNotifyMask; - BOOL bellNotifyMask; - BOOL actionMessageMask; - CARD16 accessXNotifyMask; - CARD32 iStateNotifyMask; - CARD32 iMapNotifyMask; - CARD16 altSymsNotifyMask; - CARD32 autoCtrls; - CARD32 autoCtrlValues; -} XkbInterestRec,*XkbInterestPtr; - -typedef struct _XkbRadioGroup { - CARD8 flags; - CARD8 nMembers; - CARD8 dfltDown; - CARD8 currentDown; - CARD8 members[XkbRGMaxMembers]; -} XkbRadioGroupRec, *XkbRadioGroupPtr; - -typedef struct _XkbEventCause { - CARD8 kc; - CARD8 event; - CARD8 mjr; - CARD8 mnr; - ClientPtr client; -} XkbEventCauseRec,*XkbEventCausePtr; -#define XkbSetCauseKey(c,k,e) { (c)->kc= (k),(c)->event= (e),\ - (c)->mjr= (c)->mnr= 0; \ - (c)->client= NULL; } -#define XkbSetCauseReq(c,j,n,cl) { (c)->kc= (c)->event= 0,\ - (c)->mjr= (j),(c)->mnr= (n);\ - (c)->client= (cl); } -#define XkbSetCauseCoreReq(c,e,cl) XkbSetCauseReq(c,e,0,cl) -#define XkbSetCauseXkbReq(c,e,cl) XkbSetCauseReq(c,XkbReqCode,e,cl) -#define XkbSetCauseUnknown(c) XkbSetCauseKey(c,0,0) - -#define _OFF_TIMER 0 -#define _KRG_WARN_TIMER 1 -#define _KRG_TIMER 2 -#define _SK_TIMEOUT_TIMER 3 -#define _ALL_TIMEOUT_TIMER 4 - -#define _BEEP_NONE 0 -#define _BEEP_FEATURE_ON 1 -#define _BEEP_FEATURE_OFF 2 -#define _BEEP_FEATURE_CHANGE 3 -#define _BEEP_SLOW_WARN 4 -#define _BEEP_SLOW_PRESS 5 -#define _BEEP_SLOW_ACCEPT 6 -#define _BEEP_SLOW_REJECT 7 -#define _BEEP_SLOW_RELEASE 8 -#define _BEEP_STICKY_LATCH 9 -#define _BEEP_STICKY_LOCK 10 -#define _BEEP_STICKY_UNLOCK 11 -#define _BEEP_LED_ON 12 -#define _BEEP_LED_OFF 13 -#define _BEEP_LED_CHANGE 14 -#define _BEEP_BOUNCE_REJECT 15 - -typedef struct _XkbSrvInfo { - XkbStateRec prev_state; - XkbStateRec state; - XkbDescPtr desc; - - DeviceIntPtr device; - KbdCtrlProcPtr kbdProc; - - XkbRadioGroupPtr radioGroups; - CARD8 nRadioGroups; - CARD8 clearMods; - CARD8 setMods; - INT16 groupChange; - - CARD16 dfltPtrDelta; - - double mouseKeysCurve; - double mouseKeysCurveFactor; - INT16 mouseKeysDX; - INT16 mouseKeysDY; - CARD8 mouseKeysFlags; - Bool mouseKeysAccel; - CARD8 mouseKeysCounter; - - CARD8 lockedPtrButtons; - CARD8 shiftKeyCount; - KeyCode mouseKey; - KeyCode inactiveKey; - KeyCode slowKey; - KeyCode repeatKey; - CARD8 krgTimerActive; - CARD8 beepType; - CARD8 beepCount; - - CARD32 flags; - CARD32 lastPtrEventTime; - CARD32 lastShiftEventTime; - OsTimerPtr beepTimer; - OsTimerPtr mouseKeyTimer; - OsTimerPtr slowKeysTimer; - OsTimerPtr bounceKeysTimer; - OsTimerPtr repeatKeyTimer; - OsTimerPtr krgTimer; -} XkbSrvInfoRec, *XkbSrvInfoPtr; - -#define XkbSLI_IsDefault (1L<<0) -#define XkbSLI_HasOwnState (1L<<1) - -typedef struct _XkbSrvLedInfo { - CARD16 flags; - CARD16 class; - CARD16 id; - union { - KbdFeedbackPtr kf; - LedFeedbackPtr lf; - } fb; - - CARD32 physIndicators; - CARD32 autoState; - CARD32 explicitState; - CARD32 effectiveState; - - CARD32 mapsPresent; - CARD32 namesPresent; - XkbIndicatorMapPtr maps; - Atom * names; - - CARD32 usesBase; - CARD32 usesLatched; - CARD32 usesLocked; - CARD32 usesEffective; - CARD32 usesCompat; - CARD32 usesControls; - - CARD32 usedComponents; -} XkbSrvLedInfoRec, *XkbSrvLedInfoPtr; - -/* - * Settings for xkbClientFlags field (used by DIX) - * These flags _must_ not overlap with XkbPCF_* - */ -#define _XkbClientInitialized (1<<15) - -#define _XkbWantsDetectableAutoRepeat(c)\ - ((c)->xkbClientFlags&XkbPCF_DetectableAutoRepeatMask) - -/* - * Settings for flags field - */ -#define _XkbStateNotifyInProgress (1<<0) - -typedef struct -{ - ProcessInputProc processInputProc; - ProcessInputProc realInputProc; - DeviceUnwrapProc unwrapProc; -} xkbDeviceInfoRec, *xkbDeviceInfoPtr; - -#define WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \ - device->public.processInputProc = proc; \ - oldprocs->processInputProc = \ - oldprocs->realInputProc = device->public.realInputProc; \ - device->public.realInputProc = proc; \ - oldprocs->unwrapProc = device->unwrapProc; \ - device->unwrapProc = unwrapproc; - -#define COND_WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \ - if (device->public.processInputProc == device->public.realInputProc)\ - device->public.processInputProc = proc; \ - oldprocs->processInputProc = \ - oldprocs->realInputProc = device->public.realInputProc; \ - device->public.realInputProc = proc; \ - oldprocs->unwrapProc = device->unwrapProc; \ - device->unwrapProc = unwrapproc; - -#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs) \ - device->public.processInputProc = oldprocs->processInputProc; \ - device->public.realInputProc = oldprocs->realInputProc; \ - device->unwrapProc = oldprocs->unwrapProc; - -#define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr) (dev)->devPrivates[xkbDevicePrivateIndex].ptr) - -/***====================================================================***/ - - -/***====================================================================***/ - -#define XkbAX_KRGMask (XkbSlowKeysMask|XkbBounceKeysMask) -#define XkbAllFilteredEventsMask \ - (XkbAccessXKeysMask|XkbRepeatKeysMask|XkbMouseKeysAccelMask|XkbAX_KRGMask) - -/***====================================================================***/ - -extern int XkbReqCode; -extern int XkbEventBase; -extern int XkbKeyboardErrorCode; -extern int XkbDisableLockActions; -extern char * XkbBaseDirectory; -extern char * XkbBinDirectory; -extern char * XkbInitialMap; -extern int _XkbClientMajor; -extern int _XkbClientMinor; -extern unsigned int XkbXIUnsupported; - -extern char * XkbModelUsed,*XkbLayoutUsed,*XkbVariantUsed,*XkbOptionsUsed; -extern Bool noXkbExtension; -extern Bool XkbWantRulesProp; - -extern pointer XkbLastRepeatEvent; - -extern CARD32 xkbDebugFlags; -extern CARD32 xkbDebugCtrls; - -#define _XkbAlloc(s) xalloc((s)) -#define _XkbCalloc(n,s) Xcalloc((n)*(s)) -#define _XkbRealloc(o,s) Xrealloc((o),(s)) -#define _XkbTypedAlloc(t) ((t *)xalloc(sizeof(t))) -#define _XkbTypedCalloc(n,t) ((t *)Xcalloc((n)*sizeof(t))) -#define _XkbTypedRealloc(o,n,t) \ - ((o)?(t *)Xrealloc((o),(n)*sizeof(t)):_XkbTypedCalloc(n,t)) -#define _XkbClearElems(a,f,l,t) bzero(&(a)[f],((l)-(f)+1)*sizeof(t)) -#define _XkbFree(p) Xfree(p) - -#define _XkbLibError(c,l,d) \ - { _XkbErrCode= (c); _XkbErrLocation= (l); _XkbErrData= (d); } -#define _XkbErrCode2(a,b) ((XID)((((unsigned int)(a))<<24)|((b)&0xffffff))) -#define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c)) -#define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d))) - -extern int DeviceKeyPress,DeviceKeyRelease; -extern int DeviceButtonPress,DeviceButtonRelease; - -#ifdef XINPUT -#define _XkbIsPressEvent(t) (((t)==KeyPress)||((t)==DeviceKeyPress)) -#define _XkbIsReleaseEvent(t) (((t)==KeyRelease)||((t)==DeviceKeyRelease)) -#else -#define _XkbIsPressEvent(t) ((t)==KeyPress) -#define _XkbIsReleaseEvent(t) ((t)==KeyRelease) -#endif - -#define _XkbCoreKeycodeInRange(c,k) (((k)>=(c)->curKeySyms.minKeyCode)&&\ - ((k)<=(c)->curKeySyms.maxKeyCode)) -#define _XkbCoreNumKeys(c) ((c)->curKeySyms.maxKeyCode-\ - (c)->curKeySyms.minKeyCode+1) - -#define XConvertCase(s,l,u) XkbConvertCase(s,l,u) -#undef IsKeypadKey -#define IsKeypadKey(s) XkbKSIsKeypad(s) - -typedef int Status; -typedef pointer XPointer; -typedef struct _XDisplay Display; - -#ifndef True -#define True 1 -#define False 0 -#endif - -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - -_XFUNCPROTOBEGIN - -extern void XkbUseMsg( - void -); - -extern int XkbProcessArguments( - int /* argc */, - char ** /* argv */, - int /* i */ -); - -extern void XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc); - -extern void XkbFreeCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern void XkbFreeNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern DeviceIntPtr _XkbLookupAnyDevice( - int /* id */, - int * /* why_rtrn */ -); - -extern DeviceIntPtr _XkbLookupKeyboard( - int /* id */, - int * /* why_rtrn */ -); - -extern DeviceIntPtr _XkbLookupBellDevice( - int /* id */, - int * /* why_rtrn */ -); - -extern DeviceIntPtr _XkbLookupLedDevice( - int /* id */, - int * /* why_rtrn */ -); - -extern DeviceIntPtr _XkbLookupButtonDevice( - int /* id */, - int * /* why_rtrn */ -); - -extern XkbDescPtr XkbAllocKeyboard( - void -); - -extern Status XkbAllocClientMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nTypes */ -); - -extern Status XkbAllocServerMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nNewActions */ -); - -extern void XkbFreeClientMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern void XkbFreeServerMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern Status XkbAllocIndicatorMaps( - XkbDescPtr /* xkb */ -); - -extern Status XkbAllocCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nInterpret */ -); - -extern Status XkbAllocNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* nTotalRG */, - int /* nTotalAliases */ -); - -extern Status XkbAllocControls( - XkbDescPtr /* xkb */, - unsigned int /* which*/ -); - -extern Status XkbCopyKeyType( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */ -); - -extern Status XkbCopyKeyTypes( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */, - int /* num_types */ -); - -extern Status XkbResizeKeyType( - XkbDescPtr /* xkb */, - int /* type_ndx */, - int /* map_count */, - Bool /* want_preserve */, - int /* new_num_lvls */ -); - -extern void XkbFreeKeyboard( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeDesc */ -); - -extern void XkbSetActionKeyMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* mods */ -); - -extern Bool XkbCheckActionVMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* changed */ -); - -extern Bool XkbApplyVModChanges( - XkbSrvInfoPtr /* xkbi */, - unsigned int /* changed */, - XkbChangesPtr /* pChanges */, - unsigned int * /* needChecksRtrn */, - XkbEventCausePtr /* cause */ -); - -extern void XkbApplyVModChangesToAllDevices( - DeviceIntPtr /* dev */, - XkbDescPtr /* xkb */, - unsigned int /* changed */, - XkbEventCausePtr /* cause */ -); - -extern unsigned int XkbMaskForVMask( - XkbDescPtr /* xkb */, - unsigned int /* vmask */ -); - -extern Bool XkbVirtualModsToReal( - XkbDescPtr /* xkb */, - unsigned int /* virtua_mask */, - unsigned int * /* mask_rtrn */ -); - -extern unsigned int XkbAdjustGroup( - int /* group */, - XkbControlsPtr /* ctrls */ -); - -extern KeySym *XkbResizeKeySyms( - XkbDescPtr /* xkb */, - int /* key */, - int /* needed */ -); - -extern XkbAction *XkbResizeKeyActions( - XkbDescPtr /* xkb */, - int /* key */, - int /* needed */ -); - -extern void XkbUpdateKeyTypesFromCore( - DeviceIntPtr /* pXDev */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* pChanges */ -); - -extern void XkbUpdateDescActions( - XkbDescPtr /* xkb */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* changes */ -); - -extern void XkbUpdateActions( - DeviceIntPtr /* pXDev */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* pChanges */, - unsigned int * /* needChecksRtrn */, - XkbEventCausePtr /* cause */ -); - -extern void XkbUpdateCoreDescription( - DeviceIntPtr /* keybd */, - Bool /* resize */ -); - -extern void XkbApplyMappingChange( - DeviceIntPtr /* pXDev */, - CARD8 /* request */, - KeyCode /* firstKey */, - CARD8 /* num */, - ClientPtr /* client */ -); - -extern void XkbSetIndicators( - DeviceIntPtr /* pXDev */, - CARD32 /* affect */, - CARD32 /* values */, - XkbEventCausePtr /* cause */ -); - -extern void XkbUpdateIndicators( - DeviceIntPtr /* keybd */, - CARD32 /* changed */, - Bool /* check_edevs */, - XkbChangesPtr /* pChanges */, - XkbEventCausePtr /* cause */ -); - -extern XkbSrvLedInfoPtr XkbAllocSrvLedInfo( - DeviceIntPtr /* dev */, - KbdFeedbackPtr /* kf */, - LedFeedbackPtr /* lf */, - unsigned int /* needed_parts */ -); - -extern XkbSrvLedInfoPtr XkbFindSrvLedInfo( - DeviceIntPtr /* dev */, - unsigned int /* class */, - unsigned int /* id */, - unsigned int /* needed_parts */ -); - -extern void XkbApplyLedNameChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_names */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbApplyLedMapChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_maps */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbApplyLedStateChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_leds */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbUpdateLedAutoState( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* maps_to_check */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbFlushLedEvents( - DeviceIntPtr /* dev */, - DeviceIntPtr /* kbd */, - XkbSrvLedInfoPtr /* sli */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbUpdateAllDeviceIndicators( - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern unsigned int XkbIndicatorsToUpdate( - DeviceIntPtr /* dev */, - unsigned long /* state_changes */, - Bool /* enabled_ctrl_changes */ -); - -extern void XkbComputeDerivedState( - XkbSrvInfoPtr /* xkbi */ -); - -extern void XkbCheckSecondaryEffects( - XkbSrvInfoPtr /* xkbi */, - unsigned int /* which */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void XkbCheckIndicatorMaps( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* which */ -); - -extern unsigned int XkbStateChangedFlags( - XkbStatePtr /* old */, - XkbStatePtr /* new */ -); - -extern void XkbSendStateNotify( - DeviceIntPtr /* kbd */, - xkbStateNotify * /* pSN */ -); - -extern void XkbSendMapNotify( - DeviceIntPtr /* kbd */, - xkbMapNotify * /* ev */ -); - -extern int XkbComputeControlsNotify( - DeviceIntPtr /* kbd */, - XkbControlsPtr /* old */, - XkbControlsPtr /* new */, - xkbControlsNotify * /* pCN */, - Bool /* forceCtrlProc */ -); - -extern void XkbSendControlsNotify( - DeviceIntPtr /* kbd */, - xkbControlsNotify * /* ev */ -); - -extern void XkbSendCompatMapNotify( - DeviceIntPtr /* kbd */, - xkbCompatMapNotify * /* ev */ -); - -extern void XkbSendIndicatorNotify( - DeviceIntPtr /* kbd */, - int /* xkbType */, - xkbIndicatorNotify * /* ev */ -); - -extern void XkbHandleBell( - BOOL /* force */, - BOOL /* eventOnly */, - DeviceIntPtr /* kbd */, - CARD8 /* percent */, - pointer /* ctrl */, - CARD8 /* class */, - Atom /* name */, - WindowPtr /* pWin */, - ClientPtr /* pClient */ -); - -extern void XkbSendAccessXNotify( - DeviceIntPtr /* kbd */, - xkbAccessXNotify * /* pEv */ -); - -extern void XkbSendNamesNotify( - DeviceIntPtr /* kbd */, - xkbNamesNotify * /* ev */ -); - -extern void XkbSendCompatNotify( - DeviceIntPtr /* kbd */, - xkbCompatMapNotify * /* ev */ -); - -extern void XkbSendActionMessage( - DeviceIntPtr /* kbd */, - xkbActionMessage * /* ev */ -); - -extern void XkbSendExtensionDeviceNotify( - DeviceIntPtr /* kbd */, - ClientPtr /* client */, - xkbExtensionDeviceNotify * /* ev */ -); - -extern void XkbSendNotification( - DeviceIntPtr /* kbd */, - XkbChangesPtr /* pChanges */, - XkbEventCausePtr /* cause */ -); - -extern void XkbProcessKeyboardEvent( - struct _xEvent * /* xE */, - DeviceIntPtr /* keybd */, - int /* count */ -); - -extern void XkbProcessOtherEvent( - struct _xEvent * /* xE */, - DeviceIntPtr /* keybd */, - int /* count */ -); - -extern void XkbHandleActions( - DeviceIntPtr /* dev */, - DeviceIntPtr /* kbd */, - struct _xEvent * /* xE */, - int /* count */ -); - -extern Bool XkbEnableDisableControls( - XkbSrvInfoPtr /* xkbi */, - unsigned long /* change */, - unsigned long /* newValues */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern void AccessXInit( - DeviceIntPtr /* dev */ -); - -extern Bool AccessXFilterPressEvent( - register struct _xEvent * /* xE */, - register DeviceIntPtr /* keybd */, - int /* count */ -); - -extern Bool AccessXFilterReleaseEvent( - register struct _xEvent * /* xE */, - register DeviceIntPtr /* keybd */, - int /* count */ -); - -extern void AccessXCancelRepeatKey( - XkbSrvInfoPtr /* xkbi */, - KeyCode /* key */ -); - -extern void AccessXComputeCurveFactor( - XkbSrvInfoPtr /* xkbi */, - XkbControlsPtr /* ctrls */ -); - -extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass */, - unsigned int /* ledId */ -); - -extern XkbDeviceInfoPtr XkbAllocDeviceInfo( - unsigned int /* deviceSpec */, - unsigned int /* nButtons */, - unsigned int /* szLeds */ -); - -extern void XkbFreeDeviceInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* which */, - Bool /* freeDevI */ -); - -extern Status XkbResizeDeviceButtonActions( - XkbDeviceInfoPtr /* devi */, - unsigned int /* newTotal */ -); - -extern XkbInterestPtr XkbFindClientResource( - DevicePtr /* inDev */, - ClientPtr /* client */ -); - -extern XkbInterestPtr XkbAddClientResource( - DevicePtr /* inDev */, - ClientPtr /* client */, - XID /* id */ -); - -extern int XkbRemoveClient( - DevicePtr /* inDev */, - ClientPtr /* client */ -); - -extern int XkbRemoveResourceClient( - DevicePtr /* inDev */, - XID /* id */ -); - -extern int XkbDDXInitDevice( - DeviceIntPtr /* dev */ -); - -extern int XkbDDXAccessXBeep( - DeviceIntPtr /* dev */, - unsigned int /* what */, - unsigned int /* which */ -); - -extern void XkbDDXKeyClick( - DeviceIntPtr /* dev */, - int /* keycode */, - int /* synthetic */ -); - -extern int XkbDDXUsesSoftRepeat( - DeviceIntPtr /* dev */ -); - -extern void XkbDDXKeybdCtrlProc( - DeviceIntPtr /* dev */, - KeybdCtrl * /* ctrl */ -); - -extern void XkbDDXChangeControls( - DeviceIntPtr /* dev */, - XkbControlsPtr /* old */, - XkbControlsPtr /* new */ -); - -extern void XkbDDXUpdateIndicators( - DeviceIntPtr /* keybd */, - CARD32 /* newState */ -); - -extern void XkbDDXUpdateDeviceIndicators( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - CARD32 /* newState */ -); - -extern void XkbDDXFakePointerButton( - int /* event */, - int /* button */ -); - -extern void XkbDDXFakePointerMotion( - unsigned int /* flags */, - int /* x */, - int /* y */ -); - -extern void XkbDDXFakeDeviceButton( - DeviceIntPtr /* dev */, - Bool /* press */, - int /* button */ -); - -extern int XkbDDXTerminateServer( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern int XkbDDXSwitchScreen( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern int XkbDDXPrivate( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern void XkbDisableComputedAutoRepeats( - DeviceIntPtr /* pXDev */, - unsigned int /* key */ -); - -extern void XkbSetRepeatKeys( - DeviceIntPtr /* pXDev */, - int /* key */, - int /* onoff */ -); - -extern int XkbLatchModifiers( - DeviceIntPtr /* pXDev */, - CARD8 /* mask */, - CARD8 /* latches */ -); - -extern int XkbLatchGroup( - DeviceIntPtr /* pXDev */, - int /* group */ -); - -extern void XkbClearAllLatchesAndLocks( - DeviceIntPtr /* dev */, - XkbSrvInfoPtr /* xkbi */, - Bool /* genEv */, - XkbEventCausePtr /* cause */ -); - -extern void XkbSetRulesDflts( - char * /* rulesFile */, - char * /* model */, - char * /* layout */, - char * /* variant */, - char * /* options */ -); - -extern void XkbInitDevice( - DeviceIntPtr /* pXDev */ -); - -extern Bool XkbInitKeyboardDeviceStruct( - DeviceIntPtr /* pXDev */, - XkbComponentNamesPtr /* pNames */, - KeySymsPtr /* pSyms */, - CARD8 /* pMods */[], - BellProcPtr /* bellProc */, - KbdCtrlProcPtr /* ctrlProc */ -); - -extern int SProcXkbDispatch( - ClientPtr /* client */ -); - -extern XkbGeometryPtr XkbLookupNamedGeometry( - DeviceIntPtr /* dev */, - Atom /* name */, - Bool * /* shouldFree */ -); - -extern char * _XkbDupString( - char * /* str */ -); - -extern void XkbConvertCase( - KeySym /* sym */, - KeySym * /* lower */, - KeySym * /* upper */ -); - -extern Status XkbChangeKeycodeRange( - XkbDescPtr /* xkb */, - int /* minKC */, - int /* maxKC */, - XkbChangesPtr /* changes */ -); - -extern int XkbFinishDeviceInit( - DeviceIntPtr /* pXDev */ -); - -extern void XkbFreeSrvLedInfo( - XkbSrvLedInfoPtr /* sli */ -); - -extern void XkbFreeInfo( - XkbSrvInfoPtr /* xkbi */ -); - -extern Status XkbChangeTypesOfKey( - XkbDescPtr /* xkb */, - int /* key */, - int /* nGroups */, - unsigned int /* groups */, - int * /* newTypesIn */, - XkbMapChangesPtr /* changes */ -); - -extern XkbKeyTypePtr XkbAddKeyType( - XkbDescPtr /* xkb */, - Atom /* name */, - int /* map_count */, - Bool /* want_preserve */, - int /* num_lvls */ -); - -extern Status XkbInitCanonicalKeyTypes( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* keypadVMod */ -); - -extern int XkbKeyTypesForCoreSymbols( - XkbDescPtr /* xkb */, - int /* map_width */, - KeySym * /* core_syms */, - unsigned int /* protected */, - int * /* types_inout */, - KeySym * /* xkb_syms_rtrn */ -); - -extern Bool XkbApplyCompatMapToKey( - XkbDescPtr /* xkb */, - KeyCode /* key */, - XkbChangesPtr /* changes */ -); - -extern Bool XkbUpdateMapFromCore( - XkbDescPtr /* xkb */, - KeyCode /* first_key */, - int /* num_keys */, - int /* map_width */, - KeySym * /* core_keysyms */, - XkbChangesPtr /* changes */ -); - -extern void XkbFreeControls( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern void XkbFreeIndicatorMaps( - XkbDescPtr /* xkb */ -); - -extern Bool XkbApplyVirtualModChanges( - XkbDescPtr /* xkb */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ -); - -extern Bool XkbUpdateActionVirtualMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* changed */ -); - -extern void XkbUpdateKeyTypeVirtualMods( - XkbDescPtr /* xkb */, - XkbKeyTypePtr /* type */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ -); - -extern void XkbSendNewKeyboardNotify( - DeviceIntPtr /* kbd */, - xkbNewKeyboardNotify * /* pNKN */ -); - -#ifdef XKBSRV_NEED_FILE_FUNCS - -#include -#include -#include - -#define _XkbListKeymaps 0 -#define _XkbListKeycodes 1 -#define _XkbListTypes 2 -#define _XkbListCompat 3 -#define _XkbListSymbols 4 -#define _XkbListGeometry 5 -#define _XkbListNumComponents 6 - -typedef struct _XkbSrvListInfo { - int szPool; - int nPool; - char * pool; - - int maxRtrn; - int nTotal; - - char * pattern[_XkbListNumComponents]; - int nFound[_XkbListNumComponents]; -} XkbSrvListInfoRec,*XkbSrvListInfoPtr; - -char * -XkbGetRulesDflts( - XkbRF_VarDefsPtr /* defs */ -); - -extern void XkbSetRulesUsed( - XkbRF_VarDefsPtr /* defs */ -); - - -extern Status XkbDDXList( - DeviceIntPtr /* dev */, - XkbSrvListInfoPtr /* listing */, - ClientPtr /* client */ -); - -extern unsigned int XkbDDXLoadKeymapByNames( - DeviceIntPtr /* keybd */, - XkbComponentNamesPtr /* names */, - unsigned int /* want */, - unsigned int /* need */, - XkbFileInfoPtr /* finfoRtrn */, - char * /* keymapNameRtrn */, - int /* keymapNameRtrnLen */ -); - -extern Bool XkbDDXNamesFromRules( - DeviceIntPtr /* keybd */, - char * /* rules */, - XkbRF_VarDefsPtr /* defs */, - XkbComponentNamesPtr /* names */ -); - -extern FILE *XkbDDXOpenConfigFile( - char * /* mapName */, - char * /* fileNameRtrn */, - int /* fileNameRtrnLen */ -); - -extern Bool XkbDDXApplyConfig( - XPointer /* cfg_in */, - XkbSrvInfoPtr /* xkbi */ -); - -extern XPointer XkbDDXPreloadConfig( - char ** /* rulesFileRtrn */, - XkbRF_VarDefsPtr /* defs */, - XkbComponentNamesPtr /* names */, - DeviceIntPtr /* dev */ -); - -extern int _XkbStrCaseCmp( - char * /* str1 */, - char * /* str2 */ -); - -#endif /* XKBSRV_NEED_FILE_FUNCS */ - - -_XFUNCPROTOEND - -#define XkbAtomGetString(d,s) NameForAtom(s) - -#endif /* _XKBSRV_H_ */ - - diff --git a/shell/linux-deps/include/X11/extensions/XKBstr.h b/shell/linux-deps/include/X11/extensions/XKBstr.h deleted file mode 100644 index bc63f4923..000000000 --- a/shell/linux-deps/include/X11/extensions/XKBstr.h +++ /dev/null @@ -1,614 +0,0 @@ -/* $Xorg: XKBstr.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ */ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ - -#ifndef _XKBSTR_H_ -#define _XKBSTR_H_ - -#include - -#define XkbCharToInt(v) ((v)&0x80?(int)((v)|(~0xff)):(int)((v)&0x7f)) -#define XkbIntTo2Chars(i,h,l) (((h)=((i>>8)&0xff)),((l)=((i)&0xff))) - -#if defined(WORD64) && defined(UNSIGNEDBITFIELDS) -#define Xkb2CharsToInt(h,l) ((h)&0x80?(int)(((h)<<8)|(l)|(~0xffff)):\ - (int)(((h)<<8)|(l)&0x7fff)) -#else -#define Xkb2CharsToInt(h,l) ((short)(((h)<<8)|(l))) -#endif - - /* - * Common data structures and access macros - */ - -typedef struct _XkbStateRec { - unsigned char group; - unsigned char locked_group; - unsigned short base_group; - unsigned short latched_group; - unsigned char mods; - unsigned char base_mods; - unsigned char latched_mods; - unsigned char locked_mods; - unsigned char compat_state; - unsigned char grab_mods; - unsigned char compat_grab_mods; - unsigned char lookup_mods; - unsigned char compat_lookup_mods; - unsigned short ptr_buttons; -} XkbStateRec,*XkbStatePtr; -#define XkbModLocks(s) ((s)->locked_mods) -#define XkbStateMods(s) ((s)->base_mods|(s)->latched_mods|XkbModLocks(s)) -#define XkbGroupLock(s) ((s)->locked_group) -#define XkbStateGroup(s) ((s)->base_group+(s)->latched_group+XkbGroupLock(s)) -#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods,(s)->group) -#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods,(s)->group) - -typedef struct _XkbMods { - unsigned char mask; /* effective mods */ - unsigned char real_mods; - unsigned short vmods; -} XkbModsRec,*XkbModsPtr; - -typedef struct _XkbKTMapEntry { - Bool active; - unsigned char level; - XkbModsRec mods; -} XkbKTMapEntryRec,*XkbKTMapEntryPtr; - -typedef struct _XkbKeyType { - XkbModsRec mods; - unsigned char num_levels; - unsigned char map_count; - XkbKTMapEntryPtr map; - XkbModsPtr preserve; - Atom name; - Atom * level_names; -} XkbKeyTypeRec, *XkbKeyTypePtr; - -#define XkbNumGroups(g) ((g)&0x0f) -#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0) -#define XkbOutOfRangeGroupAction(g) ((g)&0xc0) -#define XkbOutOfRangeGroupNumber(g) (((g)&0x30)>>4) -#define XkbSetGroupInfo(g,w,n) (((w)&0xc0)|(((n)&3)<<4)|((g)&0x0f)) -#define XkbSetNumGroups(g,n) (((g)&0xf0)|((n)&0x0f)) - - /* - * Structures and access macros used primarily by the server - */ - -typedef struct _XkbBehavior { - unsigned char type; - unsigned char data; -} XkbBehavior; - -#define XkbAnyActionDataSize 7 -typedef struct _XkbAnyAction { - unsigned char type; - unsigned char data[XkbAnyActionDataSize]; -} XkbAnyAction; - -typedef struct _XkbModAction { - unsigned char type; - unsigned char flags; - unsigned char mask; - unsigned char real_mods; - unsigned char vmods1; - unsigned char vmods2; -} XkbModAction; -#define XkbModActionVMods(a) \ - ((short)(((a)->vmods1<<8)|((a)->vmods2))) -#define XkbSetModActionVMods(a,v) \ - (((a)->vmods1=(((v)>>8)&0xff)),(a)->vmods2=((v)&0xff)) - -typedef struct _XkbGroupAction { - unsigned char type; - unsigned char flags; - char group_XXX; -} XkbGroupAction; -#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX)) -#define XkbSASetGroup(a,g) ((a)->group_XXX=(g)) - -typedef struct _XkbISOAction { - unsigned char type; - unsigned char flags; - unsigned char mask; - unsigned char real_mods; - char group_XXX; - unsigned char affect; - unsigned char vmods1; - unsigned char vmods2; -} XkbISOAction; - -typedef struct _XkbPtrAction { - unsigned char type; - unsigned char flags; - unsigned char high_XXX; - unsigned char low_XXX; - unsigned char high_YYY; - unsigned char low_YYY; -} XkbPtrAction; -#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX,(a)->low_XXX)) -#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY,(a)->low_YYY)) -#define XkbSetPtrActionX(a,x) (XkbIntTo2Chars(x,(a)->high_XXX,(a)->low_XXX)) -#define XkbSetPtrActionY(a,y) (XkbIntTo2Chars(y,(a)->high_YYY,(a)->low_YYY)) - -typedef struct _XkbPtrBtnAction { - unsigned char type; - unsigned char flags; - unsigned char count; - unsigned char button; -} XkbPtrBtnAction; - -typedef struct _XkbPtrDfltAction { - unsigned char type; - unsigned char flags; - unsigned char affect; - char valueXXX; -} XkbPtrDfltAction; -#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX)) -#define XkbSASetPtrDfltValue(a,c) ((a)->valueXXX= ((c)&0xff)) - -typedef struct _XkbSwitchScreenAction { - unsigned char type; - unsigned char flags; - char screenXXX; -} XkbSwitchScreenAction; -#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX)) -#define XkbSASetScreen(a,s) ((a)->screenXXX= ((s)&0xff)) - -typedef struct _XkbCtrlsAction { - unsigned char type; - unsigned char flags; - unsigned char ctrls3; - unsigned char ctrls2; - unsigned char ctrls1; - unsigned char ctrls0; -} XkbCtrlsAction; -#define XkbActionSetCtrls(a,c) (((a)->ctrls3=(((c)>>24)&0xff)),\ - ((a)->ctrls2=(((c)>>16)&0xff)),\ - ((a)->ctrls1=(((c)>>8)&0xff)),\ - ((a)->ctrls0=((c)&0xff))) -#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3)<<24)|\ - (((unsigned int)(a)->ctrls2)<<16)|\ - (((unsigned int)(a)->ctrls1)<<8)|\ - ((unsigned int)((a)->ctrls0))) - -typedef struct _XkbMessageAction { - unsigned char type; - unsigned char flags; - unsigned char message[6]; -} XkbMessageAction; - -typedef struct _XkbRedirectKeyAction { - unsigned char type; - unsigned char new_key; - unsigned char mods_mask; - unsigned char mods; - unsigned char vmods_mask0; - unsigned char vmods_mask1; - unsigned char vmods0; - unsigned char vmods1; -} XkbRedirectKeyAction; - -#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1)<<8)|\ - ((unsigned int)(a)->vmods0)) -#define XkbSARedirectSetVMods(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\ - ((a)->vmods_mask0=((m)&0xff))) -#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1)<<8)|\ - ((unsigned int)(a)->vmods_mask0)) -#define XkbSARedirectSetVModsMask(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\ - ((a)->vmods_mask0=((m)&0xff))) - -typedef struct _XkbDeviceBtnAction { - unsigned char type; - unsigned char flags; - unsigned char count; - unsigned char button; - unsigned char device; -} XkbDeviceBtnAction; - -typedef struct _XkbDeviceValuatorAction { - unsigned char type; - unsigned char device; - unsigned char v1_what; - unsigned char v1_ndx; - unsigned char v1_value; - unsigned char v2_what; - unsigned char v2_ndx; - unsigned char v2_value; -} XkbDeviceValuatorAction; - -typedef union _XkbAction { - XkbAnyAction any; - XkbModAction mods; - XkbGroupAction group; - XkbISOAction iso; - XkbPtrAction ptr; - XkbPtrBtnAction btn; - XkbPtrDfltAction dflt; - XkbSwitchScreenAction screen; - XkbCtrlsAction ctrls; - XkbMessageAction msg; - XkbRedirectKeyAction redirect; - XkbDeviceBtnAction devbtn; - XkbDeviceValuatorAction devval; - unsigned char type; -} XkbAction; - -typedef struct _XkbControls { - unsigned char mk_dflt_btn; - unsigned char num_groups; - unsigned char groups_wrap; - XkbModsRec internal; - XkbModsRec ignore_lock; - unsigned int enabled_ctrls; - unsigned short repeat_delay; - unsigned short repeat_interval; - unsigned short slow_keys_delay; - unsigned short debounce_delay; - unsigned short mk_delay; - unsigned short mk_interval; - unsigned short mk_time_to_max; - unsigned short mk_max_speed; - short mk_curve; - unsigned short ax_options; - unsigned short ax_timeout; - unsigned short axt_opts_mask; - unsigned short axt_opts_values; - unsigned int axt_ctrls_mask; - unsigned int axt_ctrls_values; - unsigned char per_key_repeat[XkbPerKeyBitArraySize]; -} XkbControlsRec, *XkbControlsPtr; - -#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls&XkbAccessXFeedbackMask) -#define XkbAX_NeedOption(c,w) ((c)->ax_options&(w)) -#define XkbAX_NeedFeedback(c,w) (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w)) - -typedef struct _XkbServerMapRec { - unsigned short num_acts; - unsigned short size_acts; - XkbAction *acts; - - XkbBehavior *behaviors; - unsigned short *key_acts; -#if defined(__cplusplus) || defined(c_plusplus) - /* explicit is a C++ reserved word */ - unsigned char *c_explicit; -#else - unsigned char *explicit; -#endif - unsigned char vmods[XkbNumVirtualMods]; - unsigned short *vmodmap; -} XkbServerMapRec, *XkbServerMapPtr; - -#define XkbSMKeyActionsPtr(m,k) (&(m)->acts[(m)->key_acts[k]]) - - /* - * Structures and access macros used primarily by clients - */ - -typedef struct _XkbSymMapRec { - unsigned char kt_index[XkbNumKbdGroups]; - unsigned char group_info; - unsigned char width; - unsigned short offset; -} XkbSymMapRec, *XkbSymMapPtr; - -typedef struct _XkbClientMapRec { - unsigned char size_types; - unsigned char num_types; - XkbKeyTypePtr types; - - unsigned short size_syms; - unsigned short num_syms; - KeySym *syms; - XkbSymMapPtr key_sym_map; - - unsigned char *modmap; -} XkbClientMapRec, *XkbClientMapPtr; - -#define XkbCMKeyGroupInfo(m,k) ((m)->key_sym_map[k].group_info) -#define XkbCMKeyNumGroups(m,k) (XkbNumGroups((m)->key_sym_map[k].group_info)) -#define XkbCMKeyGroupWidth(m,k,g) (XkbCMKeyType(m,k,g)->num_levels) -#define XkbCMKeyGroupsWidth(m,k) ((m)->key_sym_map[k].width) -#define XkbCMKeyTypeIndex(m,k,g) ((m)->key_sym_map[k].kt_index[g&0x3]) -#define XkbCMKeyType(m,k,g) (&(m)->types[XkbCMKeyTypeIndex(m,k,g)]) -#define XkbCMKeyNumSyms(m,k) (XkbCMKeyGroupsWidth(m,k)*XkbCMKeyNumGroups(m,k)) -#define XkbCMKeySymsOffset(m,k) ((m)->key_sym_map[k].offset) -#define XkbCMKeySymsPtr(m,k) (&(m)->syms[XkbCMKeySymsOffset(m,k)]) - - /* - * Compatibility structures and access macros - */ - -typedef struct _XkbSymInterpretRec { - KeySym sym; - unsigned char flags; - unsigned char match; - unsigned char mods; - unsigned char virtual_mod; - XkbAnyAction act; -} XkbSymInterpretRec,*XkbSymInterpretPtr; - -typedef struct _XkbCompatMapRec { - XkbSymInterpretPtr sym_interpret; - XkbModsRec groups[XkbNumKbdGroups]; - unsigned short num_si; - unsigned short size_si; -} XkbCompatMapRec, *XkbCompatMapPtr; - -typedef struct _XkbIndicatorMapRec { - unsigned char flags; - unsigned char which_groups; - unsigned char groups; - unsigned char which_mods; - XkbModsRec mods; - unsigned int ctrls; -} XkbIndicatorMapRec, *XkbIndicatorMapPtr; - -#define XkbIM_IsAuto(i) ((((i)->flags&XkbIM_NoAutomatic)==0)&&\ - (((i)->which_groups&&(i)->groups)||\ - ((i)->which_mods&&(i)->mods.mask)||\ - ((i)->ctrls))) -#define XkbIM_InUse(i) (((i)->flags)||((i)->which_groups)||\ - ((i)->which_mods)||((i)->ctrls)) - - -typedef struct _XkbIndicatorRec { - unsigned long phys_indicators; - XkbIndicatorMapRec maps[XkbNumIndicators]; -} XkbIndicatorRec,*XkbIndicatorPtr; - -typedef struct _XkbKeyNameRec { - char name[XkbKeyNameLength]; -} XkbKeyNameRec,*XkbKeyNamePtr; - -typedef struct _XkbKeyAliasRec { - char real[XkbKeyNameLength]; - char alias[XkbKeyNameLength]; -} XkbKeyAliasRec,*XkbKeyAliasPtr; - - /* - * Names for everything - */ -typedef struct _XkbNamesRec { - Atom keycodes; - Atom geometry; - Atom symbols; - Atom types; - Atom compat; - Atom vmods[XkbNumVirtualMods]; - Atom indicators[XkbNumIndicators]; - Atom groups[XkbNumKbdGroups]; - XkbKeyNamePtr keys; - XkbKeyAliasPtr key_aliases; - Atom *radio_groups; - Atom phys_symbols; - - unsigned char num_keys; - unsigned char num_key_aliases; - unsigned short num_rg; -} XkbNamesRec,*XkbNamesPtr; - -typedef struct _XkbGeometry *XkbGeometryPtr; - /* - * Tie it all together into one big keyboard description - */ -typedef struct _XkbDesc { - struct _XDisplay * dpy; - unsigned short flags; - unsigned short device_spec; - KeyCode min_key_code; - KeyCode max_key_code; - - XkbControlsPtr ctrls; - XkbServerMapPtr server; - XkbClientMapPtr map; - XkbIndicatorPtr indicators; - XkbNamesPtr names; - XkbCompatMapPtr compat; - XkbGeometryPtr geom; -} XkbDescRec, *XkbDescPtr; -#define XkbKeyKeyTypeIndex(d,k,g) (XkbCMKeyTypeIndex((d)->map,k,g)) -#define XkbKeyKeyType(d,k,g) (XkbCMKeyType((d)->map,k,g)) -#define XkbKeyGroupWidth(d,k,g) (XkbCMKeyGroupWidth((d)->map,k,g)) -#define XkbKeyGroupsWidth(d,k) (XkbCMKeyGroupsWidth((d)->map,k)) -#define XkbKeyGroupInfo(d,k) (XkbCMKeyGroupInfo((d)->map,(k))) -#define XkbKeyNumGroups(d,k) (XkbCMKeyNumGroups((d)->map,(k))) -#define XkbKeyNumSyms(d,k) (XkbCMKeyNumSyms((d)->map,(k))) -#define XkbKeySymsPtr(d,k) (XkbCMKeySymsPtr((d)->map,(k))) -#define XkbKeySym(d,k,n) (XkbKeySymsPtr(d,k)[n]) -#define XkbKeySymEntry(d,k,sl,g) \ - (XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl)))) -#define XkbKeyAction(d,k,n) \ - (XkbKeyHasActions(d,k)?&XkbKeyActionsPtr(d,k)[n]:NULL) -#define XkbKeyActionEntry(d,k,sl,g) \ - (XkbKeyHasActions(d,k)?\ - XkbKeyAction(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))):NULL) - -#define XkbKeyHasActions(d,k) ((d)->server->key_acts[k]!=0) -#define XkbKeyNumActions(d,k) (XkbKeyHasActions(d,k)?XkbKeyNumSyms(d,k):1) -#define XkbKeyActionsPtr(d,k) (XkbSMKeyActionsPtr((d)->server,k)) -#define XkbKeycodeInRange(d,k) (((k)>=(d)->min_key_code)&&\ - ((k)<=(d)->max_key_code)) -#define XkbNumKeys(d) ((d)->max_key_code-(d)->min_key_code+1) - - - /* - * The following structures can be used to track changes - * to a keyboard device - */ -typedef struct _XkbMapChanges { - unsigned short changed; - KeyCode min_key_code; - KeyCode max_key_code; - unsigned char first_type; - unsigned char num_types; - KeyCode first_key_sym; - unsigned char num_key_syms; - KeyCode first_key_act; - unsigned char num_key_acts; - KeyCode first_key_behavior; - unsigned char num_key_behaviors; - KeyCode first_key_explicit; - unsigned char num_key_explicit; - KeyCode first_modmap_key; - unsigned char num_modmap_keys; - KeyCode first_vmodmap_key; - unsigned char num_vmodmap_keys; - unsigned char pad; - unsigned short vmods; -} XkbMapChangesRec,*XkbMapChangesPtr; - -typedef struct _XkbControlsChanges { - unsigned int changed_ctrls; - unsigned int enabled_ctrls_changes; - Bool num_groups_changed; -} XkbControlsChangesRec,*XkbControlsChangesPtr; - -typedef struct _XkbIndicatorChanges { - unsigned int state_changes; - unsigned int map_changes; -} XkbIndicatorChangesRec,*XkbIndicatorChangesPtr; - -typedef struct _XkbNameChanges { - unsigned int changed; - unsigned char first_type; - unsigned char num_types; - unsigned char first_lvl; - unsigned char num_lvls; - unsigned char num_aliases; - unsigned char num_rg; - unsigned char first_key; - unsigned char num_keys; - unsigned short changed_vmods; - unsigned long changed_indicators; - unsigned char changed_groups; -} XkbNameChangesRec,*XkbNameChangesPtr; - -typedef struct _XkbCompatChanges { - unsigned char changed_groups; - unsigned short first_si; - unsigned short num_si; -} XkbCompatChangesRec,*XkbCompatChangesPtr; - -typedef struct _XkbChanges { - unsigned short device_spec; - unsigned short state_changes; - XkbMapChangesRec map; - XkbControlsChangesRec ctrls; - XkbIndicatorChangesRec indicators; - XkbNameChangesRec names; - XkbCompatChangesRec compat; -} XkbChangesRec, *XkbChangesPtr; - - /* - * These data structures are used to construct a keymap from - * a set of components or to list components in the server - * database. - */ -typedef struct _XkbComponentNames { - char * keymap; - char * keycodes; - char * types; - char * compat; - char * symbols; - char * geometry; -} XkbComponentNamesRec, *XkbComponentNamesPtr; - -typedef struct _XkbComponentName { - unsigned short flags; - char * name; -} XkbComponentNameRec,*XkbComponentNamePtr; - -typedef struct _XkbComponentList { - int num_keymaps; - int num_keycodes; - int num_types; - int num_compat; - int num_symbols; - int num_geometry; - XkbComponentNamePtr keymaps; - XkbComponentNamePtr keycodes; - XkbComponentNamePtr types; - XkbComponentNamePtr compat; - XkbComponentNamePtr symbols; - XkbComponentNamePtr geometry; -} XkbComponentListRec, *XkbComponentListPtr; - - /* - * The following data structures describe and track changes to a - * non-keyboard extension device - */ -typedef struct _XkbDeviceLedInfo { - unsigned short led_class; - unsigned short led_id; - unsigned int phys_indicators; - unsigned int maps_present; - unsigned int names_present; - unsigned int state; - Atom names[XkbNumIndicators]; - XkbIndicatorMapRec maps[XkbNumIndicators]; -} XkbDeviceLedInfoRec,*XkbDeviceLedInfoPtr; - -typedef struct _XkbDeviceInfo { - char * name; - Atom type; - unsigned short device_spec; - Bool has_own_state; - unsigned short supported; - unsigned short unsupported; - - unsigned short num_btns; - XkbAction * btn_acts; - - unsigned short sz_leds; - unsigned short num_leds; - unsigned short dflt_kbd_fb; - unsigned short dflt_led_fb; - XkbDeviceLedInfoPtr leds; -} XkbDeviceInfoRec,*XkbDeviceInfoPtr; - -#define XkbXI_DevHasBtnActs(d) (((d)->num_btns>0)&&((d)->btn_acts!=NULL)) -#define XkbXI_LegalDevBtn(d,b) (XkbXI_DevHasBtnActs(d)&&((b)<(d)->num_btns)) -#define XkbXI_DevHasLeds(d) (((d)->num_leds>0)&&((d)->leds!=NULL)) - -typedef struct _XkbDeviceLedChanges { - unsigned short led_class; - unsigned short led_id; - unsigned int defined; /* names or maps changed */ - struct _XkbDeviceLedChanges *next; -} XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr; - -typedef struct _XkbDeviceChanges { - unsigned int changed; - unsigned short first_btn; - unsigned short num_btns; - XkbDeviceLedChangesRec leds; -} XkbDeviceChangesRec,*XkbDeviceChangesPtr; - -#endif /* _XKBSTR_H_ */ diff --git a/shell/linux-deps/include/X11/keysym.h b/shell/linux-deps/include/X11/keysym.h deleted file mode 100644 index 4f584886c..000000000 --- a/shell/linux-deps/include/X11/keysym.h +++ /dev/null @@ -1,74 +0,0 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* default keysyms */ -#define XK_MISCELLANY -#define XK_XKB_KEYS -#define XK_LATIN1 -#define XK_LATIN2 -#define XK_LATIN3 -#define XK_LATIN4 -#define XK_LATIN8 -#define XK_LATIN9 -#define XK_CAUCASUS -#define XK_GREEK -#define XK_KATAKANA -#define XK_ARABIC -#define XK_CYRILLIC -#define XK_HEBREW -#define XK_THAI -#define XK_KOREAN -#define XK_ARMENIAN -#define XK_GEORGIAN -#define XK_VIETNAMESE -#define XK_CURRENCY -#define XK_MATHEMATICAL -#define XK_BRAILLE -#define XK_SINHALA - -#include - diff --git a/shell/linux-deps/include/X11/keysymdef.h b/shell/linux-deps/include/X11/keysymdef.h deleted file mode 100644 index 73b55339c..000000000 --- a/shell/linux-deps/include/X11/keysymdef.h +++ /dev/null @@ -1,2477 +0,0 @@ -/*********************************************************** -Copyright 1987, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* - * The "X11 Window System Protocol" standard defines in Appendix A the - * keysym codes. These 29-bit integer values identify characters or - * functions associated with each key (e.g., via the visible - * engraving) of a keyboard layout. This file assigns mnemonic macro - * names for these keysyms. - * - * This file is also compiled (by src/util/makekeys.c in libX11) into - * hash tables that can be accessed with X11 library functions such as - * XStringToKeysym() and XKeysymToString(). - * - * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode - * character, this is noted in a comment that provides both the U+xxxx - * Unicode position, as well as the official Unicode name of the - * character. - * - * Where the correspondence is either not one-to-one or semantically - * unclear, the Unicode position and name are enclosed in - * parentheses. Such legacy keysyms should be considered deprecated - * and are not recommended for use in future keyboard mappings. - * - * For any future extension of the keysyms with characters already - * found in ISO 10646 / Unicode, the following algorithm shall be - * used. The new keysym code position will simply be the character's - * Unicode number plus 0x01000000. The keysym values in the range - * 0x01000100 to 0x0110ffff are reserved to represent Unicode - * characters in the range U+0100 to U+10FFFF. - * - * While most newer Unicode-based X11 clients do already accept - * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it - * will remain necessary for clients -- in the interest of - * compatibility with existing servers -- to also understand the - * existing legacy keysym values in the range 0x0100 to 0x20ff. - * - * Where several mnemonic names are defined for the same keysym in this - * file, all but the first one listed should be considered deprecated. - * - * Mnemonic names for keysyms are defined in this file with lines - * that match one of these Perl regular expressions: - * - * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U+([0-9A-F]{4,6}) (.*) \*\/\s*$/ - * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/ - * /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/ - * - * Before adding new keysyms, please do consider the following: In - * addition to the keysym names defined in this file, the - * XStringToKeysym() and XKeysymToString() functions will also handle - * any keysym string of the form "U0020" to "U007E" and "U00A0" to - * "U10FFFF" for all possible Unicode characters. In other words, - * every possible Unicode character has already a keysym string - * defined algorithmically, even if it is not listed here. Therefore, - * defining an additional keysym macro is only necessary where a - * non-hexadecimal mnemonic name is needed, or where the new keysym - * does not represent any existing Unicode character. - * - * When adding new keysyms to this file, do not forget to also update the - * following: - * - * - the mappings in src/KeyBind.c in the repo - * git://anongit.freedesktop.org/xorg/lib/libX11 - * - * - the protocol specification in specs/XProtocol/X11.keysyms - * in the repo git://anongit.freedesktop.org/xorg/doc/xorg-docs - * - */ - -#define XK_VoidSymbol 0xffffff /* Void symbol */ - -#ifdef XK_MISCELLANY -/* - * TTY function keys, cleverly chosen to map to ASCII, for convenience of - * programming, but could have been arbitrary (at the cost of lookup - * tables in client code). - */ - -#define XK_BackSpace 0xff08 /* Back space, back char */ -#define XK_Tab 0xff09 -#define XK_Linefeed 0xff0a /* Linefeed, LF */ -#define XK_Clear 0xff0b -#define XK_Return 0xff0d /* Return, enter */ -#define XK_Pause 0xff13 /* Pause, hold */ -#define XK_Scroll_Lock 0xff14 -#define XK_Sys_Req 0xff15 -#define XK_Escape 0xff1b -#define XK_Delete 0xffff /* Delete, rubout */ - - - -/* International & multi-key character composition */ - -#define XK_Multi_key 0xff20 /* Multi-key character compose */ -#define XK_Codeinput 0xff37 -#define XK_SingleCandidate 0xff3c -#define XK_MultipleCandidate 0xff3d -#define XK_PreviousCandidate 0xff3e - -/* Japanese keyboard support */ - -#define XK_Kanji 0xff21 /* Kanji, Kanji convert */ -#define XK_Muhenkan 0xff22 /* Cancel Conversion */ -#define XK_Henkan_Mode 0xff23 /* Start/Stop Conversion */ -#define XK_Henkan 0xff23 /* Alias for Henkan_Mode */ -#define XK_Romaji 0xff24 /* to Romaji */ -#define XK_Hiragana 0xff25 /* to Hiragana */ -#define XK_Katakana 0xff26 /* to Katakana */ -#define XK_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ -#define XK_Zenkaku 0xff28 /* to Zenkaku */ -#define XK_Hankaku 0xff29 /* to Hankaku */ -#define XK_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ -#define XK_Touroku 0xff2b /* Add to Dictionary */ -#define XK_Massyo 0xff2c /* Delete from Dictionary */ -#define XK_Kana_Lock 0xff2d /* Kana Lock */ -#define XK_Kana_Shift 0xff2e /* Kana Shift */ -#define XK_Eisu_Shift 0xff2f /* Alphanumeric Shift */ -#define XK_Eisu_toggle 0xff30 /* Alphanumeric toggle */ -#define XK_Kanji_Bangou 0xff37 /* Codeinput */ -#define XK_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ -#define XK_Mae_Koho 0xff3e /* Previous Candidate */ - -/* 0xff31 thru 0xff3f are under XK_KOREAN */ - -/* Cursor control & motion */ - -#define XK_Home 0xff50 -#define XK_Left 0xff51 /* Move left, left arrow */ -#define XK_Up 0xff52 /* Move up, up arrow */ -#define XK_Right 0xff53 /* Move right, right arrow */ -#define XK_Down 0xff54 /* Move down, down arrow */ -#define XK_Prior 0xff55 /* Prior, previous */ -#define XK_Page_Up 0xff55 -#define XK_Next 0xff56 /* Next */ -#define XK_Page_Down 0xff56 -#define XK_End 0xff57 /* EOL */ -#define XK_Begin 0xff58 /* BOL */ - - -/* Misc functions */ - -#define XK_Select 0xff60 /* Select, mark */ -#define XK_Print 0xff61 -#define XK_Execute 0xff62 /* Execute, run, do */ -#define XK_Insert 0xff63 /* Insert, insert here */ -#define XK_Undo 0xff65 -#define XK_Redo 0xff66 /* Redo, again */ -#define XK_Menu 0xff67 -#define XK_Find 0xff68 /* Find, search */ -#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */ -#define XK_Help 0xff6a /* Help */ -#define XK_Break 0xff6b -#define XK_Mode_switch 0xff7e /* Character set switch */ -#define XK_script_switch 0xff7e /* Alias for mode_switch */ -#define XK_Num_Lock 0xff7f - -/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ - -#define XK_KP_Space 0xff80 /* Space */ -#define XK_KP_Tab 0xff89 -#define XK_KP_Enter 0xff8d /* Enter */ -#define XK_KP_F1 0xff91 /* PF1, KP_A, ... */ -#define XK_KP_F2 0xff92 -#define XK_KP_F3 0xff93 -#define XK_KP_F4 0xff94 -#define XK_KP_Home 0xff95 -#define XK_KP_Left 0xff96 -#define XK_KP_Up 0xff97 -#define XK_KP_Right 0xff98 -#define XK_KP_Down 0xff99 -#define XK_KP_Prior 0xff9a -#define XK_KP_Page_Up 0xff9a -#define XK_KP_Next 0xff9b -#define XK_KP_Page_Down 0xff9b -#define XK_KP_End 0xff9c -#define XK_KP_Begin 0xff9d -#define XK_KP_Insert 0xff9e -#define XK_KP_Delete 0xff9f -#define XK_KP_Equal 0xffbd /* Equals */ -#define XK_KP_Multiply 0xffaa -#define XK_KP_Add 0xffab -#define XK_KP_Separator 0xffac /* Separator, often comma */ -#define XK_KP_Subtract 0xffad -#define XK_KP_Decimal 0xffae -#define XK_KP_Divide 0xffaf - -#define XK_KP_0 0xffb0 -#define XK_KP_1 0xffb1 -#define XK_KP_2 0xffb2 -#define XK_KP_3 0xffb3 -#define XK_KP_4 0xffb4 -#define XK_KP_5 0xffb5 -#define XK_KP_6 0xffb6 -#define XK_KP_7 0xffb7 -#define XK_KP_8 0xffb8 -#define XK_KP_9 0xffb9 - - - -/* - * Auxiliary functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufacturers have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -#define XK_F1 0xffbe -#define XK_F2 0xffbf -#define XK_F3 0xffc0 -#define XK_F4 0xffc1 -#define XK_F5 0xffc2 -#define XK_F6 0xffc3 -#define XK_F7 0xffc4 -#define XK_F8 0xffc5 -#define XK_F9 0xffc6 -#define XK_F10 0xffc7 -#define XK_F11 0xffc8 -#define XK_L1 0xffc8 -#define XK_F12 0xffc9 -#define XK_L2 0xffc9 -#define XK_F13 0xffca -#define XK_L3 0xffca -#define XK_F14 0xffcb -#define XK_L4 0xffcb -#define XK_F15 0xffcc -#define XK_L5 0xffcc -#define XK_F16 0xffcd -#define XK_L6 0xffcd -#define XK_F17 0xffce -#define XK_L7 0xffce -#define XK_F18 0xffcf -#define XK_L8 0xffcf -#define XK_F19 0xffd0 -#define XK_L9 0xffd0 -#define XK_F20 0xffd1 -#define XK_L10 0xffd1 -#define XK_F21 0xffd2 -#define XK_R1 0xffd2 -#define XK_F22 0xffd3 -#define XK_R2 0xffd3 -#define XK_F23 0xffd4 -#define XK_R3 0xffd4 -#define XK_F24 0xffd5 -#define XK_R4 0xffd5 -#define XK_F25 0xffd6 -#define XK_R5 0xffd6 -#define XK_F26 0xffd7 -#define XK_R6 0xffd7 -#define XK_F27 0xffd8 -#define XK_R7 0xffd8 -#define XK_F28 0xffd9 -#define XK_R8 0xffd9 -#define XK_F29 0xffda -#define XK_R9 0xffda -#define XK_F30 0xffdb -#define XK_R10 0xffdb -#define XK_F31 0xffdc -#define XK_R11 0xffdc -#define XK_F32 0xffdd -#define XK_R12 0xffdd -#define XK_F33 0xffde -#define XK_R13 0xffde -#define XK_F34 0xffdf -#define XK_R14 0xffdf -#define XK_F35 0xffe0 -#define XK_R15 0xffe0 - -/* Modifiers */ - -#define XK_Shift_L 0xffe1 /* Left shift */ -#define XK_Shift_R 0xffe2 /* Right shift */ -#define XK_Control_L 0xffe3 /* Left control */ -#define XK_Control_R 0xffe4 /* Right control */ -#define XK_Caps_Lock 0xffe5 /* Caps lock */ -#define XK_Shift_Lock 0xffe6 /* Shift lock */ - -#define XK_Meta_L 0xffe7 /* Left meta */ -#define XK_Meta_R 0xffe8 /* Right meta */ -#define XK_Alt_L 0xffe9 /* Left alt */ -#define XK_Alt_R 0xffea /* Right alt */ -#define XK_Super_L 0xffeb /* Left super */ -#define XK_Super_R 0xffec /* Right super */ -#define XK_Hyper_L 0xffed /* Left hyper */ -#define XK_Hyper_R 0xffee /* Right hyper */ -#endif /* XK_MISCELLANY */ - -/* - * Keyboard (XKB) Extension function and modifier keys - * (from Appendix C of "The X Keyboard Extension: Protocol Specification") - * Byte 3 = 0xfe - */ - -#ifdef XK_XKB_KEYS -#define XK_ISO_Lock 0xfe01 -#define XK_ISO_Level2_Latch 0xfe02 -#define XK_ISO_Level3_Shift 0xfe03 -#define XK_ISO_Level3_Latch 0xfe04 -#define XK_ISO_Level3_Lock 0xfe05 -#define XK_ISO_Level5_Shift 0xfe11 -#define XK_ISO_Level5_Latch 0xfe12 -#define XK_ISO_Level5_Lock 0xfe13 -#define XK_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ -#define XK_ISO_Group_Latch 0xfe06 -#define XK_ISO_Group_Lock 0xfe07 -#define XK_ISO_Next_Group 0xfe08 -#define XK_ISO_Next_Group_Lock 0xfe09 -#define XK_ISO_Prev_Group 0xfe0a -#define XK_ISO_Prev_Group_Lock 0xfe0b -#define XK_ISO_First_Group 0xfe0c -#define XK_ISO_First_Group_Lock 0xfe0d -#define XK_ISO_Last_Group 0xfe0e -#define XK_ISO_Last_Group_Lock 0xfe0f - -#define XK_ISO_Left_Tab 0xfe20 -#define XK_ISO_Move_Line_Up 0xfe21 -#define XK_ISO_Move_Line_Down 0xfe22 -#define XK_ISO_Partial_Line_Up 0xfe23 -#define XK_ISO_Partial_Line_Down 0xfe24 -#define XK_ISO_Partial_Space_Left 0xfe25 -#define XK_ISO_Partial_Space_Right 0xfe26 -#define XK_ISO_Set_Margin_Left 0xfe27 -#define XK_ISO_Set_Margin_Right 0xfe28 -#define XK_ISO_Release_Margin_Left 0xfe29 -#define XK_ISO_Release_Margin_Right 0xfe2a -#define XK_ISO_Release_Both_Margins 0xfe2b -#define XK_ISO_Fast_Cursor_Left 0xfe2c -#define XK_ISO_Fast_Cursor_Right 0xfe2d -#define XK_ISO_Fast_Cursor_Up 0xfe2e -#define XK_ISO_Fast_Cursor_Down 0xfe2f -#define XK_ISO_Continuous_Underline 0xfe30 -#define XK_ISO_Discontinuous_Underline 0xfe31 -#define XK_ISO_Emphasize 0xfe32 -#define XK_ISO_Center_Object 0xfe33 -#define XK_ISO_Enter 0xfe34 - -#define XK_dead_grave 0xfe50 -#define XK_dead_acute 0xfe51 -#define XK_dead_circumflex 0xfe52 -#define XK_dead_tilde 0xfe53 -#define XK_dead_perispomeni 0xfe53 /* alias for dead_tilde */ -#define XK_dead_macron 0xfe54 -#define XK_dead_breve 0xfe55 -#define XK_dead_abovedot 0xfe56 -#define XK_dead_diaeresis 0xfe57 -#define XK_dead_abovering 0xfe58 -#define XK_dead_doubleacute 0xfe59 -#define XK_dead_caron 0xfe5a -#define XK_dead_cedilla 0xfe5b -#define XK_dead_ogonek 0xfe5c -#define XK_dead_iota 0xfe5d -#define XK_dead_voiced_sound 0xfe5e -#define XK_dead_semivoiced_sound 0xfe5f -#define XK_dead_belowdot 0xfe60 -#define XK_dead_hook 0xfe61 -#define XK_dead_horn 0xfe62 -#define XK_dead_stroke 0xfe63 -#define XK_dead_abovecomma 0xfe64 -#define XK_dead_psili 0xfe64 /* alias for dead_abovecomma */ -#define XK_dead_abovereversedcomma 0xfe65 -#define XK_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ -#define XK_dead_doublegrave 0xfe66 -#define XK_dead_belowring 0xfe67 -#define XK_dead_belowmacron 0xfe68 -#define XK_dead_belowcircumflex 0xfe69 -#define XK_dead_belowtilde 0xfe6a -#define XK_dead_belowbreve 0xfe6b -#define XK_dead_belowdiaeresis 0xfe6c -#define XK_dead_invertedbreve 0xfe6d -#define XK_dead_belowcomma 0xfe6e -#define XK_dead_currency 0xfe6f - -/* dead vowels for universal syllable entry */ -#define XK_dead_a 0xfe80 -#define XK_dead_A 0xfe81 -#define XK_dead_e 0xfe82 -#define XK_dead_E 0xfe83 -#define XK_dead_i 0xfe84 -#define XK_dead_I 0xfe85 -#define XK_dead_o 0xfe86 -#define XK_dead_O 0xfe87 -#define XK_dead_u 0xfe88 -#define XK_dead_U 0xfe89 -#define XK_dead_small_schwa 0xfe8a -#define XK_dead_capital_schwa 0xfe8b - -#define XK_First_Virtual_Screen 0xfed0 -#define XK_Prev_Virtual_Screen 0xfed1 -#define XK_Next_Virtual_Screen 0xfed2 -#define XK_Last_Virtual_Screen 0xfed4 -#define XK_Terminate_Server 0xfed5 - -#define XK_AccessX_Enable 0xfe70 -#define XK_AccessX_Feedback_Enable 0xfe71 -#define XK_RepeatKeys_Enable 0xfe72 -#define XK_SlowKeys_Enable 0xfe73 -#define XK_BounceKeys_Enable 0xfe74 -#define XK_StickyKeys_Enable 0xfe75 -#define XK_MouseKeys_Enable 0xfe76 -#define XK_MouseKeys_Accel_Enable 0xfe77 -#define XK_Overlay1_Enable 0xfe78 -#define XK_Overlay2_Enable 0xfe79 -#define XK_AudibleBell_Enable 0xfe7a - -#define XK_Pointer_Left 0xfee0 -#define XK_Pointer_Right 0xfee1 -#define XK_Pointer_Up 0xfee2 -#define XK_Pointer_Down 0xfee3 -#define XK_Pointer_UpLeft 0xfee4 -#define XK_Pointer_UpRight 0xfee5 -#define XK_Pointer_DownLeft 0xfee6 -#define XK_Pointer_DownRight 0xfee7 -#define XK_Pointer_Button_Dflt 0xfee8 -#define XK_Pointer_Button1 0xfee9 -#define XK_Pointer_Button2 0xfeea -#define XK_Pointer_Button3 0xfeeb -#define XK_Pointer_Button4 0xfeec -#define XK_Pointer_Button5 0xfeed -#define XK_Pointer_DblClick_Dflt 0xfeee -#define XK_Pointer_DblClick1 0xfeef -#define XK_Pointer_DblClick2 0xfef0 -#define XK_Pointer_DblClick3 0xfef1 -#define XK_Pointer_DblClick4 0xfef2 -#define XK_Pointer_DblClick5 0xfef3 -#define XK_Pointer_Drag_Dflt 0xfef4 -#define XK_Pointer_Drag1 0xfef5 -#define XK_Pointer_Drag2 0xfef6 -#define XK_Pointer_Drag3 0xfef7 -#define XK_Pointer_Drag4 0xfef8 -#define XK_Pointer_Drag5 0xfefd - -#define XK_Pointer_EnableKeys 0xfef9 -#define XK_Pointer_Accelerate 0xfefa -#define XK_Pointer_DfltBtnNext 0xfefb -#define XK_Pointer_DfltBtnPrev 0xfefc - -#endif /* XK_XKB_KEYS */ - -/* - * 3270 Terminal Keys - * Byte 3 = 0xfd - */ - -#ifdef XK_3270 -#define XK_3270_Duplicate 0xfd01 -#define XK_3270_FieldMark 0xfd02 -#define XK_3270_Right2 0xfd03 -#define XK_3270_Left2 0xfd04 -#define XK_3270_BackTab 0xfd05 -#define XK_3270_EraseEOF 0xfd06 -#define XK_3270_EraseInput 0xfd07 -#define XK_3270_Reset 0xfd08 -#define XK_3270_Quit 0xfd09 -#define XK_3270_PA1 0xfd0a -#define XK_3270_PA2 0xfd0b -#define XK_3270_PA3 0xfd0c -#define XK_3270_Test 0xfd0d -#define XK_3270_Attn 0xfd0e -#define XK_3270_CursorBlink 0xfd0f -#define XK_3270_AltCursor 0xfd10 -#define XK_3270_KeyClick 0xfd11 -#define XK_3270_Jump 0xfd12 -#define XK_3270_Ident 0xfd13 -#define XK_3270_Rule 0xfd14 -#define XK_3270_Copy 0xfd15 -#define XK_3270_Play 0xfd16 -#define XK_3270_Setup 0xfd17 -#define XK_3270_Record 0xfd18 -#define XK_3270_ChangeScreen 0xfd19 -#define XK_3270_DeleteWord 0xfd1a -#define XK_3270_ExSelect 0xfd1b -#define XK_3270_CursorSelect 0xfd1c -#define XK_3270_PrintScreen 0xfd1d -#define XK_3270_Enter 0xfd1e -#endif /* XK_3270 */ - -/* - * Latin 1 - * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) - * Byte 3 = 0 - */ -#ifdef XK_LATIN1 -#define XK_space 0x0020 /* U+0020 SPACE */ -#define XK_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ -#define XK_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ -#define XK_numbersign 0x0023 /* U+0023 NUMBER SIGN */ -#define XK_dollar 0x0024 /* U+0024 DOLLAR SIGN */ -#define XK_percent 0x0025 /* U+0025 PERCENT SIGN */ -#define XK_ampersand 0x0026 /* U+0026 AMPERSAND */ -#define XK_apostrophe 0x0027 /* U+0027 APOSTROPHE */ -#define XK_quoteright 0x0027 /* deprecated */ -#define XK_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ -#define XK_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ -#define XK_asterisk 0x002a /* U+002A ASTERISK */ -#define XK_plus 0x002b /* U+002B PLUS SIGN */ -#define XK_comma 0x002c /* U+002C COMMA */ -#define XK_minus 0x002d /* U+002D HYPHEN-MINUS */ -#define XK_period 0x002e /* U+002E FULL STOP */ -#define XK_slash 0x002f /* U+002F SOLIDUS */ -#define XK_0 0x0030 /* U+0030 DIGIT ZERO */ -#define XK_1 0x0031 /* U+0031 DIGIT ONE */ -#define XK_2 0x0032 /* U+0032 DIGIT TWO */ -#define XK_3 0x0033 /* U+0033 DIGIT THREE */ -#define XK_4 0x0034 /* U+0034 DIGIT FOUR */ -#define XK_5 0x0035 /* U+0035 DIGIT FIVE */ -#define XK_6 0x0036 /* U+0036 DIGIT SIX */ -#define XK_7 0x0037 /* U+0037 DIGIT SEVEN */ -#define XK_8 0x0038 /* U+0038 DIGIT EIGHT */ -#define XK_9 0x0039 /* U+0039 DIGIT NINE */ -#define XK_colon 0x003a /* U+003A COLON */ -#define XK_semicolon 0x003b /* U+003B SEMICOLON */ -#define XK_less 0x003c /* U+003C LESS-THAN SIGN */ -#define XK_equal 0x003d /* U+003D EQUALS SIGN */ -#define XK_greater 0x003e /* U+003E GREATER-THAN SIGN */ -#define XK_question 0x003f /* U+003F QUESTION MARK */ -#define XK_at 0x0040 /* U+0040 COMMERCIAL AT */ -#define XK_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ -#define XK_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ -#define XK_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ -#define XK_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ -#define XK_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ -#define XK_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ -#define XK_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ -#define XK_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ -#define XK_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ -#define XK_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ -#define XK_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ -#define XK_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ -#define XK_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ -#define XK_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ -#define XK_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ -#define XK_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ -#define XK_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ -#define XK_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ -#define XK_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ -#define XK_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ -#define XK_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ -#define XK_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ -#define XK_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ -#define XK_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ -#define XK_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ -#define XK_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ -#define XK_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ -#define XK_backslash 0x005c /* U+005C REVERSE SOLIDUS */ -#define XK_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ -#define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ -#define XK_underscore 0x005f /* U+005F LOW LINE */ -#define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */ -#define XK_quoteleft 0x0060 /* deprecated */ -#define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ -#define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ -#define XK_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ -#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ -#define XK_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ -#define XK_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ -#define XK_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ -#define XK_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ -#define XK_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ -#define XK_j 0x006a /* U+006A LATIN SMALL LETTER J */ -#define XK_k 0x006b /* U+006B LATIN SMALL LETTER K */ -#define XK_l 0x006c /* U+006C LATIN SMALL LETTER L */ -#define XK_m 0x006d /* U+006D LATIN SMALL LETTER M */ -#define XK_n 0x006e /* U+006E LATIN SMALL LETTER N */ -#define XK_o 0x006f /* U+006F LATIN SMALL LETTER O */ -#define XK_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ -#define XK_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ -#define XK_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ -#define XK_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ -#define XK_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ -#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ -#define XK_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ -#define XK_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ -#define XK_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ -#define XK_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ -#define XK_z 0x007a /* U+007A LATIN SMALL LETTER Z */ -#define XK_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ -#define XK_bar 0x007c /* U+007C VERTICAL LINE */ -#define XK_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ -#define XK_asciitilde 0x007e /* U+007E TILDE */ - -#define XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ -#define XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ -#define XK_cent 0x00a2 /* U+00A2 CENT SIGN */ -#define XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ -#define XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ -#define XK_yen 0x00a5 /* U+00A5 YEN SIGN */ -#define XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ -#define XK_section 0x00a7 /* U+00A7 SECTION SIGN */ -#define XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ -#define XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ -#define XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ -#define XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XK_notsign 0x00ac /* U+00AC NOT SIGN */ -#define XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ -#define XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ -#define XK_macron 0x00af /* U+00AF MACRON */ -#define XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ -#define XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ -#define XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ -#define XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ -#define XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ -#define XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ -#define XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ -#define XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ -#define XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ -#define XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ -#define XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ -#define XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ -#define XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ -#define XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ -#define XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ -#define XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ -#define XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ -#define XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ -#define XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ -#define XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ -#define XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ -#define XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ -#define XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ -#define XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ -#define XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ -#define XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ -#define XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ -#define XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ -#define XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ -#define XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ -#define XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ -#define XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ -#define XK_Eth 0x00d0 /* deprecated */ -#define XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ -#define XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ -#define XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ -#define XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ -#define XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ -#define XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ -#define XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ -#define XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ -#define XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ -#define XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ -#define XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ -#define XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ -#define XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ -#define XK_Thorn 0x00de /* deprecated */ -#define XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ -#define XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ -#define XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ -#define XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ -#define XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ -#define XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ -#define XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ -#define XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ -#define XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ -#define XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ -#define XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ -#define XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ -#define XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ -#define XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ -#define XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ -#define XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ -#define XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ -#define XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ -#define XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ -#define XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ -#define XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ -#define XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ -#define XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ -#define XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ -#define XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ -#define XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ -#define XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ -#define XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ -#define XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ -#define XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ -#define XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ -#define XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ -#endif /* XK_LATIN1 */ - -/* - * Latin 2 - * Byte 3 = 1 - */ - -#ifdef XK_LATIN2 -#define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ -#define XK_breve 0x01a2 /* U+02D8 BREVE */ -#define XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ -#define XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ -#define XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ -#define XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ -#define XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ -#define XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ -#define XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ -#define XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ -#define XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ -#define XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ -#define XK_ogonek 0x01b2 /* U+02DB OGONEK */ -#define XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ -#define XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ -#define XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ -#define XK_caron 0x01b7 /* U+02C7 CARON */ -#define XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ -#define XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ -#define XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ -#define XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ -#define XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ -#define XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ -#define XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ -#define XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ -#define XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ -#define XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ -#define XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ -#define XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ -#define XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ -#define XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ -#define XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ -#define XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ -#define XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ -#define XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ -#define XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ -#define XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ -#define XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ -#define XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ -#define XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ -#define XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ -#define XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ -#define XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ -#define XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ -#define XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ -#define XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ -#define XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ -#define XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ -#define XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ -#define XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ -#define XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ -#define XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ -#define XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ -#define XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ -#define XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ -#define XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ -#define XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ -#endif /* XK_LATIN2 */ - -/* - * Latin 3 - * Byte 3 = 2 - */ - -#ifdef XK_LATIN3 -#define XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ -#define XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ -#define XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ -#define XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ -#define XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ -#define XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ -#define XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ -#define XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ -#define XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ -#define XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ -#define XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ -#define XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ -#define XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ -#define XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ -#define XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ -#define XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ -#define XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ -#define XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ -#define XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ -#define XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ -#define XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ -#define XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ -#endif /* XK_LATIN3 */ - - -/* - * Latin 4 - * Byte 3 = 3 - */ - -#ifdef XK_LATIN4 -#define XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ -#define XK_kappa 0x03a2 /* deprecated */ -#define XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ -#define XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ -#define XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ -#define XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ -#define XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ -#define XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ -#define XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ -#define XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ -#define XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ -#define XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ -#define XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ -#define XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ -#define XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ -#define XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ -#define XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ -#define XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ -#define XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ -#define XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ -#define XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ -#define XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ -#define XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ -#define XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ -#define XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ -#define XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ -#define XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ -#define XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ -#define XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ -#define XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ -#define XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ -#define XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ -#define XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ -#define XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ -#define XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ -#define XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ -#endif /* XK_LATIN4 */ - -/* - * Latin 8 - */ -#ifdef XK_LATIN8 -#define XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ -#define XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ -#define XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ -#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ -#define XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ -#define XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ -#define XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ -#define XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ -#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ -#define XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ -#define XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ -#define XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ -#define XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ -#define XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ -#define XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ -#define XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ -#define XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ -#define XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ -#define XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ -#define XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ -#define XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ -#define XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ -#define XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ -#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ -#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ -#define XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ -#endif /* XK_LATIN8 */ - -/* - * Latin 9 - * Byte 3 = 0x13 - */ - -#ifdef XK_LATIN9 -#define XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ -#define XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ -#define XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ -#endif /* XK_LATIN9 */ - -/* - * Katakana - * Byte 3 = 4 - */ - -#ifdef XK_KATAKANA -#define XK_overline 0x047e /* U+203E OVERLINE */ -#define XK_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ -#define XK_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ -#define XK_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ -#define XK_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ -#define XK_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ -#define XK_kana_middledot 0x04a5 /* deprecated */ -#define XK_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ -#define XK_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ -#define XK_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ -#define XK_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ -#define XK_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ -#define XK_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ -#define XK_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ -#define XK_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ -#define XK_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ -#define XK_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ -#define XK_kana_tu 0x04af /* deprecated */ -#define XK_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ -#define XK_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ -#define XK_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ -#define XK_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ -#define XK_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ -#define XK_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ -#define XK_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ -#define XK_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ -#define XK_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ -#define XK_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ -#define XK_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ -#define XK_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ -#define XK_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ -#define XK_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ -#define XK_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ -#define XK_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ -#define XK_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ -#define XK_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ -#define XK_kana_TI 0x04c1 /* deprecated */ -#define XK_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ -#define XK_kana_TU 0x04c2 /* deprecated */ -#define XK_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ -#define XK_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ -#define XK_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ -#define XK_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ -#define XK_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ -#define XK_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ -#define XK_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ -#define XK_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ -#define XK_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ -#define XK_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ -#define XK_kana_HU 0x04cc /* deprecated */ -#define XK_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ -#define XK_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ -#define XK_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ -#define XK_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ -#define XK_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ -#define XK_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ -#define XK_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ -#define XK_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ -#define XK_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ -#define XK_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ -#define XK_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ -#define XK_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ -#define XK_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ -#define XK_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ -#define XK_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ -#define XK_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ -#define XK_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ -#define XK_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ -#define XK_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ -#define XK_kana_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_KATAKANA */ - -/* - * Arabic - * Byte 3 = 5 - */ - -#ifdef XK_ARABIC -#define XK_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ -#define XK_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ -#define XK_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ -#define XK_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ -#define XK_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ -#define XK_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ -#define XK_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ -#define XK_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ -#define XK_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ -#define XK_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ -#define XK_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ -#define XK_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ -#define XK_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ -#define XK_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ -#define XK_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ -#define XK_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ -#define XK_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ -#define XK_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ -#define XK_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ -#define XK_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ -#define XK_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ -#define XK_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ -#define XK_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ -#define XK_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ -#define XK_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ -#define XK_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ -#define XK_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ -#define XK_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ -#define XK_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ -#define XK_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ -#define XK_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ -#define XK_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ -#define XK_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ -#define XK_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ -#define XK_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ -#define XK_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ -#define XK_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ -#define XK_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ -#define XK_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ -#define XK_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ -#define XK_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ -#define XK_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ -#define XK_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ -#define XK_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ -#define XK_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ -#define XK_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ -#define XK_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ -#define XK_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ -#define XK_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ -#define XK_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ -#define XK_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ -#define XK_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ -#define XK_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ -#define XK_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ -#define XK_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ -#define XK_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ -#define XK_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ -#define XK_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ -#define XK_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ -#define XK_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ -#define XK_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ -#define XK_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ -#define XK_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ -#define XK_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ -#define XK_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ -#define XK_Arabic_heh 0x05e7 /* deprecated */ -#define XK_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ -#define XK_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ -#define XK_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ -#define XK_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ -#define XK_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ -#define XK_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ -#define XK_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ -#define XK_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ -#define XK_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ -#define XK_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ -#define XK_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ -#define XK_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ -#define XK_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ -#define XK_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ -#define XK_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ -#define XK_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ -#define XK_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ -#define XK_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ -#define XK_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ -#define XK_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ -#define XK_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XK_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XK_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ -#define XK_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ -#define XK_Arabic_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_ARABIC */ - -/* - * Cyrillic - * Byte 3 = 6 - */ -#ifdef XK_CYRILLIC -#define XK_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ -#define XK_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ -#define XK_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ -#define XK_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ -#define XK_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ -#define XK_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ -#define XK_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ -#define XK_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ -#define XK_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ -#define XK_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ -#define XK_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ -#define XK_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ -#define XK_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ -#define XK_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ -#define XK_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ -#define XK_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ -#define XK_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ -#define XK_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ -#define XK_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ -#define XK_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ -#define XK_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ -#define XK_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ - -#define XK_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ -#define XK_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ -#define XK_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ -#define XK_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ -#define XK_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ -#define XK_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ -#define XK_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ -#define XK_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ - -#define XK_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ -#define XK_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ -#define XK_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ -#define XK_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ -#define XK_Ukranian_je 0x06a4 /* deprecated */ -#define XK_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ -#define XK_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XK_Ukranian_i 0x06a6 /* deprecated */ -#define XK_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ -#define XK_Ukranian_yi 0x06a7 /* deprecated */ -#define XK_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ -#define XK_Serbian_je 0x06a8 /* deprecated */ -#define XK_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ -#define XK_Serbian_lje 0x06a9 /* deprecated */ -#define XK_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ -#define XK_Serbian_nje 0x06aa /* deprecated */ -#define XK_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ -#define XK_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ -#define XK_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ -#define XK_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ -#define XK_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ -#define XK_Serbian_dze 0x06af /* deprecated */ -#define XK_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ -#define XK_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ -#define XK_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ -#define XK_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ -#define XK_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ -#define XK_Ukranian_JE 0x06b4 /* deprecated */ -#define XK_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ -#define XK_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XK_Ukranian_I 0x06b6 /* deprecated */ -#define XK_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ -#define XK_Ukranian_YI 0x06b7 /* deprecated */ -#define XK_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ -#define XK_Serbian_JE 0x06b8 /* deprecated */ -#define XK_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ -#define XK_Serbian_LJE 0x06b9 /* deprecated */ -#define XK_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ -#define XK_Serbian_NJE 0x06ba /* deprecated */ -#define XK_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ -#define XK_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ -#define XK_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ -#define XK_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ -#define XK_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ -#define XK_Serbian_DZE 0x06bf /* deprecated */ -#define XK_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ -#define XK_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ -#define XK_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ -#define XK_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ -#define XK_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ -#define XK_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ -#define XK_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ -#define XK_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ -#define XK_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ -#define XK_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ -#define XK_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ -#define XK_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ -#define XK_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ -#define XK_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ -#define XK_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ -#define XK_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ -#define XK_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ -#define XK_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ -#define XK_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ -#define XK_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ -#define XK_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ -#define XK_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ -#define XK_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ -#define XK_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ -#define XK_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ -#define XK_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ -#define XK_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ -#define XK_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ -#define XK_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ -#define XK_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ -#define XK_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ -#define XK_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ -#define XK_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ -#define XK_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ -#define XK_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ -#define XK_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ -#define XK_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ -#define XK_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ -#define XK_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ -#define XK_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ -#define XK_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ -#define XK_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ -#define XK_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ -#define XK_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ -#define XK_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ -#define XK_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ -#define XK_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ -#define XK_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ -#define XK_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ -#define XK_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ -#define XK_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ -#define XK_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ -#define XK_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ -#define XK_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ -#define XK_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ -#define XK_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ -#define XK_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ -#define XK_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ -#define XK_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ -#define XK_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ -#define XK_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ -#define XK_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ -#define XK_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ -#define XK_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ -#endif /* XK_CYRILLIC */ - -/* - * Greek - * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7) - * Byte 3 = 7 - */ - -#ifdef XK_GREEK -#define XK_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ -#define XK_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ -#define XK_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ -#define XK_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ -#define XK_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ -#define XK_Greek_IOTAdiaeresis 0x07a5 /* old typo */ -#define XK_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ -#define XK_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ -#define XK_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ -#define XK_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ -#define XK_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ -#define XK_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ -#define XK_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ -#define XK_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ -#define XK_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ -#define XK_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ -#define XK_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ -#define XK_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ -#define XK_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ -#define XK_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ -#define XK_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ -#define XK_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ -#define XK_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ -#define XK_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ -#define XK_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ -#define XK_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ -#define XK_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ -#define XK_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ -#define XK_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ -#define XK_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ -#define XK_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ -#define XK_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ -#define XK_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ -#define XK_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XK_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XK_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ -#define XK_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ -#define XK_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ -#define XK_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ -#define XK_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ -#define XK_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ -#define XK_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ -#define XK_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ -#define XK_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ -#define XK_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ -#define XK_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ -#define XK_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ -#define XK_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ -#define XK_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ -#define XK_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ -#define XK_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ -#define XK_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ -#define XK_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ -#define XK_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ -#define XK_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ -#define XK_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ -#define XK_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ -#define XK_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ -#define XK_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XK_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XK_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ -#define XK_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ -#define XK_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ -#define XK_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ -#define XK_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ -#define XK_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ -#define XK_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ -#define XK_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ -#define XK_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ -#define XK_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ -#define XK_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ -#define XK_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ -#define XK_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ -#define XK_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ -#define XK_Greek_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_GREEK */ - -/* - * Technical - * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html) - * Byte 3 = 8 - */ - -#ifdef XK_TECHNICAL -#define XK_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ -#define XK_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ -#define XK_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ -#define XK_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ -#define XK_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ -#define XK_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ -#define XK_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ -#define XK_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ -#define XK_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ -#define XK_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ -#define XK_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ -#define XK_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ -#define XK_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ -#define XK_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ -#define XK_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ -#define XK_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ -#define XK_topleftsummation 0x08b1 -#define XK_botleftsummation 0x08b2 -#define XK_topvertsummationconnector 0x08b3 -#define XK_botvertsummationconnector 0x08b4 -#define XK_toprightsummation 0x08b5 -#define XK_botrightsummation 0x08b6 -#define XK_rightmiddlesummation 0x08b7 -#define XK_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ -#define XK_notequal 0x08bd /* U+2260 NOT EQUAL TO */ -#define XK_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ -#define XK_integral 0x08bf /* U+222B INTEGRAL */ -#define XK_therefore 0x08c0 /* U+2234 THEREFORE */ -#define XK_variation 0x08c1 /* U+221D PROPORTIONAL TO */ -#define XK_infinity 0x08c2 /* U+221E INFINITY */ -#define XK_nabla 0x08c5 /* U+2207 NABLA */ -#define XK_approximate 0x08c8 /* U+223C TILDE OPERATOR */ -#define XK_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ -#define XK_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ -#define XK_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ -#define XK_identical 0x08cf /* U+2261 IDENTICAL TO */ -#define XK_radical 0x08d6 /* U+221A SQUARE ROOT */ -#define XK_includedin 0x08da /* U+2282 SUBSET OF */ -#define XK_includes 0x08db /* U+2283 SUPERSET OF */ -#define XK_intersection 0x08dc /* U+2229 INTERSECTION */ -#define XK_union 0x08dd /* U+222A UNION */ -#define XK_logicaland 0x08de /* U+2227 LOGICAL AND */ -#define XK_logicalor 0x08df /* U+2228 LOGICAL OR */ -#define XK_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ -#define XK_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ -#define XK_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ -#define XK_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ -#define XK_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ -#define XK_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ -#endif /* XK_TECHNICAL */ - -/* - * Special - * (from the DEC VT100 Special Graphics Character Set) - * Byte 3 = 9 - */ - -#ifdef XK_SPECIAL -#define XK_blank 0x09df -#define XK_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ -#define XK_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ -#define XK_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ -#define XK_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ -#define XK_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ -#define XK_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ -#define XK_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ -#define XK_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ -#define XK_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ -#define XK_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ -#define XK_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ -#define XK_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ -#define XK_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ -#define XK_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ -#define XK_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ -#define XK_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ -#define XK_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ -#define XK_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ -#define XK_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ -#define XK_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ -#define XK_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ -#define XK_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ -#define XK_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ -#endif /* XK_SPECIAL */ - -/* - * Publishing - * (these are probably from a long forgotten DEC Publishing - * font that once shipped with DECwrite) - * Byte 3 = 0x0a - */ - -#ifdef XK_PUBLISHING -#define XK_emspace 0x0aa1 /* U+2003 EM SPACE */ -#define XK_enspace 0x0aa2 /* U+2002 EN SPACE */ -#define XK_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ -#define XK_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ -#define XK_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ -#define XK_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ -#define XK_thinspace 0x0aa7 /* U+2009 THIN SPACE */ -#define XK_hairspace 0x0aa8 /* U+200A HAIR SPACE */ -#define XK_emdash 0x0aa9 /* U+2014 EM DASH */ -#define XK_endash 0x0aaa /* U+2013 EN DASH */ -#define XK_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ -#define XK_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ -#define XK_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ -#define XK_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ -#define XK_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ -#define XK_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ -#define XK_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ -#define XK_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ -#define XK_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ -#define XK_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ -#define XK_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ -#define XK_careof 0x0ab8 /* U+2105 CARE OF */ -#define XK_figdash 0x0abb /* U+2012 FIGURE DASH */ -#define XK_leftanglebracket 0x0abc /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/ -#define XK_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ -#define XK_rightanglebracket 0x0abe /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/ -#define XK_marker 0x0abf -#define XK_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ -#define XK_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ -#define XK_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ -#define XK_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ -#define XK_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ -#define XK_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ -#define XK_trademarkincircle 0x0acb -#define XK_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ -#define XK_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ -#define XK_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ -#define XK_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ -#define XK_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ -#define XK_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ -#define XK_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ -#define XK_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ -#define XK_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ -#define XK_minutes 0x0ad6 /* U+2032 PRIME */ -#define XK_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ -#define XK_latincross 0x0ad9 /* U+271D LATIN CROSS */ -#define XK_hexagram 0x0ada -#define XK_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ -#define XK_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ -#define XK_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ -#define XK_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ -#define XK_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ -#define XK_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ -#define XK_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ -#define XK_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ -#define XK_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ -#define XK_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ -#define XK_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ -#define XK_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ -#define XK_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ -#define XK_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ -#define XK_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ -#define XK_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ -#define XK_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ -#define XK_club 0x0aec /* U+2663 BLACK CLUB SUIT */ -#define XK_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ -#define XK_heart 0x0aee /* U+2665 BLACK HEART SUIT */ -#define XK_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ -#define XK_dagger 0x0af1 /* U+2020 DAGGER */ -#define XK_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ -#define XK_checkmark 0x0af3 /* U+2713 CHECK MARK */ -#define XK_ballotcross 0x0af4 /* U+2717 BALLOT X */ -#define XK_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ -#define XK_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ -#define XK_malesymbol 0x0af7 /* U+2642 MALE SIGN */ -#define XK_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ -#define XK_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ -#define XK_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ -#define XK_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ -#define XK_caret 0x0afc /* U+2038 CARET */ -#define XK_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ -#define XK_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ -#define XK_cursor 0x0aff -#endif /* XK_PUBLISHING */ - -/* - * APL - * Byte 3 = 0x0b - */ - -#ifdef XK_APL -#define XK_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ -#define XK_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ -#define XK_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ -#define XK_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ -#define XK_overbar 0x0bc0 /*(U+00AF MACRON)*/ -#define XK_downtack 0x0bc2 /* U+22A4 DOWN TACK */ -#define XK_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ -#define XK_downstile 0x0bc4 /* U+230A LEFT FLOOR */ -#define XK_underbar 0x0bc6 /*(U+005F LOW LINE)*/ -#define XK_jot 0x0bca /* U+2218 RING OPERATOR */ -#define XK_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ -#define XK_uptack 0x0bce /* U+22A5 UP TACK */ -#define XK_circle 0x0bcf /* U+25CB WHITE CIRCLE */ -#define XK_upstile 0x0bd3 /* U+2308 LEFT CEILING */ -#define XK_downshoe 0x0bd6 /*(U+222A UNION)*/ -#define XK_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ -#define XK_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ -#define XK_lefttack 0x0bdc /* U+22A3 LEFT TACK */ -#define XK_righttack 0x0bfc /* U+22A2 RIGHT TACK */ -#endif /* XK_APL */ - -/* - * Hebrew - * Byte 3 = 0x0c - */ - -#ifdef XK_HEBREW -#define XK_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ -#define XK_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ -#define XK_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ -#define XK_hebrew_beth 0x0ce1 /* deprecated */ -#define XK_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ -#define XK_hebrew_gimmel 0x0ce2 /* deprecated */ -#define XK_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ -#define XK_hebrew_daleth 0x0ce3 /* deprecated */ -#define XK_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ -#define XK_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ -#define XK_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ -#define XK_hebrew_zayin 0x0ce6 /* deprecated */ -#define XK_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ -#define XK_hebrew_het 0x0ce7 /* deprecated */ -#define XK_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ -#define XK_hebrew_teth 0x0ce8 /* deprecated */ -#define XK_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ -#define XK_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ -#define XK_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ -#define XK_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ -#define XK_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ -#define XK_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ -#define XK_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ -#define XK_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ -#define XK_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ -#define XK_hebrew_samekh 0x0cf1 /* deprecated */ -#define XK_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ -#define XK_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ -#define XK_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ -#define XK_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ -#define XK_hebrew_finalzadi 0x0cf5 /* deprecated */ -#define XK_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ -#define XK_hebrew_zadi 0x0cf6 /* deprecated */ -#define XK_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ -#define XK_hebrew_kuf 0x0cf7 /* deprecated */ -#define XK_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ -#define XK_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ -#define XK_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ -#define XK_hebrew_taf 0x0cfa /* deprecated */ -#define XK_Hebrew_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_HEBREW */ - -/* - * Thai - * Byte 3 = 0x0d - */ - -#ifdef XK_THAI -#define XK_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ -#define XK_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ -#define XK_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ -#define XK_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ -#define XK_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ -#define XK_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ -#define XK_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ -#define XK_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ -#define XK_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ -#define XK_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ -#define XK_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ -#define XK_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ -#define XK_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ -#define XK_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ -#define XK_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ -#define XK_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ -#define XK_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ -#define XK_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ -#define XK_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ -#define XK_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ -#define XK_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ -#define XK_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ -#define XK_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ -#define XK_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ -#define XK_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ -#define XK_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ -#define XK_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ -#define XK_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ -#define XK_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ -#define XK_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ -#define XK_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ -#define XK_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ -#define XK_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ -#define XK_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ -#define XK_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ -#define XK_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ -#define XK_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ -#define XK_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ -#define XK_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ -#define XK_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ -#define XK_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ -#define XK_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ -#define XK_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ -#define XK_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ -#define XK_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ -#define XK_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ -#define XK_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ -#define XK_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ -#define XK_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ -#define XK_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ -#define XK_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ -#define XK_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ -#define XK_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ -#define XK_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ -#define XK_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ -#define XK_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ -#define XK_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ -#define XK_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ -#define XK_Thai_maihanakat_maitho 0x0dde -#define XK_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ -#define XK_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ -#define XK_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ -#define XK_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ -#define XK_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ -#define XK_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ -#define XK_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ -#define XK_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ -#define XK_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ -#define XK_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ -#define XK_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ -#define XK_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ -#define XK_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ -#define XK_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ -#define XK_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ -#define XK_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ -#define XK_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ -#define XK_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ -#define XK_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ -#define XK_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ -#define XK_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ -#define XK_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ -#define XK_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ -#define XK_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ -#define XK_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ -#endif /* XK_THAI */ - -/* - * Korean - * Byte 3 = 0x0e - */ - -#ifdef XK_KOREAN - -#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ -#define XK_Hangul_Start 0xff32 /* Hangul start */ -#define XK_Hangul_End 0xff33 /* Hangul end, English start */ -#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ -#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ -#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ -#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ -#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ -#define XK_Hangul_Banja 0xff39 /* Banja mode */ -#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ -#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ -#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ -#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ -#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ -#define XK_Hangul_Special 0xff3f /* Special symbols */ -#define XK_Hangul_switch 0xff7e /* Alias for mode_switch */ - -/* Hangul Consonant Characters */ -#define XK_Hangul_Kiyeog 0x0ea1 -#define XK_Hangul_SsangKiyeog 0x0ea2 -#define XK_Hangul_KiyeogSios 0x0ea3 -#define XK_Hangul_Nieun 0x0ea4 -#define XK_Hangul_NieunJieuj 0x0ea5 -#define XK_Hangul_NieunHieuh 0x0ea6 -#define XK_Hangul_Dikeud 0x0ea7 -#define XK_Hangul_SsangDikeud 0x0ea8 -#define XK_Hangul_Rieul 0x0ea9 -#define XK_Hangul_RieulKiyeog 0x0eaa -#define XK_Hangul_RieulMieum 0x0eab -#define XK_Hangul_RieulPieub 0x0eac -#define XK_Hangul_RieulSios 0x0ead -#define XK_Hangul_RieulTieut 0x0eae -#define XK_Hangul_RieulPhieuf 0x0eaf -#define XK_Hangul_RieulHieuh 0x0eb0 -#define XK_Hangul_Mieum 0x0eb1 -#define XK_Hangul_Pieub 0x0eb2 -#define XK_Hangul_SsangPieub 0x0eb3 -#define XK_Hangul_PieubSios 0x0eb4 -#define XK_Hangul_Sios 0x0eb5 -#define XK_Hangul_SsangSios 0x0eb6 -#define XK_Hangul_Ieung 0x0eb7 -#define XK_Hangul_Jieuj 0x0eb8 -#define XK_Hangul_SsangJieuj 0x0eb9 -#define XK_Hangul_Cieuc 0x0eba -#define XK_Hangul_Khieuq 0x0ebb -#define XK_Hangul_Tieut 0x0ebc -#define XK_Hangul_Phieuf 0x0ebd -#define XK_Hangul_Hieuh 0x0ebe - -/* Hangul Vowel Characters */ -#define XK_Hangul_A 0x0ebf -#define XK_Hangul_AE 0x0ec0 -#define XK_Hangul_YA 0x0ec1 -#define XK_Hangul_YAE 0x0ec2 -#define XK_Hangul_EO 0x0ec3 -#define XK_Hangul_E 0x0ec4 -#define XK_Hangul_YEO 0x0ec5 -#define XK_Hangul_YE 0x0ec6 -#define XK_Hangul_O 0x0ec7 -#define XK_Hangul_WA 0x0ec8 -#define XK_Hangul_WAE 0x0ec9 -#define XK_Hangul_OE 0x0eca -#define XK_Hangul_YO 0x0ecb -#define XK_Hangul_U 0x0ecc -#define XK_Hangul_WEO 0x0ecd -#define XK_Hangul_WE 0x0ece -#define XK_Hangul_WI 0x0ecf -#define XK_Hangul_YU 0x0ed0 -#define XK_Hangul_EU 0x0ed1 -#define XK_Hangul_YI 0x0ed2 -#define XK_Hangul_I 0x0ed3 - -/* Hangul syllable-final (JongSeong) Characters */ -#define XK_Hangul_J_Kiyeog 0x0ed4 -#define XK_Hangul_J_SsangKiyeog 0x0ed5 -#define XK_Hangul_J_KiyeogSios 0x0ed6 -#define XK_Hangul_J_Nieun 0x0ed7 -#define XK_Hangul_J_NieunJieuj 0x0ed8 -#define XK_Hangul_J_NieunHieuh 0x0ed9 -#define XK_Hangul_J_Dikeud 0x0eda -#define XK_Hangul_J_Rieul 0x0edb -#define XK_Hangul_J_RieulKiyeog 0x0edc -#define XK_Hangul_J_RieulMieum 0x0edd -#define XK_Hangul_J_RieulPieub 0x0ede -#define XK_Hangul_J_RieulSios 0x0edf -#define XK_Hangul_J_RieulTieut 0x0ee0 -#define XK_Hangul_J_RieulPhieuf 0x0ee1 -#define XK_Hangul_J_RieulHieuh 0x0ee2 -#define XK_Hangul_J_Mieum 0x0ee3 -#define XK_Hangul_J_Pieub 0x0ee4 -#define XK_Hangul_J_PieubSios 0x0ee5 -#define XK_Hangul_J_Sios 0x0ee6 -#define XK_Hangul_J_SsangSios 0x0ee7 -#define XK_Hangul_J_Ieung 0x0ee8 -#define XK_Hangul_J_Jieuj 0x0ee9 -#define XK_Hangul_J_Cieuc 0x0eea -#define XK_Hangul_J_Khieuq 0x0eeb -#define XK_Hangul_J_Tieut 0x0eec -#define XK_Hangul_J_Phieuf 0x0eed -#define XK_Hangul_J_Hieuh 0x0eee - -/* Ancient Hangul Consonant Characters */ -#define XK_Hangul_RieulYeorinHieuh 0x0eef -#define XK_Hangul_SunkyeongeumMieum 0x0ef0 -#define XK_Hangul_SunkyeongeumPieub 0x0ef1 -#define XK_Hangul_PanSios 0x0ef2 -#define XK_Hangul_KkogjiDalrinIeung 0x0ef3 -#define XK_Hangul_SunkyeongeumPhieuf 0x0ef4 -#define XK_Hangul_YeorinHieuh 0x0ef5 - -/* Ancient Hangul Vowel Characters */ -#define XK_Hangul_AraeA 0x0ef6 -#define XK_Hangul_AraeAE 0x0ef7 - -/* Ancient Hangul syllable-final (JongSeong) Characters */ -#define XK_Hangul_J_PanSios 0x0ef8 -#define XK_Hangul_J_KkogjiDalrinIeung 0x0ef9 -#define XK_Hangul_J_YeorinHieuh 0x0efa - -/* Korean currency symbol */ -#define XK_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ - -#endif /* XK_KOREAN */ - -/* - * Armenian - */ - -#ifdef XK_ARMENIAN -#define XK_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ -#define XK_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XK_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XK_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ -#define XK_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ -#define XK_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XK_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XK_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XK_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XK_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XK_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XK_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XK_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XK_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ -#define XK_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ -#define XK_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ -#define XK_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ -#define XK_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ -#define XK_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ -#define XK_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ -#define XK_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ -#define XK_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ -#define XK_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ -#define XK_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ -#define XK_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ -#define XK_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ -#define XK_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ -#define XK_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ -#define XK_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ -#define XK_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ -#define XK_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ -#define XK_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ -#define XK_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ -#define XK_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ -#define XK_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ -#define XK_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ -#define XK_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ -#define XK_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ -#define XK_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ -#define XK_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ -#define XK_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ -#define XK_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ -#define XK_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ -#define XK_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ -#define XK_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ -#define XK_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ -#define XK_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ -#define XK_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ -#define XK_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ -#define XK_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ -#define XK_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ -#define XK_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ -#define XK_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ -#define XK_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ -#define XK_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ -#define XK_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ -#define XK_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ -#define XK_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ -#define XK_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ -#define XK_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ -#define XK_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ -#define XK_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ -#define XK_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ -#define XK_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ -#define XK_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ -#define XK_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ -#define XK_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ -#define XK_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ -#define XK_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ -#define XK_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ -#define XK_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ -#define XK_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ -#define XK_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ -#define XK_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ -#define XK_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ -#define XK_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ -#define XK_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ -#define XK_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ -#define XK_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ -#define XK_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ -#define XK_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ -#define XK_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ -#define XK_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ -#define XK_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ -#define XK_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ -#define XK_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ -#define XK_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ -#define XK_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ -#define XK_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ -#define XK_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ -#endif /* XK_ARMENIAN */ - -/* - * Georgian - */ - -#ifdef XK_GEORGIAN -#define XK_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ -#define XK_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ -#define XK_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ -#define XK_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ -#define XK_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ -#define XK_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ -#define XK_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ -#define XK_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ -#define XK_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ -#define XK_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ -#define XK_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ -#define XK_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ -#define XK_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ -#define XK_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ -#define XK_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ -#define XK_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ -#define XK_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ -#define XK_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ -#define XK_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ -#define XK_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ -#define XK_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ -#define XK_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ -#define XK_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ -#define XK_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ -#define XK_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ -#define XK_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ -#define XK_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ -#define XK_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ -#define XK_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ -#define XK_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ -#define XK_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ -#define XK_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ -#define XK_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ -#define XK_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ -#define XK_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ -#define XK_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ -#define XK_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ -#define XK_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ -#define XK_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ -#endif /* XK_GEORGIAN */ - -/* - * Azeri (and other Turkic or Caucasian languages) - */ - -#ifdef XK_CAUCASUS -/* latin */ -#define XK_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ -#define XK_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ -#define XK_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ -#define XK_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ -#define XK_Ocaron 0x10001d1 /* U+01D2 LATIN CAPITAL LETTER O WITH CARON */ -#define XK_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ -#define XK_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ -#define XK_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ -#define XK_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ -#define XK_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ -#define XK_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ -#define XK_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ -#define XK_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ -#define XK_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ -/* those are not really Caucasus */ -/* For Inupiak */ -#define XK_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ -#define XK_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ -#endif /* XK_CAUCASUS */ - -/* - * Vietnamese - */ - -#ifdef XK_VIETNAMESE -#define XK_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ -#define XK_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ -#define XK_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ -#define XK_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ -#define XK_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XK_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XK_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XK_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XK_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XK_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XK_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ -#define XK_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ -#define XK_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ -#define XK_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ -#define XK_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XK_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XK_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ -#define XK_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ -#define XK_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ -#define XK_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ -#define XK_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ -#define XK_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ -#define XK_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ -#define XK_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ -#define XK_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ -#define XK_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ -#define XK_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XK_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XK_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XK_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XK_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XK_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XK_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ -#define XK_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ -#define XK_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ -#define XK_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ -#define XK_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ -#define XK_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ -#define XK_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ -#define XK_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ -#define XK_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XK_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XK_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XK_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XK_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XK_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XK_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ -#define XK_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ -#define XK_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ -#define XK_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ -#define XK_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ -#define XK_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ -#define XK_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ -#define XK_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ -#define XK_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ -#define XK_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ -#define XK_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ -#define XK_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ -#define XK_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ -#define XK_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ -#define XK_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ -#define XK_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ -#define XK_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ -#define XK_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ -#define XK_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ -#define XK_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ -#define XK_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ -#define XK_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ -#define XK_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ -#define XK_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ -#define XK_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ -#define XK_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ -#define XK_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ -#define XK_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ -#define XK_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ -#define XK_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ -#define XK_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ -#define XK_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ -#define XK_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ -#define XK_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ - -#endif /* XK_VIETNAMESE */ - -#ifdef XK_CURRENCY -#define XK_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ -#define XK_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ -#define XK_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ -#define XK_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ -#define XK_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ -#define XK_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ -#define XK_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ -#define XK_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ -#define XK_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ -#define XK_WonSign 0x10020a9 /* U+20A9 WON SIGN */ -#define XK_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ -#define XK_DongSign 0x10020ab /* U+20AB DONG SIGN */ -#define XK_EuroSign 0x20ac /* U+20AC EURO SIGN */ -#endif /* XK_CURRENCY */ - -#ifdef XK_MATHEMATICAL -/* one, two and three are defined above. */ -#define XK_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ -#define XK_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ -#define XK_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ -#define XK_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ -#define XK_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ -#define XK_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ -#define XK_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ -#define XK_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ -#define XK_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ -#define XK_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ -#define XK_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ -#define XK_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ -#define XK_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ -#define XK_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ -#define XK_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ -#define XK_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ -#define XK_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ -#define XK_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ -#define XK_emptyset 0x1002205 /* U+2205 NULL SET */ -#define XK_elementof 0x1002208 /* U+2208 ELEMENT OF */ -#define XK_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ -#define XK_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ -#define XK_squareroot 0x100221A /* U+221A SQUARE ROOT */ -#define XK_cuberoot 0x100221B /* U+221B CUBE ROOT */ -#define XK_fourthroot 0x100221C /* U+221C FOURTH ROOT */ -#define XK_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ -#define XK_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ -#define XK_because 0x1002235 /* U+2235 BECAUSE */ -#define XK_approxeq 0x1002248 /* U+2245 ALMOST EQUAL TO */ -#define XK_notapproxeq 0x1002247 /* U+2247 NOT ALMOST EQUAL TO */ -#define XK_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ -#define XK_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ -#endif /* XK_MATHEMATICAL */ - -#ifdef XK_BRAILLE -#define XK_braille_dot_1 0xfff1 -#define XK_braille_dot_2 0xfff2 -#define XK_braille_dot_3 0xfff3 -#define XK_braille_dot_4 0xfff4 -#define XK_braille_dot_5 0xfff5 -#define XK_braille_dot_6 0xfff6 -#define XK_braille_dot_7 0xfff7 -#define XK_braille_dot_8 0xfff8 -#define XK_braille_dot_9 0xfff9 -#define XK_braille_dot_10 0xfffa -#define XK_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ -#define XK_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ -#define XK_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ -#define XK_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ -#define XK_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ -#define XK_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ -#define XK_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ -#define XK_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ -#define XK_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ -#define XK_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ -#define XK_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ -#define XK_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ -#define XK_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ -#define XK_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ -#define XK_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ -#define XK_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ -#define XK_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ -#define XK_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ -#define XK_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ -#define XK_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ -#define XK_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ -#define XK_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ -#define XK_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ -#define XK_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ -#define XK_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ -#define XK_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ -#define XK_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ -#define XK_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ -#define XK_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ -#define XK_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ -#define XK_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ -#define XK_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ -#define XK_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ -#define XK_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ -#define XK_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ -#define XK_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ -#define XK_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ -#define XK_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ -#define XK_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ -#define XK_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ -#define XK_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ -#define XK_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ -#define XK_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ -#define XK_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ -#define XK_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ -#define XK_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ -#define XK_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ -#define XK_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ -#define XK_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ -#define XK_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ -#define XK_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ -#define XK_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ -#define XK_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ -#define XK_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ -#define XK_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ -#define XK_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ -#define XK_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ -#define XK_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ -#define XK_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ -#define XK_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ -#define XK_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ -#define XK_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ -#define XK_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ -#define XK_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ -#define XK_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ -#define XK_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ -#define XK_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ -#define XK_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ -#define XK_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ -#define XK_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ -#define XK_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ -#define XK_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ -#define XK_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ -#define XK_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ -#define XK_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ -#define XK_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ -#define XK_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ -#define XK_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ -#define XK_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ -#define XK_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ -#define XK_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ -#define XK_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ -#define XK_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ -#define XK_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ -#define XK_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ -#define XK_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ -#define XK_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ -#define XK_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ -#define XK_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ -#define XK_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ -#define XK_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ -#define XK_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ -#define XK_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ -#define XK_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ -#define XK_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ -#define XK_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ -#define XK_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ -#define XK_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ -#define XK_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ -#define XK_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ -#define XK_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ -#define XK_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ -#define XK_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ -#define XK_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ -#define XK_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ -#define XK_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ -#define XK_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ -#define XK_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ -#define XK_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ -#define XK_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ -#define XK_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ -#define XK_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ -#define XK_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ -#define XK_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ -#define XK_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ -#define XK_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ -#define XK_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ -#define XK_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ -#define XK_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ -#define XK_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ -#define XK_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ -#define XK_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ -#define XK_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ -#define XK_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ -#define XK_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ -#define XK_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ -#define XK_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ -#define XK_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ -#define XK_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ -#define XK_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ -#define XK_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ -#define XK_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ -#define XK_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ -#define XK_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ -#define XK_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ -#define XK_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ -#define XK_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ -#define XK_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ -#define XK_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ -#define XK_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ -#define XK_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ -#define XK_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ -#define XK_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ -#define XK_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ -#define XK_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ -#define XK_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ -#define XK_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ -#define XK_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ -#define XK_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ -#define XK_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ -#define XK_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ -#define XK_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ -#define XK_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ -#define XK_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ -#define XK_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ -#define XK_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ -#define XK_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ -#define XK_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ -#define XK_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ -#define XK_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ -#define XK_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ -#define XK_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ -#define XK_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ -#define XK_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ -#define XK_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ -#define XK_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ -#define XK_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ -#define XK_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ -#define XK_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ -#define XK_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ -#define XK_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ -#define XK_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ -#define XK_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ -#define XK_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ -#define XK_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ -#define XK_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ -#define XK_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ -#define XK_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ -#define XK_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ -#define XK_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ -#define XK_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ -#define XK_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ -#define XK_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ -#define XK_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ -#define XK_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ -#define XK_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ -#define XK_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ -#define XK_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ -#define XK_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ -#define XK_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ -#define XK_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ -#define XK_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ -#define XK_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ -#define XK_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ -#define XK_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ -#define XK_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ -#define XK_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ -#define XK_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ -#define XK_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ -#define XK_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ -#define XK_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ -#define XK_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ -#define XK_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ -#define XK_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ -#define XK_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ -#define XK_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ -#define XK_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ -#define XK_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ -#define XK_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ -#define XK_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ -#define XK_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ -#define XK_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ -#define XK_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ -#define XK_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ -#define XK_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ -#define XK_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ -#define XK_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ -#define XK_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ -#define XK_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ -#define XK_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ -#define XK_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ -#define XK_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ -#define XK_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ -#define XK_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ -#define XK_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ -#define XK_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ -#define XK_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ -#define XK_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ -#define XK_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ -#define XK_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ -#define XK_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ -#define XK_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ -#define XK_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ -#define XK_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ -#define XK_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ -#define XK_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ -#define XK_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ -#define XK_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ -#define XK_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ -#define XK_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ -#define XK_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ -#define XK_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ -#define XK_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ -#define XK_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ -#define XK_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ -#define XK_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ -#define XK_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ -#define XK_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ -#define XK_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ -#define XK_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ -#define XK_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ -#define XK_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ -#define XK_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ -#define XK_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ -#define XK_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ -#define XK_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ -#endif /* XK_BRAILLE */ - -/* - * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf) - * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html - */ - -#ifdef XK_SINHALA -#define XK_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ -#define XK_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ -#define XK_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ -#define XK_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ -#define XK_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ -#define XK_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ -#define XK_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ -#define XK_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ -#define XK_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ -#define XK_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ -#define XK_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ -#define XK_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ -#define XK_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ -#define XK_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ -#define XK_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ -#define XK_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ -#define XK_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ -#define XK_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ -#define XK_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ -#define XK_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ -#define XK_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ -#define XK_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ -#define XK_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ -#define XK_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ -#define XK_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ -#define XK_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ -#define XK_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ -#define XK_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ -#define XK_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ -#define XK_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ -#define XK_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ -#define XK_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ -#define XK_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ -#define XK_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ -#define XK_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ -#define XK_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ -#define XK_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ -#define XK_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ -#define XK_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ -#define XK_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ -#define XK_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ -#define XK_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ -#define XK_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ -#define XK_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ -#define XK_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ -#define XK_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ -#define XK_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ -#define XK_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ -#define XK_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ -#define XK_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ -#define XK_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ -#define XK_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ -#define XK_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ -#define XK_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ -#define XK_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ -#define XK_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ -#define XK_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ -#define XK_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ -#define XK_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ -#define XK_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ -#define XK_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ -#define XK_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ -#define XK_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ -#define XK_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ -#define XK_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ -#define XK_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ -#define XK_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ -#define XK_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ -#define XK_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ -#define XK_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ -#define XK_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ -#define XK_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ -#define XK_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ -#define XK_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ -#define XK_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ -#define XK_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ -#define XK_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ -#define XK_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ -#define XK_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ -#define XK_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ -#endif /* XK_SINHALA */ diff --git a/shell/linux-deps/include/alsa/alisp.h b/shell/linux-deps/include/alsa/alisp.h deleted file mode 100644 index 407ed646e..000000000 --- a/shell/linux-deps/include/alsa/alisp.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ALSA lisp implementation - * Copyright (c) 2003 by Jaroslav Kysela - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -struct alisp_cfg { - int verbose: 1, - warning: 1, - debug: 1; - snd_input_t *in; /* program code */ - snd_output_t *out; /* program output */ - snd_output_t *eout; /* error output */ - snd_output_t *vout; /* verbose output */ - snd_output_t *wout; /* warning output */ - snd_output_t *dout; /* debug output */ -}; - -struct alisp_instance; -struct alisp_object; -struct alisp_seq_iterator; - -struct alisp_cfg *alsa_lisp_default_cfg(snd_input_t *input); -void alsa_lisp_default_cfg_free(struct alisp_cfg *cfg); -int alsa_lisp(struct alisp_cfg *cfg, struct alisp_instance **instance); -void alsa_lisp_free(struct alisp_instance *instance); -int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterator **result, - const char *id, const char *args, ...) -#ifndef DOC_HIDDEN - __attribute__ ((format (printf, 4, 5))) -#endif - ; -void alsa_lisp_result_free(struct alisp_instance *instance, - struct alisp_seq_iterator *result); -int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id, - struct alisp_seq_iterator **seq); -int alsa_lisp_seq_next(struct alisp_seq_iterator **seq); -int alsa_lisp_seq_count(struct alisp_seq_iterator *seq); -int alsa_lisp_seq_integer(struct alisp_seq_iterator *seq, long *val); -int alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, void **ptr); diff --git a/shell/linux-deps/include/alsa/asoundef.h b/shell/linux-deps/include/alsa/asoundef.h deleted file mode 100644 index c6c4eec95..000000000 --- a/shell/linux-deps/include/alsa/asoundef.h +++ /dev/null @@ -1,310 +0,0 @@ -/** - * \file include/asoundef.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Definitions of constants for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_ASOUNDEF_H -#define __ALSA_ASOUNDEF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Digital_Audio_Interface Constants for Digital Audio Interfaces - * AES/IEC958 channel status bits. - * \{ - */ - -#define IEC958_AES0_PROFESSIONAL (1<<0) /**< 0 = consumer, 1 = professional */ -#define IEC958_AES0_NONAUDIO (1<<1) /**< 0 = audio, 1 = non-audio */ -#define IEC958_AES0_PRO_EMPHASIS (7<<2) /**< mask - emphasis */ -#define IEC958_AES0_PRO_EMPHASIS_NOTID (0<<2) /**< emphasis not indicated */ -#define IEC958_AES0_PRO_EMPHASIS_NONE (1<<2) /**< no emphasis */ -#define IEC958_AES0_PRO_EMPHASIS_5015 (3<<2) /**< 50/15us emphasis */ -#define IEC958_AES0_PRO_EMPHASIS_CCITT (7<<2) /**< CCITT J.17 emphasis */ -#define IEC958_AES0_PRO_FREQ_UNLOCKED (1<<5) /**< source sample frequency: 0 = locked, 1 = unlocked */ -#define IEC958_AES0_PRO_FS (3<<6) /**< mask - sample frequency */ -#define IEC958_AES0_PRO_FS_NOTID (0<<6) /**< fs not indicated */ -#define IEC958_AES0_PRO_FS_44100 (1<<6) /**< 44.1kHz */ -#define IEC958_AES0_PRO_FS_48000 (2<<6) /**< 48kHz */ -#define IEC958_AES0_PRO_FS_32000 (3<<6) /**< 32kHz */ -#define IEC958_AES0_CON_NOT_COPYRIGHT (1<<2) /**< 0 = copyright, 1 = not copyright */ -#define IEC958_AES0_CON_EMPHASIS (7<<3) /**< mask - emphasis */ -#define IEC958_AES0_CON_EMPHASIS_NONE (0<<3) /**< no emphasis */ -#define IEC958_AES0_CON_EMPHASIS_5015 (1<<3) /**< 50/15us emphasis */ -#define IEC958_AES0_CON_MODE (3<<6) /**< mask - mode */ -#define IEC958_AES1_PRO_MODE (15<<0) /**< mask - channel mode */ -#define IEC958_AES1_PRO_MODE_NOTID (0<<0) /**< mode not indicated */ -#define IEC958_AES1_PRO_MODE_STEREOPHONIC (2<<0) /**< stereophonic - ch A is left */ -#define IEC958_AES1_PRO_MODE_SINGLE (4<<0) /**< single channel */ -#define IEC958_AES1_PRO_MODE_TWO (8<<0) /**< two channels */ -#define IEC958_AES1_PRO_MODE_PRIMARY (12<<0) /**< primary/secondary */ -#define IEC958_AES1_PRO_MODE_BYTE3 (15<<0) /**< vector to byte 3 */ -#define IEC958_AES1_PRO_USERBITS (15<<4) /**< mask - user bits */ -#define IEC958_AES1_PRO_USERBITS_NOTID (0<<4) /**< user bits not indicated */ -#define IEC958_AES1_PRO_USERBITS_192 (8<<4) /**< 192-bit structure */ -#define IEC958_AES1_PRO_USERBITS_UDEF (12<<4) /**< user defined application */ -#define IEC958_AES1_CON_CATEGORY 0x7f /**< consumer category */ -#define IEC958_AES1_CON_GENERAL 0x00 /**< general category */ -#define IEC958_AES1_CON_LASEROPT_MASK 0x07 /**< Laser-optical mask */ -#define IEC958_AES1_CON_LASEROPT_ID 0x01 /**< Laser-optical ID */ -#define IEC958_AES1_CON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x00) /**< IEC958 CD compatible device */ -#define IEC958_AES1_CON_NON_IEC908_CD (IEC958_AES1_CON_LASEROPT_ID|0x08) /**< non-IEC958 CD compatible device */ -#define IEC958_AES1_CON_MINI_DISC (IEC958_AES1_CON_LASEROPT_ID|0x48) /**< Mini-Disc device */ -#define IEC958_AES1_CON_DVD (IEC958_AES1_CON_LASEROPT_ID|0x18) /**< DVD device */ -#define IEC958_AES1_CON_LASTEROPT_OTHER (IEC958_AES1_CON_LASEROPT_ID|0x78) /**< Other laser-optical product */ -#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07 /**< digital<->digital converter mask */ -#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02 /**< digital<->digital converter id */ -#define IEC958_AES1_CON_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00) /**< PCM coder */ -#define IEC958_AES1_CON_MIXER (IEC958_AES1_CON_DIGDIGCONV_ID|0x10) /**< Digital signal mixer */ -#define IEC958_AES1_CON_RATE_CONVERTER (IEC958_AES1_CON_DIGDIGCONV_ID|0x18) /**< Rate converter */ -#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20) /**< PCM sampler */ -#define IEC958_AES1_CON_DSP (IEC958_AES1_CON_DIGDIGCONV_ID|0x28) /**< Digital sound processor */ -#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78) /**< Other digital<->digital product */ -#define IEC958_AES1_CON_MAGNETIC_MASK 0x07 /**< Magnetic device mask */ -#define IEC958_AES1_CON_MAGNETIC_ID 0x03 /**< Magnetic device ID */ -#define IEC958_AES1_CON_DAT (IEC958_AES1_CON_MAGNETIC_ID|0x00) /**< Digital Audio Tape */ -#define IEC958_AES1_CON_VCR (IEC958_AES1_CON_MAGNETIC_ID|0x08) /**< Video recorder */ -#define IEC958_AES1_CON_DCC (IEC958_AES1_CON_MAGNETIC_ID|0x40) /**< Digital compact cassette */ -#define IEC958_AES1_CON_MAGNETIC_DISC (IEC958_AES1_CON_MAGNETIC_ID|0x18) /**< Magnetic disc digital audio device */ -#define IEC958_AES1_CON_MAGNETIC_OTHER (IEC958_AES1_CON_MAGNETIC_ID|0x78) /**< Other magnetic device */ -#define IEC958_AES1_CON_BROADCAST1_MASK 0x07 /**< Broadcast mask */ -#define IEC958_AES1_CON_BROADCAST1_ID 0x04 /**< Broadcast ID */ -#define IEC958_AES1_CON_DAB_JAPAN (IEC958_AES1_CON_BROADCAST1_ID|0x00) /**< Digital audio broadcast (Japan) */ -#define IEC958_AES1_CON_DAB_EUROPE (IEC958_AES1_CON_BROADCAST1_ID|0x08) /**< Digital audio broadcast (Europe) */ -#define IEC958_AES1_CON_DAB_USA (IEC958_AES1_CON_BROADCAST1_ID|0x60) /**< Digital audio broadcast (USA) */ -#define IEC958_AES1_CON_SOFTWARE (IEC958_AES1_CON_BROADCAST1_ID|0x40) /**< Electronic software delivery */ -#define IEC958_AES1_CON_IEC62105 (IEC958_AES1_CON_BROADCAST1_ID|0x20) /**< Used by another standard (IEC 62105) */ -#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78) /**< Other broadcast product */ -#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f /**< Broadcast alternative mask */ -#define IEC958_AES1_CON_BROADCAST2_ID 0x0e /**< Broadcast alternative ID */ -#define IEC958_AES1_CON_MUSICAL_MASK 0x07 /**< Musical device mask */ -#define IEC958_AES1_CON_MUSICAL_ID 0x05 /**< Musical device ID */ -#define IEC958_AES1_CON_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00) /**< Synthesizer */ -#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08) /**< Microphone */ -#define IEC958_AES1_CON_MUSICAL_OTHER (IEC958_AES1_CON_MUSICAL_ID|0x78) /**< Other musical device */ -#define IEC958_AES1_CON_ADC_MASK 0x1f /**< ADC Mask */ -#define IEC958_AES1_CON_ADC_ID 0x06 /**< ADC ID */ -#define IEC958_AES1_CON_ADC (IEC958_AES1_CON_ADC_ID|0x00) /**< ADC without copyright information */ -#define IEC958_AES1_CON_ADC_OTHER (IEC958_AES1_CON_ADC_ID|0x60) /**< Other ADC product (with no copyright information) */ -#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f /**< ADC Copyright mask */ -#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16 /**< ADC Copyright ID */ -#define IEC958_AES1_CON_ADC_COPYRIGHT (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00) /**< ADC with copyright information */ -#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60) /**< Other ADC with copyright information product */ -#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f /**< Solid memory based products mask */ -#define IEC958_AES1_CON_SOLIDMEM_ID 0x08 /**< Solid memory based products ID */ -#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00) /**< Digital audio recorder and player using solid state memory */ -#define IEC958_AES1_CON_SOLIDMEM_OTHER (IEC958_AES1_CON_SOLIDMEM_ID|0x70) /**< Other solid state memory based product */ -#define IEC958_AES1_CON_EXPERIMENTAL 0x40 /**< experimental category */ -#define IEC958_AES1_CON_ORIGINAL (1<<7) /**< this bits depends on the category code */ -#define IEC958_AES2_PRO_SBITS (7<<0) /**< mask - sample bits */ -#define IEC958_AES2_PRO_SBITS_20 (2<<0) /**< 20-bit - coordination */ -#define IEC958_AES2_PRO_SBITS_24 (4<<0) /**< 24-bit - main audio */ -#define IEC958_AES2_PRO_SBITS_UDEF (6<<0) /**< user defined application */ -#define IEC958_AES2_PRO_WORDLEN (7<<3) /**< mask - source word length */ -#define IEC958_AES2_PRO_WORDLEN_NOTID (0<<3) /**< source word length not indicated */ -#define IEC958_AES2_PRO_WORDLEN_22_18 (2<<3) /**< 22-bit or 18-bit */ -#define IEC958_AES2_PRO_WORDLEN_23_19 (4<<3) /**< 23-bit or 19-bit */ -#define IEC958_AES2_PRO_WORDLEN_24_20 (5<<3) /**< 24-bit or 20-bit */ -#define IEC958_AES2_PRO_WORDLEN_20_16 (6<<3) /**< 20-bit or 16-bit */ -#define IEC958_AES2_CON_SOURCE (15<<0) /**< mask - source number */ -#define IEC958_AES2_CON_SOURCE_UNSPEC (0<<0) /**< source number unspecified */ -#define IEC958_AES2_CON_CHANNEL (15<<4) /**< mask - channel number */ -#define IEC958_AES2_CON_CHANNEL_UNSPEC (0<<4) /**< channel number unspecified */ -#define IEC958_AES3_CON_FS (15<<0) /**< mask - sample frequency */ -#define IEC958_AES3_CON_FS_44100 (0<<0) /**< 44.1kHz */ -#define IEC958_AES3_CON_FS_NOTID (1<<0) /**< sample frequency non indicated */ -#define IEC958_AES3_CON_FS_48000 (2<<0) /**< 48kHz */ -#define IEC958_AES3_CON_FS_32000 (3<<0) /**< 32kHz */ -#define IEC958_AES3_CON_FS_22050 (4<<0) /**< 22.05kHz */ -#define IEC958_AES3_CON_FS_24000 (6<<0) /**< 24kHz */ -#define IEC958_AES3_CON_FS_88200 (8<<0) /**< 88.2kHz */ -#define IEC958_AES3_CON_FS_768000 (9<<0) /**< 768kHz */ -#define IEC958_AES3_CON_FS_96000 (10<<0) /**< 96kHz */ -#define IEC958_AES3_CON_FS_176400 (12<<0) /**< 176.4kHz */ -#define IEC958_AES3_CON_FS_192000 (14<<0) /**< 192kHz */ -#define IEC958_AES3_CON_CLOCK (3<<4) /**< mask - clock accuracy */ -#define IEC958_AES3_CON_CLOCK_1000PPM (0<<4) /**< 1000 ppm */ -#define IEC958_AES3_CON_CLOCK_50PPM (1<<4) /**< 50 ppm */ -#define IEC958_AES3_CON_CLOCK_VARIABLE (2<<4) /**< variable pitch */ -#define IEC958_AES4_CON_MAX_WORDLEN_24 (1<<0) /**< 0 = 20-bit, 1 = 24-bit */ -#define IEC958_AES4_CON_WORDLEN (7<<1) /**< mask - sample word length */ -#define IEC958_AES4_CON_WORDLEN_NOTID (0<<1) /**< not indicated */ -#define IEC958_AES4_CON_WORDLEN_20_16 (1<<1) /**< 20-bit or 16-bit */ -#define IEC958_AES4_CON_WORDLEN_22_18 (2<<1) /**< 22-bit or 18-bit */ -#define IEC958_AES4_CON_WORDLEN_23_19 (4<<1) /**< 23-bit or 19-bit */ -#define IEC958_AES4_CON_WORDLEN_24_20 (5<<1) /**< 24-bit or 20-bit */ -#define IEC958_AES4_CON_WORDLEN_21_17 (6<<1) /**< 21-bit or 17-bit */ -#define IEC958_AES4_CON_ORIGFS (15<<4) /**< mask - original sample frequency */ -#define IEC958_AES4_CON_ORIGFS_NOTID (0<<4) /**< original sample frequency not indicated */ -#define IEC958_AES4_CON_ORIGFS_192000 (1<<4) /**< 192kHz */ -#define IEC958_AES4_CON_ORIGFS_12000 (2<<4) /**< 12kHz */ -#define IEC958_AES4_CON_ORIGFS_176400 (3<<4) /**< 176.4kHz */ -#define IEC958_AES4_CON_ORIGFS_96000 (5<<4) /**< 96kHz */ -#define IEC958_AES4_CON_ORIGFS_8000 (6<<4) /**< 8kHz */ -#define IEC958_AES4_CON_ORIGFS_88200 (7<<4) /**< 88.2kHz */ -#define IEC958_AES4_CON_ORIGFS_16000 (8<<4) /**< 16kHz */ -#define IEC958_AES4_CON_ORIGFS_24000 (9<<4) /**< 24kHz */ -#define IEC958_AES4_CON_ORIGFS_11025 (10<<4) /**< 11.025kHz */ -#define IEC958_AES4_CON_ORIGFS_22050 (11<<4) /**< 22.05kHz */ -#define IEC958_AES4_CON_ORIGFS_32000 (12<<4) /**< 32kHz */ -#define IEC958_AES4_CON_ORIGFS_48000 (13<<4) /**< 48kHz */ -#define IEC958_AES4_CON_ORIGFS_44100 (15<<4) /**< 44.1kHz */ -#define IEC958_AES5_CON_CGMSA (3<<0) /**< mask - CGMS-A */ -#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0) /**< copying is permitted without restriction */ -#define IEC958_AES5_CON_CGMSA_COPYONCE (1<<0) /**< one generation of copies may be made */ -#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0) /**< condition not be used */ -#define IEC958_AES5_CON_CGMSA_COPYNEVER (3<<0) /**< no copying is permitted */ - -/** \} */ - -/** - * \defgroup MIDI_Interface Constants for MIDI v1.0 - * Constants for MIDI v1.0. - * \{ - */ - -#define MIDI_CHANNELS 16 /**< Number of channels per port/cable. */ -#define MIDI_GM_DRUM_CHANNEL (10-1) /**< Channel number for GM drums. */ - -/** - * \defgroup MIDI_Commands MIDI Commands - * MIDI command codes. - * \{ - */ - -#define MIDI_CMD_NOTE_OFF 0x80 /**< note off */ -#define MIDI_CMD_NOTE_ON 0x90 /**< note on */ -#define MIDI_CMD_NOTE_PRESSURE 0xa0 /**< key pressure */ -#define MIDI_CMD_CONTROL 0xb0 /**< control change */ -#define MIDI_CMD_PGM_CHANGE 0xc0 /**< program change */ -#define MIDI_CMD_CHANNEL_PRESSURE 0xd0 /**< channel pressure */ -#define MIDI_CMD_BENDER 0xe0 /**< pitch bender */ - -#define MIDI_CMD_COMMON_SYSEX 0xf0 /**< sysex (system exclusive) begin */ -#define MIDI_CMD_COMMON_MTC_QUARTER 0xf1 /**< MTC quarter frame */ -#define MIDI_CMD_COMMON_SONG_POS 0xf2 /**< song position */ -#define MIDI_CMD_COMMON_SONG_SELECT 0xf3 /**< song select */ -#define MIDI_CMD_COMMON_TUNE_REQUEST 0xf6 /**< tune request */ -#define MIDI_CMD_COMMON_SYSEX_END 0xf7 /**< end of sysex */ -#define MIDI_CMD_COMMON_CLOCK 0xf8 /**< clock */ -#define MIDI_CMD_COMMON_START 0xfa /**< start */ -#define MIDI_CMD_COMMON_CONTINUE 0xfb /**< continue */ -#define MIDI_CMD_COMMON_STOP 0xfc /**< stop */ -#define MIDI_CMD_COMMON_SENSING 0xfe /**< active sensing */ -#define MIDI_CMD_COMMON_RESET 0xff /**< reset */ - -/** \} */ - -/** - * \defgroup MIDI_Controllers MIDI Controllers - * MIDI controller numbers. - * \{ - */ - -#define MIDI_CTL_MSB_BANK 0x00 /**< Bank selection */ -#define MIDI_CTL_MSB_MODWHEEL 0x01 /**< Modulation */ -#define MIDI_CTL_MSB_BREATH 0x02 /**< Breath */ -#define MIDI_CTL_MSB_FOOT 0x04 /**< Foot */ -#define MIDI_CTL_MSB_PORTAMENTO_TIME 0x05 /**< Portamento time */ -#define MIDI_CTL_MSB_DATA_ENTRY 0x06 /**< Data entry */ -#define MIDI_CTL_MSB_MAIN_VOLUME 0x07 /**< Main volume */ -#define MIDI_CTL_MSB_BALANCE 0x08 /**< Balance */ -#define MIDI_CTL_MSB_PAN 0x0a /**< Panpot */ -#define MIDI_CTL_MSB_EXPRESSION 0x0b /**< Expression */ -#define MIDI_CTL_MSB_EFFECT1 0x0c /**< Effect1 */ -#define MIDI_CTL_MSB_EFFECT2 0x0d /**< Effect2 */ -#define MIDI_CTL_MSB_GENERAL_PURPOSE1 0x10 /**< General purpose 1 */ -#define MIDI_CTL_MSB_GENERAL_PURPOSE2 0x11 /**< General purpose 2 */ -#define MIDI_CTL_MSB_GENERAL_PURPOSE3 0x12 /**< General purpose 3 */ -#define MIDI_CTL_MSB_GENERAL_PURPOSE4 0x13 /**< General purpose 4 */ -#define MIDI_CTL_LSB_BANK 0x20 /**< Bank selection */ -#define MIDI_CTL_LSB_MODWHEEL 0x21 /**< Modulation */ -#define MIDI_CTL_LSB_BREATH 0x22 /**< Breath */ -#define MIDI_CTL_LSB_FOOT 0x24 /**< Foot */ -#define MIDI_CTL_LSB_PORTAMENTO_TIME 0x25 /**< Portamento time */ -#define MIDI_CTL_LSB_DATA_ENTRY 0x26 /**< Data entry */ -#define MIDI_CTL_LSB_MAIN_VOLUME 0x27 /**< Main volume */ -#define MIDI_CTL_LSB_BALANCE 0x28 /**< Balance */ -#define MIDI_CTL_LSB_PAN 0x2a /**< Panpot */ -#define MIDI_CTL_LSB_EXPRESSION 0x2b /**< Expression */ -#define MIDI_CTL_LSB_EFFECT1 0x2c /**< Effect1 */ -#define MIDI_CTL_LSB_EFFECT2 0x2d /**< Effect2 */ -#define MIDI_CTL_LSB_GENERAL_PURPOSE1 0x30 /**< General purpose 1 */ -#define MIDI_CTL_LSB_GENERAL_PURPOSE2 0x31 /**< General purpose 2 */ -#define MIDI_CTL_LSB_GENERAL_PURPOSE3 0x32 /**< General purpose 3 */ -#define MIDI_CTL_LSB_GENERAL_PURPOSE4 0x33 /**< General purpose 4 */ -#define MIDI_CTL_SUSTAIN 0x40 /**< Sustain pedal */ -#define MIDI_CTL_PORTAMENTO 0x41 /**< Portamento */ -#define MIDI_CTL_SOSTENUTO 0x42 /**< Sostenuto */ -#define MIDI_CTL_SUSTENUTO 0x42 /**< Sostenuto (a typo in the older version) */ -#define MIDI_CTL_SOFT_PEDAL 0x43 /**< Soft pedal */ -#define MIDI_CTL_LEGATO_FOOTSWITCH 0x44 /**< Legato foot switch */ -#define MIDI_CTL_HOLD2 0x45 /**< Hold2 */ -#define MIDI_CTL_SC1_SOUND_VARIATION 0x46 /**< SC1 Sound Variation */ -#define MIDI_CTL_SC2_TIMBRE 0x47 /**< SC2 Timbre */ -#define MIDI_CTL_SC3_RELEASE_TIME 0x48 /**< SC3 Release Time */ -#define MIDI_CTL_SC4_ATTACK_TIME 0x49 /**< SC4 Attack Time */ -#define MIDI_CTL_SC5_BRIGHTNESS 0x4a /**< SC5 Brightness */ -#define MIDI_CTL_SC6 0x4b /**< SC6 */ -#define MIDI_CTL_SC7 0x4c /**< SC7 */ -#define MIDI_CTL_SC8 0x4d /**< SC8 */ -#define MIDI_CTL_SC9 0x4e /**< SC9 */ -#define MIDI_CTL_SC10 0x4f /**< SC10 */ -#define MIDI_CTL_GENERAL_PURPOSE5 0x50 /**< General purpose 5 */ -#define MIDI_CTL_GENERAL_PURPOSE6 0x51 /**< General purpose 6 */ -#define MIDI_CTL_GENERAL_PURPOSE7 0x52 /**< General purpose 7 */ -#define MIDI_CTL_GENERAL_PURPOSE8 0x53 /**< General purpose 8 */ -#define MIDI_CTL_PORTAMENTO_CONTROL 0x54 /**< Portamento control */ -#define MIDI_CTL_E1_REVERB_DEPTH 0x5b /**< E1 Reverb Depth */ -#define MIDI_CTL_E2_TREMOLO_DEPTH 0x5c /**< E2 Tremolo Depth */ -#define MIDI_CTL_E3_CHORUS_DEPTH 0x5d /**< E3 Chorus Depth */ -#define MIDI_CTL_E4_DETUNE_DEPTH 0x5e /**< E4 Detune Depth */ -#define MIDI_CTL_E5_PHASER_DEPTH 0x5f /**< E5 Phaser Depth */ -#define MIDI_CTL_DATA_INCREMENT 0x60 /**< Data Increment */ -#define MIDI_CTL_DATA_DECREMENT 0x61 /**< Data Decrement */ -#define MIDI_CTL_NONREG_PARM_NUM_LSB 0x62 /**< Non-registered parameter number */ -#define MIDI_CTL_NONREG_PARM_NUM_MSB 0x63 /**< Non-registered parameter number */ -#define MIDI_CTL_REGIST_PARM_NUM_LSB 0x64 /**< Registered parameter number */ -#define MIDI_CTL_REGIST_PARM_NUM_MSB 0x65 /**< Registered parameter number */ -#define MIDI_CTL_ALL_SOUNDS_OFF 0x78 /**< All sounds off */ -#define MIDI_CTL_RESET_CONTROLLERS 0x79 /**< Reset Controllers */ -#define MIDI_CTL_LOCAL_CONTROL_SWITCH 0x7a /**< Local control switch */ -#define MIDI_CTL_ALL_NOTES_OFF 0x7b /**< All notes off */ -#define MIDI_CTL_OMNI_OFF 0x7c /**< Omni off */ -#define MIDI_CTL_OMNI_ON 0x7d /**< Omni on */ -#define MIDI_CTL_MONO1 0x7e /**< Mono1 */ -#define MIDI_CTL_MONO2 0x7f /**< Mono2 */ - -/** \} */ - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_ASOUNDEF_H */ diff --git a/shell/linux-deps/include/alsa/asoundlib.h b/shell/linux-deps/include/alsa/asoundlib.h deleted file mode 100644 index 9fc860a4d..000000000 --- a/shell/linux-deps/include/alsa/asoundlib.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * \file include/asoundlib.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASOUNDLIB_H -#define __ASOUNDLIB_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif /* __ASOUNDLIB_H */ diff --git a/shell/linux-deps/include/alsa/conf.h b/shell/linux-deps/include/alsa/conf.h deleted file mode 100644 index ff270f617..000000000 --- a/shell/linux-deps/include/alsa/conf.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - * \file include/conf.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_CONF_H -#define __ALSA_CONF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Config Configuration Interface - * The configuration functions and types allow you to read, enumerate, - * modify and write the contents of ALSA configuration files. - * \{ - */ - -/** \brief \c dlsym version for the config evaluate callback. */ -#define SND_CONFIG_DLSYM_VERSION_EVALUATE _dlsym_config_evaluate_001 -/** \brief \c dlsym version for the config hook callback. */ -#define SND_CONFIG_DLSYM_VERSION_HOOK _dlsym_config_hook_001 - -/** \brief Configuration node type. */ -typedef enum _snd_config_type { - /** Integer number. */ - SND_CONFIG_TYPE_INTEGER, - /** 64-bit integer number. */ - SND_CONFIG_TYPE_INTEGER64, - /** Real number. */ - SND_CONFIG_TYPE_REAL, - /** Character string. */ - SND_CONFIG_TYPE_STRING, - /** Pointer (runtime only, cannot be saved). */ - SND_CONFIG_TYPE_POINTER, - /** Compound node. */ - SND_CONFIG_TYPE_COMPOUND = 1024 -} snd_config_type_t; - -/** - * \brief Internal structure for a configuration node object. - * - * The ALSA library uses a pointer to this structure as a handle to a - * configuration node. Applications don't access its contents directly. - */ -typedef struct _snd_config snd_config_t; -/** - * \brief Type for a configuration compound iterator. - * - * The ALSA library uses this pointer type as a handle to a configuration - * compound iterator. Applications don't directly access the contents of - * the structure pointed to by this type. - */ -typedef struct _snd_config_iterator *snd_config_iterator_t; -/** - * \brief Internal structure for a configuration private update object. - * - * The ALSA library uses this structure to save private update information. - */ -typedef struct _snd_config_update snd_config_update_t; - -extern snd_config_t *snd_config; - -int snd_config_top(snd_config_t **config); - -int snd_config_load(snd_config_t *config, snd_input_t *in); -int snd_config_load_override(snd_config_t *config, snd_input_t *in); -int snd_config_save(snd_config_t *config, snd_output_t *out); -int snd_config_update(void); -int snd_config_update_r(snd_config_t **top, snd_config_update_t **update, const char *path); -int snd_config_update_free(snd_config_update_t *update); -int snd_config_update_free_global(void); - -int snd_config_search(snd_config_t *config, const char *key, - snd_config_t **result); -int snd_config_searchv(snd_config_t *config, - snd_config_t **result, ...); -int snd_config_search_definition(snd_config_t *config, - const char *base, const char *key, - snd_config_t **result); - -int snd_config_expand(snd_config_t *config, snd_config_t *root, - const char *args, snd_config_t *private_data, - snd_config_t **result); -int snd_config_evaluate(snd_config_t *config, snd_config_t *root, - snd_config_t *private_data, snd_config_t **result); - -int snd_config_add(snd_config_t *config, snd_config_t *leaf); -int snd_config_delete(snd_config_t *config); -int snd_config_delete_compound_members(const snd_config_t *config); -int snd_config_copy(snd_config_t **dst, snd_config_t *src); - -int snd_config_make(snd_config_t **config, const char *key, - snd_config_type_t type); -int snd_config_make_integer(snd_config_t **config, const char *key); -int snd_config_make_integer64(snd_config_t **config, const char *key); -int snd_config_make_real(snd_config_t **config, const char *key); -int snd_config_make_string(snd_config_t **config, const char *key); -int snd_config_make_pointer(snd_config_t **config, const char *key); -int snd_config_make_compound(snd_config_t **config, const char *key, int join); - -int snd_config_imake_integer(snd_config_t **config, const char *key, const long value); -int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value); -int snd_config_imake_real(snd_config_t **config, const char *key, const double value); -int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii); -int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr); - -snd_config_type_t snd_config_get_type(const snd_config_t *config); - -int snd_config_set_id(snd_config_t *config, const char *id); -int snd_config_set_integer(snd_config_t *config, long value); -int snd_config_set_integer64(snd_config_t *config, long long value); -int snd_config_set_real(snd_config_t *config, double value); -int snd_config_set_string(snd_config_t *config, const char *value); -int snd_config_set_ascii(snd_config_t *config, const char *ascii); -int snd_config_set_pointer(snd_config_t *config, const void *ptr); -int snd_config_get_id(const snd_config_t *config, const char **value); -int snd_config_get_integer(const snd_config_t *config, long *value); -int snd_config_get_integer64(const snd_config_t *config, long long *value); -int snd_config_get_real(const snd_config_t *config, double *value); -int snd_config_get_ireal(const snd_config_t *config, double *value); -int snd_config_get_string(const snd_config_t *config, const char **value); -int snd_config_get_ascii(const snd_config_t *config, char **value); -int snd_config_get_pointer(const snd_config_t *config, const void **value); -int snd_config_test_id(const snd_config_t *config, const char *id); - -snd_config_iterator_t snd_config_iterator_first(const snd_config_t *node); -snd_config_iterator_t snd_config_iterator_next(const snd_config_iterator_t iterator); -snd_config_iterator_t snd_config_iterator_end(const snd_config_t *node); -snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator); - -/** - * \brief Helper macro to iterate over the children of a compound node. - * \param[in,out] pos Iterator variable for the current node. - * \param[in,out] next Temporary iterator variable for the next node. - * \param[in] node Handle to the compound configuration node to iterate over. - * - * Use this macro like a \c for statement, e.g.: - * \code - * snd_config_iterator_t pos, next; - * snd_config_for_each(pos, next, node) { - * snd_config_t *entry = snd_config_iterator_entry(pos); - * ... - * } - * \endcode - * - * This macro allows deleting or removing the current node. - */ -#define snd_config_for_each(pos, next, node) \ - for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos)) - -/* Misc functions */ - -int snd_config_get_bool_ascii(const char *ascii); -int snd_config_get_bool(const snd_config_t *conf); -int snd_config_get_ctl_iface_ascii(const char *ascii); -int snd_config_get_ctl_iface(const snd_config_t *conf); - -/* Names functions */ - -/** - * Device-name list element - */ -typedef struct snd_devname snd_devname_t; - -/** - * Device-name list element (definition) - */ -struct snd_devname { - char *name; /**< Device name string */ - char *comment; /**< Comments */ - snd_devname_t *next; /**< Next pointer */ -}; - -int snd_names_list(const char *iface, snd_devname_t **list); -void snd_names_list_free(snd_devname_t *list); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_CONF_H */ diff --git a/shell/linux-deps/include/alsa/control.h b/shell/linux-deps/include/alsa/control.h deleted file mode 100644 index 488629d9f..000000000 --- a/shell/linux-deps/include/alsa/control.h +++ /dev/null @@ -1,590 +0,0 @@ -/** - * \file include/control.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_CONTROL_H -#define __ALSA_CONTROL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Control Control Interface - * The control interface. - * See \ref control page for more details. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_CONTROL_DLSYM_VERSION _dlsym_control_001 - -/** IEC958 structure */ -typedef struct snd_aes_iec958 { - unsigned char status[24]; /**< AES/IEC958 channel status bits */ - unsigned char subcode[147]; /**< AES/IEC958 subcode bits */ - unsigned char pad; /**< nothing */ - unsigned char dig_subframe[4]; /**< AES/IEC958 subframe bits */ -} snd_aes_iec958_t; - -/** CTL card info container */ -typedef struct _snd_ctl_card_info snd_ctl_card_info_t; - -/** CTL element identifier container */ -typedef struct _snd_ctl_elem_id snd_ctl_elem_id_t; - -/** CTL element identifier list container */ -typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t; - -/** CTL element info container */ -typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t; - -/** CTL element value container */ -typedef struct _snd_ctl_elem_value snd_ctl_elem_value_t; - -/** CTL event container */ -typedef struct _snd_ctl_event snd_ctl_event_t; - -/** CTL element type */ -typedef enum _snd_ctl_elem_type { - /** Invalid type */ - SND_CTL_ELEM_TYPE_NONE = 0, - /** Boolean contents */ - SND_CTL_ELEM_TYPE_BOOLEAN, - /** Integer contents */ - SND_CTL_ELEM_TYPE_INTEGER, - /** Enumerated contents */ - SND_CTL_ELEM_TYPE_ENUMERATED, - /** Bytes contents */ - SND_CTL_ELEM_TYPE_BYTES, - /** IEC958 (S/PDIF) setting content */ - SND_CTL_ELEM_TYPE_IEC958, - /** 64-bit integer contents */ - SND_CTL_ELEM_TYPE_INTEGER64, - SND_CTL_ELEM_TYPE_LAST = SND_CTL_ELEM_TYPE_INTEGER64 -} snd_ctl_elem_type_t; - -/** CTL related interface */ -typedef enum _snd_ctl_elem_iface { - /** Card level */ - SND_CTL_ELEM_IFACE_CARD = 0, - /** Hardware dependent device */ - SND_CTL_ELEM_IFACE_HWDEP, - /** Mixer */ - SND_CTL_ELEM_IFACE_MIXER, - /** PCM */ - SND_CTL_ELEM_IFACE_PCM, - /** RawMidi */ - SND_CTL_ELEM_IFACE_RAWMIDI, - /** Timer */ - SND_CTL_ELEM_IFACE_TIMER, - /** Sequencer */ - SND_CTL_ELEM_IFACE_SEQUENCER, - SND_CTL_ELEM_IFACE_LAST = SND_CTL_ELEM_IFACE_SEQUENCER -} snd_ctl_elem_iface_t; - -/** Event class */ -typedef enum _snd_ctl_event_type { - /** Elements related event */ - SND_CTL_EVENT_ELEM = 0, - SND_CTL_EVENT_LAST = SND_CTL_EVENT_ELEM -}snd_ctl_event_type_t; - -/** Element has been removed (Warning: test this first and if set don't - * test the other masks) \hideinitializer */ -#define SND_CTL_EVENT_MASK_REMOVE (~0U) -/** Element value has been changed \hideinitializer */ -#define SND_CTL_EVENT_MASK_VALUE (1<<0) -/** Element info has been changed \hideinitializer */ -#define SND_CTL_EVENT_MASK_INFO (1<<1) -/** Element has been added \hideinitializer */ -#define SND_CTL_EVENT_MASK_ADD (1<<2) -/** Element's TLV value has been changed \hideinitializer */ -#define SND_CTL_EVENT_MASK_TLV (1<<3) - -/** CTL name helper */ -#define SND_CTL_NAME_NONE "" -/** CTL name helper */ -#define SND_CTL_NAME_PLAYBACK "Playback " -/** CTL name helper */ -#define SND_CTL_NAME_CAPTURE "Capture " - -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_NONE "" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_SWITCH "Switch" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_VOLUME "Volume" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_DEFAULT "Default" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_MASK "Mask" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_CON_MASK "Con Mask" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_PRO_MASK "Pro Mask" -/** CTL name helper */ -#define SND_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" -/** Element name for IEC958 (S/PDIF) */ -#define SND_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SND_CTL_NAME_##direction SND_CTL_NAME_IEC958_##what - -/** Mask for the major Power State identifier */ -#define SND_CTL_POWER_MASK 0xff00 -/** ACPI/PCI Power State D0 */ -#define SND_CTL_POWER_D0 0x0000 -/** ACPI/PCI Power State D1 */ -#define SND_CTL_POWER_D1 0x0100 -/** ACPI/PCI Power State D2 */ -#define SND_CTL_POWER_D2 0x0200 -/** ACPI/PCI Power State D3 */ -#define SND_CTL_POWER_D3 0x0300 -/** ACPI/PCI Power State D3hot */ -#define SND_CTL_POWER_D3hot (SND_CTL_POWER_D3|0x0000) -/** ACPI/PCI Power State D3cold */ -#define SND_CTL_POWER_D3cold (SND_CTL_POWER_D3|0x0001) - -/** TLV type - Container */ -#define SND_CTL_TLVT_CONTAINER 0x0000 -/** TLV type - basic dB scale */ -#define SND_CTL_TLVT_DB_SCALE 0x0001 -/** TLV type - linear volume */ -#define SND_CTL_TLVT_DB_LINEAR 0x0002 -/** TLV type - dB range container */ -#define SND_CTL_TLVT_DB_RANGE 0x0003 -/** TLV type - dB scale specified by min/max values */ -#define SND_CTL_TLVT_DB_MINMAX 0x0004 -/** TLV type - dB scale specified by min/max values (with mute) */ -#define SND_CTL_TLVT_DB_MINMAX_MUTE 0x0005 - -/** Mute state */ -#define SND_CTL_TLV_DB_GAIN_MUTE -9999999 - -/** CTL type */ -typedef enum _snd_ctl_type { - /** Kernel level CTL */ - SND_CTL_TYPE_HW, - /** Shared memory client CTL */ - SND_CTL_TYPE_SHM, - /** INET client CTL (not yet implemented) */ - SND_CTL_TYPE_INET, - /** External control plugin */ - SND_CTL_TYPE_EXT -} snd_ctl_type_t; - -/** Non blocking mode (flag for open mode) \hideinitializer */ -#define SND_CTL_NONBLOCK 0x0001 - -/** Async notification (flag for open mode) \hideinitializer */ -#define SND_CTL_ASYNC 0x0002 - -/** Read only (flag for open mode) \hideinitializer */ -#define SND_CTL_READONLY 0x0004 - -/** CTL handle */ -typedef struct _snd_ctl snd_ctl_t; - -/** Don't destroy the ctl handle when close */ -#define SND_SCTL_NOFREE 0x0001 - -/** SCTL type */ -typedef struct _snd_sctl snd_sctl_t; - -int snd_card_load(int card); -int snd_card_next(int *card); -int snd_card_get_index(const char *name); -int snd_card_get_name(int card, char **name); -int snd_card_get_longname(int card, char **name); - -int snd_device_name_hint(int card, const char *iface, void ***hints); -int snd_device_name_free_hint(void **hints); -char *snd_device_name_get_hint(const void *hint, const char *id); - -int snd_ctl_open(snd_ctl_t **ctl, const char *name, int mode); -int snd_ctl_open_lconf(snd_ctl_t **ctl, const char *name, int mode, snd_config_t *lconf); -int snd_ctl_open_fallback(snd_ctl_t **ctl, snd_config_t *root, const char *name, const char *orig_name, int mode); -int snd_ctl_close(snd_ctl_t *ctl); -int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock); -int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl, - snd_async_callback_t callback, void *private_data); -snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler); -int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl); -int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space); -int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe); -int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info); -int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list); -int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info); -int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *value); -int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *value); -int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); -int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); -int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - unsigned int *tlv, unsigned int tlv_size); -int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - const unsigned int *tlv); -int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - const unsigned int *tlv); -#ifdef __ALSA_HWDEP_H -int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int * device); -int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info); -#endif -#ifdef __ALSA_PCM_H -int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int *device); -int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info); -int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev); -#endif -#ifdef __ALSA_RAWMIDI_H -int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device); -int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info); -int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev); -#endif -int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state); -int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state); - -int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event); -int snd_ctl_wait(snd_ctl_t *ctl, int timeout); -const char *snd_ctl_name(snd_ctl_t *ctl); -snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl); - -const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type); -const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface); -const char *snd_ctl_event_type_name(snd_ctl_event_type_t type); - -unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj); -unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj); -void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr); -snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj); -unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj); -unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj); -const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj); -unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj); - -int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries); -void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj); - -char *snd_ctl_ascii_elem_id_get(snd_ctl_elem_id_t *id); -int snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str); -int snd_ctl_ascii_value_parse(snd_ctl_t *handle, - snd_ctl_elem_value_t *dst, - snd_ctl_elem_info_t *info, - const char *value); - -size_t snd_ctl_elem_id_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_elem_id_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_elem_id_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_id) -int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr); -void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj); -void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj); -void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src); -unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj); -snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj); -unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj); -unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj); -const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj); -unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj); -void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val); -void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val); -void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val); -void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val); -void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val); -void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val); - -size_t snd_ctl_card_info_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_card_info_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_card_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_card_info) -int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr); -void snd_ctl_card_info_free(snd_ctl_card_info_t *obj); -void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj); -void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src); -int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj); -const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj); - -size_t snd_ctl_event_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_event_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event) -int snd_ctl_event_malloc(snd_ctl_event_t **ptr); -void snd_ctl_event_free(snd_ctl_event_t *obj); -void snd_ctl_event_clear(snd_ctl_event_t *obj); -void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src); -snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj); - -size_t snd_ctl_elem_list_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_elem_list_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_elem_list_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_list) -int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr); -void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj); -void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj); -void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src); -void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val); -unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj); -unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj); -void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr); -unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx); -snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx); -unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx); -unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx); -const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx); -unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx); - -size_t snd_ctl_elem_info_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_elem_info_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_elem_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_info) -int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr); -void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj); -void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj); -void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src); -snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj); -pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj); -unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj); -long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj); -long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj); -long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj); -long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj); -long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj); -long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj); -unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj); -void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val); -const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj); -int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx); -void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr); -unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj); -snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj); -unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj); -unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj); -const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj); -unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj); -void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr); -void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val); -void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val); -void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val); -void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val); -void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val); -void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val); - -int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long imin, long imax, long istep); -int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, long long imin, long long imax, long long istep); -int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count); -int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, unsigned int count, unsigned int items, const char *const names[]); -int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id); -int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id); - -size_t snd_ctl_elem_value_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_ctl_elem_value_t using standard alloca - * \param ptr returned pointer - */ -#define snd_ctl_elem_value_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_value) -int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr); -void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj); -void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj); -void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src); -int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right); -void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr); -unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj); -snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj); -unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj); -unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj); -const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj); -unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj); -void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr); -void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val); -void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val); -void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val); -void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val); -void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val); -void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val); -int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx); -long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx); -long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx); -unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx); -unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx); -void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val); -void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val); -void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val); -void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val); -void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val); -void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size); -const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj); -void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr); -void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr); - -int snd_tlv_parse_dB_info(unsigned int *tlv, unsigned int tlv_size, - unsigned int **db_tlvp); -int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, - long *min, long *max); -int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, - long volume, long *db_gain); -int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, - long db_gain, long *value, int xdir); -int snd_ctl_get_dB_range(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - long *min, long *max); -int snd_ctl_convert_to_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - long volume, long *db_gain); -int snd_ctl_convert_from_dB(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, - long db_gain, long *value, int xdir); - -/** - * \defgroup HControl High level Control Interface - * \ingroup Control - * The high level control interface. - * See \ref hcontrol page for more details. - * \{ - */ - -/** HCTL element handle */ -typedef struct _snd_hctl_elem snd_hctl_elem_t; - -/** HCTL handle */ -typedef struct _snd_hctl snd_hctl_t; - -/** - * \brief Compare function for sorting HCTL elements - * \param e1 First element - * \param e2 Second element - * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2 - */ -typedef int (*snd_hctl_compare_t)(const snd_hctl_elem_t *e1, - const snd_hctl_elem_t *e2); -int snd_hctl_compare_fast(const snd_hctl_elem_t *c1, - const snd_hctl_elem_t *c2); -/** - * \brief HCTL callback function - * \param hctl HCTL handle - * \param mask event mask - * \param elem related HCTL element (if any) - * \return 0 on success otherwise a negative error code - */ -typedef int (*snd_hctl_callback_t)(snd_hctl_t *hctl, - unsigned int mask, - snd_hctl_elem_t *elem); -/** - * \brief HCTL element callback function - * \param elem HCTL element - * \param mask event mask - * \return 0 on success otherwise a negative error code - */ -typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem, - unsigned int mask); - -int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode); -int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl); -int snd_hctl_close(snd_hctl_t *hctl); -int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock); -int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl); -int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space); -int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -unsigned int snd_hctl_get_count(snd_hctl_t *hctl); -int snd_hctl_set_compare(snd_hctl_t *hctl, snd_hctl_compare_t hsort); -snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl); -snd_hctl_elem_t *snd_hctl_last_elem(snd_hctl_t *hctl); -snd_hctl_elem_t *snd_hctl_find_elem(snd_hctl_t *hctl, const snd_ctl_elem_id_t *id); -void snd_hctl_set_callback(snd_hctl_t *hctl, snd_hctl_callback_t callback); -void snd_hctl_set_callback_private(snd_hctl_t *hctl, void *data); -void *snd_hctl_get_callback_private(snd_hctl_t *hctl); -int snd_hctl_load(snd_hctl_t *hctl); -int snd_hctl_free(snd_hctl_t *hctl); -int snd_hctl_handle_events(snd_hctl_t *hctl); -const char *snd_hctl_name(snd_hctl_t *hctl); -int snd_hctl_wait(snd_hctl_t *hctl, int timeout); -snd_ctl_t *snd_hctl_ctl(snd_hctl_t *hctl); - -snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem); -snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem); -int snd_hctl_elem_info(snd_hctl_elem_t *elem, snd_ctl_elem_info_t * info); -int snd_hctl_elem_read(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value); -int snd_hctl_elem_write(snd_hctl_elem_t *elem, snd_ctl_elem_value_t * value); -int snd_hctl_elem_tlv_read(snd_hctl_elem_t *elem, unsigned int *tlv, unsigned int tlv_size); -int snd_hctl_elem_tlv_write(snd_hctl_elem_t *elem, const unsigned int *tlv); -int snd_hctl_elem_tlv_command(snd_hctl_elem_t *elem, const unsigned int *tlv); - -snd_hctl_t *snd_hctl_elem_get_hctl(snd_hctl_elem_t *elem); - -void snd_hctl_elem_get_id(const snd_hctl_elem_t *obj, snd_ctl_elem_id_t *ptr); -unsigned int snd_hctl_elem_get_numid(const snd_hctl_elem_t *obj); -snd_ctl_elem_iface_t snd_hctl_elem_get_interface(const snd_hctl_elem_t *obj); -unsigned int snd_hctl_elem_get_device(const snd_hctl_elem_t *obj); -unsigned int snd_hctl_elem_get_subdevice(const snd_hctl_elem_t *obj); -const char *snd_hctl_elem_get_name(const snd_hctl_elem_t *obj); -unsigned int snd_hctl_elem_get_index(const snd_hctl_elem_t *obj); -void snd_hctl_elem_set_callback(snd_hctl_elem_t *obj, snd_hctl_elem_callback_t val); -void * snd_hctl_elem_get_callback_private(const snd_hctl_elem_t *obj); -void snd_hctl_elem_set_callback_private(snd_hctl_elem_t *obj, void * val); - -/** \} */ - -/** \} */ - -/** - * \defgroup SControl Setup Control Interface - * \ingroup Control - * The setup control interface - set or modify control elements from a configuration file. - * \{ - */ - -int snd_sctl_build(snd_sctl_t **ctl, snd_ctl_t *handle, snd_config_t *config, - snd_config_t *private_data, int mode); -int snd_sctl_free(snd_sctl_t *handle); -int snd_sctl_install(snd_sctl_t *handle); -int snd_sctl_remove(snd_sctl_t *handle); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_CONTROL_H */ diff --git a/shell/linux-deps/include/alsa/control_external.h b/shell/linux-deps/include/alsa/control_external.h deleted file mode 100644 index 7c066cf9e..000000000 --- a/shell/linux-deps/include/alsa/control_external.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - * \file include/control_external.h - * \brief External control plugin SDK - * \author Takashi Iwai - * \date 2005 - * - * External control plugin SDK. - */ - -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __ALSA_CONTROL_EXTERNAL_H -#define __ALSA_CONTROL_EXTERNAL_H - -#include "control.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup CtlPlugin_SDK External Control Plugin SDK - * \{ - */ - -/** - * Define the object entry for external control plugins - */ -#define SND_CTL_PLUGIN_ENTRY(name) _snd_ctl_##name##_open - -/** - * Define the symbols of the given control plugin with versions - */ -#define SND_CTL_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_CTL_PLUGIN_ENTRY(name), SND_CONTROL_DLSYM_VERSION); - -/** - * Define the control plugin - */ -#define SND_CTL_PLUGIN_DEFINE_FUNC(plugin) \ -int SND_CTL_PLUGIN_ENTRY(plugin) (snd_ctl_t **handlep, const char *name,\ - snd_config_t *root, snd_config_t *conf, int mode) - -/** External control plugin handle */ -typedef struct snd_ctl_ext snd_ctl_ext_t; -/** Callback table of control ext */ -typedef struct snd_ctl_ext_callback snd_ctl_ext_callback_t; -/** Key to access a control pointer */ -typedef unsigned long snd_ctl_ext_key_t; - -/* - * Protocol version - */ -#define SND_CTL_EXT_VERSION_MAJOR 1 /**< Protocol major version */ -#define SND_CTL_EXT_VERSION_MINOR 0 /**< Protocol minor version */ -#define SND_CTL_EXT_VERSION_TINY 0 /**< Protocol tiny version */ -/** - * external plugin protocol version - */ -#define SND_CTL_EXT_VERSION ((SND_CTL_EXT_VERSION_MAJOR<<16) |\ - (SND_CTL_EXT_VERSION_MINOR<<8) |\ - (SND_CTL_EXT_VERSION_TINY)) - -/** Handle of control ext */ -struct snd_ctl_ext { - /** - * protocol version; #SND_CTL_EXT_VERSION must be filled here - * before calling #snd_ctl_ext_create() - */ - unsigned int version; - /** - * Index of this card; must be filled before calling #snd_ctl_ext_create() - */ - int card_idx; - /** - * ID string of this card; must be filled before calling #snd_ctl_ext_create() - */ - char id[16]; - /** - * Driver name of this card; must be filled before calling #snd_ctl_ext_create() - */ - char driver[16]; - /** - * short name of this card; must be filled before calling #snd_ctl_ext_create() - */ - char name[32]; - /** - * Long name of this card; must be filled before calling #snd_ctl_ext_create() - */ - char longname[80]; - /** - * Mixer name of this card; must be filled before calling #snd_ctl_ext_create() - */ - char mixername[80]; - /** - * poll descriptor - */ - int poll_fd; - - /** - * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create() - */ - const snd_ctl_ext_callback_t *callback; - /** - * private data, which can be used freely in the driver callbacks - */ - void *private_data; - /** - * control handle filled by #snd_ctl_ext_create() - */ - snd_ctl_t *handle; - - int nonblock; /**< non-block mode; read-only */ - int subscribed; /**< events subscribed; read-only */ -}; - -/** Callback table of ext */ -struct snd_ctl_ext_callback { - /** - * close the control handle; optional - */ - void (*close)(snd_ctl_ext_t *ext); - /** - * return the total number of elements; required - */ - int (*elem_count)(snd_ctl_ext_t *ext); - /** - * return the element id of the given offset (array index); required - */ - int (*elem_list)(snd_ctl_ext_t *ext, unsigned int offset, snd_ctl_elem_id_t *id); - /** - * convert the element id to a search key; required - */ - snd_ctl_ext_key_t (*find_elem)(snd_ctl_ext_t *ext, const snd_ctl_elem_id_t *id); - /** - * the destructor of the key; optional - */ - void (*free_key)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key); - /** - * get the attribute of the element; required - */ - int (*get_attribute)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, - int *type, unsigned int *acc, unsigned int *count); - /** - * get the element information of integer type - */ - int (*get_integer_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, - long *imin, long *imax, long *istep); - /** - * get the element information of integer64 type - */ - int (*get_integer64_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, - int64_t *imin, int64_t *imax, int64_t *istep); - /** - * get the element information of enumerated type - */ - int (*get_enumerated_info)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); - /** - * get the name of the enumerated item - */ - int (*get_enumerated_name)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int item, - char *name, size_t name_max_len); - /** - * read the current values of integer type - */ - int (*read_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value); - /** - * read the current values of integer64 type - */ - int (*read_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value); - /** - * read the current values of enumerated type - */ - int (*read_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); - /** - * read the current values of bytes type - */ - int (*read_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data, - size_t max_bytes); - /** - * read the current values of iec958 type - */ - int (*read_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958); - /** - * update the current values of integer type with the given values - */ - int (*write_integer)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, long *value); - /** - * update the current values of integer64 type with the given values - */ - int (*write_integer64)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int64_t *value); - /** - * update the current values of enumerated type with the given values - */ - int (*write_enumerated)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned int *items); - /** - * update the current values of bytes type with the given values - */ - int (*write_bytes)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, unsigned char *data, - size_t max_bytes); - /** - * update the current values of iec958 type with the given values - */ - int (*write_iec958)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, snd_aes_iec958_t *iec958); - /** - * subscribe/unsubscribe the event notification; optional - */ - void (*subscribe_events)(snd_ctl_ext_t *ext, int subscribe); - /** - * read a pending notification event; optional - */ - int (*read_event)(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id, unsigned int *event_mask); - /** - * return the number of poll descriptors; optional - */ - int (*poll_descriptors_count)(snd_ctl_ext_t *ext); - /** - * fill the poll descriptors; optional - */ - int (*poll_descriptors)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int space); - /** - * mangle the revents of poll descriptors - */ - int (*poll_revents)(snd_ctl_ext_t *ext, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -}; - -/** - * The access type bits stored in get_attribute callback - */ -typedef enum snd_ctl_ext_access { - SND_CTL_EXT_ACCESS_READ = (1<<0), - SND_CTL_EXT_ACCESS_WRITE = (1<<1), - SND_CTL_EXT_ACCESS_READWRITE = (3<<0), - SND_CTL_EXT_ACCESS_VOLATILE = (1<<2), - SND_CTL_EXT_ACCESS_INACTIVE = (1<<8), -} snd_ctl_ext_access_t; - -/** - * find_elem callback returns this if no matching control element is found - */ -#define SND_CTL_EXT_KEY_NOT_FOUND (snd_ctl_ext_key_t)(-1) - -int snd_ctl_ext_create(snd_ctl_ext_t *ext, const char *name, int mode); -int snd_ctl_ext_delete(snd_ctl_ext_t *ext); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_CONTROL_EXTERNAL_H */ diff --git a/shell/linux-deps/include/alsa/error.h b/shell/linux-deps/include/alsa/error.h deleted file mode 100644 index 6d27083b7..000000000 --- a/shell/linux-deps/include/alsa/error.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * \file include/error.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_ERROR_H -#define __ALSA_ERROR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Error Error handling - * Error handling macros and functions. - * \{ - */ - -#define SND_ERROR_BEGIN 500000 /**< Lower boundary of sound error codes. */ -#define SND_ERROR_INCOMPATIBLE_VERSION (SND_ERROR_BEGIN+0) /**< Kernel/library protocols are not compatible. */ -#define SND_ERROR_ALISP_NIL (SND_ERROR_BEGIN+1) /**< Lisp encountered an error during acall. */ - -const char *snd_strerror(int errnum); - -/** - * \brief Error handler callback. - * \param file Source file name. - * \param line Line number. - * \param function Function name. - * \param err Value of \c errno, or 0 if not relevant. - * \param fmt \c printf(3) format. - * \param ... \c printf(3) arguments. - * - * A function of this type is called by the ALSA library when an error occurs. - * This function usually shows the message on the screen, and/or logs it. - */ -typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */; -extern snd_lib_error_handler_t snd_lib_error; -extern int snd_lib_error_set_handler(snd_lib_error_handler_t handler); - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 95) -#define SNDERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, __VA_ARGS__) /**< Shows a sound error message. */ -#define SYSERR(...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, __VA_ARGS__) /**< Shows a system error message (related to \c errno). */ -#else -#define SNDERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, 0, ##args) /**< Shows a sound error message. */ -#define SYSERR(args...) snd_lib_error(__FILE__, __LINE__, __FUNCTION__, errno, ##args) /**< Shows a system error message (related to \c errno). */ -#endif - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_ERROR_H */ - diff --git a/shell/linux-deps/include/alsa/global.h b/shell/linux-deps/include/alsa/global.h deleted file mode 100644 index 3e3680fb6..000000000 --- a/shell/linux-deps/include/alsa/global.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * \file include/global.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_GLOBAL_H_ -#define __ALSA_GLOBAL_H_ - -/* for timeval and timespec */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Global Global defines and functions - * Global defines and functions. - * \par - * The ALSA library implementation uses these macros and functions. - * Most applications probably do not need them. - * \{ - */ - -const char *snd_asoundlib_version(void); - -#ifndef ATTRIBUTE_UNUSED -/** do not print warning (gcc) when function parameter is not used */ -#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -#ifdef PIC /* dynamic build */ - -/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */ -#define __SND_DLSYM_VERSION(name, version) _ ## name ## version -/** - * \hideinitializer - * \brief Appends the build version to the name of a versioned dynamic symbol. - */ -#define SND_DLSYM_BUILD_VERSION(name, version) char __SND_DLSYM_VERSION(name, version); - -#else /* static build */ - -struct snd_dlsym_link { - struct snd_dlsym_link *next; - const char *dlsym_name; - const void *dlsym_ptr; -}; - -extern struct snd_dlsym_link *snd_dlsym_start; - -/** \hideinitializer \brief Helper macro for #SND_DLSYM_BUILD_VERSION. */ -#define __SND_DLSYM_VERSION(prefix, name, version) _ ## prefix ## name ## version -/** - * \hideinitializer - * \brief Appends the build version to the name of a versioned dynamic symbol. - */ -#define SND_DLSYM_BUILD_VERSION(name, version) \ - static struct snd_dlsym_link __SND_DLSYM_VERSION(snd_dlsym_, name, version); \ - void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) __attribute__ ((constructor)); \ - void __SND_DLSYM_VERSION(snd_dlsym_constructor_, name, version) (void) { \ - __SND_DLSYM_VERSION(snd_dlsym_, name, version).next = snd_dlsym_start; \ - __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_name = # name; \ - __SND_DLSYM_VERSION(snd_dlsym_, name, version).dlsym_ptr = (void *)&name; \ - snd_dlsym_start = &__SND_DLSYM_VERSION(snd_dlsym_, name, version); \ - } - -#endif - -#ifndef __STRING -/** \brief Return 'x' argument as string */ -#define __STRING(x) #x -#endif - -/** \brief Returns the version of a dynamic symbol as a string. */ -#define SND_DLSYM_VERSION(version) __STRING(version) - -void *snd_dlopen(const char *file, int mode); -void *snd_dlsym(void *handle, const char *name, const char *version); -int snd_dlclose(void *handle); - - -/** \brief alloca helper macro. */ -#define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0) - -/** - * \brief Internal structure for an async notification client handler. - * - * The ALSA library uses a pointer to this structure as a handle to an async - * notification object. Applications don't access its contents directly. - */ -typedef struct _snd_async_handler snd_async_handler_t; - -/** - * \brief Async notification callback. - * - * See the #snd_async_add_handler function for details. - */ -typedef void (*snd_async_callback_t)(snd_async_handler_t *handler); - -int snd_async_add_handler(snd_async_handler_t **handler, int fd, - snd_async_callback_t callback, void *private_data); -int snd_async_del_handler(snd_async_handler_t *handler); -int snd_async_handler_get_fd(snd_async_handler_t *handler); -int snd_async_handler_get_signo(snd_async_handler_t *handler); -void *snd_async_handler_get_callback_private(snd_async_handler_t *handler); - -struct snd_shm_area *snd_shm_area_create(int shmid, void *ptr); -struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area); -int snd_shm_area_destroy(struct snd_shm_area *area); - -int snd_user_file(const char *file, char **result); - -#if !defined(_POSIX_C_SOURCE) && !defined(_POSIX_SOURCE) -struct timeval { - time_t tv_sec; /* seconds */ - long tv_usec; /* microseconds */ -}; - -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* nanoseconds */ -}; -#endif - -/** Timestamp */ -typedef struct timeval snd_timestamp_t; -/** Hi-res timestamp */ -typedef struct timespec snd_htimestamp_t; - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_GLOBAL_H */ diff --git a/shell/linux-deps/include/alsa/hwdep.h b/shell/linux-deps/include/alsa/hwdep.h deleted file mode 100644 index ab12822cf..000000000 --- a/shell/linux-deps/include/alsa/hwdep.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * \file include/hwdep.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_HWDEP_H -#define __ALSA_HWDEP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup HwDep Hardware Dependant Interface - * The Hardware Dependant Interface. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_HWDEP_DLSYM_VERSION _dlsym_hwdep_001 - -/** HwDep information container */ -typedef struct _snd_hwdep_info snd_hwdep_info_t; - -/** HwDep DSP status container */ -typedef struct _snd_hwdep_dsp_status snd_hwdep_dsp_status_t; - -/** HwDep DSP image container */ -typedef struct _snd_hwdep_dsp_image snd_hwdep_dsp_image_t; - -/** HwDep interface */ -typedef enum _snd_hwdep_iface { - SND_HWDEP_IFACE_OPL2 = 0, /**< OPL2 raw driver */ - SND_HWDEP_IFACE_OPL3, /**< OPL3 raw driver */ - SND_HWDEP_IFACE_OPL4, /**< OPL4 raw driver */ - SND_HWDEP_IFACE_SB16CSP, /**< SB16CSP driver */ - SND_HWDEP_IFACE_EMU10K1, /**< EMU10K1 driver */ - SND_HWDEP_IFACE_YSS225, /**< YSS225 driver */ - SND_HWDEP_IFACE_ICS2115, /**< ICS2115 driver */ - SND_HWDEP_IFACE_SSCAPE, /**< Ensoniq SoundScape ISA card (MC68EC000) */ - SND_HWDEP_IFACE_VX, /**< Digigram VX cards */ - SND_HWDEP_IFACE_MIXART, /**< Digigram miXart cards */ - SND_HWDEP_IFACE_USX2Y, /**< Tascam US122, US224 & US428 usb */ - SND_HWDEP_IFACE_EMUX_WAVETABLE, /**< EmuX wavetable */ - SND_HWDEP_IFACE_BLUETOOTH, /**< Bluetooth audio */ - SND_HWDEP_IFACE_USX2Y_PCM, /**< Tascam US122, US224 & US428 raw USB PCM */ - SND_HWDEP_IFACE_PCXHR, /**< Digigram PCXHR */ - SND_HWDEP_IFACE_SB_RC, /**< SB Extigy/Audigy2NX remote control */ - - SND_HWDEP_IFACE_LAST = SND_HWDEP_IFACE_SB_RC /**< last known hwdep interface */ -} snd_hwdep_iface_t; - -/** open for reading */ -#define SND_HWDEP_OPEN_READ (O_RDONLY) -/** open for writing */ -#define SND_HWDEP_OPEN_WRITE (O_WRONLY) -/** open for reading and writing */ -#define SND_HWDEP_OPEN_DUPLEX (O_RDWR) -/** open mode flag: open in nonblock mode */ -#define SND_HWDEP_OPEN_NONBLOCK (O_NONBLOCK) - -/** HwDep handle type */ -typedef enum _snd_hwdep_type { - /** Kernel level HwDep */ - SND_HWDEP_TYPE_HW, - /** Shared memory client HwDep (not yet implemented) */ - SND_HWDEP_TYPE_SHM, - /** INET client HwDep (not yet implemented) */ - SND_HWDEP_TYPE_INET -} snd_hwdep_type_t; - -/** HwDep handle */ -typedef struct _snd_hwdep snd_hwdep_t; - -int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode); -int snd_hwdep_close(snd_hwdep_t *hwdep); -int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space); -int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock); -int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info); -int snd_hwdep_dsp_status(snd_hwdep_t *hwdep, snd_hwdep_dsp_status_t *status); -int snd_hwdep_dsp_load(snd_hwdep_t *hwdep, snd_hwdep_dsp_image_t *block); -int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg); -ssize_t snd_hwdep_write(snd_hwdep_t *hwdep, const void *buffer, size_t size); -ssize_t snd_hwdep_read(snd_hwdep_t *hwdep, void *buffer, size_t size); - -size_t snd_hwdep_info_sizeof(void); -/** allocate #snd_hwdep_info_t container on stack */ -#define snd_hwdep_info_alloca(ptr) __snd_alloca(ptr, snd_hwdep_info) -int snd_hwdep_info_malloc(snd_hwdep_info_t **ptr); -void snd_hwdep_info_free(snd_hwdep_info_t *obj); -void snd_hwdep_info_copy(snd_hwdep_info_t *dst, const snd_hwdep_info_t *src); - -unsigned int snd_hwdep_info_get_device(const snd_hwdep_info_t *obj); -int snd_hwdep_info_get_card(const snd_hwdep_info_t *obj); -const char *snd_hwdep_info_get_id(const snd_hwdep_info_t *obj); -const char *snd_hwdep_info_get_name(const snd_hwdep_info_t *obj); -snd_hwdep_iface_t snd_hwdep_info_get_iface(const snd_hwdep_info_t *obj); -void snd_hwdep_info_set_device(snd_hwdep_info_t *obj, unsigned int val); - -size_t snd_hwdep_dsp_status_sizeof(void); -/** allocate #snd_hwdep_dsp_status_t container on stack */ -#define snd_hwdep_dsp_status_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_status) -int snd_hwdep_dsp_status_malloc(snd_hwdep_dsp_status_t **ptr); -void snd_hwdep_dsp_status_free(snd_hwdep_dsp_status_t *obj); -void snd_hwdep_dsp_status_copy(snd_hwdep_dsp_status_t *dst, const snd_hwdep_dsp_status_t *src); - -unsigned int snd_hwdep_dsp_status_get_version(const snd_hwdep_dsp_status_t *obj); -const char *snd_hwdep_dsp_status_get_id(const snd_hwdep_dsp_status_t *obj); -unsigned int snd_hwdep_dsp_status_get_num_dsps(const snd_hwdep_dsp_status_t *obj); -unsigned int snd_hwdep_dsp_status_get_dsp_loaded(const snd_hwdep_dsp_status_t *obj); -unsigned int snd_hwdep_dsp_status_get_chip_ready(const snd_hwdep_dsp_status_t *obj); - -size_t snd_hwdep_dsp_image_sizeof(void); -/** allocate #snd_hwdep_dsp_image_t container on stack */ -#define snd_hwdep_dsp_image_alloca(ptr) __snd_alloca(ptr, snd_hwdep_dsp_image) -int snd_hwdep_dsp_image_malloc(snd_hwdep_dsp_image_t **ptr); -void snd_hwdep_dsp_image_free(snd_hwdep_dsp_image_t *obj); -void snd_hwdep_dsp_image_copy(snd_hwdep_dsp_image_t *dst, const snd_hwdep_dsp_image_t *src); - -unsigned int snd_hwdep_dsp_image_get_index(const snd_hwdep_dsp_image_t *obj); -const char *snd_hwdep_dsp_image_get_name(const snd_hwdep_dsp_image_t *obj); -const void *snd_hwdep_dsp_image_get_image(const snd_hwdep_dsp_image_t *obj); -size_t snd_hwdep_dsp_image_get_length(const snd_hwdep_dsp_image_t *obj); - -void snd_hwdep_dsp_image_set_index(snd_hwdep_dsp_image_t *obj, unsigned int _index); -void snd_hwdep_dsp_image_set_name(snd_hwdep_dsp_image_t *obj, const char *name); -void snd_hwdep_dsp_image_set_image(snd_hwdep_dsp_image_t *obj, void *buffer); -void snd_hwdep_dsp_image_set_length(snd_hwdep_dsp_image_t *obj, size_t length); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_HWDEP_H */ - diff --git a/shell/linux-deps/include/alsa/iatomic.h b/shell/linux-deps/include/alsa/iatomic.h deleted file mode 100644 index e92dbfd4e..000000000 --- a/shell/linux-deps/include/alsa/iatomic.h +++ /dev/null @@ -1,1198 +0,0 @@ -#ifndef __ALSA_IATOMIC_H -#define __ALSA_IATOMIC_H - -#if defined(__i386__) || defined(__x86_64__) - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc.. - */ - -#define ATOMIC_SMP_LOCK "lock ; " - -/* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -/** - * atomic_read - read atomic variable - * @v: pointer of type atomic_t - * - * Atomically reads the value of @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_read(v) ((v)->counter) - -/** - * atomic_set - set atomic variable - * @v: pointer of type atomic_t - * @i: required value - * - * Atomically sets the value of @v to @i. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_set(v,i) (((v)->counter) = (i)) - -/** - * atomic_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. Note that the guaranteed useful range - * of an atomic_t is only 24 bits. - */ -static __inline__ void atomic_add(int i, atomic_t *v) -{ - __asm__ __volatile__( - ATOMIC_SMP_LOCK "addl %1,%0" - :"=m" (v->counter) - :"ir" (i), "m" (v->counter)); -} - -/** - * atomic_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ void atomic_sub(int i, atomic_t *v) -{ - __asm__ __volatile__( - ATOMIC_SMP_LOCK "subl %1,%0" - :"=m" (v->counter) - :"ir" (i), "m" (v->counter)); -} - -/** - * atomic_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v and returns - * true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ int atomic_sub_and_test(int i, atomic_t *v) -{ - unsigned char c; - - __asm__ __volatile__( - ATOMIC_SMP_LOCK "subl %2,%0; sete %1" - :"=m" (v->counter), "=qm" (c) - :"ir" (i), "m" (v->counter) : "memory"); - return c; -} - -/** - * atomic_inc - increment atomic variable - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ void atomic_inc(atomic_t *v) -{ - __asm__ __volatile__( - ATOMIC_SMP_LOCK "incl %0" - :"=m" (v->counter) - :"m" (v->counter)); -} - -/** - * atomic_dec - decrement atomic variable - * @v: pointer of type atomic_t - * - * Atomically decrements @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ void atomic_dec(atomic_t *v) -{ - __asm__ __volatile__( - ATOMIC_SMP_LOCK "decl %0" - :"=m" (v->counter) - :"m" (v->counter)); -} - -/** - * atomic_dec_and_test - decrement and test - * @v: pointer of type atomic_t - * - * Atomically decrements @v by 1 and - * returns true if the result is 0, or false for all other - * cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ int atomic_dec_and_test(atomic_t *v) -{ - unsigned char c; - - __asm__ __volatile__( - ATOMIC_SMP_LOCK "decl %0; sete %1" - :"=m" (v->counter), "=qm" (c) - :"m" (v->counter) : "memory"); - return c != 0; -} - -/** - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ int atomic_inc_and_test(atomic_t *v) -{ - unsigned char c; - - __asm__ __volatile__( - ATOMIC_SMP_LOCK "incl %0; sete %1" - :"=m" (v->counter), "=qm" (c) - :"m" (v->counter) : "memory"); - return c != 0; -} - -/** - * atomic_add_negative - add and test if negative - * @v: pointer of type atomic_t - * @i: integer value to add - * - * Atomically adds @i to @v and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ int atomic_add_negative(int i, atomic_t *v) -{ - unsigned char c; - - __asm__ __volatile__( - ATOMIC_SMP_LOCK "addl %2,%0; sets %1" - :"=m" (v->counter), "=qm" (c) - :"ir" (i), "m" (v->counter) : "memory"); - return c; -} - -/* These are x86-specific, used by some header files */ -#define atomic_clear_mask(mask, addr) \ -__asm__ __volatile__(ATOMIC_SMP_LOCK "andl %0,%1" \ -: : "r" (~(mask)),"m" (*addr) : "memory") - -#define atomic_set_mask(mask, addr) \ -__asm__ __volatile__(ATOMIC_SMP_LOCK "orl %0,%1" \ -: : "r" (mask),"m" (*addr) : "memory") - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - * - * For now, "wmb()" doesn't actually do anything, as all - * Intel CPU's follow what Intel calls a *Processor Order*, - * in which all writes are seen in the program order even - * outside the CPU. - * - * I expect future Intel CPU's to have a weaker ordering, - * but I'd also expect them to finally get their act together - * and add some real memory barriers if so. - */ - -#ifdef __i386__ -#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") -#define rmb() mb() -#define wmb() __asm__ __volatile__ ("": : :"memory") -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence":::"memory") -#endif - -#undef ATOMIC_SMP_LOCK - -#define IATOMIC_DEFINED 1 - -#endif /* __i386__ */ - -#ifdef __ia64__ - -/* - * On IA-64, counter must always be volatile to ensure that that the - * memory accesses are ordered. - */ -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) ((atomic_t) { (i) }) - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -/* stripped version - we need only 4byte version */ -#define ia64_cmpxchg(sem,ptr,old,new,size) \ -({ \ - __typeof__(ptr) _p_ = (ptr); \ - __typeof__(new) _n_ = (new); \ - unsigned long _o_, _r_; \ - _o_ = (unsigned int) (long) (old); \ - __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_)); \ - __asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv" \ - : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ - (__typeof__(old)) _r_; \ -}) - -static __inline__ int -ia64_atomic_add (int i, atomic_t *v) -{ - int old, new; - // CMPXCHG_BUGCHECK_DECL - - do { - // CMPXCHG_BUGCHECK(v); - old = atomic_read(v); - new = old + i; - } while (ia64_cmpxchg("acq", v, old, old + i, sizeof(atomic_t)) != old); - return new; -} - -static __inline__ int -ia64_atomic_sub (int i, atomic_t *v) -{ - int old, new; - // CMPXCHG_BUGCHECK_DECL - - do { - // CMPXCHG_BUGCHECK(v); - old = atomic_read(v); - new = old - i; - } while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old); - return new; -} - -#define IA64_FETCHADD(tmp,v,n,sz) \ -({ \ - switch (sz) { \ - case 4: \ - __asm__ __volatile__ ("fetchadd4.rel %0=[%1],%2" \ - : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ - break; \ - \ - case 8: \ - __asm__ __volatile__ ("fetchadd8.rel %0=[%1],%2" \ - : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ - break; \ - } \ -}) - -#define ia64_fetch_and_add(i,v) \ -({ \ - unsigned long _tmp; \ - volatile __typeof__(*(v)) *_v = (v); \ - switch (i) { \ - case -16: IA64_FETCHADD(_tmp, _v, -16, sizeof(*(v))); break; \ - case -8: IA64_FETCHADD(_tmp, _v, -8, sizeof(*(v))); break; \ - case -4: IA64_FETCHADD(_tmp, _v, -4, sizeof(*(v))); break; \ - case -1: IA64_FETCHADD(_tmp, _v, -1, sizeof(*(v))); break; \ - case 1: IA64_FETCHADD(_tmp, _v, 1, sizeof(*(v))); break; \ - case 4: IA64_FETCHADD(_tmp, _v, 4, sizeof(*(v))); break; \ - case 8: IA64_FETCHADD(_tmp, _v, 8, sizeof(*(v))); break; \ - case 16: IA64_FETCHADD(_tmp, _v, 16, sizeof(*(v))); break; \ - } \ - (__typeof__(*v)) (_tmp + (i)); /* return new value */ \ -}) - -/* - * Atomically add I to V and return TRUE if the resulting value is - * negative. - */ -static __inline__ int -atomic_add_negative (int i, atomic_t *v) -{ - return ia64_atomic_add(i, v) < 0; -} - -#define atomic_add_return(i,v) \ - ((__builtin_constant_p(i) && \ - ( (i == 1) || (i == 4) || (i == 8) || (i == 16) \ - || (i == -1) || (i == -4) || (i == -8) || (i == -16))) \ - ? ia64_fetch_and_add(i, &(v)->counter) \ - : ia64_atomic_add(i, v)) - -#define atomic_sub_return(i,v) \ - ((__builtin_constant_p(i) && \ - ( (i == 1) || (i == 4) || (i == 8) || (i == 16) \ - || (i == -1) || (i == -4) || (i == -8) || (i == -16))) \ - ? ia64_fetch_and_add(-(i), &(v)->counter) \ - : ia64_atomic_sub(i, v)) - -#define atomic_dec_return(v) atomic_sub_return(1, (v)) -#define atomic_inc_return(v) atomic_add_return(1, (v)) - -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) != 0) - -#define atomic_add(i,v) atomic_add_return((i), (v)) -#define atomic_sub(i,v) atomic_sub_return((i), (v)) -#define atomic_inc(v) atomic_add(1, (v)) -#define atomic_dec(v) atomic_sub(1, (v)) - -/* - * Macros to force memory ordering. In these descriptions, "previous" - * and "subsequent" refer to program order; "visible" means that all - * architecturally visible effects of a memory access have occurred - * (at a minimum, this means the memory has been read or written). - * - * wmb(): Guarantees that all preceding stores to memory- - * like regions are visible before any subsequent - * stores and that all following stores will be - * visible only after all previous stores. - * rmb(): Like wmb(), but for reads. - * mb(): wmb()/rmb() combo, i.e., all previous memory - * accesses are visible before all subsequent - * accesses and vice versa. This is also known as - * a "fence." - * - * Note: "mb()" and its variants cannot be used as a fence to order - * accesses to memory mapped I/O registers. For that, mf.a needs to - * be used. However, we don't want to always use mf.a because (a) - * it's (presumably) much slower than mf and (b) mf.a is supported for - * sequential memory pages only. - */ -#define mb() __asm__ __volatile__ ("mf" ::: "memory") -#define rmb() mb() -#define wmb() mb() - -#define IATOMIC_DEFINED 1 - -#endif /* __ia64__ */ - -#ifdef __alpha__ - -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc... - * - * But use these as seldom as possible since they are much slower - * than regular operations. - */ - - -/* - * Counter is volatile to make sure gcc doesn't try to be clever - * and move things around on us. We need to use _exactly_ the address - * the user gave us, not some alias that contains the same information. - */ -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) ((v)->counter = (i)) - -/* - * To get proper branch prediction for the main line, we must branch - * forward to code at the end of this object's .text section, then - * branch back to restart the operation. - */ - -static __inline__ void atomic_add(int i, atomic_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " addl %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); -} - -static __inline__ void atomic_sub(int i, atomic_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " subl %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); -} - -/* - * Same as above, but return the result value - */ -static __inline__ long atomic_add_return(int i, atomic_t * v) -{ - long temp, result; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " addl %0,%3,%2\n" - " addl %0,%3,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - " mb\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - return result; -} - -static __inline__ long atomic_sub_return(int i, atomic_t * v) -{ - long temp, result; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " subl %0,%3,%2\n" - " subl %0,%3,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - " mb\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - return result; -} - -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) - -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) - -#define atomic_inc(v) atomic_add(1,(v)) -#define atomic_dec(v) atomic_sub(1,(v)) - -#define mb() \ -__asm__ __volatile__("mb": : :"memory") - -#define rmb() \ -__asm__ __volatile__("mb": : :"memory") - -#define wmb() \ -__asm__ __volatile__("wmb": : :"memory") - -#define IATOMIC_DEFINED 1 - -#endif /* __alpha__ */ - -#ifdef __powerpc__ - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); -extern void atomic_set_mask(unsigned long mask, unsigned long *addr); - -#define SMP_ISYNC "\n\tisync" - -static __inline__ void atomic_add(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_add_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_sub(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_sub_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_inc(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_inc\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_inc_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_dec(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_dec\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_dec_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) - -/* - * Atomically test *v and decrement if it is greater than 0. - * The function returns the old value of *v minus 1. - */ -static __inline__ int atomic_dec_if_positive(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ - addic. %0,%0,-1\n\ - blt- 2f\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - SMP_ISYNC - "\n\ -2:" : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -/* - * Memory barrier. - * The sync instruction guarantees that all memory accesses initiated - * by this processor have been performed (with respect to all other - * mechanisms that access memory). The eieio instruction is a barrier - * providing an ordering (separately) for (a) cacheable stores and (b) - * loads and stores to non-cacheable memory (e.g. I/O devices). - * - * mb() prevents loads and stores being reordered across this point. - * rmb() prevents loads being reordered across this point. - * wmb() prevents stores being reordered across this point. - * - * We can use the eieio instruction for wmb, but since it doesn't - * give any ordering guarantees about loads, we have to use the - * stronger but slower sync instruction for mb and rmb. - */ -#define mb() __asm__ __volatile__ ("sync" : : : "memory") -#define rmb() __asm__ __volatile__ ("sync" : : : "memory") -#define wmb() __asm__ __volatile__ ("eieio" : : : "memory") - -#define IATOMIC_DEFINED 1 - -#endif /* __powerpc__ */ - -#ifdef __mips__ - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -/* - * atomic_read - read atomic variable - * @v: pointer of type atomic_t - * - * Atomically reads the value of @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_read(v) ((v)->counter) - -/* - * atomic_set - set atomic variable - * @v: pointer of type atomic_t - * @i: required value - * - * Atomically sets the value of @v to @i. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_set(v,i) ((v)->counter = (i)) - -/* - * for MIPS II and better we can use ll/sc instruction, and kernel 2.4.3+ - * will emulate it on MIPS I. - */ - -/* - * atomic_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. Note that the guaranteed useful range - * of an atomic_t is only 24 bits. - */ -extern __inline__ void atomic_add(int i, atomic_t * v) -{ - unsigned long temp; - - __asm__ __volatile__( - ".set push \n" - ".set mips2 \n" - "1: ll %0, %1 # atomic_add\n" - " addu %0, %2 \n" - " sc %0, %1 \n" - " beqz %0, 1b \n" - ".set pop \n" - : "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter)); -} - -/* - * atomic_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -extern __inline__ void atomic_sub(int i, atomic_t * v) -{ - unsigned long temp; - - __asm__ __volatile__( - ".set push \n" - ".set mips2 \n" - "1: ll %0, %1 # atomic_sub\n" - " subu %0, %2 \n" - " sc %0, %1 \n" - " beqz %0, 1b \n" - ".set pop \n" - : "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter)); -} - -/* - * Same as above, but return the result value - */ -extern __inline__ int atomic_add_return(int i, atomic_t * v) -{ - unsigned long temp, result; - - __asm__ __volatile__( - ".set push # atomic_add_return\n" - ".set noreorder \n" - ".set mips2 \n" - "1: ll %1, %2 \n" - " addu %0, %1, %3 \n" - " sc %0, %2 \n" - " beqz %0, 1b \n" - " addu %0, %1, %3 \n" - ".set pop \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - - return result; -} - -extern __inline__ int atomic_sub_return(int i, atomic_t * v) -{ - unsigned long temp, result; - - __asm__ __volatile__( - ".set push \n" - ".set mips2 \n" - ".set noreorder # atomic_sub_return\n" - "1: ll %1, %2 \n" - " subu %0, %1, %3 \n" - " sc %0, %2 \n" - " beqz %0, 1b \n" - " subu %0, %1, %3 \n" - ".set pop \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - - return result; -} - -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) - -/* - * atomic_sub_and_test - subtract value from variable and test result - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v and returns - * true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_inc_and_test(v) (atomic_inc_return(1, (v)) == 0) - -/* - * atomic_dec_and_test - decrement by 1 and test - * @v: pointer of type atomic_t - * - * Atomically decrements @v by 1 and - * returns true if the result is 0, or false for all other - * cases. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) - -/* - * atomic_inc - increment atomic variable - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_inc(v) atomic_add(1,(v)) - -/* - * atomic_dec - decrement and test - * @v: pointer of type atomic_t - * - * Atomically decrements @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -#define atomic_dec(v) atomic_sub(1,(v)) - -/* - * atomic_add_negative - add and test if negative - * @v: pointer of type atomic_t - * @i: integer value to add - * - * Atomically adds @i to @v and returns true - * if the result is negative, or false when - * result is greater than or equal to zero. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - * - * Currently not implemented for MIPS. - */ - -#define mb() \ -__asm__ __volatile__( \ - "# prevent instructions being moved around\n\t" \ - ".set\tnoreorder\n\t" \ - "# 8 nops to fool the R4400 pipeline\n\t" \ - "nop;nop;nop;nop;nop;nop;nop;nop\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#define rmb() mb() -#define wmb() mb() - -#define IATOMIC_DEFINED 1 - -#endif /* __mips__ */ - -#ifdef __arm__ - -/* - * FIXME: bellow code is valid only for SA11xx - */ - -/* - * Save the current interrupt enable state & disable IRQs - */ -#define local_irq_save(x) \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ -" orr %1, %0, #128\n" \ -" msr cpsr_c, %1" \ - : "=r" (x), "=r" (temp) \ - : \ - : "memory"); \ - }) - -/* - * restore saved IRQ & FIQ state - */ -#define local_irq_restore(x) \ - __asm__ __volatile__( \ - "msr cpsr_c, %0 @ local_irq_restore\n" \ - : \ - : "r" (x) \ - : "memory") - -#define __save_flags_cli(x) local_irq_save(x) -#define __restore_flags(x) local_irq_restore(x) - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -static __inline__ void atomic_add(int i, volatile atomic_t *v) -{ - unsigned long flags; - - __save_flags_cli(flags); - v->counter += i; - __restore_flags(flags); -} - -static __inline__ void atomic_sub(int i, volatile atomic_t *v) -{ - unsigned long flags; - - __save_flags_cli(flags); - v->counter -= i; - __restore_flags(flags); -} - -static __inline__ void atomic_inc(volatile atomic_t *v) -{ - unsigned long flags; - - __save_flags_cli(flags); - v->counter += 1; - __restore_flags(flags); -} - -static __inline__ void atomic_dec(volatile atomic_t *v) -{ - unsigned long flags; - - __save_flags_cli(flags); - v->counter -= 1; - __restore_flags(flags); -} - -static __inline__ int atomic_dec_and_test(volatile atomic_t *v) -{ - unsigned long flags; - int result; - - __save_flags_cli(flags); - v->counter -= 1; - result = (v->counter == 0); - __restore_flags(flags); - - return result; -} - -static inline int atomic_add_negative(int i, volatile atomic_t *v) -{ - unsigned long flags; - int result; - - __save_flags_cli(flags); - v->counter += i; - result = (v->counter < 0); - __restore_flags(flags); - - return result; -} - -static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long flags; - - __save_flags_cli(flags); - *addr &= ~mask; - __restore_flags(flags); -} - -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() - -#define IATOMIC_DEFINED 1 - -#endif /* __arm__ */ - -#ifdef __sh__ - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -#define atomic_dec_return(v) atomic_sub_return(1,(v)) -#define atomic_inc_return(v) atomic_add_return(1,(v)) - -#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) != 0) - -#define atomic_add(i,v) atomic_add_return((i),(v)) -#define atomic_sub(i,v) atomic_sub_return((i),(v)) -#define atomic_inc(v) atomic_add(1,(v)) -#define atomic_dec(v) atomic_sub(1,(v)) - -static __inline__ int atomic_add_return(int i, volatile atomic_t *v) -{ - int result; - - asm volatile ( - " .align 2\n" - " mova 99f, r0\n" - " mov r15, r1\n" - " mov #-6, r15\n" - " mov.l @%2, %0\n" - " add %1, %0\n" - " mov.l %0, @%2\n" - "99: mov r1, r15" - : "=&r"(result) - : "r"(i), "r"(v) - : "r0", "r1"); - - return result; -} - -static __inline__ int atomic_sub_return(int i, volatile atomic_t *v) -{ - int result; - - asm volatile ( - " .align 2\n" - " mova 99f, r0\n" - " mov r15, r1\n" - " mov #-6, r15\n" - " mov.l @%2, %0\n" - " sub %1, %0\n" - " mov.l %0, @%2\n" - "99: mov r1, r15" - : "=&r"(result) - : "r"(i), "r"(v) - : "r0", "r1"); - - return result; -} - -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() - -#define IATOMIC_DEFINED 1 - -#endif /* __sh__ */ - -#ifdef __bfin__ - -#include - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) -#define atomic_add(i,v) bfin_atomic_add32(&(v)->counter, i) -#define atomic_sub(i,v) bfin_atomic_sub32(&(v)->counter, i) -#define atomic_inc(v) bfin_atomic_inc32(&(v)->counter); -#define atomic_dec(v) bfin_atomic_dec32(&(v)->counter); - -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() - -#define IATOMIC_DEFINED 1 - -#endif /* __bfin__ */ - -#ifndef IATOMIC_DEFINED -/* - * non supported architecture. - */ -#warning "Atomic operations are not supported on this architecture." - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) -#define atomic_add(i,v) (((v)->counter) += (i)) -#define atomic_sub(i,v) (((v)->counter) -= (i)) -#define atomic_inc(v) (((v)->counter)++) -#define atomic_dec(v) (((v)->counter)--) - -#define mb() -#define rmb() -#define wmb() - -#define IATOMIC_DEFINED 1 - -#endif /* IATOMIC_DEFINED */ - -/* - * Atomic read/write - * Copyright (c) 2001 by Abramo Bagnara - */ - -/* Max number of times we must spin on a spin-lock calling sched_yield(). - After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */ - -#ifndef MAX_SPIN_COUNT -#define MAX_SPIN_COUNT 50 -#endif - -/* Duration of sleep (in nanoseconds) when we can't acquire a spin-lock - after MAX_SPIN_COUNT iterations of sched_yield(). - This MUST BE > 2ms. - (Otherwise the kernel does busy-waiting for real-time threads, - giving other threads no chance to run.) */ - -#ifndef SPIN_SLEEP_DURATION -#define SPIN_SLEEP_DURATION 2000001 -#endif - -typedef struct { - unsigned int begin, end; -} snd_atomic_write_t; - -typedef struct { - volatile const snd_atomic_write_t *write; - unsigned int end; -} snd_atomic_read_t; - -void snd_atomic_read_wait(snd_atomic_read_t *t); - -static inline void snd_atomic_write_init(snd_atomic_write_t *w) -{ - w->begin = 0; - w->end = 0; -} - -static inline void snd_atomic_write_begin(snd_atomic_write_t *w) -{ - w->begin++; - wmb(); -} - -static inline void snd_atomic_write_end(snd_atomic_write_t *w) -{ - wmb(); - w->end++; -} - -static inline void snd_atomic_read_init(snd_atomic_read_t *r, snd_atomic_write_t *w) -{ - r->write = w; -} - -static inline void snd_atomic_read_begin(snd_atomic_read_t *r) -{ - r->end = r->write->end; - rmb(); -} - -static inline int snd_atomic_read_ok(snd_atomic_read_t *r) -{ - rmb(); - return r->end == r->write->begin; -} - -#endif /* __ALSA_IATOMIC_H */ diff --git a/shell/linux-deps/include/alsa/input.h b/shell/linux-deps/include/alsa/input.h deleted file mode 100644 index fc5d0e677..000000000 --- a/shell/linux-deps/include/alsa/input.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * \file include/input.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_INPUT_H -#define __ALSA_INPUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Input Input Interface - * - * The input functions present an interface similar to the stdio functions - * on top of different underlying input sources. - * - * The #snd_config_load function uses such an input handle to be able to - * load configurations not only from standard files but also from other - * sources, e.g. from memory buffers. - * - * \{ - */ - -/** - * \brief Internal structure for an input object. - * - * The ALSA library uses a pointer to this structure as a handle to an - * input object. Applications don't access its contents directly. - */ -typedef struct _snd_input snd_input_t; - -/** Input type. */ -typedef enum _snd_input_type { - /** Input from a stdio stream. */ - SND_INPUT_STDIO, - /** Input from a memory buffer. */ - SND_INPUT_BUFFER -} snd_input_type_t; - -int snd_input_stdio_open(snd_input_t **inputp, const char *file, const char *mode); -int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int _close); -int snd_input_buffer_open(snd_input_t **inputp, const char *buffer, ssize_t size); -int snd_input_close(snd_input_t *input); -int snd_input_scanf(snd_input_t *input, const char *format, ...) -#ifndef DOC_HIDDEN - __attribute__ ((format (scanf, 2, 3))) -#endif - ; -char *snd_input_gets(snd_input_t *input, char *str, size_t size); -int snd_input_getc(snd_input_t *input); -int snd_input_ungetc(snd_input_t *input, int c); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_INPUT_H */ diff --git a/shell/linux-deps/include/alsa/mixer.h b/shell/linux-deps/include/alsa/mixer.h deleted file mode 100644 index 58256a633..000000000 --- a/shell/linux-deps/include/alsa/mixer.h +++ /dev/null @@ -1,317 +0,0 @@ -/** - * \file include/mixer.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_MIXER_H -#define __ALSA_MIXER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Mixer Mixer Interface - * The mixer interface. - * \{ - */ - -/** Mixer handle */ -typedef struct _snd_mixer snd_mixer_t; -/** Mixer elements class handle */ -typedef struct _snd_mixer_class snd_mixer_class_t; -/** Mixer element handle */ -typedef struct _snd_mixer_elem snd_mixer_elem_t; - -/** - * \brief Mixer callback function - * \param mixer Mixer handle - * \param mask event mask - * \param elem related mixer element (if any) - * \return 0 on success otherwise a negative error code - */ -typedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl, - unsigned int mask, - snd_mixer_elem_t *elem); - -/** - * \brief Mixer element callback function - * \param elem Mixer element - * \param mask event mask - * \return 0 on success otherwise a negative error code - */ -typedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem, - unsigned int mask); - -/** - * \brief Compare function for sorting mixer elements - * \param e1 First element - * \param e2 Second element - * \return -1 if e1 < e2, 0 if e1 == e2, 1 if e1 > e2 - */ -typedef int (*snd_mixer_compare_t)(const snd_mixer_elem_t *e1, - const snd_mixer_elem_t *e2); - -/** - * \brief Event callback for the mixer class - * \param class_ Mixer class - * \param mask Event mask (SND_CTL_EVENT_*) - * \param helem HCTL element which invoked the event - * \param melem Mixer element associated to HCTL element - * \return zero if success, otherwise a negative error value - */ -typedef int (*snd_mixer_event_t)(snd_mixer_class_t *class_, unsigned int mask, - snd_hctl_elem_t *helem, snd_mixer_elem_t *melem); - - -/** Mixer element type */ -typedef enum _snd_mixer_elem_type { - /* Simple mixer elements */ - SND_MIXER_ELEM_SIMPLE, - SND_MIXER_ELEM_LAST = SND_MIXER_ELEM_SIMPLE -} snd_mixer_elem_type_t; - -int snd_mixer_open(snd_mixer_t **mixer, int mode); -int snd_mixer_close(snd_mixer_t *mixer); -snd_mixer_elem_t *snd_mixer_first_elem(snd_mixer_t *mixer); -snd_mixer_elem_t *snd_mixer_last_elem(snd_mixer_t *mixer); -int snd_mixer_handle_events(snd_mixer_t *mixer); -int snd_mixer_attach(snd_mixer_t *mixer, const char *name); -int snd_mixer_attach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl); -int snd_mixer_detach(snd_mixer_t *mixer, const char *name); -int snd_mixer_detach_hctl(snd_mixer_t *mixer, snd_hctl_t *hctl); -int snd_mixer_get_hctl(snd_mixer_t *mixer, const char *name, snd_hctl_t **hctl); -int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer); -int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space); -int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_mixer_load(snd_mixer_t *mixer); -void snd_mixer_free(snd_mixer_t *mixer); -int snd_mixer_wait(snd_mixer_t *mixer, int timeout); -int snd_mixer_set_compare(snd_mixer_t *mixer, snd_mixer_compare_t msort); -void snd_mixer_set_callback(snd_mixer_t *obj, snd_mixer_callback_t val); -void * snd_mixer_get_callback_private(const snd_mixer_t *obj); -void snd_mixer_set_callback_private(snd_mixer_t *obj, void * val); -unsigned int snd_mixer_get_count(const snd_mixer_t *obj); -int snd_mixer_class_unregister(snd_mixer_class_t *clss); - -snd_mixer_elem_t *snd_mixer_elem_next(snd_mixer_elem_t *elem); -snd_mixer_elem_t *snd_mixer_elem_prev(snd_mixer_elem_t *elem); -void snd_mixer_elem_set_callback(snd_mixer_elem_t *obj, snd_mixer_elem_callback_t val); -void * snd_mixer_elem_get_callback_private(const snd_mixer_elem_t *obj); -void snd_mixer_elem_set_callback_private(snd_mixer_elem_t *obj, void * val); -snd_mixer_elem_type_t snd_mixer_elem_get_type(const snd_mixer_elem_t *obj); - -int snd_mixer_class_register(snd_mixer_class_t *class_, snd_mixer_t *mixer); -int snd_mixer_elem_new(snd_mixer_elem_t **elem, - snd_mixer_elem_type_t type, - int compare_weight, - void *private_data, - void (*private_free)(snd_mixer_elem_t *elem)); -int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class_); -int snd_mixer_elem_remove(snd_mixer_elem_t *elem); -void snd_mixer_elem_free(snd_mixer_elem_t *elem); -int snd_mixer_elem_info(snd_mixer_elem_t *elem); -int snd_mixer_elem_value(snd_mixer_elem_t *elem); -int snd_mixer_elem_attach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem); -int snd_mixer_elem_detach(snd_mixer_elem_t *melem, snd_hctl_elem_t *helem); -int snd_mixer_elem_empty(snd_mixer_elem_t *melem); -void *snd_mixer_elem_get_private(const snd_mixer_elem_t *melem); - -size_t snd_mixer_class_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_mixer_class_t using standard alloca - * \param ptr returned pointer - */ -#define snd_mixer_class_alloca(ptr) __snd_alloca(ptr, snd_mixer_class) -int snd_mixer_class_malloc(snd_mixer_class_t **ptr); -void snd_mixer_class_free(snd_mixer_class_t *obj); -void snd_mixer_class_copy(snd_mixer_class_t *dst, const snd_mixer_class_t *src); -snd_mixer_t *snd_mixer_class_get_mixer(const snd_mixer_class_t *class_); -snd_mixer_event_t snd_mixer_class_get_event(const snd_mixer_class_t *class_); -void *snd_mixer_class_get_private(const snd_mixer_class_t *class_); -snd_mixer_compare_t snd_mixer_class_get_compare(const snd_mixer_class_t *class_); -int snd_mixer_class_set_event(snd_mixer_class_t *class_, snd_mixer_event_t event); -int snd_mixer_class_set_private(snd_mixer_class_t *class_, void *private_data); -int snd_mixer_class_set_private_free(snd_mixer_class_t *class_, void (*private_free)(snd_mixer_class_t *class_)); -int snd_mixer_class_set_compare(snd_mixer_class_t *class_, snd_mixer_compare_t compare); - -/** - * \defgroup SimpleMixer Simple Mixer Interface - * \ingroup Mixer - * The simple mixer interface. - * \{ - */ - -/* Simple mixer elements API */ - -/** Mixer simple element channel identifier */ -typedef enum _snd_mixer_selem_channel_id { - /** Unknown */ - SND_MIXER_SCHN_UNKNOWN = -1, - /** Front left */ - SND_MIXER_SCHN_FRONT_LEFT = 0, - /** Front right */ - SND_MIXER_SCHN_FRONT_RIGHT, - /** Rear left */ - SND_MIXER_SCHN_REAR_LEFT, - /** Rear right */ - SND_MIXER_SCHN_REAR_RIGHT, - /** Front center */ - SND_MIXER_SCHN_FRONT_CENTER, - /** Woofer */ - SND_MIXER_SCHN_WOOFER, - /** Side Left */ - SND_MIXER_SCHN_SIDE_LEFT, - /** Side Right */ - SND_MIXER_SCHN_SIDE_RIGHT, - /** Rear Center */ - SND_MIXER_SCHN_REAR_CENTER, - SND_MIXER_SCHN_LAST = 31, - /** Mono (Front left alias) */ - SND_MIXER_SCHN_MONO = SND_MIXER_SCHN_FRONT_LEFT -} snd_mixer_selem_channel_id_t; - -/** Mixer simple element - register options - abstraction level */ -enum snd_mixer_selem_regopt_abstract { - /** no abstraction - try use all universal controls from driver */ - SND_MIXER_SABSTRACT_NONE = 0, - /** basic abstraction - Master,PCM,CD,Aux,Record-Gain etc. */ - SND_MIXER_SABSTRACT_BASIC, -}; - -/** Mixer simple element - register options */ -struct snd_mixer_selem_regopt { - /** structure version */ - int ver; - /** v1: abstract layer selection */ - enum snd_mixer_selem_regopt_abstract abstract; - /** v1: device name (must be NULL when playback_pcm or capture_pcm != NULL) */ - const char *device; - /** v1: playback PCM connected to mixer device (NULL == none) */ - snd_pcm_t *playback_pcm; - /** v1: capture PCM connected to mixer device (NULL == none) */ - snd_pcm_t *capture_pcm; -}; - -/** Mixer simple element identifier */ -typedef struct _snd_mixer_selem_id snd_mixer_selem_id_t; - -const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel); - -int snd_mixer_selem_register(snd_mixer_t *mixer, - struct snd_mixer_selem_regopt *options, - snd_mixer_class_t **classp); -void snd_mixer_selem_get_id(snd_mixer_elem_t *element, - snd_mixer_selem_id_t *id); -const char *snd_mixer_selem_get_name(snd_mixer_elem_t *elem); -unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem); -snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, - const snd_mixer_selem_id_t *id); - -int snd_mixer_selem_is_active(snd_mixer_elem_t *elem); -int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel); -int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel); -int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_common_volume(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_playback_volume_joined(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_volume_joined(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_common_switch(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_switch_joined(snd_mixer_elem_t *elem); -int snd_mixer_selem_has_capture_switch_exclusive(snd_mixer_elem_t *elem); - -int snd_mixer_selem_ask_playback_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue); -int snd_mixer_selem_ask_capture_vol_dB(snd_mixer_elem_t *elem, long value, long *dBvalue); -int snd_mixer_selem_ask_playback_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value); -int snd_mixer_selem_ask_capture_dB_vol(snd_mixer_elem_t *elem, long dBvalue, int dir, long *value); -int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); -int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); -int snd_mixer_selem_get_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); -int snd_mixer_selem_get_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value); -int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value); -int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value); -int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value); -int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value); -int snd_mixer_selem_set_playback_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir); -int snd_mixer_selem_set_capture_dB(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long value, int dir); -int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value); -int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value); -int snd_mixer_selem_set_playback_dB_all(snd_mixer_elem_t *elem, long value, int dir); -int snd_mixer_selem_set_capture_dB_all(snd_mixer_elem_t *elem, long value, int dir); -int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value); -int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int value); -int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value); -int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value); -int snd_mixer_selem_get_playback_volume_range(snd_mixer_elem_t *elem, - long *min, long *max); -int snd_mixer_selem_get_playback_dB_range(snd_mixer_elem_t *elem, - long *min, long *max); -int snd_mixer_selem_set_playback_volume_range(snd_mixer_elem_t *elem, - long min, long max); -int snd_mixer_selem_get_capture_volume_range(snd_mixer_elem_t *elem, - long *min, long *max); -int snd_mixer_selem_get_capture_dB_range(snd_mixer_elem_t *elem, - long *min, long *max); -int snd_mixer_selem_set_capture_volume_range(snd_mixer_elem_t *elem, - long min, long max); - -int snd_mixer_selem_is_enumerated(snd_mixer_elem_t *elem); -int snd_mixer_selem_is_enum_playback(snd_mixer_elem_t *elem); -int snd_mixer_selem_is_enum_capture(snd_mixer_elem_t *elem); -int snd_mixer_selem_get_enum_items(snd_mixer_elem_t *elem); -int snd_mixer_selem_get_enum_item_name(snd_mixer_elem_t *elem, unsigned int idx, size_t maxlen, char *str); -int snd_mixer_selem_get_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *idxp); -int snd_mixer_selem_set_enum_item(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int idx); - -size_t snd_mixer_selem_id_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_mixer_selem_id_t using standard alloca - * \param ptr returned pointer - */ -#define snd_mixer_selem_id_alloca(ptr) __snd_alloca(ptr, snd_mixer_selem_id) -int snd_mixer_selem_id_malloc(snd_mixer_selem_id_t **ptr); -void snd_mixer_selem_id_free(snd_mixer_selem_id_t *obj); -void snd_mixer_selem_id_copy(snd_mixer_selem_id_t *dst, const snd_mixer_selem_id_t *src); -const char *snd_mixer_selem_id_get_name(const snd_mixer_selem_id_t *obj); -unsigned int snd_mixer_selem_id_get_index(const snd_mixer_selem_id_t *obj); -void snd_mixer_selem_id_set_name(snd_mixer_selem_id_t *obj, const char *val); -void snd_mixer_selem_id_set_index(snd_mixer_selem_id_t *obj, unsigned int val); - -/** \} */ - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_MIXER_H */ - diff --git a/shell/linux-deps/include/alsa/mixer_abst.h b/shell/linux-deps/include/alsa/mixer_abst.h deleted file mode 100644 index 7844b1910..000000000 --- a/shell/linux-deps/include/alsa/mixer_abst.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * \file include/mixer_abst.h - * \brief Mixer abstract implementation interface library for the ALSA library - * \author Jaroslav Kysela - * \date 2005 - * - * Mixer abstact implementation interface library for the ALSA library - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_MIXER_ABST_H -#define __ALSA_MIXER_ABST_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Mixer_Abstract Mixer Abstact Module Interface - * The mixer abstact module interface. - * \{ - */ - -#define SM_PLAY 0 -#define SM_CAPT 1 - -#define SM_CAP_GVOLUME (1<<1) -#define SM_CAP_GSWITCH (1<<2) -#define SM_CAP_PVOLUME (1<<3) -#define SM_CAP_PVOLUME_JOIN (1<<4) -#define SM_CAP_PSWITCH (1<<5) -#define SM_CAP_PSWITCH_JOIN (1<<6) -#define SM_CAP_CVOLUME (1<<7) -#define SM_CAP_CVOLUME_JOIN (1<<8) -#define SM_CAP_CSWITCH (1<<9) -#define SM_CAP_CSWITCH_JOIN (1<<10) -#define SM_CAP_CSWITCH_EXCL (1<<11) -#define SM_CAP_PENUM (1<<12) -#define SM_CAP_CENUM (1<<13) -/* SM_CAP_* 24-31 => private for module use */ - -#define SM_OPS_IS_ACTIVE 0 -#define SM_OPS_IS_MONO 1 -#define SM_OPS_IS_CHANNEL 2 -#define SM_OPS_IS_ENUMERATED 3 -#define SM_OPS_IS_ENUMCNT 4 - -#define sm_selem(x) ((sm_selem_t *)((x)->private_data)) -#define sm_selem_ops(x) ((sm_selem_t *)((x)->private_data))->ops - -typedef struct _sm_selem { - snd_mixer_selem_id_t *id; - struct sm_elem_ops *ops; - unsigned int caps; - unsigned int capture_group; -} sm_selem_t; - -typedef struct _sm_class_basic { - char *device; - snd_ctl_t *ctl; - snd_hctl_t *hctl; - snd_ctl_card_info_t *info; -} sm_class_basic_t; - -struct sm_elem_ops { - int (*is)(snd_mixer_elem_t *elem, int dir, int cmd, int val); - int (*get_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); - int (*set_range)(snd_mixer_elem_t *elem, int dir, long min, long max); - int (*get_dB_range)(snd_mixer_elem_t *elem, int dir, long *min, long *max); - int (*ask_vol_dB)(snd_mixer_elem_t *elem, int dir, long value, long *dbValue); - int (*ask_dB_vol)(snd_mixer_elem_t *elem, int dir, long dbValue, long *value, int xdir); - int (*get_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); - int (*get_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long *value); - int (*set_volume)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value); - int (*set_dB)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, long value, int xdir); - int (*get_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int *value); - int (*set_switch)(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value); - int (*enum_item_name)(snd_mixer_elem_t *elem, unsigned int item, size_t maxlen, char *buf); - int (*get_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int *itemp); - int (*set_enum_item)(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, unsigned int item); -}; - -int snd_mixer_selem_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2); - -int snd_mixer_sbasic_info(const snd_mixer_class_t *class, sm_class_basic_t *info); -void *snd_mixer_sbasic_get_private(const snd_mixer_class_t *class); -void snd_mixer_sbasic_set_private(const snd_mixer_class_t *class, void *private_data); -void snd_mixer_sbasic_set_private_free(const snd_mixer_class_t *class, void (*private_free)(snd_mixer_class_t *class)); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_MIXER_ABST_H */ - diff --git a/shell/linux-deps/include/alsa/output.h b/shell/linux-deps/include/alsa/output.h deleted file mode 100644 index 5279aa2ed..000000000 --- a/shell/linux-deps/include/alsa/output.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * \file include/output.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_OUTPUT_H -#define __ALSA_OUTPUT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Output Output Interface - * - * The output functions present an interface similar to the stdio functions - * on top of different underlying output destinations. - * - * Many PCM debugging functions (\c snd_pcm_xxx_dump_xxx) use such an output - * handle to be able to write not only to the screen but also to other - * destinations, e.g. to files or to memory buffers. - * - * \{ - */ - -/** - * \brief Internal structure for an output object. - * - * The ALSA library uses a pointer to this structure as a handle to an - * output object. Applications don't access its contents directly. - */ -typedef struct _snd_output snd_output_t; - -/** Output type. */ -typedef enum _snd_output_type { - /** Output to a stdio stream. */ - SND_OUTPUT_STDIO, - /** Output to a memory buffer. */ - SND_OUTPUT_BUFFER -} snd_output_type_t; - -int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode); -int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close); -int snd_output_buffer_open(snd_output_t **outputp); -size_t snd_output_buffer_string(snd_output_t *output, char **buf); -int snd_output_close(snd_output_t *output); -int snd_output_printf(snd_output_t *output, const char *format, ...) -#ifndef DOC_HIDDEN - __attribute__ ((format (printf, 2, 3))) -#endif - ; -int snd_output_vprintf(snd_output_t *output, const char *format, va_list args); -int snd_output_puts(snd_output_t *output, const char *str); -int snd_output_putc(snd_output_t *output, int c); -int snd_output_flush(snd_output_t *output); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_OUTPUT_H */ - diff --git a/shell/linux-deps/include/alsa/pcm.h b/shell/linux-deps/include/alsa/pcm.h deleted file mode 100644 index 499755709..000000000 --- a/shell/linux-deps/include/alsa/pcm.h +++ /dev/null @@ -1,1160 +0,0 @@ -/** - * \file include/pcm.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver. - * See the \ref pcm page for more details. - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_H -#define __ALSA_PCM_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup PCM PCM Interface - * See the \ref pcm page for more details. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_PCM_DLSYM_VERSION _dlsym_pcm_001 - -/** PCM generic info container */ -typedef struct _snd_pcm_info snd_pcm_info_t; - -/** PCM hardware configuration space container - * - * snd_pcm_hw_params_t is an opaque structure which contains a set of possible - * PCM hardware configurations. For example, a given instance might include a - * range of buffer sizes, a range of period sizes, and a set of several sample - * formats. Some subset of all possible combinations these sets may be valid, - * but not necessarily any combination will be valid. - * - * When a parameter is set or restricted using a snd_pcm_hw_params_set* - * function, all of the other ranges will be updated to exclude as many - * impossible configurations as possible. Attempting to set a parameter - * outside of its acceptable range will result in the function failing - * and an error code being returned. - */ -typedef struct _snd_pcm_hw_params snd_pcm_hw_params_t; - -/** PCM software configuration container */ -typedef struct _snd_pcm_sw_params snd_pcm_sw_params_t; -/** PCM status container */ - typedef struct _snd_pcm_status snd_pcm_status_t; -/** PCM access types mask */ -typedef struct _snd_pcm_access_mask snd_pcm_access_mask_t; -/** PCM formats mask */ -typedef struct _snd_pcm_format_mask snd_pcm_format_mask_t; -/** PCM subformats mask */ -typedef struct _snd_pcm_subformat_mask snd_pcm_subformat_mask_t; - -/** PCM class */ -typedef enum _snd_pcm_class { - /** standard device */ - - SND_PCM_CLASS_GENERIC = 0, - /** multichannel device */ - SND_PCM_CLASS_MULTI, - /** software modem device */ - SND_PCM_CLASS_MODEM, - /** digitizer device */ - SND_PCM_CLASS_DIGITIZER, - SND_PCM_CLASS_LAST = SND_PCM_CLASS_DIGITIZER -} snd_pcm_class_t; - -/** PCM subclass */ -typedef enum _snd_pcm_subclass { - /** subdevices are mixed together */ - SND_PCM_SUBCLASS_GENERIC_MIX = 0, - /** multichannel subdevices are mixed together */ - SND_PCM_SUBCLASS_MULTI_MIX, - SND_PCM_SUBCLASS_LAST = SND_PCM_SUBCLASS_MULTI_MIX -} snd_pcm_subclass_t; - -/** PCM stream (direction) */ -typedef enum _snd_pcm_stream { - /** Playback stream */ - SND_PCM_STREAM_PLAYBACK = 0, - /** Capture stream */ - SND_PCM_STREAM_CAPTURE, - SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE -} snd_pcm_stream_t; - -/** PCM access type */ -typedef enum _snd_pcm_access { - /** mmap access with simple interleaved channels */ - SND_PCM_ACCESS_MMAP_INTERLEAVED = 0, - /** mmap access with simple non interleaved channels */ - SND_PCM_ACCESS_MMAP_NONINTERLEAVED, - /** mmap access with complex placement */ - SND_PCM_ACCESS_MMAP_COMPLEX, - /** snd_pcm_readi/snd_pcm_writei access */ - SND_PCM_ACCESS_RW_INTERLEAVED, - /** snd_pcm_readn/snd_pcm_writen access */ - SND_PCM_ACCESS_RW_NONINTERLEAVED, - SND_PCM_ACCESS_LAST = SND_PCM_ACCESS_RW_NONINTERLEAVED -} snd_pcm_access_t; - -/** PCM sample format */ -typedef enum _snd_pcm_format { - /** Unknown */ - SND_PCM_FORMAT_UNKNOWN = -1, - /** Signed 8 bit */ - SND_PCM_FORMAT_S8 = 0, - /** Unsigned 8 bit */ - SND_PCM_FORMAT_U8, - /** Signed 16 bit Little Endian */ - SND_PCM_FORMAT_S16_LE, - /** Signed 16 bit Big Endian */ - SND_PCM_FORMAT_S16_BE, - /** Unsigned 16 bit Little Endian */ - SND_PCM_FORMAT_U16_LE, - /** Unsigned 16 bit Big Endian */ - SND_PCM_FORMAT_U16_BE, - /** Signed 24 bit Little Endian using low three bytes in 32-bit word */ - SND_PCM_FORMAT_S24_LE, - /** Signed 24 bit Big Endian using low three bytes in 32-bit word */ - SND_PCM_FORMAT_S24_BE, - /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ - SND_PCM_FORMAT_U24_LE, - /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ - SND_PCM_FORMAT_U24_BE, - /** Signed 32 bit Little Endian */ - SND_PCM_FORMAT_S32_LE, - /** Signed 32 bit Big Endian */ - SND_PCM_FORMAT_S32_BE, - /** Unsigned 32 bit Little Endian */ - SND_PCM_FORMAT_U32_LE, - /** Unsigned 32 bit Big Endian */ - SND_PCM_FORMAT_U32_BE, - /** Float 32 bit Little Endian, Range -1.0 to 1.0 */ - SND_PCM_FORMAT_FLOAT_LE, - /** Float 32 bit Big Endian, Range -1.0 to 1.0 */ - SND_PCM_FORMAT_FLOAT_BE, - /** Float 64 bit Little Endian, Range -1.0 to 1.0 */ - SND_PCM_FORMAT_FLOAT64_LE, - /** Float 64 bit Big Endian, Range -1.0 to 1.0 */ - SND_PCM_FORMAT_FLOAT64_BE, - /** IEC-958 Little Endian */ - SND_PCM_FORMAT_IEC958_SUBFRAME_LE, - /** IEC-958 Big Endian */ - SND_PCM_FORMAT_IEC958_SUBFRAME_BE, - /** Mu-Law */ - SND_PCM_FORMAT_MU_LAW, - /** A-Law */ - SND_PCM_FORMAT_A_LAW, - /** Ima-ADPCM */ - SND_PCM_FORMAT_IMA_ADPCM, - /** MPEG */ - SND_PCM_FORMAT_MPEG, - /** GSM */ - SND_PCM_FORMAT_GSM, - /** Special */ - SND_PCM_FORMAT_SPECIAL = 31, - /** Signed 24bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_S24_3LE = 32, - /** Signed 24bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_S24_3BE, - /** Unsigned 24bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_U24_3LE, - /** Unsigned 24bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_U24_3BE, - /** Signed 20bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_S20_3LE, - /** Signed 20bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_S20_3BE, - /** Unsigned 20bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_U20_3LE, - /** Unsigned 20bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_U20_3BE, - /** Signed 18bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_S18_3LE, - /** Signed 18bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_S18_3BE, - /** Unsigned 18bit Little Endian in 3bytes format */ - SND_PCM_FORMAT_U18_3LE, - /** Unsigned 18bit Big Endian in 3bytes format */ - SND_PCM_FORMAT_U18_3BE, - SND_PCM_FORMAT_LAST = SND_PCM_FORMAT_U18_3BE, - -#if __BYTE_ORDER == __LITTLE_ENDIAN - /** Signed 16 bit CPU endian */ - SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_LE, - /** Unsigned 16 bit CPU endian */ - SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_LE, - /** Signed 24 bit CPU endian */ - SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_LE, - /** Unsigned 24 bit CPU endian */ - SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_LE, - /** Signed 32 bit CPU endian */ - SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_LE, - /** Unsigned 32 bit CPU endian */ - SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_LE, - /** Float 32 bit CPU endian */ - SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_LE, - /** Float 64 bit CPU endian */ - SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_LE, - /** IEC-958 CPU Endian */ - SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_LE -#elif __BYTE_ORDER == __BIG_ENDIAN - /** Signed 16 bit CPU endian */ - SND_PCM_FORMAT_S16 = SND_PCM_FORMAT_S16_BE, - /** Unsigned 16 bit CPU endian */ - SND_PCM_FORMAT_U16 = SND_PCM_FORMAT_U16_BE, - /** Signed 24 bit CPU endian */ - SND_PCM_FORMAT_S24 = SND_PCM_FORMAT_S24_BE, - /** Unsigned 24 bit CPU endian */ - SND_PCM_FORMAT_U24 = SND_PCM_FORMAT_U24_BE, - /** Signed 32 bit CPU endian */ - SND_PCM_FORMAT_S32 = SND_PCM_FORMAT_S32_BE, - /** Unsigned 32 bit CPU endian */ - SND_PCM_FORMAT_U32 = SND_PCM_FORMAT_U32_BE, - /** Float 32 bit CPU endian */ - SND_PCM_FORMAT_FLOAT = SND_PCM_FORMAT_FLOAT_BE, - /** Float 64 bit CPU endian */ - SND_PCM_FORMAT_FLOAT64 = SND_PCM_FORMAT_FLOAT64_BE, - /** IEC-958 CPU Endian */ - SND_PCM_FORMAT_IEC958_SUBFRAME = SND_PCM_FORMAT_IEC958_SUBFRAME_BE -#else -#error "Unknown endian" -#endif -} snd_pcm_format_t; - -/** PCM sample subformat */ -typedef enum _snd_pcm_subformat { - /** Standard */ - SND_PCM_SUBFORMAT_STD = 0, - SND_PCM_SUBFORMAT_LAST = SND_PCM_SUBFORMAT_STD -} snd_pcm_subformat_t; - -/** PCM state */ -typedef enum _snd_pcm_state { - /** Open */ - SND_PCM_STATE_OPEN = 0, - /** Setup installed */ - SND_PCM_STATE_SETUP, - /** Ready to start */ - SND_PCM_STATE_PREPARED, - /** Running */ - SND_PCM_STATE_RUNNING, - /** Stopped: underrun (playback) or overrun (capture) detected */ - SND_PCM_STATE_XRUN, - /** Draining: running (playback) or stopped (capture) */ - SND_PCM_STATE_DRAINING, - /** Paused */ - SND_PCM_STATE_PAUSED, - /** Hardware is suspended */ - SND_PCM_STATE_SUSPENDED, - /** Hardware is disconnected */ - SND_PCM_STATE_DISCONNECTED, - SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED -} snd_pcm_state_t; - -/** PCM start mode */ -typedef enum _snd_pcm_start { - /** Automatic start on data read/write */ - SND_PCM_START_DATA = 0, - /** Explicit start */ - SND_PCM_START_EXPLICIT, - SND_PCM_START_LAST = SND_PCM_START_EXPLICIT -} snd_pcm_start_t; - -/** PCM xrun mode */ -typedef enum _snd_pcm_xrun { - /** Xrun detection disabled */ - SND_PCM_XRUN_NONE = 0, - /** Stop on xrun detection */ - SND_PCM_XRUN_STOP, - SND_PCM_XRUN_LAST = SND_PCM_XRUN_STOP -} snd_pcm_xrun_t; - -/** PCM timestamp mode */ -typedef enum _snd_pcm_tstamp { - /** No timestamp */ - SND_PCM_TSTAMP_NONE = 0, - /** Update timestamp at every hardware position update */ - SND_PCM_TSTAMP_ENABLE, - /** Equivalent with #SND_PCM_TSTAMP_ENABLE, - * just for compatibility with older versions - */ - SND_PCM_TSTAMP_MMAP = SND_PCM_TSTAMP_ENABLE, - SND_PCM_TSTAMP_LAST = SND_PCM_TSTAMP_ENABLE -} snd_pcm_tstamp_t; - -/** Unsigned frames quantity */ -typedef unsigned long snd_pcm_uframes_t; -/** Signed frames quantity */ -typedef long snd_pcm_sframes_t; - -/** Non blocking mode (flag for open mode) \hideinitializer */ -#define SND_PCM_NONBLOCK 0x00000001 -/** Async notification (flag for open mode) \hideinitializer */ -#define SND_PCM_ASYNC 0x00000002 -/** Disable automatic (but not forced!) rate resamplinig */ -#define SND_PCM_NO_AUTO_RESAMPLE 0x00010000 -/** Disable automatic (but not forced!) channel conversion */ -#define SND_PCM_NO_AUTO_CHANNELS 0x00020000 -/** Disable automatic (but not forced!) format conversion */ -#define SND_PCM_NO_AUTO_FORMAT 0x00040000 -/** Disable soft volume control */ -#define SND_PCM_NO_SOFTVOL 0x00080000 - -/** PCM handle */ -typedef struct _snd_pcm snd_pcm_t; - -/** PCM type */ -enum _snd_pcm_type { - /** Kernel level PCM */ - SND_PCM_TYPE_HW = 0, - /** Hooked PCM */ - SND_PCM_TYPE_HOOKS, - /** One or more linked PCM with exclusive access to selected - channels */ - SND_PCM_TYPE_MULTI, - /** File writing plugin */ - SND_PCM_TYPE_FILE, - /** Null endpoint PCM */ - SND_PCM_TYPE_NULL, - /** Shared memory client PCM */ - SND_PCM_TYPE_SHM, - /** INET client PCM (not yet implemented) */ - SND_PCM_TYPE_INET, - /** Copying plugin */ - SND_PCM_TYPE_COPY, - /** Linear format conversion PCM */ - SND_PCM_TYPE_LINEAR, - /** A-Law format conversion PCM */ - SND_PCM_TYPE_ALAW, - /** Mu-Law format conversion PCM */ - SND_PCM_TYPE_MULAW, - /** IMA-ADPCM format conversion PCM */ - SND_PCM_TYPE_ADPCM, - /** Rate conversion PCM */ - SND_PCM_TYPE_RATE, - /** Attenuated static route PCM */ - SND_PCM_TYPE_ROUTE, - /** Format adjusted PCM */ - SND_PCM_TYPE_PLUG, - /** Sharing PCM */ - SND_PCM_TYPE_SHARE, - /** Meter plugin */ - SND_PCM_TYPE_METER, - /** Mixing PCM */ - SND_PCM_TYPE_MIX, - /** Attenuated dynamic route PCM (not yet implemented) */ - SND_PCM_TYPE_DROUTE, - /** Loopback server plugin (not yet implemented) */ - SND_PCM_TYPE_LBSERVER, - /** Linear Integer <-> Linear Float format conversion PCM */ - SND_PCM_TYPE_LINEAR_FLOAT, - /** LADSPA integration plugin */ - SND_PCM_TYPE_LADSPA, - /** Direct Mixing plugin */ - SND_PCM_TYPE_DMIX, - /** Jack Audio Connection Kit plugin */ - SND_PCM_TYPE_JACK, - /** Direct Snooping plugin */ - SND_PCM_TYPE_DSNOOP, - /** Direct Sharing plugin */ - SND_PCM_TYPE_DSHARE, - /** IEC958 subframe plugin */ - SND_PCM_TYPE_IEC958, - /** Soft volume plugin */ - SND_PCM_TYPE_SOFTVOL, - /** External I/O plugin */ - SND_PCM_TYPE_IOPLUG, - /** External filter plugin */ - SND_PCM_TYPE_EXTPLUG, - /** Mmap-emulation plugin */ - SND_PCM_TYPE_MMAP_EMUL, - SND_PCM_TYPE_LAST = SND_PCM_TYPE_MMAP_EMUL -}; - -/** PCM type */ -typedef enum _snd_pcm_type snd_pcm_type_t; - -/** PCM area specification */ -typedef struct _snd_pcm_channel_area { - /** base address of channel samples */ - void *addr; - /** offset to first sample in bits */ - unsigned int first; - /** samples distance in bits */ - unsigned int step; -} snd_pcm_channel_area_t; - -/** PCM synchronization ID */ -typedef union _snd_pcm_sync_id { - /** 8-bit ID */ - unsigned char id[16]; - /** 16-bit ID */ - unsigned short id16[8]; - /** 32-bit ID */ - unsigned int id32[4]; -} snd_pcm_sync_id_t; - -/** #SND_PCM_TYPE_METER scope handle */ -typedef struct _snd_pcm_scope snd_pcm_scope_t; - -int snd_pcm_open(snd_pcm_t **pcm, const char *name, - snd_pcm_stream_t stream, int mode); -int snd_pcm_open_lconf(snd_pcm_t **pcm, const char *name, - snd_pcm_stream_t stream, int mode, - snd_config_t *lconf); -int snd_pcm_open_fallback(snd_pcm_t **pcm, snd_config_t *root, - const char *name, const char *orig_name, - snd_pcm_stream_t stream, int mode); - -int snd_pcm_close(snd_pcm_t *pcm); -const char *snd_pcm_name(snd_pcm_t *pcm); -snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm); -snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm); -int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm); -int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); -int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock); -int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, - snd_async_callback_t callback, void *private_data); -snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler); -int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info); -int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -int snd_pcm_hw_free(snd_pcm_t *pcm); -int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); -int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); -int snd_pcm_prepare(snd_pcm_t *pcm); -int snd_pcm_reset(snd_pcm_t *pcm); -int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status); -int snd_pcm_start(snd_pcm_t *pcm); -int snd_pcm_drop(snd_pcm_t *pcm); -int snd_pcm_drain(snd_pcm_t *pcm); -int snd_pcm_pause(snd_pcm_t *pcm, int enable); -snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm); -int snd_pcm_hwsync(snd_pcm_t *pcm); -int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp); -int snd_pcm_resume(snd_pcm_t *pcm); -int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp); -snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm); -snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm); -int snd_pcm_avail_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp); -snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm); -snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames); -snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm); -snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); -snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); -int snd_pcm_wait(snd_pcm_t *pcm, int timeout); - -int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2); -int snd_pcm_unlink(snd_pcm_t *pcm); - -//int snd_pcm_mixer_element(snd_pcm_t *pcm, snd_mixer_t *mixer, snd_mixer_elem_t **elem); - -/* - * application helpers - these functions are implemented on top - * of the basic API - */ - -int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent); -int snd_pcm_set_params(snd_pcm_t *pcm, - snd_pcm_format_t format, - snd_pcm_access_t access, - unsigned int channels, - unsigned int rate, - int soft_resample, - unsigned int latency); -int snd_pcm_get_params(snd_pcm_t *pcm, - snd_pcm_uframes_t *buffer_size, - snd_pcm_uframes_t *period_size); - -/** \} */ - -/** - * \defgroup PCM_Info Stream Information - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_info_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_pcm_info_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_info_alloca(ptr) __snd_alloca(ptr, snd_pcm_info) -int snd_pcm_info_malloc(snd_pcm_info_t **ptr); -void snd_pcm_info_free(snd_pcm_info_t *obj); -void snd_pcm_info_copy(snd_pcm_info_t *dst, const snd_pcm_info_t *src); -unsigned int snd_pcm_info_get_device(const snd_pcm_info_t *obj); -unsigned int snd_pcm_info_get_subdevice(const snd_pcm_info_t *obj); -snd_pcm_stream_t snd_pcm_info_get_stream(const snd_pcm_info_t *obj); -int snd_pcm_info_get_card(const snd_pcm_info_t *obj); -const char *snd_pcm_info_get_id(const snd_pcm_info_t *obj); -const char *snd_pcm_info_get_name(const snd_pcm_info_t *obj); -const char *snd_pcm_info_get_subdevice_name(const snd_pcm_info_t *obj); -snd_pcm_class_t snd_pcm_info_get_class(const snd_pcm_info_t *obj); -snd_pcm_subclass_t snd_pcm_info_get_subclass(const snd_pcm_info_t *obj); -unsigned int snd_pcm_info_get_subdevices_count(const snd_pcm_info_t *obj); -unsigned int snd_pcm_info_get_subdevices_avail(const snd_pcm_info_t *obj); -snd_pcm_sync_id_t snd_pcm_info_get_sync(const snd_pcm_info_t *obj); -void snd_pcm_info_set_device(snd_pcm_info_t *obj, unsigned int val); -void snd_pcm_info_set_subdevice(snd_pcm_info_t *obj, unsigned int val); -void snd_pcm_info_set_stream(snd_pcm_info_t *obj, snd_pcm_stream_t val); - -/** \} */ - -/** - * \defgroup PCM_HW_Params Hardware Parameters - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_can_disable_period_wakeup(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, - unsigned int *rate_num, - unsigned int *rate_den); -int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params); - -#if 0 -typedef struct _snd_pcm_hw_strategy snd_pcm_hw_strategy_t; - -/* choices need to be sorted on ascending badness */ -typedef struct _snd_pcm_hw_strategy_simple_choices_list { - unsigned int value; - unsigned int badness; -} snd_pcm_hw_strategy_simple_choices_list_t; - -int snd_pcm_hw_params_strategy(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - const snd_pcm_hw_strategy_t *strategy, - unsigned int badness_min, - unsigned int badness_max); - -void snd_pcm_hw_strategy_free(snd_pcm_hw_strategy_t *strategy); -int snd_pcm_hw_strategy_simple(snd_pcm_hw_strategy_t **strategyp, - unsigned int badness_min, - unsigned int badness_max); -int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, - snd_pcm_hw_params_t *fail, - snd_pcm_hw_params_t *success, - unsigned int depth, - snd_output_t *out); - -#endif - -size_t snd_pcm_hw_params_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_pcm_hw_params_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_hw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_hw_params) -int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr); -void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj); -void snd_pcm_hw_params_copy(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src); - -#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API) - -int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); -int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access); -int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t _access); -int snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); -int snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t *_access); -int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); -int snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); - -int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *val); -int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); -int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); -int snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); -int snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t *format); -int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); -void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); - -int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); -int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); -int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat); -int snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); -int snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat); -int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); -void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); - -int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max); -int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); - -int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_get_export_buffer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); - -int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); - -int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); -int snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); -int snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); -int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); -int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); -int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir); -int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); - -int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max); -int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); - -#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */ - -int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); - -/** \} */ - -/** - * \defgroup PCM_SW_Params Software Parameters - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_sw_params_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_pcm_sw_params_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_sw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_sw_params) -int snd_pcm_sw_params_malloc(snd_pcm_sw_params_t **ptr); -void snd_pcm_sw_params_free(snd_pcm_sw_params_t *obj); -void snd_pcm_sw_params_copy(snd_pcm_sw_params_t *dst, const snd_pcm_sw_params_t *src); -int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); - -#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API) - -int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val); -int snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params, snd_pcm_tstamp_t *val); -int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_sw_params_set_period_event(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, int val); -int snd_pcm_sw_params_get_period_event(const snd_pcm_sw_params_t *params, int *val); -int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *paramsm, snd_pcm_uframes_t *val); -int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); - -#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */ - -/** \} */ - -/* include old API */ -#ifndef ALSA_LIBRARY_BUILD -#if defined(ALSA_PCM_OLD_HW_PARAMS_API) || defined(ALSA_PCM_OLD_SW_PARAMS_API) -#include "pcm_old.h" -#endif -#endif - -/** - * \defgroup PCM_Access Access Mask Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_access_mask_sizeof(void); -/** \hideinitializer - * \brief allocate an empty #snd_pcm_access_mask_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_access_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_access_mask) -int snd_pcm_access_mask_malloc(snd_pcm_access_mask_t **ptr); -void snd_pcm_access_mask_free(snd_pcm_access_mask_t *obj); -void snd_pcm_access_mask_copy(snd_pcm_access_mask_t *dst, const snd_pcm_access_mask_t *src); -void snd_pcm_access_mask_none(snd_pcm_access_mask_t *mask); -void snd_pcm_access_mask_any(snd_pcm_access_mask_t *mask); -int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t val); -int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask); -void snd_pcm_access_mask_set(snd_pcm_access_mask_t *mask, snd_pcm_access_t val); -void snd_pcm_access_mask_reset(snd_pcm_access_mask_t *mask, snd_pcm_access_t val); - -/** \} */ - -/** - * \defgroup PCM_Format Format Mask Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_format_mask_sizeof(void); -/** \hideinitializer - * \brief allocate an empty #snd_pcm_format_mask_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_format_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_format_mask) -int snd_pcm_format_mask_malloc(snd_pcm_format_mask_t **ptr); -void snd_pcm_format_mask_free(snd_pcm_format_mask_t *obj); -void snd_pcm_format_mask_copy(snd_pcm_format_mask_t *dst, const snd_pcm_format_mask_t *src); -void snd_pcm_format_mask_none(snd_pcm_format_mask_t *mask); -void snd_pcm_format_mask_any(snd_pcm_format_mask_t *mask); -int snd_pcm_format_mask_test(const snd_pcm_format_mask_t *mask, snd_pcm_format_t val); -int snd_pcm_format_mask_empty(const snd_pcm_format_mask_t *mask); -void snd_pcm_format_mask_set(snd_pcm_format_mask_t *mask, snd_pcm_format_t val); -void snd_pcm_format_mask_reset(snd_pcm_format_mask_t *mask, snd_pcm_format_t val); - -/** \} */ - -/** - * \defgroup PCM_SubFormat Subformat Mask Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_subformat_mask_sizeof(void); -/** \hideinitializer - * \brief allocate an empty #snd_pcm_subformat_mask_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_subformat_mask_alloca(ptr) __snd_alloca(ptr, snd_pcm_subformat_mask) -int snd_pcm_subformat_mask_malloc(snd_pcm_subformat_mask_t **ptr); -void snd_pcm_subformat_mask_free(snd_pcm_subformat_mask_t *obj); -void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_subformat_mask_t *src); -void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask); -void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask); -int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); -int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask); -void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); -void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); - -/** \} */ - -/** - * \defgroup PCM_Status Status Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -size_t snd_pcm_status_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_pcm_status_t using standard alloca - * \param ptr returned pointer - */ -#define snd_pcm_status_alloca(ptr) __snd_alloca(ptr, snd_pcm_status) -int snd_pcm_status_malloc(snd_pcm_status_t **ptr); -void snd_pcm_status_free(snd_pcm_status_t *obj); -void snd_pcm_status_copy(snd_pcm_status_t *dst, const snd_pcm_status_t *src); -snd_pcm_state_t snd_pcm_status_get_state(const snd_pcm_status_t *obj); -void snd_pcm_status_get_trigger_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); -void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); -void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr); -void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr); -snd_pcm_sframes_t snd_pcm_status_get_delay(const snd_pcm_status_t *obj); -snd_pcm_uframes_t snd_pcm_status_get_avail(const snd_pcm_status_t *obj); -snd_pcm_uframes_t snd_pcm_status_get_avail_max(const snd_pcm_status_t *obj); -snd_pcm_uframes_t snd_pcm_status_get_overrange(const snd_pcm_status_t *obj); - -/** \} */ - -/** - * \defgroup PCM_Description Description Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -const char *snd_pcm_type_name(snd_pcm_type_t type); -const char *snd_pcm_stream_name(const snd_pcm_stream_t stream); -const char *snd_pcm_access_name(const snd_pcm_access_t _access); -const char *snd_pcm_format_name(const snd_pcm_format_t format); -const char *snd_pcm_format_description(const snd_pcm_format_t format); -const char *snd_pcm_subformat_name(const snd_pcm_subformat_t subformat); -const char *snd_pcm_subformat_description(const snd_pcm_subformat_t subformat); -snd_pcm_format_t snd_pcm_format_value(const char* name); -const char *snd_pcm_tstamp_mode_name(const snd_pcm_tstamp_t mode); -const char *snd_pcm_state_name(const snd_pcm_state_t state); - -/** \} */ - -/** - * \defgroup PCM_Dump Debug Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out); -int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out); -int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out); -int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out); -int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out); -int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out); -int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out); - -/** \} */ - -/** - * \defgroup PCM_Direct Direct Access (MMAP) Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -int snd_pcm_mmap_begin(snd_pcm_t *pcm, - const snd_pcm_channel_area_t **areas, - snd_pcm_uframes_t *offset, - snd_pcm_uframes_t *frames); -snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm, - snd_pcm_uframes_t offset, - snd_pcm_uframes_t frames); -snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_mmap_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); -snd_pcm_sframes_t snd_pcm_mmap_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); - -/** \} */ - -/** - * \defgroup PCM_Helpers Helper Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -int snd_pcm_format_signed(snd_pcm_format_t format); -int snd_pcm_format_unsigned(snd_pcm_format_t format); -int snd_pcm_format_linear(snd_pcm_format_t format); -int snd_pcm_format_float(snd_pcm_format_t format); -int snd_pcm_format_little_endian(snd_pcm_format_t format); -int snd_pcm_format_big_endian(snd_pcm_format_t format); -int snd_pcm_format_cpu_endian(snd_pcm_format_t format); -int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */ -int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */ -snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian); -ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples); -u_int8_t snd_pcm_format_silence(snd_pcm_format_t format); -u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format); -u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format); -u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format); -int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int samples); - -snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes); -ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames); -long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes); -ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples); - -int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, - unsigned int samples, snd_pcm_format_t format); -int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, - unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); -int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, - const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset, - unsigned int samples, snd_pcm_format_t format); -int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, - const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, - unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); - -/** \} */ - -/** - * \defgroup PCM_Hook Hook Extension - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -/** type of pcm hook */ -typedef enum _snd_pcm_hook_type { - SND_PCM_HOOK_TYPE_HW_PARAMS = 0, - SND_PCM_HOOK_TYPE_HW_FREE, - SND_PCM_HOOK_TYPE_CLOSE, - SND_PCM_HOOK_TYPE_LAST = SND_PCM_HOOK_TYPE_CLOSE -} snd_pcm_hook_type_t; - -/** PCM hook container */ -typedef struct _snd_pcm_hook snd_pcm_hook_t; -/** PCM hook callback function */ -typedef int (*snd_pcm_hook_func_t)(snd_pcm_hook_t *hook); -snd_pcm_t *snd_pcm_hook_get_pcm(snd_pcm_hook_t *hook); -void *snd_pcm_hook_get_private(snd_pcm_hook_t *hook); -void snd_pcm_hook_set_private(snd_pcm_hook_t *hook, void *private_data); -int snd_pcm_hook_add(snd_pcm_hook_t **hookp, snd_pcm_t *pcm, - snd_pcm_hook_type_t type, - snd_pcm_hook_func_t func, void *private_data); -int snd_pcm_hook_remove(snd_pcm_hook_t *hook); - -/** \} */ - -/** - * \defgroup PCM_Scope Scope Plugin Extension - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -/** #SND_PCM_TYPE_METER scope functions */ -typedef struct _snd_pcm_scope_ops { - /** \brief Enable and prepare it using current params - * \param scope scope handle - */ - int (*enable)(snd_pcm_scope_t *scope); - /** \brief Disable - * \param scope scope handle - */ - void (*disable)(snd_pcm_scope_t *scope); - /** \brief PCM has been started - * \param scope scope handle - */ - void (*start)(snd_pcm_scope_t *scope); - /** \brief PCM has been stopped - * \param scope scope handle - */ - void (*stop)(snd_pcm_scope_t *scope); - /** \brief New frames are present - * \param scope scope handle - */ - void (*update)(snd_pcm_scope_t *scope); - /** \brief Reset status - * \param scope scope handle - */ - void (*reset)(snd_pcm_scope_t *scope); - /** \brief PCM is closing - * \param scope scope handle - */ - void (*close)(snd_pcm_scope_t *scope); -} snd_pcm_scope_ops_t; - -snd_pcm_uframes_t snd_pcm_meter_get_bufsize(snd_pcm_t *pcm); -unsigned int snd_pcm_meter_get_channels(snd_pcm_t *pcm); -unsigned int snd_pcm_meter_get_rate(snd_pcm_t *pcm); -snd_pcm_uframes_t snd_pcm_meter_get_now(snd_pcm_t *pcm); -snd_pcm_uframes_t snd_pcm_meter_get_boundary(snd_pcm_t *pcm); -int snd_pcm_meter_add_scope(snd_pcm_t *pcm, snd_pcm_scope_t *scope); -snd_pcm_scope_t *snd_pcm_meter_search_scope(snd_pcm_t *pcm, const char *name); -int snd_pcm_scope_malloc(snd_pcm_scope_t **ptr); -void snd_pcm_scope_set_ops(snd_pcm_scope_t *scope, - const snd_pcm_scope_ops_t *val); -void snd_pcm_scope_set_name(snd_pcm_scope_t *scope, const char *val); -const char *snd_pcm_scope_get_name(snd_pcm_scope_t *scope); -void *snd_pcm_scope_get_callback_private(snd_pcm_scope_t *scope); -void snd_pcm_scope_set_callback_private(snd_pcm_scope_t *scope, void *val); -int snd_pcm_scope_s16_open(snd_pcm_t *pcm, const char *name, - snd_pcm_scope_t **scopep); -int16_t *snd_pcm_scope_s16_get_channel_buffer(snd_pcm_scope_t *scope, - unsigned int channel); - -/** \} */ - -/** - * \defgroup PCM_Simple Simple setup functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -/** Simple PCM latency type */ -typedef enum _snd_spcm_latency { - /** standard latency - for standard playback or capture - (estimated latency in one direction 350ms) */ - SND_SPCM_LATENCY_STANDARD = 0, - /** medium latency - software phones etc. - (estimated latency in one direction maximally 25ms */ - SND_SPCM_LATENCY_MEDIUM, - /** realtime latency - realtime applications (effect processors etc.) - (estimated latency in one direction 5ms and better) */ - SND_SPCM_LATENCY_REALTIME -} snd_spcm_latency_t; - -/** Simple PCM xrun type */ -typedef enum _snd_spcm_xrun_type { - /** driver / library will ignore all xruns, the stream runs forever */ - SND_SPCM_XRUN_IGNORE = 0, - /** driver / library stops the stream when an xrun occurs */ - SND_SPCM_XRUN_STOP -} snd_spcm_xrun_type_t; - -/** Simple PCM duplex type */ -typedef enum _snd_spcm_duplex_type { - /** liberal duplex - the buffer and period sizes might not match */ - SND_SPCM_DUPLEX_LIBERAL = 0, - /** pedantic duplex - the buffer and period sizes MUST match */ - SND_SPCM_DUPLEX_PEDANTIC -} snd_spcm_duplex_type_t; - -int snd_spcm_init(snd_pcm_t *pcm, - unsigned int rate, - unsigned int channels, - snd_pcm_format_t format, - snd_pcm_subformat_t subformat, - snd_spcm_latency_t latency, - snd_pcm_access_t _access, - snd_spcm_xrun_type_t xrun_type); - -int snd_spcm_init_duplex(snd_pcm_t *playback_pcm, - snd_pcm_t *capture_pcm, - unsigned int rate, - unsigned int channels, - snd_pcm_format_t format, - snd_pcm_subformat_t subformat, - snd_spcm_latency_t latency, - snd_pcm_access_t _access, - snd_spcm_xrun_type_t xrun_type, - snd_spcm_duplex_type_t duplex_type); - -int snd_spcm_init_get_params(snd_pcm_t *pcm, - unsigned int *rate, - snd_pcm_uframes_t *buffer_size, - snd_pcm_uframes_t *period_size); - -/** \} */ - -/** - * \defgroup PCM_Deprecated Deprecated Functions - * \ingroup PCM - * See the \ref pcm page for more details. - * \{ - */ - -/* Deprecated functions, for compatibility */ -const char *snd_pcm_start_mode_name(snd_pcm_start_t mode) __attribute__((deprecated)); -const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode) __attribute__((deprecated)); -int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_start_t val) __attribute__((deprecated)); -snd_pcm_start_t snd_pcm_sw_params_get_start_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated)); -int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_xrun_t val) __attribute__((deprecated)); -snd_pcm_xrun_t snd_pcm_sw_params_get_xrun_mode(const snd_pcm_sw_params_t *params) __attribute__((deprecated)); -#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_SW_PARAMS_API) -int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val) __attribute__((deprecated)); -int snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val) __attribute__((deprecated)); -int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val) __attribute__((deprecated)); -int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params, unsigned int *val) __attribute__((deprecated)); -#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_SW_PARAMS_API */ -#if !defined(ALSA_LIBRARY_BUILD) && !defined(ALSA_PCM_OLD_HW_PARAMS_API) -int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) __attribute__((deprecated)); -#endif /* !ALSA_LIBRARY_BUILD && !ALSA_PCM_OLD_HW_PARAMS_API */ - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_PCM_H */ diff --git a/shell/linux-deps/include/alsa/pcm_external.h b/shell/linux-deps/include/alsa/pcm_external.h deleted file mode 100644 index 575041888..000000000 --- a/shell/linux-deps/include/alsa/pcm_external.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * \file include/pcm_external.h - * \brief External PCM plugin SDK - * \author Takashi Iwai - * \date 2005 - * - * Extern PCM plugin SDK. - */ - -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __ALSA_PCM_EXTERNAL_H -#define __ALSA_PCM_EXTERNAL_H - -#include "pcm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Plugin_SDK External PCM plugin SDK - * \{ - */ - -/** - * Define the object entry for external PCM plugins - */ -#define SND_PCM_PLUGIN_ENTRY(name) _snd_pcm_##name##_open - -/** - * Define the symbols of the given plugin with versions - */ -#define SND_PCM_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_PCM_PLUGIN_ENTRY(name), SND_PCM_DLSYM_VERSION); - -/** - * Define the plugin - */ -#define SND_PCM_PLUGIN_DEFINE_FUNC(plugin) \ -int SND_PCM_PLUGIN_ENTRY(plugin) (snd_pcm_t **pcmp, const char *name,\ - snd_config_t *root, snd_config_t *conf, \ - snd_pcm_stream_t stream, int mode) - -#include "pcm_ioplug.h" -#include "pcm_extplug.h" - -int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp, - int *cchannelsp, int *hwctlp); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_PCM_EXTERNAL_H */ diff --git a/shell/linux-deps/include/alsa/pcm_extplug.h b/shell/linux-deps/include/alsa/pcm_extplug.h deleted file mode 100644 index b14c5be4f..000000000 --- a/shell/linux-deps/include/alsa/pcm_extplug.h +++ /dev/null @@ -1,189 +0,0 @@ -/** - * \file include/pcm_extplug.h - * \brief External Filter-Plugin SDK - * \author Takashi Iwai - * \date 2005 - * - * External Filter-Plugin SDK - */ - -/* - * ALSA external PCM plugin SDK (draft version) - * - * Copyright (c) 2005 Takashi Iwai - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_EXTPLUG_H -#define __ALSA_PCM_EXTPLUG_H - -/** - * \defgroup PCM_ExtPlug External Filter plugin SDK - * \ingroup Plugin_SDK - * See the \ref pcm page for more details. - * \{ - */ - -/** hw constraints for extplug */ -enum { - SND_PCM_EXTPLUG_HW_FORMAT, /**< format */ - SND_PCM_EXTPLUG_HW_CHANNELS, /**< channels */ - SND_PCM_EXTPLUG_HW_PARAMS /**< max number of hw constraints */ -}; - -/** Handle of external filter plugin */ -typedef struct snd_pcm_extplug snd_pcm_extplug_t; -/** Callback table of extplug */ -typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t; - -/* - * Protocol version - */ -#define SND_PCM_EXTPLUG_VERSION_MAJOR 1 /**< Protocol major version */ -#define SND_PCM_EXTPLUG_VERSION_MINOR 0 /**< Protocol minor version */ -#define SND_PCM_EXTPLUG_VERSION_TINY 1 /**< Protocol tiny version */ -/** - * Filter-plugin protocol version - */ -#define SND_PCM_EXTPLUG_VERSION ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\ - (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\ - (SND_PCM_EXTPLUG_VERSION_TINY)) - -/** Handle of extplug */ -struct snd_pcm_extplug { - /** - * protocol version; #SND_PCM_EXTPLUG_VERSION must be filled here - * before calling #snd_pcm_extplug_create() - */ - unsigned int version; - /** - * name of this plugin; must be filled before calling #snd_pcm_extplug_create() - */ - const char *name; - /** - * callbacks of this plugin; must be filled before calling #snd_pcm_extplug_create() - */ - const snd_pcm_extplug_callback_t *callback; - /** - * private data, which can be used freely in the driver callbacks - */ - void *private_data; - /** - * PCM handle filled by #snd_pcm_extplug_create() - */ - snd_pcm_t *pcm; - /** - * stream direction; read-only status - */ - snd_pcm_stream_t stream; - /** - * format hw parameter; filled after hw_params is caled - */ - snd_pcm_format_t format; - /** - * subformat hw parameter; filled after hw_params is caled - */ - snd_pcm_subformat_t subformat; - /** - * channels hw parameter; filled after hw_params is caled - */ - unsigned int channels; - /** - * rate hw parameter; filled after hw_params is caled - */ - unsigned int rate; - /** - * slave_format hw parameter; filled after hw_params is caled - */ - snd_pcm_format_t slave_format; - /** - * slave_subformat hw parameter; filled after hw_params is caled - */ - snd_pcm_subformat_t slave_subformat; - /** - * slave_channels hw parameter; filled after hw_params is caled - */ - unsigned int slave_channels; -}; - -/** Callback table of extplug */ -struct snd_pcm_extplug_callback { - /** - * transfer between source and destination; this is a required callback - */ - snd_pcm_sframes_t (*transfer)(snd_pcm_extplug_t *ext, - const snd_pcm_channel_area_t *dst_areas, - snd_pcm_uframes_t dst_offset, - const snd_pcm_channel_area_t *src_areas, - snd_pcm_uframes_t src_offset, - snd_pcm_uframes_t size); - /** - * close the PCM; optional - */ - int (*close)(snd_pcm_extplug_t *ext); - /** - * hw_params; optional - */ - int (*hw_params)(snd_pcm_extplug_t *ext, snd_pcm_hw_params_t *params); - /** - * hw_free; optional - */ - int (*hw_free)(snd_pcm_extplug_t *ext); - /** - * dump; optional - */ - void (*dump)(snd_pcm_extplug_t *ext, snd_output_t *out); - /** - * init; optional initialization called at prepare or reset - */ - int (*init)(snd_pcm_extplug_t *ext); -}; - - -int snd_pcm_extplug_create(snd_pcm_extplug_t *ext, const char *name, - snd_config_t *root, snd_config_t *slave_conf, - snd_pcm_stream_t stream, int mode); -int snd_pcm_extplug_delete(snd_pcm_extplug_t *ext); - -/* clear hw_parameter setting */ -void snd_pcm_extplug_params_reset(snd_pcm_extplug_t *ext); - -/* hw_parameter setting */ -int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list); -int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max); -int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list); -int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max); - -/** - * set the parameter constraint with a single value - */ -static inline int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug, int type, unsigned int val) -{ - return snd_pcm_extplug_set_param_list(extplug, type, 1, &val); -} - -/** - * set the parameter constraint for slave PCM with a single value - */ -static inline int snd_pcm_extplug_set_slave_param(snd_pcm_extplug_t *extplug, int type, unsigned int val) -{ - return snd_pcm_extplug_set_slave_param_list(extplug, type, 1, &val); -} - -/** \} */ - -#endif /* __ALSA_PCM_EXTPLUG_H */ diff --git a/shell/linux-deps/include/alsa/pcm_ioplug.h b/shell/linux-deps/include/alsa/pcm_ioplug.h deleted file mode 100644 index 6331cf071..000000000 --- a/shell/linux-deps/include/alsa/pcm_ioplug.h +++ /dev/null @@ -1,217 +0,0 @@ -/** - * \file include/pcm_ioplug.h - * \brief External I/O-Plugin SDK - * \author Takashi Iwai - * \date 2005 - * - * External I/O-Plugin SDK - */ - -/* - * ALSA external PCM plugin SDK - * - * Copyright (c) 2005 Takashi Iwai - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_IOPLUG_H -#define __ALSA_PCM_IOPLUG_H - -/** - * \defgroup PCM_IOPlug External I/O plugin SDK - * \ingroup Plugin_SDK - * See the \ref pcm page for more details. - * \{ - */ - -/** hw constraints for ioplug */ -enum { - SND_PCM_IOPLUG_HW_ACCESS = 0, /**< access type */ - SND_PCM_IOPLUG_HW_FORMAT, /**< format */ - SND_PCM_IOPLUG_HW_CHANNELS, /**< channels */ - SND_PCM_IOPLUG_HW_RATE, /**< rate */ - SND_PCM_IOPLUG_HW_PERIOD_BYTES, /**< period bytes */ - SND_PCM_IOPLUG_HW_BUFFER_BYTES, /**< buffer bytes */ - SND_PCM_IOPLUG_HW_PERIODS, /**< number of periods */ - SND_PCM_IOPLUG_HW_PARAMS /**< max number of hw constraints */ -}; - -/** I/O plugin handle */ -typedef struct snd_pcm_ioplug snd_pcm_ioplug_t; -/** Callback table of ioplug */ -typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t; - -/* - * bit flags for additional conditions - */ -#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /**< list up this PCM */ -#define SND_PCM_IOPLUG_FLAG_MONOTONIC (1<<1) /**< monotonic timestamps */ - -/* - * Protocol version - */ -#define SND_PCM_IOPLUG_VERSION_MAJOR 1 /**< Protocol major version */ -#define SND_PCM_IOPLUG_VERSION_MINOR 0 /**< Protocol minor version */ -#define SND_PCM_IOPLUG_VERSION_TINY 1 /**< Protocol tiny version */ -/** - * IO-plugin protocol version - */ -#define SND_PCM_IOPLUG_VERSION ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\ - (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\ - (SND_PCM_IOPLUG_VERSION_TINY)) - -/** Handle of ioplug */ -struct snd_pcm_ioplug { - /** - * protocol version; #SND_PCM_IOPLUG_VERSION must be filled here - * before calling #snd_pcm_ioplug_create() - */ - unsigned int version; - /** - * name of this plugin; must be filled before calling #snd_pcm_ioplug_create() - */ - const char *name; - unsigned int flags; /**< SND_PCM_IOPLUG_FLAG_XXX */ - int poll_fd; /**< poll file descriptor */ - unsigned int poll_events; /**< poll events */ - unsigned int mmap_rw; /**< pseudo mmap mode */ - /** - * callbacks of this plugin; must be filled before calling #snd_pcm_ioplug_create() - */ - const snd_pcm_ioplug_callback_t *callback; - /** - * private data, which can be used freely in the driver callbacks - */ - void *private_data; - /** - * PCM handle filled by #snd_pcm_extplug_create() - */ - snd_pcm_t *pcm; - - snd_pcm_stream_t stream; /**< stream direcion; read-only */ - snd_pcm_state_t state; /**< current PCM state; read-only */ - volatile snd_pcm_uframes_t appl_ptr; /**< application pointer; read-only */ - volatile snd_pcm_uframes_t hw_ptr; /**< hw pointer; read-only */ - int nonblock; /**< non-block mode; read-only */ - - snd_pcm_access_t access; /**< access type; filled after hw_params is called */ - snd_pcm_format_t format; /**< PCM format; filled after hw_params is called */ - unsigned int channels; /**< number of channels; filled after hw_params is called */ - unsigned int rate; /**< rate; filled after hw_params is called */ - snd_pcm_uframes_t period_size; /**< period size; filled after hw_params is called */ - snd_pcm_uframes_t buffer_size; /**< buffer size; filled after hw_params is called */ -}; - -/** Callback table of ioplug */ -struct snd_pcm_ioplug_callback { - /** - * start the PCM; required - */ - int (*start)(snd_pcm_ioplug_t *io); - /** - * stop the PCM; required - */ - int (*stop)(snd_pcm_ioplug_t *io); - /** - * get the current DMA position; required - */ - snd_pcm_sframes_t (*pointer)(snd_pcm_ioplug_t *io); - /** - * transfer the data; optional - */ - snd_pcm_sframes_t (*transfer)(snd_pcm_ioplug_t *io, - const snd_pcm_channel_area_t *areas, - snd_pcm_uframes_t offset, - snd_pcm_uframes_t size); - /** - * close the PCM; optional - */ - int (*close)(snd_pcm_ioplug_t *io); - /** - * hw_params; optional - */ - int (*hw_params)(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params); - /** - * hw_free; optional - */ - int (*hw_free)(snd_pcm_ioplug_t *io); - /** - * sw_params; optional - */ - int (*sw_params)(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params); - /** - * prepare; optional - */ - int (*prepare)(snd_pcm_ioplug_t *io); - /** - * drain; optional - */ - int (*drain)(snd_pcm_ioplug_t *io); - /** - * toggle pause; optional - */ - int (*pause)(snd_pcm_ioplug_t *io, int enable); - /** - * resume; optional - */ - int (*resume)(snd_pcm_ioplug_t *io); - /** - * poll descriptors count; optional - */ - int (*poll_descriptors_count)(snd_pcm_ioplug_t *io); - /** - * poll descriptors; optional - */ - int (*poll_descriptors)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int space); - /** - * mangle poll events; optional - */ - int (*poll_revents)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int nfds, unsigned short *revents); - /** - * dump; optional - */ - void (*dump)(snd_pcm_ioplug_t *io, snd_output_t *out); - /** - * get the delay for the running PCM; optional - */ - int (*delay)(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp); -}; - - -int snd_pcm_ioplug_create(snd_pcm_ioplug_t *io, const char *name, - snd_pcm_stream_t stream, int mode); -int snd_pcm_ioplug_delete(snd_pcm_ioplug_t *io); - -/* update poll_fd and mmap_rw */ -int snd_pcm_ioplug_reinit_status(snd_pcm_ioplug_t *ioplug); - -/* get a mmap area (for mmap_rw only) */ -const snd_pcm_channel_area_t *snd_pcm_ioplug_mmap_areas(snd_pcm_ioplug_t *ioplug); - -/* clear hw_parameter setting */ -void snd_pcm_ioplug_params_reset(snd_pcm_ioplug_t *io); - -/* hw_parameter setting */ -int snd_pcm_ioplug_set_param_minmax(snd_pcm_ioplug_t *io, int type, unsigned int min, unsigned int max); -int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *io, int type, unsigned int num_list, const unsigned int *list); - -/* change PCM status */ -int snd_pcm_ioplug_set_state(snd_pcm_ioplug_t *ioplug, snd_pcm_state_t state); - -/** \} */ - -#endif /* __ALSA_PCM_IOPLUG_H */ diff --git a/shell/linux-deps/include/alsa/pcm_old.h b/shell/linux-deps/include/alsa/pcm_old.h deleted file mode 100644 index f0de4c39f..000000000 --- a/shell/linux-deps/include/alsa/pcm_old.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Old ALSA 0.9.x API - */ - -#ifdef ALSA_PCM_OLD_HW_PARAMS_API - -asm(".symver snd_pcm_hw_params_get_access,snd_pcm_hw_params_get_access@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_access_first,snd_pcm_hw_params_set_access_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_access_last,snd_pcm_hw_params_set_access_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_test_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val); -int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t val); -snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_set_access_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); -void snd_pcm_hw_params_get_access_mask(snd_pcm_hw_params_t *params, snd_pcm_access_mask_t *mask); - -asm(".symver snd_pcm_hw_params_get_format,snd_pcm_hw_params_get_format@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_format_first,snd_pcm_hw_params_set_format_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_format_last,snd_pcm_hw_params_set_format_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_test_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); -int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); -snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_set_format_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); -void snd_pcm_hw_params_get_format_mask(snd_pcm_hw_params_t *params, snd_pcm_format_mask_t *mask); - -asm(".symver snd_pcm_hw_params_get_subformat,snd_pcm_hw_params_get_subformat@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_subformat_first,snd_pcm_hw_params_set_subformat_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_subformat_last,snd_pcm_hw_params_set_subformat_last@ALSA_0.9"); - -int snd_pcm_hw_params_test_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val); -int snd_pcm_hw_params_get_subformat(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t val); -snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_set_subformat_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); -void snd_pcm_hw_params_get_subformat_mask(snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask); - -asm(".symver snd_pcm_hw_params_get_channels,snd_pcm_hw_params_get_channels@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_channels_min,snd_pcm_hw_params_get_channels_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_channels_max,snd_pcm_hw_params_get_channels_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_channels_near,snd_pcm_hw_params_set_channels_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_channels_first,snd_pcm_hw_params_set_channels_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_channels_last,snd_pcm_hw_params_set_channels_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params); -unsigned int snd_pcm_hw_params_get_channels_min(const snd_pcm_hw_params_t *params); -unsigned int snd_pcm_hw_params_get_channels_max(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_test_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_set_channels_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); -int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max); -unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -asm(".symver snd_pcm_hw_params_get_rate,snd_pcm_hw_params_get_rate@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_rate_min,snd_pcm_hw_params_get_rate_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_rate_max,snd_pcm_hw_params_get_rate_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_rate_near,snd_pcm_hw_params_set_rate_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_rate_first,snd_pcm_hw_params_set_rate_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_rate_last,snd_pcm_hw_params_set_rate_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_rate_min(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_rate_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_rate_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); -unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); -int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val); - -asm(".symver snd_pcm_hw_params_get_period_time,snd_pcm_hw_params_get_period_time@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_period_time_min,snd_pcm_hw_params_get_period_time_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_period_time_max,snd_pcm_hw_params_get_period_time_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_time_near,snd_pcm_hw_params_set_period_time_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_time_first,snd_pcm_hw_params_set_period_time_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_time_last,snd_pcm_hw_params_set_period_time_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_period_time_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_period_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); -unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); - -asm(".symver snd_pcm_hw_params_get_period_size,snd_pcm_hw_params_get_period_size@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_period_size_min,snd_pcm_hw_params_get_period_size_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_period_size_max,snd_pcm_hw_params_get_period_size_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_size_near,snd_pcm_hw_params_set_period_size_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_size_first,snd_pcm_hw_params_set_period_size_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_period_size_last,snd_pcm_hw_params_set_period_size_last@ALSA_0.9"); - -snd_pcm_sframes_t snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, int *dir); -snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_min(const snd_pcm_hw_params_t *params, int *dir); -snd_pcm_uframes_t snd_pcm_hw_params_get_period_size_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); -int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); -int snd_pcm_hw_params_set_period_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); -int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, int *mindir, snd_pcm_uframes_t *max, int *maxdir); -snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir); -snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_set_period_size_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -asm(".symver snd_pcm_hw_params_get_periods,snd_pcm_hw_params_get_periods@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_periods_min,snd_pcm_hw_params_get_periods_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_periods_max,snd_pcm_hw_params_get_periods_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_periods_near,snd_pcm_hw_params_set_periods_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_periods_first,snd_pcm_hw_params_set_periods_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_periods_last,snd_pcm_hw_params_set_periods_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_periods_min(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_periods_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_periods_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); -unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_set_periods_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -asm(".symver snd_pcm_hw_params_get_buffer_time,snd_pcm_hw_params_get_buffer_time@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_buffer_time_min,snd_pcm_hw_params_get_buffer_time_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_buffer_time_max,snd_pcm_hw_params_get_buffer_time_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_time_near,snd_pcm_hw_params_set_buffer_time_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_time_first,snd_pcm_hw_params_set_buffer_time_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_time_last,snd_pcm_hw_params_set_buffer_time_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_buffer_time(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_buffer_time_min(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_buffer_time_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_buffer_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); -unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); - -asm(".symver snd_pcm_hw_params_get_buffer_size,snd_pcm_hw_params_get_buffer_size@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_buffer_size_min,snd_pcm_hw_params_get_buffer_size_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_buffer_size_max,snd_pcm_hw_params_get_buffer_size_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_size_near,snd_pcm_hw_params_set_buffer_size_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_size_first,snd_pcm_hw_params_set_buffer_size_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_buffer_size_last,snd_pcm_hw_params_set_buffer_size_last@ALSA_0.9"); - -snd_pcm_sframes_t snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params); -snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_min(const snd_pcm_hw_params_t *params); -snd_pcm_uframes_t snd_pcm_hw_params_get_buffer_size_max(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_test_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); -int snd_pcm_hw_params_set_buffer_size_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); -int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *min, snd_pcm_uframes_t *max); -snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); -snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); - -asm(".symver snd_pcm_hw_params_get_tick_time,snd_pcm_hw_params_get_tick_time@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_tick_time_min,snd_pcm_hw_params_get_tick_time_min@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_get_tick_time_max,snd_pcm_hw_params_get_tick_time_max@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_tick_time_near,snd_pcm_hw_params_set_tick_time_near@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_tick_time_first,snd_pcm_hw_params_set_tick_time_first@ALSA_0.9"); -asm(".symver snd_pcm_hw_params_set_tick_time_last,snd_pcm_hw_params_set_tick_time_last@ALSA_0.9"); - -int snd_pcm_hw_params_get_tick_time(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_tick_time_min(const snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_get_tick_time_max(const snd_pcm_hw_params_t *params, int *dir); -int snd_pcm_hw_params_test_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_tick_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); -int snd_pcm_hw_params_set_tick_time_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_tick_time_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); -int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, int *mindir, unsigned int *max, int *maxdir); -unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); -unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); -unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir); - -#endif /* ALSA_PCM_OLD_HW_PARAMS_API */ - - -#ifdef ALSA_PCM_OLD_SW_PARAMS_API - -asm(".symver snd_pcm_sw_params_get_tstamp_mode,snd_pcm_sw_params_get_tstamp_mode@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_sleep_min,snd_pcm_sw_params_get_sleep_min@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_avail_min,snd_pcm_sw_params_get_avail_min@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_xfer_align,snd_pcm_sw_params_get_xfer_align@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_start_threshold,snd_pcm_sw_params_get_start_threshold@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_stop_threshold,snd_pcm_sw_params_set_stop_threshold@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_silence_threshold,snd_pcm_sw_params_get_silence_threshold@ALSA_0.9"); -asm(".symver snd_pcm_sw_params_get_silence_size,snd_pcm_sw_params_get_silence_size@ALSA_0.9"); - -int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_tstamp_t val); -snd_pcm_tstamp_t snd_pcm_sw_params_get_tstamp_mode(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_sleep_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, unsigned int val); -unsigned int snd_pcm_sw_params_get_sleep_min(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_xfer_align(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_start_threshold(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_stop_threshold(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_silence_threshold(const snd_pcm_sw_params_t *params); -int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); -snd_pcm_uframes_t snd_pcm_sw_params_get_silence_size(const snd_pcm_sw_params_t *params); - -#endif /* ALSA_PCM_OLD_SW_PARAMS_API */ diff --git a/shell/linux-deps/include/alsa/pcm_plugin.h b/shell/linux-deps/include/alsa/pcm_plugin.h deleted file mode 100644 index eea1d82d8..000000000 --- a/shell/linux-deps/include/alsa/pcm_plugin.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - * \file include/pcm_plugin.h - * \brief Common PCM plugin code - * \author Abramo Bagnara - * \author Jaroslav Kysela - * \date 2000-2001 - * - * Application interface library for the ALSA driver. - * See the \ref pcm_plugins page for more details. - * - * \warning Using of contents of this header file might be dangerous - * in the sense of compatibility reasons. The contents might be - * freely changed in future. - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_PLUGIN_H - -/** - * \defgroup PCM_Plugins PCM Plugins - * \ingroup PCM - * See the \ref pcm_plugins page for more details. - * \{ - */ - -#define SND_PCM_PLUGIN_RATE_MIN 4000 /**< minimal rate for the rate plugin */ -#define SND_PCM_PLUGIN_RATE_MAX 192000 /**< maximal rate for the rate plugin */ - -/* ROUTE_FLOAT should be set to 0 for machines without FP unit - like iPAQ */ -#ifdef HAVE_SOFT_FLOAT -#define SND_PCM_PLUGIN_ROUTE_FLOAT 0 /**< use integers for route plugin */ -#else -#define SND_PCM_PLUGIN_ROUTE_FLOAT 1 /**< use floats for route plugin */ -#endif - -#define SND_PCM_PLUGIN_ROUTE_RESOLUTION 16 /**< integer resolution for route plugin */ - -#if SND_PCM_PLUGIN_ROUTE_FLOAT -/** route ttable entry type */ -typedef float snd_pcm_route_ttable_entry_t; -#define SND_PCM_PLUGIN_ROUTE_HALF 0.5 /**< half value */ -#define SND_PCM_PLUGIN_ROUTE_FULL 1.0 /**< full value */ -#else -/** route ttable entry type */ -typedef int snd_pcm_route_ttable_entry_t; -#define SND_PCM_PLUGIN_ROUTE_HALF (SND_PCM_PLUGIN_ROUTE_RESOLUTION / 2) /**< half value */ -#define SND_PCM_PLUGIN_ROUTE_FULL SND_PCM_PLUGIN_ROUTE_RESOLUTION /**< full value */ -#endif - -/* - * Hardware plugin - */ -int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, - int card, int device, int subdevice, - snd_pcm_stream_t stream, int mode, - int mmap_emulation, int sync_ptr_ioctl); -int _snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Copy plugin - */ -int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_t *slave, int close_slave); -int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Linear conversion plugin - */ -int snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, snd_pcm_t *slave, - int close_slave); -int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Linear<->Float conversion plugin - */ -int snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, snd_pcm_t *slave, - int close_slave); -int _snd_pcm_lfloat_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Linear<->mu-Law conversion plugin - */ -int snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, snd_pcm_t *slave, - int close_slave); -int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Linear<->a-Law conversion plugin - */ -int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, snd_pcm_t *slave, - int close_slave); -int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Linear<->Ima-ADPCM conversion plugin - */ -int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, snd_pcm_t *slave, - int close_slave); -int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Route plugin for linear formats - */ -int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable, - unsigned int tt_csize, unsigned int tt_ssize, - unsigned int *tt_cused, unsigned int *tt_sused, - int schannels); -int snd_pcm_route_determine_ttable(snd_config_t *tt, - unsigned int *tt_csize, - unsigned int *tt_ssize); -int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, int schannels, - snd_pcm_route_ttable_entry_t *ttable, - unsigned int tt_ssize, - unsigned int tt_cused, unsigned int tt_sused, - snd_pcm_t *slave, int close_slave); -int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Rate plugin for linear formats - */ -int snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_format_t sformat, unsigned int srate, - const snd_config_t *converter, - snd_pcm_t *slave, int close_slave); -int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Hooks plugin - */ -int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, - snd_pcm_t *slave, int close_slave); -int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * LADSPA plugin - */ -int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, - const char *ladspa_path, - unsigned int channels, - snd_config_t *ladspa_pplugins, - snd_config_t *ladspa_cplugins, - snd_pcm_t *slave, int close_slave); -int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - -/* - * Jack plugin - */ -int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *playback_conf, - snd_config_t *capture_conf, - snd_pcm_stream_t stream, int mode); -int _snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name, - snd_config_t *root, snd_config_t *conf, - snd_pcm_stream_t stream, int mode); - - -/** \} */ - -#endif /* __ALSA_PCM_PLUGIN_H */ diff --git a/shell/linux-deps/include/alsa/pcm_rate.h b/shell/linux-deps/include/alsa/pcm_rate.h deleted file mode 100644 index 4d70df269..000000000 --- a/shell/linux-deps/include/alsa/pcm_rate.h +++ /dev/null @@ -1,153 +0,0 @@ -/** - * \file include/pcm_rate.h - * \brief External Rate-Converter-Plugin SDK - * \author Takashi Iwai - * \date 2006 - * - * External Rate-Converter-Plugin SDK - */ - -/* - * ALSA external PCM rate-converter plugin SDK (draft version) - * - * Copyright (c) 2006 Takashi Iwai - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_PCM_RATE_H -#define __ALSA_PCM_RATE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Protocol version - */ -#define SND_PCM_RATE_PLUGIN_VERSION 0x010002 - -/** hw_params information for a single side */ -typedef struct snd_pcm_rate_side_info { - snd_pcm_format_t format; - unsigned int rate; - snd_pcm_uframes_t buffer_size; - snd_pcm_uframes_t period_size; -} snd_pcm_rate_side_info_t; - -/** hw_params information */ -typedef struct snd_pcm_rate_info { - struct snd_pcm_rate_side_info in; - struct snd_pcm_rate_side_info out; - unsigned int channels; -} snd_pcm_rate_info_t; - -/** Callback table of rate-converter */ -typedef struct snd_pcm_rate_ops { - /** - * close the converter; optional - */ - void (*close)(void *obj); - /** - * initialize the converter, called at hw_params - */ - int (*init)(void *obj, snd_pcm_rate_info_t *info); - /** - * free the converter; optional - */ - void (*free)(void *obj); - /** - * reset the converter, called at prepare; optional - */ - void (*reset)(void *obj); - /** - * adjust the pitch, called at sw_params; optional - */ - int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info); - /** - * convert the data - */ - void (*convert)(void *obj, - const snd_pcm_channel_area_t *dst_areas, - snd_pcm_uframes_t dst_offset, unsigned int dst_frames, - const snd_pcm_channel_area_t *src_areas, - snd_pcm_uframes_t src_offset, unsigned int src_frames); - /** - * convert an s16 interleaved-data array; exclusive with convert - */ - void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames, - const int16_t *src, unsigned int src_frames); - /** - * compute the frame size for input - */ - snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames); - /** - * compute the frame size for output - */ - snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames); - /** - * the protocol version the plugin supports; - * new field since version 0x010002 - */ - unsigned int version; - /** - * return the supported min / max sample rates; - * new ops since version 0x010002 - */ - int (*get_supported_rates)(void *obj, unsigned int *rate_min, - unsigned int *rate_max); - /** - * show some status messages for verbose mode; - * new ops since version 0x010002 - */ - void (*dump)(void *obj, snd_output_t *out); -} snd_pcm_rate_ops_t; - -/** open function type */ -typedef int (*snd_pcm_rate_open_func_t)(unsigned int version, void **objp, - snd_pcm_rate_ops_t *opsp); - -/** - * Define the object entry for external PCM rate-converter plugins - */ -#define SND_PCM_RATE_PLUGIN_ENTRY(name) _snd_pcm_rate_##name##_open - - -#ifndef DOC_HIDDEN -/* old rate_ops for protocol version 0x010001 */ -typedef struct snd_pcm_rate_old_ops { - void (*close)(void *obj); - int (*init)(void *obj, snd_pcm_rate_info_t *info); - void (*free)(void *obj); - void (*reset)(void *obj); - int (*adjust_pitch)(void *obj, snd_pcm_rate_info_t *info); - void (*convert)(void *obj, - const snd_pcm_channel_area_t *dst_areas, - snd_pcm_uframes_t dst_offset, unsigned int dst_frames, - const snd_pcm_channel_area_t *src_areas, - snd_pcm_uframes_t src_offset, unsigned int src_frames); - void (*convert_s16)(void *obj, int16_t *dst, unsigned int dst_frames, - const int16_t *src, unsigned int src_frames); - snd_pcm_uframes_t (*input_frames)(void *obj, snd_pcm_uframes_t frames); - snd_pcm_uframes_t (*output_frames)(void *obj, snd_pcm_uframes_t frames); -} snd_pcm_rate_old_ops_t; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_PCM_RATE_H */ diff --git a/shell/linux-deps/include/alsa/rawmidi.h b/shell/linux-deps/include/alsa/rawmidi.h deleted file mode 100644 index 1d8fd5627..000000000 --- a/shell/linux-deps/include/alsa/rawmidi.h +++ /dev/null @@ -1,159 +0,0 @@ -/** - * \file include/rawmidi.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_RAWMIDI_H -#define __ALSA_RAWMIDI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup RawMidi RawMidi Interface - * The RawMidi Interface. See \ref rawmidi page for more details. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_RAWMIDI_DLSYM_VERSION _dlsym_rawmidi_001 - -/** RawMidi information container */ -typedef struct _snd_rawmidi_info snd_rawmidi_info_t; -/** RawMidi settings container */ -typedef struct _snd_rawmidi_params snd_rawmidi_params_t; -/** RawMidi status container */ -typedef struct _snd_rawmidi_status snd_rawmidi_status_t; - -/** RawMidi stream (direction) */ -typedef enum _snd_rawmidi_stream { - /** Output stream */ - SND_RAWMIDI_STREAM_OUTPUT = 0, - /** Input stream */ - SND_RAWMIDI_STREAM_INPUT, - SND_RAWMIDI_STREAM_LAST = SND_RAWMIDI_STREAM_INPUT -} snd_rawmidi_stream_t; - -/** Append (flag to open mode) \hideinitializer */ -#define SND_RAWMIDI_APPEND 0x0001 -/** Non blocking mode (flag to open mode) \hideinitializer */ -#define SND_RAWMIDI_NONBLOCK 0x0002 -/** Write sync mode (Flag to open mode) \hideinitializer */ -#define SND_RAWMIDI_SYNC 0x0004 - -/** RawMidi handle */ -typedef struct _snd_rawmidi snd_rawmidi_t; - -/** RawMidi type */ -typedef enum _snd_rawmidi_type { - /** Kernel level RawMidi */ - SND_RAWMIDI_TYPE_HW, - /** Shared memory client RawMidi (not yet implemented) */ - SND_RAWMIDI_TYPE_SHM, - /** INET client RawMidi (not yet implemented) */ - SND_RAWMIDI_TYPE_INET, - /** Virtual (sequencer) RawMidi */ - SND_RAWMIDI_TYPE_VIRTUAL -} snd_rawmidi_type_t; - -int snd_rawmidi_open(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, - const char *name, int mode); -int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi, - const char *name, int mode, snd_config_t *lconf); -int snd_rawmidi_close(snd_rawmidi_t *rmidi); -int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi); -int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space); -int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent); -int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock); -size_t snd_rawmidi_info_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_rawmidi_info_t using standard alloca - * \param ptr returned pointer - */ -#define snd_rawmidi_info_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_info) -int snd_rawmidi_info_malloc(snd_rawmidi_info_t **ptr); -void snd_rawmidi_info_free(snd_rawmidi_info_t *obj); -void snd_rawmidi_info_copy(snd_rawmidi_info_t *dst, const snd_rawmidi_info_t *src); -unsigned int snd_rawmidi_info_get_device(const snd_rawmidi_info_t *obj); -unsigned int snd_rawmidi_info_get_subdevice(const snd_rawmidi_info_t *obj); -snd_rawmidi_stream_t snd_rawmidi_info_get_stream(const snd_rawmidi_info_t *obj); -int snd_rawmidi_info_get_card(const snd_rawmidi_info_t *obj); -unsigned int snd_rawmidi_info_get_flags(const snd_rawmidi_info_t *obj); -const char *snd_rawmidi_info_get_id(const snd_rawmidi_info_t *obj); -const char *snd_rawmidi_info_get_name(const snd_rawmidi_info_t *obj); -const char *snd_rawmidi_info_get_subdevice_name(const snd_rawmidi_info_t *obj); -unsigned int snd_rawmidi_info_get_subdevices_count(const snd_rawmidi_info_t *obj); -unsigned int snd_rawmidi_info_get_subdevices_avail(const snd_rawmidi_info_t *obj); -void snd_rawmidi_info_set_device(snd_rawmidi_info_t *obj, unsigned int val); -void snd_rawmidi_info_set_subdevice(snd_rawmidi_info_t *obj, unsigned int val); -void snd_rawmidi_info_set_stream(snd_rawmidi_info_t *obj, snd_rawmidi_stream_t val); -int snd_rawmidi_info(snd_rawmidi_t *rmidi, snd_rawmidi_info_t * info); -size_t snd_rawmidi_params_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_rawmidi_params_t using standard alloca - * \param ptr returned pointer - */ -#define snd_rawmidi_params_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_params) -int snd_rawmidi_params_malloc(snd_rawmidi_params_t **ptr); -void snd_rawmidi_params_free(snd_rawmidi_params_t *obj); -void snd_rawmidi_params_copy(snd_rawmidi_params_t *dst, const snd_rawmidi_params_t *src); -int snd_rawmidi_params_set_buffer_size(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val); -size_t snd_rawmidi_params_get_buffer_size(const snd_rawmidi_params_t *params); -int snd_rawmidi_params_set_avail_min(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, size_t val); -size_t snd_rawmidi_params_get_avail_min(const snd_rawmidi_params_t *params); -int snd_rawmidi_params_set_no_active_sensing(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params, int val); -int snd_rawmidi_params_get_no_active_sensing(const snd_rawmidi_params_t *params); -int snd_rawmidi_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params); -int snd_rawmidi_params_current(snd_rawmidi_t *rmidi, snd_rawmidi_params_t *params); -size_t snd_rawmidi_status_sizeof(void); -/** \hideinitializer - * \brief allocate an invalid #snd_rawmidi_status_t using standard alloca - * \param ptr returned pointer - */ -#define snd_rawmidi_status_alloca(ptr) __snd_alloca(ptr, snd_rawmidi_status) -int snd_rawmidi_status_malloc(snd_rawmidi_status_t **ptr); -void snd_rawmidi_status_free(snd_rawmidi_status_t *obj); -void snd_rawmidi_status_copy(snd_rawmidi_status_t *dst, const snd_rawmidi_status_t *src); -void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj, snd_htimestamp_t *ptr); -size_t snd_rawmidi_status_get_avail(const snd_rawmidi_status_t *obj); -size_t snd_rawmidi_status_get_xruns(const snd_rawmidi_status_t *obj); -int snd_rawmidi_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status); -int snd_rawmidi_drain(snd_rawmidi_t *rmidi); -int snd_rawmidi_drop(snd_rawmidi_t *rmidi); -ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size); -ssize_t snd_rawmidi_read(snd_rawmidi_t *rmidi, void *buffer, size_t size); -const char *snd_rawmidi_name(snd_rawmidi_t *rmidi); -snd_rawmidi_type_t snd_rawmidi_type(snd_rawmidi_t *rmidi); -snd_rawmidi_stream_t snd_rawmidi_stream(snd_rawmidi_t *rawmidi); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RAWMIDI_H */ - diff --git a/shell/linux-deps/include/alsa/seq.h b/shell/linux-deps/include/alsa/seq.h deleted file mode 100644 index 957682201..000000000 --- a/shell/linux-deps/include/alsa/seq.h +++ /dev/null @@ -1,737 +0,0 @@ -/** - * \file include/seq.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - */ -/* - * Application interface library for the ALSA driver - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_SEQ_H -#define __ALSA_SEQ_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Sequencer MIDI Sequencer - * MIDI Sequencer Interface. - * See \ref seq page for more details. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_SEQ_DLSYM_VERSION _dlsym_seq_001 - -/** Sequencer handle */ -typedef struct _snd_seq snd_seq_t; - -/** - * sequencer opening stream types - */ -#define SND_SEQ_OPEN_OUTPUT 1 /**< open for output (write) */ -#define SND_SEQ_OPEN_INPUT 2 /**< open for input (read) */ -#define SND_SEQ_OPEN_DUPLEX (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT) /**< open for both input and output (read/write) */ - -/** - * sequencer opening mode - */ -#define SND_SEQ_NONBLOCK 0x0001 /**< non-blocking mode (flag to open mode) */ - -/** sequencer handle type */ -typedef enum _snd_seq_type { - SND_SEQ_TYPE_HW, /**< hardware */ - SND_SEQ_TYPE_SHM, /**< shared memory (NYI) */ - SND_SEQ_TYPE_INET /**< network (NYI) */ -} snd_seq_type_t; - -/** special client (port) ids */ -#define SND_SEQ_ADDRESS_UNKNOWN 253 /**< unknown source */ -#define SND_SEQ_ADDRESS_SUBSCRIBERS 254 /**< send event to all subscribed ports */ -#define SND_SEQ_ADDRESS_BROADCAST 255 /**< send event to all queues/clients/ports/channels */ - -/** known client numbers */ -#define SND_SEQ_CLIENT_SYSTEM 0 /**< system client */ - -/* - */ -int snd_seq_open(snd_seq_t **handle, const char *name, int streams, int mode); -int snd_seq_open_lconf(snd_seq_t **handle, const char *name, int streams, int mode, snd_config_t *lconf); -const char *snd_seq_name(snd_seq_t *seq); -snd_seq_type_t snd_seq_type(snd_seq_t *seq); -int snd_seq_close(snd_seq_t *handle); -int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events); -int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events); -int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_seq_nonblock(snd_seq_t *handle, int nonblock); -int snd_seq_client_id(snd_seq_t *handle); - -size_t snd_seq_get_output_buffer_size(snd_seq_t *handle); -size_t snd_seq_get_input_buffer_size(snd_seq_t *handle); -int snd_seq_set_output_buffer_size(snd_seq_t *handle, size_t size); -int snd_seq_set_input_buffer_size(snd_seq_t *handle, size_t size); - -/** system information container */ -typedef struct _snd_seq_system_info snd_seq_system_info_t; - -size_t snd_seq_system_info_sizeof(void); -/** allocate a #snd_seq_system_info_t container on stack */ -#define snd_seq_system_info_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_system_info) -int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr); -void snd_seq_system_info_free(snd_seq_system_info_t *ptr); -void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src); - -int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info); -int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info); -int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info); -int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info); -int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info); -int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info); - -int snd_seq_system_info(snd_seq_t *handle, snd_seq_system_info_t *info); - -/** \} */ - - -/** - * \defgroup SeqClient Sequencer Client Interface - * Sequencer Client Interface - * \ingroup Sequencer - * \{ - */ - -/** client information container */ -typedef struct _snd_seq_client_info snd_seq_client_info_t; - -/** client types */ -typedef enum snd_seq_client_type { - SND_SEQ_USER_CLIENT = 1, /**< user client */ - SND_SEQ_KERNEL_CLIENT = 2 /**< kernel client */ -} snd_seq_client_type_t; - -size_t snd_seq_client_info_sizeof(void); -/** allocate a #snd_seq_client_info_t container on stack */ -#define snd_seq_client_info_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_client_info) -int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr); -void snd_seq_client_info_free(snd_seq_client_info_t *ptr); -void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src); - -int snd_seq_client_info_get_client(const snd_seq_client_info_t *info); -snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info); -const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info); -int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info); -int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info); -const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info); -int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info); -int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info); - -void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client); -void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name); -void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val); -void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val); -void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter); - -void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info); -void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type); -void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type); -int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type); - -int snd_seq_get_client_info(snd_seq_t *handle, snd_seq_client_info_t *info); -int snd_seq_get_any_client_info(snd_seq_t *handle, int client, snd_seq_client_info_t *info); -int snd_seq_set_client_info(snd_seq_t *handle, snd_seq_client_info_t *info); -int snd_seq_query_next_client(snd_seq_t *handle, snd_seq_client_info_t *info); - -/* - */ - -/** client pool information container */ -typedef struct _snd_seq_client_pool snd_seq_client_pool_t; - -size_t snd_seq_client_pool_sizeof(void); -/** allocate a #snd_seq_client_pool_t container on stack */ -#define snd_seq_client_pool_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_client_pool) -int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr); -void snd_seq_client_pool_free(snd_seq_client_pool_t *ptr); -void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src); - -int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info); -size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info); -size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info); -size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info); -size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info); -size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info); -void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size); -void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size); -void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size); - -int snd_seq_get_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info); -int snd_seq_set_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info); - - -/** \} */ - - -/** - * \defgroup SeqPort Sequencer Port Interface - * Sequencer Port Interface - * \ingroup Sequencer - * \{ - */ - -/** port information container */ -typedef struct _snd_seq_port_info snd_seq_port_info_t; - -/** known port numbers */ -#define SND_SEQ_PORT_SYSTEM_TIMER 0 /**< system timer port */ -#define SND_SEQ_PORT_SYSTEM_ANNOUNCE 1 /**< system announce port */ - -/** port capabilities (32 bits) */ -#define SND_SEQ_PORT_CAP_READ (1<<0) /**< readable from this port */ -#define SND_SEQ_PORT_CAP_WRITE (1<<1) /**< writable to this port */ - -#define SND_SEQ_PORT_CAP_SYNC_READ (1<<2) /**< allow read subscriptions */ -#define SND_SEQ_PORT_CAP_SYNC_WRITE (1<<3) /**< allow write subscriptions */ - -#define SND_SEQ_PORT_CAP_DUPLEX (1<<4) /**< allow read/write duplex */ - -#define SND_SEQ_PORT_CAP_SUBS_READ (1<<5) /**< allow read subscription */ -#define SND_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /**< allow write subscription */ -#define SND_SEQ_PORT_CAP_NO_EXPORT (1<<7) /**< routing not allowed */ - -/* port type */ -/** Messages sent from/to this port have device-specific semantics. */ -#define SND_SEQ_PORT_TYPE_SPECIFIC (1<<0) -/** This port understands MIDI messages. */ -#define SND_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1) -/** This port is compatible with the General MIDI specification. */ -#define SND_SEQ_PORT_TYPE_MIDI_GM (1<<2) -/** This port is compatible with the Roland GS standard. */ -#define SND_SEQ_PORT_TYPE_MIDI_GS (1<<3) -/** This port is compatible with the Yamaha XG specification. */ -#define SND_SEQ_PORT_TYPE_MIDI_XG (1<<4) -/** This port is compatible with the Roland MT-32. */ -#define SND_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) -/** This port is compatible with the General MIDI 2 specification. */ -#define SND_SEQ_PORT_TYPE_MIDI_GM2 (1<<6) -/** This port understands SND_SEQ_EVENT_SAMPLE_xxx messages - (these are not MIDI messages). */ -#define SND_SEQ_PORT_TYPE_SYNTH (1<<10) -/** Instruments can be downloaded to this port - (with SND_SEQ_EVENT_INSTR_xxx messages sent directly). */ -#define SND_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) -/** Instruments can be downloaded to this port - (with SND_SEQ_EVENT_INSTR_xxx messages sent directly or through a queue). */ -#define SND_SEQ_PORT_TYPE_SAMPLE (1<<12) -/** This port is implemented in hardware. */ -#define SND_SEQ_PORT_TYPE_HARDWARE (1<<16) -/** This port is implemented in software. */ -#define SND_SEQ_PORT_TYPE_SOFTWARE (1<<17) -/** Messages sent to this port will generate sounds. */ -#define SND_SEQ_PORT_TYPE_SYNTHESIZER (1<<18) -/** This port may connect to other devices - (whose characteristics are not known). */ -#define SND_SEQ_PORT_TYPE_PORT (1<<19) -/** This port belongs to an application, such as a sequencer or editor. */ -#define SND_SEQ_PORT_TYPE_APPLICATION (1<<20) - - -size_t snd_seq_port_info_sizeof(void); -/** allocate a #snd_seq_port_info_t container on stack */ -#define snd_seq_port_info_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_port_info) -int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr); -void snd_seq_port_info_free(snd_seq_port_info_t *ptr); -void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src); - -int snd_seq_port_info_get_client(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_port(const snd_seq_port_info_t *info); -const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info); -const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info); -unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info); -unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info); -int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info); - -void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client); -void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port); -void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr); -void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name); -void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability); -void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type); -void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels); -void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices); -void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices); -void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val); -void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable); -void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int realtime); -void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue); - -int snd_seq_create_port(snd_seq_t *handle, snd_seq_port_info_t *info); -int snd_seq_delete_port(snd_seq_t *handle, int port); -int snd_seq_get_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info); -int snd_seq_get_any_port_info(snd_seq_t *handle, int client, int port, snd_seq_port_info_t *info); -int snd_seq_set_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info); -int snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t *info); - -/** \} */ - - -/** - * \defgroup SeqSubscribe Sequencer Port Subscription - * Sequencer Port Subscription - * \ingroup Sequencer - * \{ - */ - -/** port subscription container */ -typedef struct _snd_seq_port_subscribe snd_seq_port_subscribe_t; - -size_t snd_seq_port_subscribe_sizeof(void); -/** allocate a #snd_seq_port_subscribe_t container on stack */ -#define snd_seq_port_subscribe_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_port_subscribe) -int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr); -void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *ptr); -void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src); - -const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info); -const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info); -int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info); -int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info); -int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info); -int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info); - -void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr); -void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr); -void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q); -void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val); -void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val); -void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val); - -int snd_seq_get_port_subscription(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); -int snd_seq_subscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); -int snd_seq_unsubscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub); - -/* - */ - -/** subscription query container */ -typedef struct _snd_seq_query_subscribe snd_seq_query_subscribe_t; - -/** type of query subscription */ -typedef enum { - SND_SEQ_QUERY_SUBS_READ, /**< query read subscriptions */ - SND_SEQ_QUERY_SUBS_WRITE /**< query write subscriptions */ -} snd_seq_query_subs_type_t; - -size_t snd_seq_query_subscribe_sizeof(void); -/** allocate a #snd_seq_query_subscribe_t container on stack */ -#define snd_seq_query_subscribe_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_query_subscribe) -int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr); -void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *ptr); -void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src); - -int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info); -const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info); -snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info); -const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info); -int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info); - -void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client); -void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port); -void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr); -void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type); -void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int _index); - -int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs); - -/** \} */ - - -/** - * \defgroup SeqQueue Sequencer Queue Interface - * Sequencer Queue Interface - * \ingroup Sequencer - * \{ - */ - -/** queue information container */ -typedef struct _snd_seq_queue_info snd_seq_queue_info_t; -/** queue status container */ -typedef struct _snd_seq_queue_status snd_seq_queue_status_t; -/** queue tempo container */ -typedef struct _snd_seq_queue_tempo snd_seq_queue_tempo_t; -/** queue timer information container */ -typedef struct _snd_seq_queue_timer snd_seq_queue_timer_t; - -/** special queue ids */ -#define SND_SEQ_QUEUE_DIRECT 253 /**< direct dispatch */ - -size_t snd_seq_queue_info_sizeof(void); -/** allocate a #snd_seq_queue_info_t container on stack */ -#define snd_seq_queue_info_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_queue_info) -int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr); -void snd_seq_queue_info_free(snd_seq_queue_info_t *ptr); -void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src); - -int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info); -const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info); -int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info); -int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info); -unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info); - -void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name); -void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner); -void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked); -void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags); - -int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info); -int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name); -int snd_seq_alloc_queue(snd_seq_t *handle); -int snd_seq_free_queue(snd_seq_t *handle, int q); -int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info); -int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info); -int snd_seq_query_named_queue(snd_seq_t *seq, const char *name); - -int snd_seq_get_queue_usage(snd_seq_t *handle, int q); -int snd_seq_set_queue_usage(snd_seq_t *handle, int q, int used); - -/* - */ -size_t snd_seq_queue_status_sizeof(void); -/** allocate a #snd_seq_queue_status_t container on stack */ -#define snd_seq_queue_status_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_queue_status) -int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr); -void snd_seq_queue_status_free(snd_seq_queue_status_t *ptr); -void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src); - -int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info); -int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info); -snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info); -const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info); -unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info); - -int snd_seq_get_queue_status(snd_seq_t *handle, int q, snd_seq_queue_status_t *status); - -/* - */ -size_t snd_seq_queue_tempo_sizeof(void); -/** allocate a #snd_seq_queue_tempo_t container on stack */ -#define snd_seq_queue_tempo_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_queue_tempo) -int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr); -void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *ptr); -void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src); - -int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info); -unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info); -int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info); -unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info); -unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info); -void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo); -void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq); -void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew); -void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base); - -int snd_seq_get_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); -int snd_seq_set_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); - -/* - */ - -/** sequencer timer sources */ -typedef enum { - SND_SEQ_TIMER_ALSA = 0, /* ALSA timer */ - SND_SEQ_TIMER_MIDI_CLOCK = 1, /* Midi Clock (CLOCK event) */ - SND_SEQ_TIMER_MIDI_TICK = 2 /* Midi Timer Tick (TICK event */ -} snd_seq_queue_timer_type_t; - -size_t snd_seq_queue_timer_sizeof(void); -/** allocate a #snd_seq_queue_timer_t container on stack */ -#define snd_seq_queue_timer_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_queue_timer) -int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr); -void snd_seq_queue_timer_free(snd_seq_queue_timer_t *ptr); -void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src); - -int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info); -snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info); -const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info); -unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info); - -void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type); -void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id); -void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution); - -int snd_seq_get_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer); -int snd_seq_set_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer); - -/** \} */ - -/** - * \defgroup SeqEvent Sequencer Event API - * Sequencer Event API - * \ingroup Sequencer - * \{ - */ - -int snd_seq_free_event(snd_seq_event_t *ev); -ssize_t snd_seq_event_length(snd_seq_event_t *ev); -int snd_seq_event_output(snd_seq_t *handle, snd_seq_event_t *ev); -int snd_seq_event_output_buffer(snd_seq_t *handle, snd_seq_event_t *ev); -int snd_seq_event_output_direct(snd_seq_t *handle, snd_seq_event_t *ev); -int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev); -int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer); -int snd_seq_drain_output(snd_seq_t *handle); -int snd_seq_event_output_pending(snd_seq_t *seq); -int snd_seq_extract_output(snd_seq_t *handle, snd_seq_event_t **ev); -int snd_seq_drop_output(snd_seq_t *handle); -int snd_seq_drop_output_buffer(snd_seq_t *handle); -int snd_seq_drop_input(snd_seq_t *handle); -int snd_seq_drop_input_buffer(snd_seq_t *handle); - -/** event removal conditionals */ -typedef struct _snd_seq_remove_events snd_seq_remove_events_t; - -/** Remove conditional flags */ -#define SND_SEQ_REMOVE_INPUT (1<<0) /**< Flush input queues */ -#define SND_SEQ_REMOVE_OUTPUT (1<<1) /**< Flush output queues */ -#define SND_SEQ_REMOVE_DEST (1<<2) /**< Restrict by destination q:client:port */ -#define SND_SEQ_REMOVE_DEST_CHANNEL (1<<3) /**< Restrict by channel */ -#define SND_SEQ_REMOVE_TIME_BEFORE (1<<4) /**< Restrict to before time */ -#define SND_SEQ_REMOVE_TIME_AFTER (1<<5) /**< Restrict to time or after */ -#define SND_SEQ_REMOVE_TIME_TICK (1<<6) /**< Time is in ticks */ -#define SND_SEQ_REMOVE_EVENT_TYPE (1<<7) /**< Restrict to event type */ -#define SND_SEQ_REMOVE_IGNORE_OFF (1<<8) /**< Do not flush off events */ -#define SND_SEQ_REMOVE_TAG_MATCH (1<<9) /**< Restrict to events with given tag */ - -size_t snd_seq_remove_events_sizeof(void); -/** allocate a #snd_seq_remove_events_t container on stack */ -#define snd_seq_remove_events_alloca(ptr) \ - __snd_alloca(ptr, snd_seq_remove_events) -int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr); -void snd_seq_remove_events_free(snd_seq_remove_events_t *ptr); -void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src); - -unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info); -int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info); -const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info); -const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info); -int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info); -int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info); -int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info); - -void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags); -void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue); -void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time); -void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr); -void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel); -void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type); -void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag); - -int snd_seq_remove_events(snd_seq_t *handle, snd_seq_remove_events_t *info); - -/** \} */ - -/** - * \defgroup SeqMisc Sequencer Miscellaneous - * Sequencer Miscellaneous - * \ingroup Sequencer - * \{ - */ - -void snd_seq_set_bit(int nr, void *array); -void snd_seq_unset_bit(int nr, void *array); -int snd_seq_change_bit(int nr, void *array); -int snd_seq_get_bit(int nr, void *array); - -/** \} */ - - -/** - * \defgroup SeqEvType Sequencer Event Type Checks - * Sequencer Event Type Checks - * \ingroup Sequencer - * \{ - */ - -/* event type macros */ -enum { - SND_SEQ_EVFLG_RESULT, - SND_SEQ_EVFLG_NOTE, - SND_SEQ_EVFLG_CONTROL, - SND_SEQ_EVFLG_QUEUE, - SND_SEQ_EVFLG_SYSTEM, - SND_SEQ_EVFLG_MESSAGE, - SND_SEQ_EVFLG_CONNECTION, - SND_SEQ_EVFLG_SAMPLE, - SND_SEQ_EVFLG_USERS, - SND_SEQ_EVFLG_INSTR, - SND_SEQ_EVFLG_QUOTE, - SND_SEQ_EVFLG_NONE, - SND_SEQ_EVFLG_RAW, - SND_SEQ_EVFLG_FIXED, - SND_SEQ_EVFLG_VARIABLE, - SND_SEQ_EVFLG_VARUSR -}; - -enum { - SND_SEQ_EVFLG_NOTE_ONEARG, - SND_SEQ_EVFLG_NOTE_TWOARG -}; - -enum { - SND_SEQ_EVFLG_QUEUE_NOARG, - SND_SEQ_EVFLG_QUEUE_TICK, - SND_SEQ_EVFLG_QUEUE_TIME, - SND_SEQ_EVFLG_QUEUE_VALUE -}; - -/** - * Exported event type table - * - * This table is referred by snd_seq_ev_is_xxx. - */ -extern const unsigned int snd_seq_event_types[]; - -#define _SND_SEQ_TYPE(x) (1<<(x)) /**< master type - 24bit */ -#define _SND_SEQ_TYPE_OPT(x) ((x)<<24) /**< optional type - 8bit */ - -/** check the event type */ -#define snd_seq_type_check(ev,x) (snd_seq_event_types[(ev)->type] & _SND_SEQ_TYPE(x)) - -/** event type check: result events */ -#define snd_seq_ev_is_result_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_RESULT) -/** event type check: note events */ -#define snd_seq_ev_is_note_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_NOTE) -/** event type check: control events */ -#define snd_seq_ev_is_control_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_CONTROL) -/** event type check: channel specific events */ -#define snd_seq_ev_is_channel_type(ev) \ - (snd_seq_event_types[(ev)->type] & (_SND_SEQ_TYPE(SND_SEQ_EVFLG_NOTE) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_CONTROL))) - -/** event type check: queue control events */ -#define snd_seq_ev_is_queue_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_QUEUE) -/** event type check: system status messages */ -#define snd_seq_ev_is_message_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_MESSAGE) -/** event type check: system status messages */ -#define snd_seq_ev_is_subscribe_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_CONNECTION) -/** event type check: sample messages */ -#define snd_seq_ev_is_sample_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_SAMPLE) -/** event type check: user-defined messages */ -#define snd_seq_ev_is_user_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_USERS) -/** event type check: instrument layer events */ -#define snd_seq_ev_is_instr_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_INSTR) -/** event type check: fixed length events */ -#define snd_seq_ev_is_fixed_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_FIXED) -/** event type check: variable length events */ -#define snd_seq_ev_is_variable_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_VARIABLE) -/** event type check: user pointer events */ -#define snd_seq_ev_is_varusr_type(ev) \ - snd_seq_type_check(ev, SND_SEQ_EVFLG_VARUSR) -/** event type check: reserved for kernel */ -#define snd_seq_ev_is_reserved(ev) \ - (! snd_seq_event_types[(ev)->type]) - -/** - * macros to check event flags - */ -/** prior events */ -#define snd_seq_ev_is_prior(ev) \ - (((ev)->flags & SND_SEQ_PRIORITY_MASK) == SND_SEQ_PRIORITY_HIGH) - -/** get the data length type */ -#define snd_seq_ev_length_type(ev) \ - ((ev)->flags & SND_SEQ_EVENT_LENGTH_MASK) -/** fixed length events */ -#define snd_seq_ev_is_fixed(ev) \ - (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_FIXED) -/** variable length events */ -#define snd_seq_ev_is_variable(ev) \ - (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARIABLE) -/** variable length on user-space */ -#define snd_seq_ev_is_varusr(ev) \ - (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARUSR) - -/** time-stamp type */ -#define snd_seq_ev_timestamp_type(ev) \ - ((ev)->flags & SND_SEQ_TIME_STAMP_MASK) -/** event is in tick time */ -#define snd_seq_ev_is_tick(ev) \ - (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_TICK) -/** event is in real-time */ -#define snd_seq_ev_is_real(ev) \ - (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_REAL) - -/** time-mode type */ -#define snd_seq_ev_timemode_type(ev) \ - ((ev)->flags & SND_SEQ_TIME_MODE_MASK) -/** scheduled in absolute time */ -#define snd_seq_ev_is_abstime(ev) \ - (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_ABS) -/** scheduled in relative time */ -#define snd_seq_ev_is_reltime(ev) \ - (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_REL) - -/** direct dispatched events */ -#define snd_seq_ev_is_direct(ev) \ - ((ev)->queue == SND_SEQ_QUEUE_DIRECT) - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_SEQ_H */ - diff --git a/shell/linux-deps/include/alsa/seq_event.h b/shell/linux-deps/include/alsa/seq_event.h deleted file mode 100644 index 583f1d069..000000000 --- a/shell/linux-deps/include/alsa/seq_event.h +++ /dev/null @@ -1,319 +0,0 @@ -/** - * \file include/seq_event.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_SEQ_EVENT_H -#define __ALSA_SEQ_EVENT_H - -/** - * \defgroup SeqEvents Sequencer Event Definitions - * Sequencer Event Definitions - * \ingroup Sequencer - * \{ - */ - -/** - * Sequencer event data type - */ -typedef unsigned char snd_seq_event_type_t; - -/** Sequencer event type */ -enum snd_seq_event_type { - /** system status; event data type = #snd_seq_result_t */ - SND_SEQ_EVENT_SYSTEM = 0, - /** returned result status; event data type = #snd_seq_result_t */ - SND_SEQ_EVENT_RESULT, - - /** note on and off with duration; event data type = #snd_seq_ev_note_t */ - SND_SEQ_EVENT_NOTE = 5, - /** note on; event data type = #snd_seq_ev_note_t */ - SND_SEQ_EVENT_NOTEON, - /** note off; event data type = #snd_seq_ev_note_t */ - SND_SEQ_EVENT_NOTEOFF, - /** key pressure change (aftertouch); event data type = #snd_seq_ev_note_t */ - SND_SEQ_EVENT_KEYPRESS, - - /** controller; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_CONTROLLER = 10, - /** program change; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_PGMCHANGE, - /** channel pressure; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_CHANPRESS, - /** pitchwheel; event data type = #snd_seq_ev_ctrl_t; data is from -8192 to 8191) */ - SND_SEQ_EVENT_PITCHBEND, - /** 14 bit controller value; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_CONTROL14, - /** 14 bit NRPN; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_NONREGPARAM, - /** 14 bit RPN; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_REGPARAM, - - /** SPP with LSB and MSB values; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_SONGPOS = 20, - /** Song Select with song ID number; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_SONGSEL, - /** midi time code quarter frame; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_QFRAME, - /** SMF Time Signature event; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_TIMESIGN, - /** SMF Key Signature event; event data type = #snd_seq_ev_ctrl_t */ - SND_SEQ_EVENT_KEYSIGN, - - /** MIDI Real Time Start message; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_START = 30, - /** MIDI Real Time Continue message; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_CONTINUE, - /** MIDI Real Time Stop message; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_STOP, - /** Set tick queue position; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_SETPOS_TICK, - /** Set real-time queue position; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_SETPOS_TIME, - /** (SMF) Tempo event; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_TEMPO, - /** MIDI Real Time Clock message; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_CLOCK, - /** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_TICK, - /** Queue timer skew; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_QUEUE_SKEW, - /** Sync position changed; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_SYNC_POS, - - /** Tune request; event data type = none */ - SND_SEQ_EVENT_TUNE_REQUEST = 40, - /** Reset to power-on state; event data type = none */ - SND_SEQ_EVENT_RESET, - /** Active sensing event; event data type = none */ - SND_SEQ_EVENT_SENSING, - - /** Echo-back event; event data type = any type */ - SND_SEQ_EVENT_ECHO = 50, - /** OSS emulation raw event; event data type = any type */ - SND_SEQ_EVENT_OSS, - - /** New client has connected; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_CLIENT_START = 60, - /** Client has left the system; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_CLIENT_EXIT, - /** Client status/info has changed; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_CLIENT_CHANGE, - /** New port was created; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_PORT_START, - /** Port was deleted from system; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_PORT_EXIT, - /** Port status/info has changed; event data type = #snd_seq_addr_t */ - SND_SEQ_EVENT_PORT_CHANGE, - - /** Ports connected; event data type = #snd_seq_connect_t */ - SND_SEQ_EVENT_PORT_SUBSCRIBED, - /** Ports disconnected; event data type = #snd_seq_connect_t */ - SND_SEQ_EVENT_PORT_UNSUBSCRIBED, - - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR0 = 90, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR1, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR2, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR3, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR4, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR5, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR6, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR7, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR8, - /** user-defined event; event data type = any (fixed size) */ - SND_SEQ_EVENT_USR9, - - /** system exclusive data (variable length); event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_SYSEX = 130, - /** error event; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_BOUNCE, - /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_USR_VAR0 = 135, - /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_USR_VAR1, - /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_USR_VAR2, - /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_USR_VAR3, - /** reserved for user apps; event data type = #snd_seq_ev_ext_t */ - SND_SEQ_EVENT_USR_VAR4, - - /** NOP; ignored in any case */ - SND_SEQ_EVENT_NONE = 255 -}; - - -/** Sequencer event address */ -typedef struct snd_seq_addr { - unsigned char client; /**< Client id */ - unsigned char port; /**< Port id */ -} snd_seq_addr_t; - -/** Connection (subscription) between ports */ -typedef struct snd_seq_connect { - snd_seq_addr_t sender; /**< sender address */ - snd_seq_addr_t dest; /**< destination address */ -} snd_seq_connect_t; - - -/** Real-time data record */ -typedef struct snd_seq_real_time { - unsigned int tv_sec; /**< seconds */ - unsigned int tv_nsec; /**< nanoseconds */ -} snd_seq_real_time_t; - -/** (MIDI) Tick-time data record */ -typedef unsigned int snd_seq_tick_time_t; - -/** unioned time stamp */ -typedef union snd_seq_timestamp { - snd_seq_tick_time_t tick; /**< tick-time */ - struct snd_seq_real_time time; /**< real-time */ -} snd_seq_timestamp_t; - - -/** - * Event mode flags - * - * NOTE: only 8 bits available! - */ -#define SND_SEQ_TIME_STAMP_TICK (0<<0) /**< timestamp in clock ticks */ -#define SND_SEQ_TIME_STAMP_REAL (1<<0) /**< timestamp in real time */ -#define SND_SEQ_TIME_STAMP_MASK (1<<0) /**< mask for timestamp bits */ - -#define SND_SEQ_TIME_MODE_ABS (0<<1) /**< absolute timestamp */ -#define SND_SEQ_TIME_MODE_REL (1<<1) /**< relative to current time */ -#define SND_SEQ_TIME_MODE_MASK (1<<1) /**< mask for time mode bits */ - -#define SND_SEQ_EVENT_LENGTH_FIXED (0<<2) /**< fixed event size */ -#define SND_SEQ_EVENT_LENGTH_VARIABLE (1<<2) /**< variable event size */ -#define SND_SEQ_EVENT_LENGTH_VARUSR (2<<2) /**< variable event size - user memory space */ -#define SND_SEQ_EVENT_LENGTH_MASK (3<<2) /**< mask for event length bits */ - -#define SND_SEQ_PRIORITY_NORMAL (0<<4) /**< normal priority */ -#define SND_SEQ_PRIORITY_HIGH (1<<4) /**< event should be processed before others */ -#define SND_SEQ_PRIORITY_MASK (1<<4) /**< mask for priority bits */ - - -/** Note event */ -typedef struct snd_seq_ev_note { - unsigned char channel; /**< channel number */ - unsigned char note; /**< note */ - unsigned char velocity; /**< velocity */ - unsigned char off_velocity; /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */ - unsigned int duration; /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */ -} snd_seq_ev_note_t; - -/** Controller event */ -typedef struct snd_seq_ev_ctrl { - unsigned char channel; /**< channel number */ - unsigned char unused[3]; /**< reserved */ - unsigned int param; /**< control parameter */ - signed int value; /**< control value */ -} snd_seq_ev_ctrl_t; - -/** generic set of bytes (12x8 bit) */ -typedef struct snd_seq_ev_raw8 { - unsigned char d[12]; /**< 8 bit value */ -} snd_seq_ev_raw8_t; - -/** generic set of integers (3x32 bit) */ -typedef struct snd_seq_ev_raw32 { - unsigned int d[3]; /**< 32 bit value */ -} snd_seq_ev_raw32_t; - -/** external stored data */ -typedef struct snd_seq_ev_ext { - unsigned int len; /**< length of data */ - void *ptr; /**< pointer to data (note: can be 64-bit) */ -} __attribute__((packed)) snd_seq_ev_ext_t; - -/** Result events */ -typedef struct snd_seq_result { - int event; /**< processed event type */ - int result; /**< status */ -} snd_seq_result_t; - -/** Queue skew values */ -typedef struct snd_seq_queue_skew { - unsigned int value; /**< skew value */ - unsigned int base; /**< skew base */ -} snd_seq_queue_skew_t; - -/** queue timer control */ -typedef struct snd_seq_ev_queue_control { - unsigned char queue; /**< affected queue */ - unsigned char unused[3]; /**< reserved */ - union { - signed int value; /**< affected value (e.g. tempo) */ - snd_seq_timestamp_t time; /**< time */ - unsigned int position; /**< sync position */ - snd_seq_queue_skew_t skew; /**< queue skew */ - unsigned int d32[2]; /**< any data */ - unsigned char d8[8]; /**< any data */ - } param; /**< data value union */ -} snd_seq_ev_queue_control_t; - - -/** Sequencer event */ -typedef struct snd_seq_event { - snd_seq_event_type_t type; /**< event type */ - unsigned char flags; /**< event flags */ - unsigned char tag; /**< tag */ - - unsigned char queue; /**< schedule queue */ - snd_seq_timestamp_t time; /**< schedule time */ - - snd_seq_addr_t source; /**< source address */ - snd_seq_addr_t dest; /**< destination address */ - - union { - snd_seq_ev_note_t note; /**< note information */ - snd_seq_ev_ctrl_t control; /**< MIDI control information */ - snd_seq_ev_raw8_t raw8; /**< raw8 data */ - snd_seq_ev_raw32_t raw32; /**< raw32 data */ - snd_seq_ev_ext_t ext; /**< external data */ - snd_seq_ev_queue_control_t queue; /**< queue control */ - snd_seq_timestamp_t time; /**< timestamp */ - snd_seq_addr_t addr; /**< address */ - snd_seq_connect_t connect; /**< connect information */ - snd_seq_result_t result; /**< operation result code */ - } data; /**< event data... */ -} snd_seq_event_t; - - -/** \} */ - -#endif /* __ALSA_SEQ_EVENT_H */ - diff --git a/shell/linux-deps/include/alsa/seq_midi_event.h b/shell/linux-deps/include/alsa/seq_midi_event.h deleted file mode 100644 index 9b8ee5963..000000000 --- a/shell/linux-deps/include/alsa/seq_midi_event.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * \file include/seq_midi_event.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_SEQ_MIDI_EVENT_H -#define __ALSA_SEQ_MIDI_EVENT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup MIDI_Event Sequencer event <-> MIDI byte stream coder - * \ingroup Sequencer - * Sequencer event <-> MIDI byte stream coder - * \{ - */ - -/** container for sequencer midi event parsers */ -typedef struct snd_midi_event snd_midi_event_t; - -int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev); -int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize); -void snd_midi_event_free(snd_midi_event_t *dev); -void snd_midi_event_init(snd_midi_event_t *dev); -void snd_midi_event_reset_encode(snd_midi_event_t *dev); -void snd_midi_event_reset_decode(snd_midi_event_t *dev); -void snd_midi_event_no_status(snd_midi_event_t *dev, int on); -/* encode from byte stream - return number of written bytes if success */ -long snd_midi_event_encode(snd_midi_event_t *dev, const unsigned char *buf, long count, snd_seq_event_t *ev); -int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev); -/* decode from event to bytes - return number of written bytes if success */ -long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, const snd_seq_event_t *ev); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_SEQ_MIDI_EVENT_H */ - diff --git a/shell/linux-deps/include/alsa/seqmid.h b/shell/linux-deps/include/alsa/seqmid.h deleted file mode 100644 index 68069b2aa..000000000 --- a/shell/linux-deps/include/alsa/seqmid.h +++ /dev/null @@ -1,490 +0,0 @@ -/** - * \file include/seqmid.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_SEQMID_H -#define __ALSA_SEQMID_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup SeqMiddle Sequencer Middle Level Interface - * Sequencer Middle Level Interface - * \ingroup Sequencer - * \{ - */ - -/** - * \brief initialize event record - * \param ev event record pointer - * - * This macro clears the given event record pointer to the default status. - */ -#define snd_seq_ev_clear(ev) \ - memset(ev, 0, sizeof(snd_seq_event_t)) - -/** - * \brief set the tag for given event - * \param ev event record - * \param t event tag - * - * This macro sets the tag to the given event record. - */ -#define snd_seq_ev_set_tag(ev,t) \ - ((ev)->tag = (t)) - -/** - * \brief set the explicit destination - * \param ev event record - * \param c destination client id - * \param p destination port id - * - * This macro sets the client and port id numbers to the given event record. - * - * \sa snd_seq_ev_set_subs() - */ -#define snd_seq_ev_set_dest(ev,c,p) \ - ((ev)->dest.client = (c), (ev)->dest.port = (p)) - -/** - * \brief set broadcasting to subscribers - * \param ev event record - * - * This macro sets the destination as the subscribers. - * - * \sa snd_seq_ev_set_dest() - */ -#define snd_seq_ev_set_subs(ev) \ - ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\ - (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN) - -/** - * \brief set broadcasting to all clients/ports - * \param ev event record - * - * This macro sets the destination as the broadcasting. - * - * \sa snd_seq_ev_set_dest() - */ -#define snd_seq_ev_set_broadcast(ev) \ - ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\ - (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST) - -/** - * \brief set the source port - * \param ev event record - * \param p source port id - * - * This macro sets the source port id number. - */ -#define snd_seq_ev_set_source(ev,p) \ - ((ev)->source.port = (p)) - -/** - * \brief set direct passing mode (without queued) - * \param ev event instance - * - * This macro sets the event to the direct passing mode - * to be delivered immediately without queueing. - * - * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_schedule_real() - */ -#define snd_seq_ev_set_direct(ev) \ - ((ev)->queue = SND_SEQ_QUEUE_DIRECT) - -/** - * \brief set tick-scheduling mode on queue - * \param ev event instance - * \param q queue id to schedule - * \param relative relative time-stamp if non-zero - * \param ttick tick time-stamp to be delivered - * - * This macro sets the scheduling of the event in the - * MIDI tick mode. - * - * \sa snd_seq_ev_schedule_real(), snd_seq_ev_set_direct() - */ -#define snd_seq_ev_schedule_tick(ev, q, relative, ttick) \ - ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ - (ev)->flags |= SND_SEQ_TIME_STAMP_TICK,\ - (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ - (ev)->time.tick = (ttick),\ - (ev)->queue = (q)) - -/** - * \brief set real-time-scheduling mode on queue - * \param ev event instance - * \param q queue id to schedule - * \param relative relative time-stamp if non-zero - * \param rtime time-stamp to be delivered - * - * This macro sets the scheduling of the event in the - * realtime mode. - * - * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_set_direct() - */ -#define snd_seq_ev_schedule_real(ev, q, relative, rtime) \ - ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ - (ev)->flags |= SND_SEQ_TIME_STAMP_REAL,\ - (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ - (ev)->time.time = *(rtime),\ - (ev)->queue = (q)) - -/** - * \brief set event priority - * \param ev event instance - * \param high_prior 1 for high priority mode - */ -#define snd_seq_ev_set_priority(ev, high_prior) \ - ((ev)->flags &= ~SND_SEQ_PRIORITY_MASK,\ - (ev)->flags |= (high_prior) ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL) - -/** - * \brief set fixed data - * \param ev event instance - * - * Sets the event length mode as fixed size. - * - * \sa snd_seq_ev_set_variable(), snd_seq_ev_set_varusr() - */ -#define snd_seq_ev_set_fixed(ev) \ - ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ - (ev)->flags |= SND_SEQ_EVENT_LENGTH_FIXED) - -/** - * \brief set variable data - * \param ev event instance - * \param datalen length of the external data - * \param dataptr pointer of the external data - * - * Sets the event length mode as variable length and stores the data. - * - * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_varusr() - */ -#define snd_seq_ev_set_variable(ev, datalen, dataptr) \ - ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ - (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE,\ - (ev)->data.ext.len = (datalen),\ - (ev)->data.ext.ptr = (dataptr)) - -/** - * \brief set varusr data - * \param ev event instance - * \param datalen length of the external data - * \param dataptr pointer of the external data - * - * Sets the event length mode as variable user-space data and stores the data. - * - * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_variable() - */ -#define snd_seq_ev_set_varusr(ev, datalen, dataptr) \ - ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ - (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARUSR,\ - (ev)->data.ext.len = (datalen),\ - (ev)->data.ext.ptr = (dataptr)) - -/** - * \brief set queue controls - * \param ev event record - * \param typ event type - * \param q queue id - * \param val control value - */ -#define snd_seq_ev_set_queue_control(ev, typ, q, val) \ - ((ev)->type = (typ),\ - snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ - (ev)->data.queue.queue = (q),\ - (ev)->data.queue.param.value = (val)) - -/** - * \brief set the start queue event - * \param ev event record - * \param q queue id to start - * - * \sa snd_seq_ev_set_queue_stop(), snd_seq_ev_set_queue_continue() - */ -#define snd_seq_ev_set_queue_start(ev, q) \ - snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0) - -/** - * \brief set the stop queue event - * \param ev event record - * \param q queue id to stop - * - * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_continue() - */ -#define snd_seq_ev_set_queue_stop(ev, q) \ - snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0) - -/** - * \brief set the stop queue event - * \param ev event record - * \param q queue id to continue - * - * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop() - */ -#define snd_seq_ev_set_queue_continue(ev, q) \ - snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0) - -/** - * \brief set the stop queue event - * \param ev event record - * \param q queue id to change tempo - * \param val the new tempo value - */ -#define snd_seq_ev_set_queue_tempo(ev, q, val) \ - snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val) - -/** - * \brief set the real-time position of a queue - * \param ev event record - * \param q queue id to change tempo - * \param rtime the new real-time pointer - */ -#define snd_seq_ev_set_queue_pos_real(ev, q, rtime) \ - ((ev)->type = SND_SEQ_EVENT_SETPOS_TIME,\ - snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ - (ev)->data.queue.queue = (q),\ - (ev)->data.queue.param.time.time = *(rtime)) - -/** - * \brief set the tick-time position of a queue - * \param ev event record - * \param q queue id to change tempo - * \param ttime the new tick-time - */ -#define snd_seq_ev_set_queue_pos_tick(ev, q, ttime) \ - ((ev)->type = SND_SEQ_EVENT_SETPOS_TICK,\ - snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ - (ev)->data.queue.queue = (q),\ - (ev)->data.queue.param.time.tick = (ttime)) - -/* set and send a queue control event */ -int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev); - -/** - * \brief start the specified queue - * \param seq sequencer handle - * \param q queue id to start - * \param ev optional event record (see #snd_seq_control_queue) - */ -#define snd_seq_start_queue(seq, q, ev) \ - snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev) - -/** - * \brief stop the specified queue - * \param seq sequencer handle - * \param q queue id to stop - * \param ev optional event record (see #snd_seq_control_queue) - */ -#define snd_seq_stop_queue(seq, q, ev) \ - snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev) - -/** - * \brief continue the specified queue - * \param seq sequencer handle - * \param q queue id to continue - * \param ev optional event record (see #snd_seq_control_queue) - */ -#define snd_seq_continue_queue(seq, q, ev) \ - snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev) - -/** - * \brief change the tempo of the specified queue - * \param seq sequencer handle - * \param q queue id - * \param tempo the new tempo value - * \param ev optional event record (see #snd_seq_control_queue) - */ -#define snd_seq_change_queue_tempo(seq, q, tempo, ev) \ - snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev) - -/* create a port - simple version - return the port number */ -int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, - unsigned int caps, unsigned int type); -/* delete the port */ -int snd_seq_delete_simple_port(snd_seq_t *seq, int port); - -/* simple subscription between this port and another port - (w/o exclusive & time conversion) - */ -int snd_seq_connect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); -int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); -int snd_seq_disconnect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); -int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); - -/* - * set client information - */ -int snd_seq_set_client_name(snd_seq_t *seq, const char *name); -int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type); -int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size); -int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size); -int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size); -/* sync output queue */ -int snd_seq_sync_output_queue(snd_seq_t *seq); - -/* - * parse the given string and get the sequencer address - */ -int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *str); - -/* - * reset client input/output pool - */ -int snd_seq_reset_pool_output(snd_seq_t *seq); -int snd_seq_reset_pool_input(snd_seq_t *seq); - -/** - * \brief set note event - * \param ev event record - * \param ch channel number - * \param key note key - * \param vel velocity - * \param dur duration (in tick or msec) - */ -#define snd_seq_ev_set_note(ev, ch, key, vel, dur) \ - ((ev)->type = SND_SEQ_EVENT_NOTE,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.note.channel = (ch),\ - (ev)->data.note.note = (key),\ - (ev)->data.note.velocity = (vel),\ - (ev)->data.note.duration = (dur)) - -/** - * \brief set note-on event - * \param ev event record - * \param ch channel number - * \param key note key - * \param vel velocity - */ -#define snd_seq_ev_set_noteon(ev, ch, key, vel) \ - ((ev)->type = SND_SEQ_EVENT_NOTEON,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.note.channel = (ch),\ - (ev)->data.note.note = (key),\ - (ev)->data.note.velocity = (vel)) - -/** - * \brief set note-off event - * \param ev event record - * \param ch channel number - * \param key note key - * \param vel velocity - */ -#define snd_seq_ev_set_noteoff(ev, ch, key, vel) \ - ((ev)->type = SND_SEQ_EVENT_NOTEOFF,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.note.channel = (ch),\ - (ev)->data.note.note = (key),\ - (ev)->data.note.velocity = (vel)) - -/** - * \brief set key-pressure event - * \param ev event record - * \param ch channel number - * \param key note key - * \param vel velocity - */ -#define snd_seq_ev_set_keypress(ev,ch,key,vel) \ - ((ev)->type = SND_SEQ_EVENT_KEYPRESS,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.note.channel = (ch),\ - (ev)->data.note.note = (key),\ - (ev)->data.note.velocity = (vel)) - -/** - * \brief set MIDI controller event - * \param ev event record - * \param ch channel number - * \param cc controller number - * \param val control value - */ -#define snd_seq_ev_set_controller(ev,ch,cc,val) \ - ((ev)->type = SND_SEQ_EVENT_CONTROLLER,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.control.channel = (ch),\ - (ev)->data.control.param = (cc),\ - (ev)->data.control.value = (val)) - -/** - * \brief set program change event - * \param ev event record - * \param ch channel number - * \param val program number - */ -#define snd_seq_ev_set_pgmchange(ev,ch,val) \ - ((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.control.channel = (ch),\ - (ev)->data.control.value = (val)) - -/** - * \brief set pitch-bend event - * \param ev event record - * \param ch channel number - * \param val pitch bend; zero centered from -8192 to 8191 - */ -#define snd_seq_ev_set_pitchbend(ev,ch,val) \ - ((ev)->type = SND_SEQ_EVENT_PITCHBEND,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.control.channel = (ch),\ - (ev)->data.control.value = (val)) - -/** - * \brief set channel pressure event - * \param ev event record - * \param ch channel number - * \param val channel pressure value - */ -#define snd_seq_ev_set_chanpress(ev,ch,val) \ - ((ev)->type = SND_SEQ_EVENT_CHANPRESS,\ - snd_seq_ev_set_fixed(ev),\ - (ev)->data.control.channel = (ch),\ - (ev)->data.control.value = (val)) - -/** - * \brief set sysex event - * \param ev event record - * \param datalen length of sysex data - * \param dataptr sysex data pointer - * - * the sysex data must contain the start byte 0xf0 and the end byte 0xf7. - */ -#define snd_seq_ev_set_sysex(ev,datalen,dataptr) \ - ((ev)->type = SND_SEQ_EVENT_SYSEX,\ - snd_seq_ev_set_variable(ev, datalen, dataptr)) - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_SEQMID_H */ - diff --git a/shell/linux-deps/include/alsa/sound/asound_fm.h b/shell/linux-deps/include/alsa/sound/asound_fm.h deleted file mode 100644 index c2a4b967d..000000000 --- a/shell/linux-deps/include/alsa/sound/asound_fm.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __SOUND_ASOUND_FM_H -#define __SOUND_ASOUND_FM_H - -/* - * Advanced Linux Sound Architecture - ALSA - * - * Interface file between ALSA driver & user space - * Copyright (c) 1994-98 by Jaroslav Kysela , - * 4Front Technologies - * - * Direct FM control - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define SNDRV_DM_FM_MODE_OPL2 0x00 -#define SNDRV_DM_FM_MODE_OPL3 0x01 - -struct snd_dm_fm_info { - unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ - unsigned char rhythm; /* percussion mode flag */ -}; - -/* - * Data structure composing an FM "note" or sound event. - */ - -struct snd_dm_fm_voice { - unsigned char op; /* operator cell (0 or 1) */ - unsigned char voice; /* FM voice (0 to 17) */ - - unsigned char am; /* amplitude modulation */ - unsigned char vibrato; /* vibrato effect */ - unsigned char do_sustain; /* sustain phase */ - unsigned char kbd_scale; /* keyboard scaling */ - unsigned char harmonic; /* 4 bits: harmonic and multiplier */ - unsigned char scale_level; /* 2 bits: decrease output freq rises */ - unsigned char volume; /* 6 bits: volume */ - - unsigned char attack; /* 4 bits: attack rate */ - unsigned char decay; /* 4 bits: decay rate */ - unsigned char sustain; /* 4 bits: sustain level */ - unsigned char release; /* 4 bits: release rate */ - - unsigned char feedback; /* 3 bits: feedback for op0 */ - unsigned char connection; /* 0 for serial, 1 for parallel */ - unsigned char left; /* stereo left */ - unsigned char right; /* stereo right */ - unsigned char waveform; /* 3 bits: waveform shape */ -}; - -/* - * This describes an FM note by its voice, octave, frequency number (10bit) - * and key on/off. - */ - -struct snd_dm_fm_note { - unsigned char voice; /* 0-17 voice channel */ - unsigned char octave; /* 3 bits: what octave to play */ - unsigned int fnum; /* 10 bits: frequency number */ - unsigned char key_on; /* set for active, clear for silent */ -}; - -/* - * FM parameters that apply globally to all voices, and thus are not "notes" - */ - -struct snd_dm_fm_params { - unsigned char am_depth; /* amplitude modulation depth (1=hi) */ - unsigned char vib_depth; /* vibrato depth (1=hi) */ - unsigned char kbd_split; /* keyboard split */ - unsigned char rhythm; /* percussion mode select */ - - /* This block is the percussion instrument data */ - unsigned char bass; - unsigned char snare; - unsigned char tomtom; - unsigned char cymbal; - unsigned char hihat; -}; - -/* - * FM mode ioctl settings - */ - -#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, struct snd_dm_fm_info) -#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21) -#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, struct snd_dm_fm_note) -#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, struct snd_dm_fm_voice) -#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, struct snd_dm_fm_params) -#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int) -/* for OPL3 only */ -#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int) -/* SBI patch management */ -#define SNDRV_DM_FM_IOCTL_CLEAR_PATCHES _IO ('H', 0x40) - -#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20 -#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21 -#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22 -#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23 -#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24 -#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25 - -/* - * Patch Record - fixed size for write - */ - -#define FM_KEY_SBI "SBI\032" -#define FM_KEY_2OP "2OP\032" -#define FM_KEY_4OP "4OP\032" - -struct sbi_patch { - unsigned char prog; - unsigned char bank; - char key[4]; - char name[25]; - char extension[7]; - unsigned char data[32]; -}; - -#endif /* __SOUND_ASOUND_FM_H */ diff --git a/shell/linux-deps/include/alsa/sound/emu10k1.h b/shell/linux-deps/include/alsa/sound/emu10k1.h deleted file mode 100644 index 94018b74d..000000000 --- a/shell/linux-deps/include/alsa/sound/emu10k1.h +++ /dev/null @@ -1,349 +0,0 @@ -#ifndef __SOUND_EMU10K1_H -#define __SOUND_EMU10K1_H - -/* - * Copyright (c) by Jaroslav Kysela , - * Creative Labs, Inc. - * Definitions for EMU10K1 (SB Live!) chips - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include - -/* - * ---- FX8010 ---- - */ - -#define EMU10K1_CARD_CREATIVE 0x00000000 -#define EMU10K1_CARD_EMUAPS 0x00000001 - -#define EMU10K1_FX8010_PCM_COUNT 8 - -/* instruction set */ -#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */ -#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */ -#define iMAC2 0x02 /* R = A + (X * Y >> 31) ; wraparound */ -#define iMAC3 0x03 /* R = A + (-X * Y >> 31) ; wraparound */ -#define iMACINT0 0x04 /* R = A + X * Y ; saturation */ -#define iMACINT1 0x05 /* R = A + X * Y ; wraparound (31-bit) */ -#define iACC3 0x06 /* R = A + X + Y ; saturation */ -#define iMACMV 0x07 /* R = A, acc += X * Y >> 31 */ -#define iANDXOR 0x08 /* R = (A & X) ^ Y */ -#define iTSTNEG 0x09 /* R = (A >= Y) ? X : ~X */ -#define iLIMITGE 0x0a /* R = (A >= Y) ? X : Y */ -#define iLIMITLT 0x0b /* R = (A < Y) ? X : Y */ -#define iLOG 0x0c /* R = linear_data, A (log_data), X (max_exp), Y (format_word) */ -#define iEXP 0x0d /* R = log_data, A (linear_data), X (max_exp), Y (format_word) */ -#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */ -#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */ - -/* GPRs */ -#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */ -#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */ -#define EXTOUT(x) (0x20 + (x)) /* x = 0x00 - 0x0f */ -#define C_00000000 0x40 -#define C_00000001 0x41 -#define C_00000002 0x42 -#define C_00000003 0x43 -#define C_00000004 0x44 -#define C_00000008 0x45 -#define C_00000010 0x46 -#define C_00000020 0x47 -#define C_00000100 0x48 -#define C_00010000 0x49 -#define C_00080000 0x4a -#define C_10000000 0x4b -#define C_20000000 0x4c -#define C_40000000 0x4d -#define C_80000000 0x4e -#define C_7fffffff 0x4f -#define C_ffffffff 0x50 -#define C_fffffffe 0x51 -#define C_c0000000 0x52 -#define C_4f1bbcdc 0x53 -#define C_5a7ef9db 0x54 -#define C_00100000 0x55 /* ?? */ -#define GPR_ACCU 0x56 /* ACCUM, accumulator */ -#define GPR_COND 0x57 /* CCR, condition register */ -#define GPR_NOISE0 0x58 /* noise source */ -#define GPR_NOISE1 0x59 /* noise source */ -#define GPR_IRQ 0x5a /* IRQ register */ -#define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */ -#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */ -#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */ -#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */ -#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */ -#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */ - -#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f? */ -#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x1f? */ -#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f? */ -#define A_GPR(x) (A_FXGPREGBASE + (x)) - -/* cc_reg constants */ -#define CC_REG_NORMALIZED C_00000001 -#define CC_REG_BORROW C_00000002 -#define CC_REG_MINUS C_00000004 -#define CC_REG_ZERO C_00000008 -#define CC_REG_SATURATE C_00000010 -#define CC_REG_NONZERO C_00000100 - -/* FX buses */ -#define FXBUS_PCM_LEFT 0x00 -#define FXBUS_PCM_RIGHT 0x01 -#define FXBUS_PCM_LEFT_REAR 0x02 -#define FXBUS_PCM_RIGHT_REAR 0x03 -#define FXBUS_MIDI_LEFT 0x04 -#define FXBUS_MIDI_RIGHT 0x05 -#define FXBUS_PCM_CENTER 0x06 -#define FXBUS_PCM_LFE 0x07 -#define FXBUS_PCM_LEFT_FRONT 0x08 -#define FXBUS_PCM_RIGHT_FRONT 0x09 -#define FXBUS_MIDI_REVERB 0x0c -#define FXBUS_MIDI_CHORUS 0x0d -#define FXBUS_PCM_LEFT_SIDE 0x0e -#define FXBUS_PCM_RIGHT_SIDE 0x0f -#define FXBUS_PT_LEFT 0x14 -#define FXBUS_PT_RIGHT 0x15 - -/* Inputs */ -#define EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ -#define EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ -#define EXTIN_SPDIF_CD_L 0x02 /* internal S/PDIF CD - onboard - left */ -#define EXTIN_SPDIF_CD_R 0x03 /* internal S/PDIF CD - onboard - right */ -#define EXTIN_ZOOM_L 0x04 /* Zoom Video I2S - left */ -#define EXTIN_ZOOM_R 0x05 /* Zoom Video I2S - right */ -#define EXTIN_TOSLINK_L 0x06 /* LiveDrive - TOSLink Optical - left */ -#define EXTIN_TOSLINK_R 0x07 /* LiveDrive - TOSLink Optical - right */ -#define EXTIN_LINE1_L 0x08 /* LiveDrive - Line/Mic 1 - left */ -#define EXTIN_LINE1_R 0x09 /* LiveDrive - Line/Mic 1 - right */ -#define EXTIN_COAX_SPDIF_L 0x0a /* LiveDrive - Coaxial S/PDIF - left */ -#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */ -#define EXTIN_LINE2_L 0x0c /* LiveDrive - Line/Mic 2 - left */ -#define EXTIN_LINE2_R 0x0d /* LiveDrive - Line/Mic 2 - right */ - -/* Outputs */ -#define EXTOUT_AC97_L 0x00 /* AC'97 playback channel - left */ -#define EXTOUT_AC97_R 0x01 /* AC'97 playback channel - right */ -#define EXTOUT_TOSLINK_L 0x02 /* LiveDrive - TOSLink Optical - left */ -#define EXTOUT_TOSLINK_R 0x03 /* LiveDrive - TOSLink Optical - right */ -#define EXTOUT_AC97_CENTER 0x04 /* SB Live 5.1 - center */ -#define EXTOUT_AC97_LFE 0x05 /* SB Live 5.1 - LFE */ -#define EXTOUT_HEADPHONE_L 0x06 /* LiveDrive - Headphone - left */ -#define EXTOUT_HEADPHONE_R 0x07 /* LiveDrive - Headphone - right */ -#define EXTOUT_REAR_L 0x08 /* Rear channel - left */ -#define EXTOUT_REAR_R 0x09 /* Rear channel - right */ -#define EXTOUT_ADC_CAP_L 0x0a /* ADC Capture buffer - left */ -#define EXTOUT_ADC_CAP_R 0x0b /* ADC Capture buffer - right */ -#define EXTOUT_MIC_CAP 0x0c /* MIC Capture buffer */ -#define EXTOUT_AC97_REAR_L 0x0d /* SB Live 5.1 (c) 2003 - Rear Left */ -#define EXTOUT_AC97_REAR_R 0x0e /* SB Live 5.1 (c) 2003 - Rear Right */ -#define EXTOUT_ACENTER 0x11 /* Analog Center */ -#define EXTOUT_ALFE 0x12 /* Analog LFE */ - -/* Audigy Inputs */ -#define A_EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ -#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ -#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */ -#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */ -#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */ -#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */ -#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */ -#define A_EXTIN_LINE2_R 0x09 /* right */ -#define A_EXTIN_ADC_L 0x0a /* Philips ADC - left */ -#define A_EXTIN_ADC_R 0x0b /* right */ -#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */ -#define A_EXTIN_AUX2_R 0x0d /* - right */ - -/* Audigiy Outputs */ -#define A_EXTOUT_FRONT_L 0x00 /* digital front left */ -#define A_EXTOUT_FRONT_R 0x01 /* right */ -#define A_EXTOUT_CENTER 0x02 /* digital front center */ -#define A_EXTOUT_LFE 0x03 /* digital front lfe */ -#define A_EXTOUT_HEADPHONE_L 0x04 /* headphone audigy drive left */ -#define A_EXTOUT_HEADPHONE_R 0x05 /* right */ -#define A_EXTOUT_REAR_L 0x06 /* digital rear left */ -#define A_EXTOUT_REAR_R 0x07 /* right */ -#define A_EXTOUT_AFRONT_L 0x08 /* analog front left */ -#define A_EXTOUT_AFRONT_R 0x09 /* right */ -#define A_EXTOUT_ACENTER 0x0a /* analog center */ -#define A_EXTOUT_ALFE 0x0b /* analog LFE */ -#define A_EXTOUT_ASIDE_L 0x0c /* analog side left - Audigy 2 ZS */ -#define A_EXTOUT_ASIDE_R 0x0d /* right - Audigy 2 ZS */ -#define A_EXTOUT_AREAR_L 0x0e /* analog rear left */ -#define A_EXTOUT_AREAR_R 0x0f /* right */ -#define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */ -#define A_EXTOUT_AC97_R 0x11 /* right */ -#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */ -#define A_EXTOUT_ADC_CAP_R 0x17 /* right */ -#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */ - -/* Audigy constants */ -#define A_C_00000000 0xc0 -#define A_C_00000001 0xc1 -#define A_C_00000002 0xc2 -#define A_C_00000003 0xc3 -#define A_C_00000004 0xc4 -#define A_C_00000008 0xc5 -#define A_C_00000010 0xc6 -#define A_C_00000020 0xc7 -#define A_C_00000100 0xc8 -#define A_C_00010000 0xc9 -#define A_C_00000800 0xca -#define A_C_10000000 0xcb -#define A_C_20000000 0xcc -#define A_C_40000000 0xcd -#define A_C_80000000 0xce -#define A_C_7fffffff 0xcf -#define A_C_ffffffff 0xd0 -#define A_C_fffffffe 0xd1 -#define A_C_c0000000 0xd2 -#define A_C_4f1bbcdc 0xd3 -#define A_C_5a7ef9db 0xd4 -#define A_C_00100000 0xd5 -#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */ -#define A_GPR_COND 0xd7 /* CCR, condition register */ -#define A_GPR_NOISE0 0xd8 /* noise source */ -#define A_GPR_NOISE1 0xd9 /* noise source */ -#define A_GPR_IRQ 0xda /* IRQ register */ -#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */ -#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */ - -/* definitions for debug register */ -#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */ -#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */ -#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */ -#define EMU10K1_DBG_SINGLE_STEP 0x00008000 /* single step mode */ -#define EMU10K1_DBG_STEP 0x00004000 /* start single step */ -#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */ -#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */ - -/* tank memory address line */ -#ifndef __KERNEL__ -#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */ -#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */ -#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */ -#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */ -#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */ -#endif - -typedef struct { - unsigned int internal_tram_size; /* in samples */ - unsigned int external_tram_size; /* in samples */ - char fxbus_names[16][32]; /* names of FXBUSes */ - char extin_names[16][32]; /* names of external inputs */ - char extout_names[32][32]; /* names of external outputs */ - unsigned int gpr_controls; /* count of GPR controls */ -} emu10k1_fx8010_info_t; - -#define EMU10K1_GPR_TRANSLATION_NONE 0 -#define EMU10K1_GPR_TRANSLATION_TABLE100 1 -#define EMU10K1_GPR_TRANSLATION_BASS 2 -#define EMU10K1_GPR_TRANSLATION_TREBLE 3 -#define EMU10K1_GPR_TRANSLATION_ONOFF 4 - -enum emu10k1_ctl_elem_iface { - EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ - EMU10K1_CTL_ELEM_IFACE_PCM = 3, /* PCM device */ -}; - -typedef struct { - unsigned int pad; /* don't use */ - int iface; /* interface identifier */ - unsigned int device; /* device/client number */ - unsigned int subdevice; /* subdevice (substream) number */ - unsigned char name[44]; /* ASCII name of item */ - unsigned int index; /* index of item */ -} emu10k1_ctl_elem_id_t; - -typedef struct { - emu10k1_ctl_elem_id_t id; /* full control ID definition */ - unsigned int vcount; /* visible count */ - unsigned int count; /* count of GPR (1..16) */ - unsigned short gpr[32]; /* GPR number(s) */ - unsigned int value[32]; /* initial values */ - unsigned int min; /* minimum range */ - unsigned int max; /* maximum range */ - unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ - unsigned int *tlv; -} emu10k1_fx8010_control_gpr_t; - -typedef struct { - char name[128]; - - unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ - uint32_t *gpr_map; /* initializers */ - - unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */ - emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */ - - unsigned int gpr_del_control_count; /* count of GPR controls to remove */ - emu10k1_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */ - - unsigned int gpr_list_control_count; /* count of GPR controls to list */ - unsigned int gpr_list_control_total; /* total count of GPR controls */ - emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */ - - unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */ - uint32_t *tram_data_map; /* data initializers */ - uint32_t *tram_addr_map; /* map initializers */ - - unsigned long code_valid[1024/(sizeof(unsigned long)*8)]; /* bitmask of valid instructions */ - uint32_t *code; /* one instruction - 64 bits */ -} emu10k1_fx8010_code_t; - -typedef struct { - unsigned int address; /* 31.bit == 1 -> external TRAM */ - unsigned int size; /* size in samples (4 bytes) */ - unsigned int *samples; /* pointer to samples (20-bit) */ - /* NULL->clear memory */ -} emu10k1_fx8010_tram_t; - -typedef struct { - unsigned int substream; /* substream number */ - unsigned int res1; /* reserved */ - unsigned int channels; /* 16-bit channels count, zero = remove this substream */ - unsigned int tram_start; /* ring buffer position in TRAM (in samples) */ - unsigned int buffer_size; /* count of buffered samples */ - unsigned short gpr_size; /* GPR containing size of ringbuffer in samples (host) */ - unsigned short gpr_ptr; /* GPR containing current pointer in the ring buffer (host = reset, FX8010) */ - unsigned short gpr_count; /* GPR containing count of samples between two interrupts (host) */ - unsigned short gpr_tmpcount; /* GPR containing current count of samples to interrupt (host = set, FX8010) */ - unsigned short gpr_trigger; /* GPR containing trigger (activate) information (host) */ - unsigned short gpr_running; /* GPR containing info if PCM is running (FX8010) */ - unsigned char pad; /* reserved */ - unsigned char etram[32]; /* external TRAM address & data (one per channel) */ - unsigned int res2; /* reserved */ -} emu10k1_fx8010_pcm_t; - -#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t) -#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t) -#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t) -#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int) -#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t) -#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t) -#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t) -#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t) -#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int) -#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80) -#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81) -#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82) -#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int) -#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int) - -#endif /* __SOUND_EMU10K1_H */ diff --git a/shell/linux-deps/include/alsa/sound/hdsp.h b/shell/linux-deps/include/alsa/sound/hdsp.h deleted file mode 100644 index 5adaf7b0e..000000000 --- a/shell/linux-deps/include/alsa/sound/hdsp.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef __SOUND_HDSP_H -#define __SOUND_HDSP_H - -/* - * Copyright (C) 2003 Thomas Charbonnel (thomas@undata.org) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#define HDSP_MATRIX_MIXER_SIZE 2048 - -typedef enum { - Digiface, - Multiface, - H9652, - H9632, - RPM, - Undefined, -} HDSP_IO_Type; - -typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t; - -struct _snd_hdsp_peak_rms { - uint32_t input_peaks[26]; - uint32_t playback_peaks[26]; - uint32_t output_peaks[28]; - uint64_t input_rms[26]; - uint64_t playback_rms[26]; - /* These are only used for H96xx cards */ - uint64_t output_rms[26]; -}; - -#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t) - -typedef struct _snd_hdsp_config_info hdsp_config_info_t; - -struct _snd_hdsp_config_info { - unsigned char pref_sync_ref; - unsigned char wordclock_sync_check; - unsigned char spdif_sync_check; - unsigned char adatsync_sync_check; - unsigned char adat_sync_check[3]; - unsigned char spdif_in; - unsigned char spdif_out; - unsigned char spdif_professional; - unsigned char spdif_emphasis; - unsigned char spdif_nonaudio; - unsigned int spdif_sample_rate; - unsigned int system_sample_rate; - unsigned int autosync_sample_rate; - unsigned char system_clock_mode; - unsigned char clock_source; - unsigned char autosync_ref; - unsigned char line_out; - unsigned char passthru; - unsigned char da_gain; - unsigned char ad_gain; - unsigned char phone_gain; - unsigned char xlr_breakout_cable; - unsigned char analog_extension_board; -}; - -#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t) - -typedef struct _snd_hdsp_firmware hdsp_firmware_t; - -struct _snd_hdsp_firmware { - void *firmware_data; /* 24413 x 4 bytes */ -}; - -#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t) - -typedef struct _snd_hdsp_version hdsp_version_t; - -struct _snd_hdsp_version { - HDSP_IO_Type io_type; - unsigned short firmware_rev; -}; - -#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t) - -typedef struct _snd_hdsp_mixer hdsp_mixer_t; - -struct _snd_hdsp_mixer { - unsigned short matrix[HDSP_MATRIX_MIXER_SIZE]; -}; - -#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t) - -typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t; - -struct _snd_hdsp_9632_aeb { - int aebi; - int aebo; -}; - -#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t) - -#endif /* __SOUND_HDSP_H */ diff --git a/shell/linux-deps/include/alsa/sound/hdspm.h b/shell/linux-deps/include/alsa/sound/hdspm.h deleted file mode 100644 index 1774ff5ff..000000000 --- a/shell/linux-deps/include/alsa/sound/hdspm.h +++ /dev/null @@ -1,229 +0,0 @@ -#ifndef __SOUND_HDSPM_H -#define __SOUND_HDSPM_H -/* - * Copyright (C) 2003 Winfried Ritsch (IEM) - * based on hdsp.h from Thomas Charbonnel (thomas@undata.org) - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */ -#define HDSPM_MAX_CHANNELS 64 - -enum hdspm_io_type { - MADI, - MADIface, - AIO, - AES32, - RayDAT -}; - -enum hdspm_speed { - ss, - ds, - qs -}; - -/* -------------------- IOCTL Peak/RMS Meters -------------------- */ - -struct hdspm_peak_rms { - uint32_t input_peaks[64]; - uint32_t playback_peaks[64]; - uint32_t output_peaks[64]; - - uint64_t input_rms[64]; - uint64_t playback_rms[64]; - uint64_t output_rms[64]; - - uint8_t speed; /* enum {ss, ds, qs} */ - int status2; -}; - -#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS \ - _IOR('H', 0x42, struct hdspm_peak_rms) - -/* ------------ CONFIG block IOCTL ---------------------- */ - -struct hdspm_config { - unsigned char pref_sync_ref; - unsigned char wordclock_sync_check; - unsigned char madi_sync_check; - unsigned int system_sample_rate; - unsigned int autosync_sample_rate; - unsigned char system_clock_mode; - unsigned char clock_source; - unsigned char autosync_ref; - unsigned char line_out; - unsigned int passthru; - unsigned int analog_out; -}; - -#define SNDRV_HDSPM_IOCTL_GET_CONFIG \ - _IOR('H', 0x41, struct hdspm_config) - -/** - * If there's a TCO (TimeCode Option) board installed, - * there are further options and status data available. - * The hdspm_ltc structure contains the current SMPTE - * timecode and some status information and can be - * obtained via SNDRV_HDSPM_IOCTL_GET_LTC or in the - * hdspm_status struct. - **/ - -enum hdspm_ltc_format { - format_invalid, - fps_24, - fps_25, - fps_2997, - fps_30 -}; - -enum hdspm_ltc_frame { - frame_invalid, - drop_frame, - full_frame -}; - -enum hdspm_ltc_input_format { - ntsc, - pal, - no_video -}; - -struct hdspm_ltc { - unsigned int ltc; - - enum hdspm_ltc_format format; - enum hdspm_ltc_frame frame; - enum hdspm_ltc_input_format input_format; -}; - -#define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_mixer_ioctl) - -/** - * The status data reflects the device's current state - * as determined by the card's configuration and - * connection status. - **/ - -enum hdspm_sync { - hdspm_sync_no_lock = 0, - hdspm_sync_lock = 1, - hdspm_sync_sync = 2 -}; - -enum hdspm_madi_input { - hdspm_input_optical = 0, - hdspm_input_coax = 1 -}; - -enum hdspm_madi_channel_format { - hdspm_format_ch_64 = 0, - hdspm_format_ch_56 = 1 -}; - -enum hdspm_madi_frame_format { - hdspm_frame_48 = 0, - hdspm_frame_96 = 1 -}; - -enum hdspm_syncsource { - syncsource_wc = 0, - syncsource_madi = 1, - syncsource_tco = 2, - syncsource_sync = 3, - syncsource_none = 4 -}; - -struct hdspm_status { - uint8_t card_type; /* enum hdspm_io_type */ - enum hdspm_syncsource autosync_source; - - uint64_t card_clock; - uint32_t master_period; - - union { - struct { - uint8_t sync_wc; /* enum hdspm_sync */ - uint8_t sync_madi; /* enum hdspm_sync */ - uint8_t sync_tco; /* enum hdspm_sync */ - uint8_t sync_in; /* enum hdspm_sync */ - uint8_t madi_input; /* enum hdspm_madi_input */ - uint8_t channel_format; /* enum hdspm_madi_channel_format */ - uint8_t frame_format; /* enum hdspm_madi_frame_format */ - } madi; - } card_specific; -}; - -#define SNDRV_HDSPM_IOCTL_GET_STATUS \ - _IOR('H', 0x47, struct hdspm_status) - -/** - * Get information about the card and its add-ons. - **/ - -#define HDSPM_ADDON_TCO 1 - -struct hdspm_version { - uint8_t card_type; /* enum hdspm_io_type */ - char cardname[20]; - unsigned int serial; - unsigned short firmware_rev; - int addons; -}; - -#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x48, struct hdspm_version) - -/* ------------- get Matrix Mixer IOCTL --------------- */ - -/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte = - * 32768 Bytes - */ - -/* organisation is 64 channelfader in a continous memory block */ -/* equivalent to hardware definition, maybe for future feature of mmap of - * them - */ -/* each of 64 outputs has 64 infader and 64 outfader: - Ins to Outs mixer[out].in[in], Outstreams to Outs mixer[out].pb[pb] */ - -#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS - -struct hdspm_channelfader { - unsigned int in[HDSPM_MIXER_CHANNELS]; - unsigned int pb[HDSPM_MIXER_CHANNELS]; -}; - -struct hdspm_mixer { - struct hdspm_channelfader ch[HDSPM_MIXER_CHANNELS]; -}; - -struct hdspm_mixer_ioctl { - struct hdspm_mixer *mixer; -}; - -/* use indirect access due to the limit of ioctl bit size */ -#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl) - -/* typedefs for compatibility to user-space */ -typedef struct hdspm_peak_rms hdspm_peak_rms_t; -typedef struct hdspm_config_info hdspm_config_info_t; -typedef struct hdspm_version hdspm_version_t; -typedef struct hdspm_channelfader snd_hdspm_channelfader_t; -typedef struct hdspm_mixer hdspm_mixer_t; - - -#endif diff --git a/shell/linux-deps/include/alsa/sound/sb16_csp.h b/shell/linux-deps/include/alsa/sound/sb16_csp.h deleted file mode 100644 index 78817b40c..000000000 --- a/shell/linux-deps/include/alsa/sound/sb16_csp.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef __SOUND_SB16_CSP_H -#define __SOUND_SB16_CSP_H - -/* - * Copyright (c) 1999 by Uros Bizjak - * Takashi Iwai - * - * SB16ASP/AWE32 CSP control - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* CSP modes */ -#define SNDRV_SB_CSP_MODE_NONE 0x00 -#define SNDRV_SB_CSP_MODE_DSP_READ 0x01 /* Record from DSP */ -#define SNDRV_SB_CSP_MODE_DSP_WRITE 0x02 /* Play to DSP */ -#define SNDRV_SB_CSP_MODE_QSOUND 0x04 /* QSound */ - -/* CSP load flags */ -#define SNDRV_SB_CSP_LOAD_FROMUSER 0x01 -#define SNDRV_SB_CSP_LOAD_INITBLOCK 0x02 - -/* CSP sample width */ -#define SNDRV_SB_CSP_SAMPLE_8BIT 0x01 -#define SNDRV_SB_CSP_SAMPLE_16BIT 0x02 - -/* CSP channels */ -#define SNDRV_SB_CSP_MONO 0x01 -#define SNDRV_SB_CSP_STEREO 0x02 - -/* CSP rates */ -#define SNDRV_SB_CSP_RATE_8000 0x01 -#define SNDRV_SB_CSP_RATE_11025 0x02 -#define SNDRV_SB_CSP_RATE_22050 0x04 -#define SNDRV_SB_CSP_RATE_44100 0x08 -#define SNDRV_SB_CSP_RATE_ALL 0x0f - -/* CSP running state */ -#define SNDRV_SB_CSP_ST_IDLE 0x00 -#define SNDRV_SB_CSP_ST_LOADED 0x01 -#define SNDRV_SB_CSP_ST_RUNNING 0x02 -#define SNDRV_SB_CSP_ST_PAUSED 0x04 -#define SNDRV_SB_CSP_ST_AUTO 0x08 -#define SNDRV_SB_CSP_ST_QSOUND 0x10 - -/* maximum QSound value (180 degrees right) */ -#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT 0x20 - -/* maximum microcode RIFF file size */ -#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000 - -/* microcode header */ -typedef struct snd_sb_csp_mc_header { - char codec_name[16]; /* id name of codec */ - unsigned short func_req; /* requested function */ -} snd_sb_csp_mc_header_t; - -/* microcode to be loaded */ -typedef struct snd_sb_csp_microcode { - snd_sb_csp_mc_header_t info; - unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE]; -} snd_sb_csp_microcode_t; - -/* start CSP with sample_width in mono/stereo */ -typedef struct snd_sb_csp_start { - int sample_width; /* sample width, look above */ - int channels; /* channels, look above */ -} snd_sb_csp_start_t; - -/* CSP information */ -typedef struct snd_sb_csp_info { - char codec_name[16]; /* id name of codec */ - unsigned short func_nr; /* function number */ - unsigned int acc_format; /* accepted PCM formats */ - unsigned short acc_channels; /* accepted channels */ - unsigned short acc_width; /* accepted sample width */ - unsigned short acc_rates; /* accepted sample rates */ - unsigned short csp_mode; /* CSP mode, see above */ - unsigned short run_channels; /* current channels */ - unsigned short run_width; /* current sample width */ - unsigned short version; /* version id: 0x10 - 0x1f */ - unsigned short state; /* state bits */ -} snd_sb_csp_info_t; - -/* HWDEP controls */ -/* get CSP information */ -#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t) -/* load microcode to CSP */ -#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t) -/* unload microcode from CSP */ -#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12) -/* start CSP */ -#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t) -/* stop CSP */ -#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14) -/* pause CSP and DMA transfer */ -#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15) -/* restart CSP and DMA transfer */ -#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16) - - -#endif /* __SOUND_SB16_CSP */ diff --git a/shell/linux-deps/include/alsa/sound/sscape_ioctl.h b/shell/linux-deps/include/alsa/sound/sscape_ioctl.h deleted file mode 100644 index c6653ebfb..000000000 --- a/shell/linux-deps/include/alsa/sound/sscape_ioctl.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SSCAPE_IOCTL_H -#define SSCAPE_IOCTL_H - - -struct sscape_bootblock -{ - unsigned char code[256]; - unsigned version; -}; - -#define SSCAPE_MICROCODE_SIZE 65536 - -struct sscape_microcode -{ - unsigned char *code; -}; - -#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock) -#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode) - -#endif diff --git a/shell/linux-deps/include/alsa/sound/type_compat.h b/shell/linux-deps/include/alsa/sound/type_compat.h deleted file mode 100644 index eec86e4bc..000000000 --- a/shell/linux-deps/include/alsa/sound/type_compat.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __TYPE_COMPAT_H -#define __TYPE_COMPAT_H - -#ifndef DOC_HIDDEN -#include -typedef uint8_t __u8; -typedef uint16_t __u16; -typedef uint32_t __u32; -typedef int8_t __s8; -typedef int16_t __s16; -typedef int32_t __s32; - -#include -#include -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define __cpu_to_le32(x) (x) -#define __cpu_to_be32(x) bswap_32(x) -#define __cpu_to_le16(x) (x) -#define __cpu_to_be16(x) bswap_16(x) -#else -#define __cpu_to_le32(x) bswap_32(x) -#define __cpu_to_be32(x) (x) -#define __cpu_to_le16(x) bswap_16(x) -#define __cpu_to_be16(x) (x) -#endif - -#define __le32_to_cpu __cpu_to_le32 -#define __be32_to_cpu __cpu_to_be32 -#define __le16_to_cpu __cpu_to_le16 -#define __be16_to_cpu __cpu_to_be16 - -#define __le64 __u64 -#define __le32 __u32 -#define __le16 __u16 -#define __be64 __u64 -#define __be32 __u32 -#define __be16 __u16 -#endif /* DOC_HIDDEN */ - -#endif /* __TYPE_COMPAT_H */ diff --git a/shell/linux-deps/include/alsa/timer.h b/shell/linux-deps/include/alsa/timer.h deleted file mode 100644 index 2803f5327..000000000 --- a/shell/linux-deps/include/alsa/timer.h +++ /dev/null @@ -1,259 +0,0 @@ -/** - * \file include/timer.h - * \brief Application interface library for the ALSA driver - * \author Jaroslav Kysela - * \author Abramo Bagnara - * \author Takashi Iwai - * \date 1998-2001 - * - * Application interface library for the ALSA driver - */ -/* - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ALSA_TIMER_H -#define __ALSA_TIMER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Timer Timer Interface - * Timer Interface. See \ref timer page for more details. - * \{ - */ - -/** dlsym version for interface entry callback */ -#define SND_TIMER_DLSYM_VERSION _dlsym_timer_001 -/** dlsym version for interface entry callback */ -#define SND_TIMER_QUERY_DLSYM_VERSION _dlsym_timer_query_001 - -/** timer identification structure */ -typedef struct _snd_timer_id snd_timer_id_t; -/** timer global info structure */ -typedef struct _snd_timer_ginfo snd_timer_ginfo_t; -/** timer global params structure */ -typedef struct _snd_timer_gparams snd_timer_gparams_t; -/** timer global status structure */ -typedef struct _snd_timer_gstatus snd_timer_gstatus_t; -/** timer info structure */ -typedef struct _snd_timer_info snd_timer_info_t; -/** timer params structure */ -typedef struct _snd_timer_params snd_timer_params_t; -/** timer status structure */ -typedef struct _snd_timer_status snd_timer_status_t; -/** timer master class */ -typedef enum _snd_timer_class { - SND_TIMER_CLASS_NONE = -1, /**< invalid */ - SND_TIMER_CLASS_SLAVE = 0, /**< slave timer */ - SND_TIMER_CLASS_GLOBAL, /**< global timer */ - SND_TIMER_CLASS_CARD, /**< card timer */ - SND_TIMER_CLASS_PCM, /**< PCM timer */ - SND_TIMER_CLASS_LAST = SND_TIMER_CLASS_PCM /**< last timer */ -} snd_timer_class_t; - -/** timer slave class */ -typedef enum _snd_timer_slave_class { - SND_TIMER_SCLASS_NONE = 0, /**< none */ - SND_TIMER_SCLASS_APPLICATION, /**< for internal use */ - SND_TIMER_SCLASS_SEQUENCER, /**< sequencer timer */ - SND_TIMER_SCLASS_OSS_SEQUENCER, /**< OSS sequencer timer */ - SND_TIMER_SCLASS_LAST = SND_TIMER_SCLASS_OSS_SEQUENCER /**< last slave timer */ -} snd_timer_slave_class_t; - -/** timer read event identification */ -typedef enum _snd_timer_event { - SND_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ - SND_TIMER_EVENT_TICK, /* val = ticks */ - SND_TIMER_EVENT_START, /* val = resolution in ns */ - SND_TIMER_EVENT_STOP, /* val = 0 */ - SND_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ - SND_TIMER_EVENT_PAUSE, /* val = 0 */ - SND_TIMER_EVENT_EARLY, /* val = 0 */ - SND_TIMER_EVENT_SUSPEND, /* val = 0 */ - SND_TIMER_EVENT_RESUME, /* val = resolution in ns */ - /* master timer events for slave timer instances */ - SND_TIMER_EVENT_MSTART = SND_TIMER_EVENT_START + 10, - SND_TIMER_EVENT_MSTOP = SND_TIMER_EVENT_STOP + 10, - SND_TIMER_EVENT_MCONTINUE = SND_TIMER_EVENT_CONTINUE + 10, - SND_TIMER_EVENT_MPAUSE = SND_TIMER_EVENT_PAUSE + 10, - SND_TIMER_EVENT_MSUSPEND = SND_TIMER_EVENT_SUSPEND + 10, - SND_TIMER_EVENT_MRESUME = SND_TIMER_EVENT_RESUME + 10 -} snd_timer_event_t; - -/** timer read structure */ -typedef struct _snd_timer_read { - unsigned int resolution; /**< tick resolution in nanoseconds */ - unsigned int ticks; /**< count of happened ticks */ -} snd_timer_read_t; - -/** timer tstamp + event read structure */ -typedef struct _snd_timer_tread { - snd_timer_event_t event; /**< Timer event */ - snd_htimestamp_t tstamp; /**< Time stamp of each event */ - unsigned int val; /**< Event value */ -} snd_timer_tread_t; - -/** global timer - system */ -#define SND_TIMER_GLOBAL_SYSTEM 0 -/** global timer - RTC */ -#define SND_TIMER_GLOBAL_RTC 1 -/** global timer - HPET */ -#define SND_TIMER_GLOBAL_HPET 2 -/** global timer - HRTIMER */ -#define SND_TIMER_GLOBAL_HRTIMER 3 - -/** timer open mode flag - non-blocking behaviour */ -#define SND_TIMER_OPEN_NONBLOCK (1<<0) -/** use timestamps and event notification - enhanced read */ -#define SND_TIMER_OPEN_TREAD (1<<1) - -/** timer handle type */ -typedef enum _snd_timer_type { - /** Kernel level HwDep */ - SND_TIMER_TYPE_HW = 0, - /** Shared memory client timer (not yet implemented) */ - SND_TIMER_TYPE_SHM, - /** INET client timer (not yet implemented) */ - SND_TIMER_TYPE_INET -} snd_timer_type_t; - -/** timer query handle */ -typedef struct _snd_timer_query snd_timer_query_t; -/** timer handle */ -typedef struct _snd_timer snd_timer_t; - - -int snd_timer_query_open(snd_timer_query_t **handle, const char *name, int mode); -int snd_timer_query_open_lconf(snd_timer_query_t **handle, const char *name, int mode, snd_config_t *lconf); -int snd_timer_query_close(snd_timer_query_t *handle); -int snd_timer_query_next_device(snd_timer_query_t *handle, snd_timer_id_t *tid); -int snd_timer_query_info(snd_timer_query_t *handle, snd_timer_ginfo_t *info); -int snd_timer_query_params(snd_timer_query_t *handle, snd_timer_gparams_t *params); -int snd_timer_query_status(snd_timer_query_t *handle, snd_timer_gstatus_t *status); - -int snd_timer_open(snd_timer_t **handle, const char *name, int mode); -int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_config_t *lconf); -int snd_timer_close(snd_timer_t *handle); -int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer, - snd_async_callback_t callback, void *private_data); -snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler); -int snd_timer_poll_descriptors_count(snd_timer_t *handle); -int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space); -int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); -int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer); -int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params); -int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status); -int snd_timer_start(snd_timer_t *handle); -int snd_timer_stop(snd_timer_t *handle); -int snd_timer_continue(snd_timer_t *handle); -ssize_t snd_timer_read(snd_timer_t *handle, void *buffer, size_t size); - -size_t snd_timer_id_sizeof(void); -/** allocate #snd_timer_id_t container on stack */ -#define snd_timer_id_alloca(ptr) __snd_alloca(ptr, snd_timer_id) -int snd_timer_id_malloc(snd_timer_id_t **ptr); -void snd_timer_id_free(snd_timer_id_t *obj); -void snd_timer_id_copy(snd_timer_id_t *dst, const snd_timer_id_t *src); - -void snd_timer_id_set_class(snd_timer_id_t *id, int dev_class); -int snd_timer_id_get_class(snd_timer_id_t *id); -void snd_timer_id_set_sclass(snd_timer_id_t *id, int dev_sclass); -int snd_timer_id_get_sclass(snd_timer_id_t *id); -void snd_timer_id_set_card(snd_timer_id_t *id, int card); -int snd_timer_id_get_card(snd_timer_id_t *id); -void snd_timer_id_set_device(snd_timer_id_t *id, int device); -int snd_timer_id_get_device(snd_timer_id_t *id); -void snd_timer_id_set_subdevice(snd_timer_id_t *id, int subdevice); -int snd_timer_id_get_subdevice(snd_timer_id_t *id); - -size_t snd_timer_ginfo_sizeof(void); -/** allocate #snd_timer_ginfo_t container on stack */ -#define snd_timer_ginfo_alloca(ptr) __snd_alloca(ptr, snd_timer_ginfo) -int snd_timer_ginfo_malloc(snd_timer_ginfo_t **ptr); -void snd_timer_ginfo_free(snd_timer_ginfo_t *obj); -void snd_timer_ginfo_copy(snd_timer_ginfo_t *dst, const snd_timer_ginfo_t *src); - -int snd_timer_ginfo_set_tid(snd_timer_ginfo_t *obj, snd_timer_id_t *tid); -snd_timer_id_t *snd_timer_ginfo_get_tid(snd_timer_ginfo_t *obj); -unsigned int snd_timer_ginfo_get_flags(snd_timer_ginfo_t *obj); -int snd_timer_ginfo_get_card(snd_timer_ginfo_t *obj); -char *snd_timer_ginfo_get_id(snd_timer_ginfo_t *obj); -char *snd_timer_ginfo_get_name(snd_timer_ginfo_t *obj); -unsigned long snd_timer_ginfo_get_resolution(snd_timer_ginfo_t *obj); -unsigned long snd_timer_ginfo_get_resolution_min(snd_timer_ginfo_t *obj); -unsigned long snd_timer_ginfo_get_resolution_max(snd_timer_ginfo_t *obj); -unsigned int snd_timer_ginfo_get_clients(snd_timer_ginfo_t *obj); - -size_t snd_timer_info_sizeof(void); -/** allocate #snd_timer_info_t container on stack */ -#define snd_timer_info_alloca(ptr) __snd_alloca(ptr, snd_timer_info) -int snd_timer_info_malloc(snd_timer_info_t **ptr); -void snd_timer_info_free(snd_timer_info_t *obj); -void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src); - -int snd_timer_info_is_slave(snd_timer_info_t * info); -int snd_timer_info_get_card(snd_timer_info_t * info); -const char *snd_timer_info_get_id(snd_timer_info_t * info); -const char *snd_timer_info_get_name(snd_timer_info_t * info); -long snd_timer_info_get_resolution(snd_timer_info_t * info); - -size_t snd_timer_params_sizeof(void); -/** allocate #snd_timer_params_t container on stack */ -#define snd_timer_params_alloca(ptr) __snd_alloca(ptr, snd_timer_params) -int snd_timer_params_malloc(snd_timer_params_t **ptr); -void snd_timer_params_free(snd_timer_params_t *obj); -void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src); - -int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start); -int snd_timer_params_get_auto_start(snd_timer_params_t * params); -int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive); -int snd_timer_params_get_exclusive(snd_timer_params_t * params); -int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event); -int snd_timer_params_get_early_event(snd_timer_params_t * params); -void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks); -long snd_timer_params_get_ticks(snd_timer_params_t * params); -void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size); -long snd_timer_params_get_queue_size(snd_timer_params_t * params); -void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter); -unsigned int snd_timer_params_get_filter(snd_timer_params_t * params); - -size_t snd_timer_status_sizeof(void); -/** allocate #snd_timer_status_t container on stack */ -#define snd_timer_status_alloca(ptr) __snd_alloca(ptr, snd_timer_status) -int snd_timer_status_malloc(snd_timer_status_t **ptr); -void snd_timer_status_free(snd_timer_status_t *obj); -void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src); - -snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status); -long snd_timer_status_get_resolution(snd_timer_status_t * status); -long snd_timer_status_get_lost(snd_timer_status_t * status); -long snd_timer_status_get_overrun(snd_timer_status_t * status); -long snd_timer_status_get_queue(snd_timer_status_t * status); - -/* deprecated functions, for compatibility */ -long snd_timer_info_get_ticks(snd_timer_info_t * info); - -/** \} */ - -#ifdef __cplusplus -} -#endif - -#endif /** __ALSA_TIMER_H */ - diff --git a/shell/linux-deps/include/alsa/use-case.h b/shell/linux-deps/include/alsa/use-case.h deleted file mode 100644 index c37c842aa..000000000 --- a/shell/linux-deps/include/alsa/use-case.h +++ /dev/null @@ -1,381 +0,0 @@ -/** - * \file include/use-case.h - * \brief use case interface for the ALSA driver - * \author Liam Girdwood - * \author Stefan Schmidt - * \author Jaroslav Kysela - * \author Justin Xu - * \date 2008-2010 - */ -/* - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Copyright (C) 2008-2010 SlimLogic Ltd - * Copyright (C) 2010 Wolfson Microelectronics PLC - * Copyright (C) 2010 Texas Instruments Inc. - * - * Support for the verb/device/modifier core logic and API, - * command line tool and file parser was kindly sponsored by - * Texas Instruments Inc. - * Support for multiple active modifiers and devices, - * transition sequences, multiple client access and user defined use - * cases was kindly sponsored by Wolfson Microelectronics PLC. - */ - -#ifndef __ALSA_USE_CASE_H -#define __ALSA_USE_CASE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup Use Case Interface - * The ALSA Use Case manager interface. - * See \ref Usecase page for more details. - * \{ - */ - -/** - * ALSA Use Case Interface - * - * The use case manager works by configuring the sound card ALSA kcontrols to - * change the hardware digital and analog audio routing to match the requested - * device use case. The use case manager kcontrol configurations are stored in - * easy to modify text files. - * - * An audio use case can be defined by a verb and device parameter. The verb - * describes the use case action i.e. a phone call, listening to music, recording - * a conversation etc. The device describes the physical audio capture and playback - * hardware i.e. headphones, phone handset, bluetooth headset, etc. - * - * It's intended clients will mostly only need to set the use case verb and - * device for each system use case change (as the verb and device parameters - * cover most audio use cases). - * - * However there are times when a use case has to be modified at runtime. e.g. - * - * o Incoming phone call when the device is playing music - * o Recording sections of a phone call - * o Playing tones during a call. - * - * In order to allow asynchronous runtime use case adaptations, we have a third - * optional modifier parameter that can be used to further configure - * the use case during live audio runtime. - * - * This interface allows clients to :- - * - * o Query the supported use case verbs, devices and modifiers for the machine. - * o Set and Get use case verbs, devices and modifiers for the machine. - * o Get the ALSA PCM playback and capture device PCMs for use case verb, - * use case device and modifier. - * o Get the TQ parameter for each use case verb, use case device and - * modifier. - * o Get the ALSA master playback and capture volume/switch kcontrols - * for each use case. - */ - - -/* - * Use Case Verb. - * - * The use case verb is the main device audio action. e.g. the "HiFi" use - * case verb will configure the audio hardware for HiFi Music playback - * and capture. - */ -#define SND_USE_CASE_VERB_INACTIVE "Inactive" -#define SND_USE_CASE_VERB_HIFI "HiFi" -#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power" -#define SND_USE_CASE_VERB_VOICE "Voice" -#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power" -#define SND_USE_CASE_VERB_VOICECALL "Voice Call" -#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP" -#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio" -#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio" -/* add new verbs to end of list */ - - -/* - * Use Case Device. - * - * Physical system devices the render and capture audio. Devices can be OR'ed - * together to support audio on simultaneous devices. - */ -#define SND_USE_CASE_DEV_NONE "None" -#define SND_USE_CASE_DEV_SPEAKER "Speaker" -#define SND_USE_CASE_DEV_LINE "Line" -#define SND_USE_CASE_DEV_HEADPHONES "Headphones" -#define SND_USE_CASE_DEV_HEADSET "Headset" -#define SND_USE_CASE_DEV_HANDSET "Handset" -#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth" -#define SND_USE_CASE_DEV_EARPIECE "Earpiece" -#define SND_USE_CASE_DEV_SPDIF "SPDIF" -#define SND_USE_CASE_DEV_HDMI "HDMI" -/* add new devices to end of list */ - - -/* - * Use Case Modifiers. - * - * The use case modifier allows runtime configuration changes to deal with - * asynchronous events. - * - * e.g. to record a voice call :- - * 1. Set verb to SND_USE_CASE_VERB_VOICECALL (for voice call) - * 2. Set modifier SND_USE_CASE_MOD_CAPTURE_VOICE when capture required. - * 3. Call snd_use_case_get("CapturePCM") to get ALSA source PCM name - * with captured voice pcm data. - * - * e.g. to play a ring tone when listenin to MP3 Music :- - * 1. Set verb to SND_USE_CASE_VERB_HIFI (for MP3 playback) - * 2. Set modifier to SND_USE_CASE_MOD_PLAY_TONE when incoming call happens. - * 3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for - * ringtone pcm data. - */ -#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice" -#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music" -#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music" -#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice" -#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone" -#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference" -/* add new modifiers to end of list */ - - -/** - * TQ - Tone Quality - * - * The interface allows clients to determine the audio TQ required for each - * use case verb and modifier. It's intended as an optional hint to the - * audio driver in order to lower power consumption. - * - */ -#define SND_USE_CASE_TQ_MUSIC "Music" -#define SND_USE_CASE_TQ_VOICE "Voice" -#define SND_USE_CASE_TQ_TONES "Tones" - -/** use case container */ -typedef struct snd_use_case_mgr snd_use_case_mgr_t; - -/** - * \brief Create an identifier - * \param fmt Format (sprintf like) - * \param ... Optional arguments for sprintf like format - * \return Allocated string identifier or NULL on error - */ -char *snd_use_case_identifier(const char *fmt, ...); - -/** - * \brief Free a string list - * \param list The string list to free - * \param items Count of strings - * \return Zero if success, otherwise a negative error code - */ -int snd_use_case_free_list(const char *list[], int items); - -/** - * \brief Obtain a list of entries - * \param uc_mgr Use case manager (may be NULL - card list) - * \param identifier (may be NULL - card list) - * \param list Returned allocated list - * \return Number of list entries if success, otherwise a negative error code - * - * Defined identifiers: - * NULL - get card list - * (in pair cardname+comment) - * _verbs - get verb list - * (in pair verb+comment) - * _devices[/] - get list of supported devices - * (in pair device+comment) - * _modifiers[/]- get list of supported modifiers - * (in pair modifier+comment) - * TQ[/] - get list of TQ identifiers - * _enadevs - get list of enabled devices - * _enamods - get list of enabled modifiers - * - * _supporteddevs/|[/] - list of supported devices - * _conflictingdevs/|[/] - list of conflicting devices - * Note that at most one of the supported/conflicting devs lists has - * any entries, and when neither is present, all devices are supported. - * - */ -int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr, - const char *identifier, - const char **list[]); - - -/** - * \brief Get current - string - * \param uc_mgr Use case manager - * \param identifier - * \param value Value pointer - * \return Zero if success, otherwise a negative error code - * - * Note: String is dynamically allocated, use free() to - * deallocate this string. - * - * Known identifiers: - * NULL - return current card - * _verb - return current verb - * - * [=][/[|][/]] - * - value identifier - * - Search starts at given modifier or device if any, - * else at a verb - * - Search starts at given verb if any, - * else current verb - * - Searches modifier/device, then verb, then defaults - * - Specify a leading "=" to search only the exact - * device/modifier/verb specified, and not search - * through each object in turn. - * - Examples: - * "PlaybackPCM/Play Music" - * "CapturePCM/SPDIF" - * From ValueDefaults only: - * "=Variable" - * From current active verb: - * "=Variable//" - * From verb "Verb": - * "=Variable//Verb" - * From "Modifier" in current active verb: - * "=Variable/Modifier/" - * From "Modifier" in "Verb": - * "=Variable/Modifier/Verb" - * - * Recommended names for values: - * TQ - Tone Quality - * PlaybackPCM - full PCM playback device name - * CapturePCM - full PCM capture device name - * PlaybackCTL - playback control device name - * PlaybackVolume - playback control volume ID string - * PlaybackSwitch - playback control switch ID string - * CaptureCTL - capture control device name - * CaptureVolume - capture control volume ID string - * CaptureSwitch - capture control switch ID string - * PlaybackMixer - name of playback mixer - * PlaybackMixerID - mixer playback ID - * CaptureMixer - name of capture mixer - * CaptureMixerID - mixer capture ID - */ -int snd_use_case_get(snd_use_case_mgr_t *uc_mgr, - const char *identifier, - const char **value); - -/** - * \brief Get current - integer - * \param uc_mgr Use case manager - * \param identifier - * \param value result - * \return Zero if success, otherwise a negative error code - * - * Known identifiers: - * _devstatus/ - return status for given device - * _modstatus/ - return status for given modifier - */ -int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr, - const char *identifier, - long *value); - -/** - * \brief Set new - * \param uc_mgr Use case manager - * \param identifier - * \param value Value - * \return Zero if success, otherwise a negative error code - * - * Known identifiers: - * _verb - set current verb = value - * _enadev - enable given device = value - * _disdev - disable given device = value - * _swdev/ - new_device = value - * - disable old_device and then enable new_device - * - if old_device is not enabled just return - * - check transmit sequence firstly - * _enamod - enable given modifier = value - * _dismod - disable given modifier = value - * _swmod/ - new_modifier = value - * - disable old_modifier and then enable new_modifier - * - if old_modifier is not enabled just return - * - check transmit sequence firstly - */ -int snd_use_case_set(snd_use_case_mgr_t *uc_mgr, - const char *identifier, - const char *value); - -/** - * \brief Open and initialise use case core for sound card - * \param uc_mgr Returned use case manager pointer - * \param card_name Sound card name. - * \return zero if success, otherwise a negative error code - */ -int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name); - - -/** - * \brief Reload and re-parse use case configuration files for sound card. - * \param uc_mgr Use case manager - * \return zero if success, otherwise a negative error code - */ -int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr); - -/** - * \brief Close use case manager - * \param uc_mgr Use case manager - * \return zero if success, otherwise a negative error code - */ -int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr); - -/** - * \brief Reset use case manager verb, device, modifier to deafult settings. - * \param uc_mgr Use case manager - * \return zero if success, otherwise a negative error code - */ -int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr); - -/* - * helper functions - */ - -/** - * \brief Obtain a list of cards - * \param list Returned allocated list - * \return Number of list entries if success, otherwise a negative error code - */ -static inline int snd_use_case_card_list(const char **list[]) -{ - return snd_use_case_get_list(NULL, NULL, list); -} - -/** - * \brief Obtain a list of verbs - * \param uc_mgr Use case manager - * \param list Returned list of verbs - * \return Number of list entries if success, otherwise a negative error code - */ -static inline int snd_use_case_verb_list(snd_use_case_mgr_t *uc_mgr, - const char **list[]) -{ - return snd_use_case_get_list(uc_mgr, "_verbs", list); -} - -/** - * \} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALSA_USE_CASE_H */ diff --git a/shell/linux-deps/include/alsa/version.h b/shell/linux-deps/include/alsa/version.h deleted file mode 100644 index 434ce9e93..000000000 --- a/shell/linux-deps/include/alsa/version.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * version.h - */ - -#define SND_LIB_MAJOR 1 /**< major number of library version */ -#define SND_LIB_MINOR 0 /**< minor number of library version */ -#define SND_LIB_SUBMINOR 25 /**< subminor number of library version */ -#define SND_LIB_EXTRAVER 1000000 /**< extra version number, used mainly for betas */ -/** library version */ -#define SND_LIB_VERSION ((SND_LIB_MAJOR<<16)|\ - (SND_LIB_MINOR<<8)|\ - SND_LIB_SUBMINOR) -/** library version (string) */ -#define SND_LIB_VERSION_STR "1.0.25" - diff --git a/shell/linux-deps/lib/alibX11.so b/shell/linux-deps/lib/alibX11.so deleted file mode 100644 index 08ec7fbeff2e84e1242509e7836d94e9f78038ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 909984 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%0DvV+s4aMTB3QF#bmve+_>r8S0{qrJ(I-p^UE;E zLk9LkKvuT?49p)@I4{$s_&&_HsyKf!q4-kJw*u>3jz5*gkVouigRN}&G_)6bQY5!` zHL%wfuwO9aYeA? z$Y(J8>3K9iTwA8mhQAM`?h5_DdY}_czvPecd+_vY?f`yVkjUxr!W#2Aenjau&0h_{ z_@xj3f#UsPe>Mu_+ZgGYUQ)SzJP&=W#Qp`x?>F7xA7TFCjd+8fHC}w!TkNJ zY$#5-V1B$0|0gR~B46Klfj*WR$_%;JNBH9n{$GJn`9SI2r8&wA_8*OVKz|1+vA-co z@~1(t%tm9sljeVJfcZjje(}Hp^r#oh?bS=jd&y&-ehsKUCsrh1Up5E79ry6|@^TmK zC&9m!Px63$;h78W;v{lB6oW`8G*^zS6}(-BNmr~SLz7V_{` z#H7*u>)>zZ6!H7-$j%gFz4iifNXpk^yxM~Ez3%W|GQ0BUwJ*?~bw`|E()xb)27M3V zJ`-)P9QjiO`)Ar%NZ1we>o0eVrx^U={QtKYk6AnZeCRpsZ?Kn$iK6ud!=6iF&y8q% zUZ7{gUCbvG-vPr>dJg;3H2*8ulTzHrbD``nAjUf=&f ze;WnuA?ZSUJitRDpXS2$W`J`2`+2cd{HEBX28H4LQ`{*ou{&u2BP7XEn4$b6et&I|3fjkhGt3xUzwThjYa9N& zKO6e>OQ6qrPz)~}_-|BRw?p2vA#V}1{6Vx=|5hTme?I6>Knia!eL$%F0(*|GF{(59 z^LJmgpWcB#&mRSS$Q#V4>zS))Pp>)7BWQav7@7bl{yxDq2u``+yrVhh`$l_- ze1ACt^wfhr9!C5B9pfwP%+vEd_)+st!v2OXu`fFAnEwU#;Wg}E{%PFTqV11tf%$v^ z@2^~geW-@LgIKckooWdAtmgMey81)@vA@sB_aE5jm)K9?a4YDm??-+=WH0!Y3Vy*2 zW$T*`eX_uM8N*<4gO2cbMv0m2v_F$zPYSVr&dI+U=wAW($1vFZ=N%wFmnHbU_a^*b z$YZKtd`>+^m(}!wd|`iqlfS;8Pd?}aHnRD*VEn}xe;UP44g!4y>({xC*gw0&`{R$W-YCV7 ztQyh$YamatIFErCvh}@#y>k)F-v^PgVvtyV-#8TmJD|(2cZb=+{yXyfLt~-O^#XZ* zMED`FhtDuyMX%=PPi@Gr85R%bwEcYazp9+~H>N9^7e`i)EJYiW84=;8GY z{sQ!h^miuowWk#O548W^QJ)6(kGT4#L-2iZel&!Z9{~BaHs{aNqlZKO#LDvXuP2y@ z>+N`bo(@41VZV0;Eq@smdBsTO`z>Cb;a_BnnLL{Q81_H|{x-yp?O$g^as~Qn-3#Nz z`V(e{O%HT{eG}a0SvLayc0c~UVOt2=Qpg9F-wN}~OUy5v{J)1iuS^xm{r3u#w-nr0 zbi(-CIbeN3>EjCeID$U9wEcYWKV9J8|AD?+3-ND@F4C!F_7DFK`F@+cfpRh?=fiqK4W|h&-wdV zu|&RaVt<3?AKeo65A@tZ@i6eCl#HT-GX|5hewANL`q(fSOa=(%XW6UEgr{~oZ#{SPYt zzkRX3hd+Iern^GEiXmT|Jw68ctN)L`uS@P_E*0=M5%d#{hdk5r@4>Hgg8h#;2wo}t z0Zqyu2Ospm5c_4ceM|5^YZ`xErsa+KaShI!K{ukGVrQgB@bg1GznlF8RRkl60dLHz}xRmdrlw5z+PloV1I<_%R)2EC&^;=xAqBr^1UF> znNs=pX^+rO$ z;%|&$&#*tswbvi~{)PMAQFJ_;F#k5fKR|PAd*>lI0l2@UPw|nkPa<3jnLzX32Y+(( zmE`wT_CdZaaUVgA=3fN*_^yRNLHWJR59u#>{p<$+Z0Q*Od~ky*+7H8i4Xs}Z{H^WB z-w)kt1A75`X+-P)jPa*q{K&@kwjAa6Ki=HxM|IphJvff%s;S&Q--0{i_139*n5 zu$@gmhW_SYJ*iId{^)P2E7tFH{GO1%D;fNJ(=!nC$NUSk!Itj;fAS^fUyy~xH-R3$ zpobR4*A9VyJ%R7v802rjeLP!Q{{_fnnZQ0@1bxb}ztV}8_XK}SU>`Voy!V0q!g`&P z@7v((Q-MAGhJpEFz08d-6a0GBTm$w4>cZ1-*^@M!U{D(oP^eTQm>;y;0*pRpH9Wfte;JlBc zUn|&$TKMOjKa__4d!YXu-Wh}~6zorqL;c#=-{IP;MMhs!vHX5WYYnWQk|3Xy-uAHP z<@o0WFKGXiFt8G1W%+*l2h2D1*gw2Z(|;PFJ|})Z;w^AJ;GBF7?1uH6VE;Z4^pZjT zpVIQFm=CTC_Mex4ei4&X{ThnzRbl4{{>cISyd{x;UzP&Hkn7B^w|9a++Hmg3 zI)>z5fbo?7%b%|f)P{eOgY$Koz8QkAcZ|Qk<%97Yz~zE5bUdfgf5&G0`QN%>m@jdk zEkfK>|6HQ)?IrU4Cu8up7W)@tX?Y#Ulkrmi{;(_Trz-Y?KvuSYYaw6Oke4MCp9FjI zNN~R}4f5Y8kpKR$-^T>{d;S^4^r1dMKzgIM{zd^?j z*Mv#M`5&kM-5gP09nM>5enVa8TRHAOQv4$rS^i8(eqK|K@z`NL(4pzI=zpfb9u~u1 z2E4(34Q=l}6uTDwE7-!0Uv&WNgN;P~J-0O~%EW#rNB??^w_+IP2U`9d`QAMf-9KVh^v`44c0JO%UqsZ-G3 z_cg2`FO@;O{b|z+_2ayCJ~tje(EpiKzJEUq^eqH^p>}NhPchz%-TZz~3jCKUCH_3z z7W!PJt}LG)jA4IfV!gr1<57$!KtSIW&`;lX{CwpPSEM1{oOY%zj9V?SpZO)r4{is0{cq4<(OvVW}1 zJf!$=KiE^O_wG>~DD!e2zkZAYy{?SKeLJP5`t?B{=}NRm^P9phR`=%bzrV%&`b)6> z{m%sa6rAT9L0>Bc`vKXould-2*hcF!#`x;+z0*#L-^93raKD!8e-891-&vXce|2QM zkx;~**nj2hhaJj^U|f#S@=ln4tDyWG{eMGIGSOd7Umk!zzMv<}Bul?^7s&fh{ya?^ z4ciI!AGd)qS>SIn&EE%tkzvn&&tM9DZG=Avv%uC@1^dwx%D~y+VxL8}_5dkGCJkIzyfW z?R9~C2kaEVBWo(Z5sF@j`Jb~l6=+{?npnQyUu+KfuIBwachF~^8-KoW0|PAwzq#_q zVQ;KpZ;1UM_NEy8e~I%nxDafAFG5}#(f&Z%{%@$_WtHYq* znD2+s^h)$!75eEz@zoHdp1pYga5dUD5}eogf*;WWeHzjq^BcaWilXJ8VPbK_{bYz0 z+x{4L*hj(r!V?%@zChlGI>A2Te&$}9|2r5{f%#wt#WP?p>|B)PzxUD({cZ5&zb|_R z!j#Rb8E-!%Fif${BupAjw}T+eY=`w4rMENaXN>jV2%7#C^V=A~{k=6{T)fT>IT&w+nIKYZ)!S*cbaV_xbhs7RZot&(O>eM=KH|Q>PKx8GfXTpo z#`WLV2>il&V+>870DXLv&F|Oz@&vs$N#*u_@uT|GI$nI+drf9U-6LsGs6l#9m{)$IUMj z-O)dRzEz@~Xxxt(OWRup{fotTP%Yd4&Y<5ftY=Xzi{t7GT6dEKM(@x_bm zKk?rynxg&;f&UiR4f2ZlfwNzyFn$f}=f}|cZo6Wke_Av|NbA7}6 zf6GuVz(B-2qvaP5!hCgs->*6a`}8Ya#QtATBA;={r>6&;=C6XkS&i9-xkKbRp z-W&c8)@vXWn?A80_|+ErP33VI+HX9H-}eFEN%=6?Q&oKL!0BrWa2fD%wEPp;r_g<% zCoO*!_U!-~<@Q510oQvdmESL6LPEyJ#>a&uC5I*^hlDU8kgqNmB2 zkRg*p{AA;!laghL&M~1$NwOp+&@m<^KHNDzCO*+w788@igarD@5@J#j4vtAliemB5 zh^Bl~Tqn!olK(2?6B8Q8R+Ew(kAkw$WbZg8&^anJZoF)$EHx}XG%>ZKz~{C$mqC;_$f}I;Som)IVL_y<`O?8&MQ7bCTN%? zRBUJhH$*pQ5GWuaA~ad%=Ik6A9tA2l5spJ+WwGH2gq;2|GCb!fS@=YcNS2Uz=^~p% zl9J;SW$Y{G`1py@q>d&^`=-cJWLzn)(4>i6xxtAtVFAK68R1Pxa(qZE^3jHdrzXfE zn#we_%)V$My70Ba8^SzF5jkO-sO6IwpCC(2PGvBx*!amHP1Ae-(8)4z4lIs{7#=Uj z{A484;KcY?`KzY#7&V{#WOlD)YjCr-nqvG2x*^ z_s}kgN9Zh@O4{>`51%N{0^veKf4y)3yoH#@ z6N1Diq|&Y;#)-3ITm%^=S`UwfE+GLj?k5Z9-m}FBiAWl&@`$qiaEeYwR>EPI&}2dY z_N`C!)FvfiF;dVcCD|i3bUYCl_8r%9Qy#? z*`|iL-nhl2CPZn!8mH*rs{V}YJ9 z)h@Dx zjcX|lg;d@MUDpnEYOc1TE4LL!W5WJq`v%ur&in=Bbh5TBA5 zE+dSIBi0bFJ>sI1qnqZXrc8sQV`PMgVWCNADlwLhPW}oNCu5!<)rLfdM#qqrgj2O?ff7(PmxUWuXz?k*-rAAxW?aM94^yxCrk! zg_o=`S9nMGCVz#IVFq(dg5ea9Gc=i1hLAuu;V;r9Ma70DGx!^x9K%FTNsLa0P(;N> z;9W9i`$Q%XQ(j^!Ygb_{ZEc*Q$45eQh;$`JKptAQyE zjbY0nTTD3AED=ocBy)C5_%P@A*o4qTnTNl(C)g6#lNG2$h$kz#5LH%E<(090VpWpF zFi#~%dBjD=qb@%X)CWEi^t{QSbDd+;`67I;30LVL{x*cvem7a)ru=LME_0JTY#K5V zFgj?DB$m0)+z9Y754VxUVD>ygiOHX6-!I+NO@Mp zmIO&n+!VZ^MjsXut`#8$EL(Kkc$hFK9jnZtG5?!LOQj%<%g@Sla+08Gj)QFX@dwH$ z_XJsGOCk0U2?X&^PNf+9$Al=zr|Z;&_$2rVU>owtZFW-?ZnF4Th%u}nOItY_Ld*cG zGMop_;griwex_q`d~B1a$>s+pw;?2niWckElQ?_>`1TAtu{%3^NB%8u#4^Va?*n=K zp<19G>jU_?IT2S9^F3RbUnG#3C1FZjXlzI#iKawHG`&FtZ<;K5Q$?iHoGtf~C61RH zcQ|{n+==0#$*iKW!*-8PN=BuiDaK6gFR87ms^Rgzuu7?;F(w4^dO=MkYXDTHkVk@E?NKU`3EOlwU^Bfa?esQCC;9vc>) z7#kYHHUvC-#b}DfP=pVoDfS5Ms-}|DS~% z@_NCUijQN7&Cx`WMvAmhTvDJG`pPRbA%WFgyy6<;-qHD)9W%s|lV7rAXtGq^k(>ua zhQPVH-c#a;nIo?R_Kd~h&P1@wQph&zrXtfwFQP1L{*hk)$KKn=M^&AB-)l0HWPkwC z1Pu^yNKgYo3=lO6)sPGuBEduwFe=LAl^K#u#v}*|t>L9dELfwV9t5;Jr<@)tXcNWW zpipR~l?wJu4E9jPHVPUfsDlU11|oTW*IL(}*^>nAxu5%Uf1W?8ANa0y?X}nY%eAhx z_7GZl<&*3xs{1+E-I3ZPt5KzB+P_f5_slUeryiqTa%flSrE$qoqs8lMN^9gsTP?(_ zwy9~gsI0tX3C7?<6_~2=3ihK}OX}-sjVHHJH$k6ra4jlNL3yp5;IVkqsG^ykHet%m zLgXwYrEH>?dMX|<>XEjpvSslkxK*W9&S>t+5)`+n%2Psr`2#Dv+UJ-;-jl6DB3||Cyh1HQilhQ8`?eZolWtZzuStY>=9Z%p>&h2q zJ)(A}$Tjr*y8QB5EUD!*m`D+l?~oRlUtcR*n?SBGj# za7)8W(1VU(xYa8(p{bXQ35}x&+tgB|q&FPNQUZ(#$X{?fy{$a_FMEd><NH5wE5uM%3&@a2A!8i9Tr%*uo?@F2PQoUS7;LM`%7yx}2F+brsYnnt4=VfZI9h8>Vc*_>{D-4TC z1}mw>?xVCA6R(kg6xVqc!3rBLTUu<&hDv#fwDtspDIrvB=swhm3S}v1>GMp=@ES%7 zdSa|12uh|U)#v*NxfZC%6pH(e94UBZo)u_I(RlupCCe0OfScM+*@Tq3p# zvu{?pXOSCIqWR$*>@C6`n*>Iz{9M_+S((U&6&g{gMRY#aLDHR#MSDIb2Wdq!1Xv|J zN}__!h4vxm4363ukz75}mJ_U<-~?5qEJ*XHSF#(DJTiY9eyOg>)rJ-%esov)GU&n& zL0`ptx#)7U$;QAEWRc9NWIZ<2B+gVY1AXPn%$ZkVv}33NL$XkFg=C>-3(2_5Mk)I| zkd@I#IulzIBXy2Jb(xS@Hh##fT0i8MkLSz@2~+^HM0J2r2-yQd-Z>sGStGF@G;%Vh zcv&xrv!=X`cGB~(^Q0An{B(=~Emm6dv0BmooNV@?XjF7+{Dh=z=#s4q6%I9vd0Qo(gj zrieUr6(Vw%XWsq=JqwG-ej%+!(rf{j3_QosK+t4)K@Zmu;=~MOm@ME{Gjh?SNk!RN zm==t41d7@im$coMrw#~0dt|T4kP1UgO;uGzncVr)gip4XdK{|JdBvjg`h|7aj6)Au zSYdj}cvfA!%u~GtTXr>BEQFm_&ZczW;jV@1PhFw1WL{lpMMZvDRikbUpELpFI72Qp zKGXrS4h46$@Gq$++j3}!9?}-Fu#jMMNQFZ+0<;f=S94_Wjq+tQ3v#^D_>f;-9z6Hz zqh!)UV~g$G& zJ5bOIQxfeiu$h2jgSJ4AWf32-nl{I>DhvATLZvupS&%-{9$(czbO|{S(H(F`f%(Sh z?<&qxC}E{oCUHgwD+KfgG#8oLX%kuuI~5stOvV(fI9NT{wjwR2Sy)TdNS9uv87P~q zbfY4J;fzxYDZq>%$FKAR_oKnE1@#^ujzsuvswp{1)YsAOONKJZOlcJ2P{0Tvcf@kG z;{m@gCy%;*DNSR=Woi+HJx*$&qCy`1RN#4?sH=n3qe4`a(hjM2X!4iJ^KUk;Vh~n% z7QuRF%q#TV5X~`!&}e;GHOpl0;a71ZbHWtmLZa6}ZuEm4=TWm7+V>yA2^`{`%VD(ECL-wZ@|v)xP>if}V$92{Jsg znR0^3P)>tB+R&(*0;o}RpR7k{6+sbti|IreV$vPW;i*=Au&#T9Dk4TW9oMM(LqD2Z zQ;!{k@nt6}Zs^8A$VN!djFTXG!!&H+3yw~>O?E%{!fajeo9uq@1!qXOje#FlX1V~N z3{VKs*W5=@(1i_U?t{-{?xVF0%V}PLT5Jrf3YG_1WSWl6b}GDl&z#<+>YaP3AO-8Q zw~Cjr+kJ-T8Y#> z4&#AT1C{wmJ&?&DgVfg2t@@-XgGMhfZ1%>4jjE;-Y&22u zP#>mcNQE~HUCJklOfxP$BCph);em|-KBYJt&v?Q%1q=(OcI2U)Askt)$!Y;hQ7zVG zxKLtJn9XP2^Sp~pMo#53x)z0|r|=uj;L@U=7{*RaioL8pcohqhStFJLWBP{9#;Plw z;XyCPx@i{NQ(Wr{rlss|#;b~I;f0b^?=C|X2OrJ}9UB6J)Oq!Ov{ErDJTrZi*g6fVG)0s=G=ZJl{nM2ZB2#v<2W z-b_nfKaa72QOZ`RIBLI#u8$mqr1vOIO_||)ifZJ20ZX+jjz^5eUh}GJbR}oeaQ@P}ZkF-0~ zBn(LmRNFQgWI@RF$Inc^gO1kt8kFp(v_KX`)bPf-;RhcLwklO6|jF zGx94-5|%o)e|7F9^{}IPWm`ThJT-Iy0*TQes`1r}iVD7M>8Vx|C#j0mE%=UsAx3`l zd~$-QDD@%=Iyg};$fbt*uQYOpdqvjDr(QZ+P9q2xxmw;y{g z$T1VsA+nKPPMvH!lLR$7=MjtrY9b>PWZ22o_LWipi^}VZ5u=;| zVTVVV*h6M!sN;A}H7$n~+&-kG+{GRmE^6dp0MswUWJ%^zBV(LC#-h6LfGsy!Mb)*3 zU?|zIatjNTc42y5KFI6mL4lk+=iQZ4L`$`_=yE%%C$iG|f0T3AjKZ5Q|ET{bh1vP) zLDBqTwVd4reZ0I(4LkIzoS+2*Z4vUQusJY!@Q#<96e4IUp?AYQd<;DgrW`zCUk=PH z^lo*D9AxBNs>T~Rm*8M9D6cLFKhIcN8t$jSVG=AsIC|}G5R$z>ntfpBQPY6BdV=}D zFmfSVCQA*ugR}n}c`)I{JvAsX*iV;W|3Zq0vDL}xHvr8Os3AJbMBSh>RFx`ohDm^q zo?R#(sR}lXrM-ffykzsqF67xj&Rgi3!Ku!iBB>+=9y)I2j1-tAFl5Y_r;O)nZl#%( zF5gHgw{<^HRCfD$Koh*&dn~JxI!>8KUJxng8zPI;MG@=~<%N;j@;ZJ17s-m{HEx+W z;=xUf;XsSxlo+clMH%YjCO%gf^ zH+h}qy<${~K`_M9(mJ}1wh)7+PF}ObKr*ZTY9qi)&(hM%KBBR6*@sI@Y1L87I!A^6 zl531^Sznkna1E93&~a~|3w4xzY33vcFSlH3><|sZE!8Jo?UWZRDWpl8;Sy28y|y(} zYRYuKkBk!a`>?9Cx}?5lDXD^0rAte323#VY)g^T#rtAa*RO4`%rv6|sQy>JD7gtp@ zco)xPP_t8AWRO9n1&9*IbIPDh$8Z;y)YPJz@`|zui%vB(`z5uwxxWknWpASH5gg#E z7ov}mRCW5k&t_&#%1E1%*6(9XMKlRJl1SR6IQ~U%TKQFazc~3{kQ>8xp## zN>*I%^!R=SQ)6&PN;TXkVG@RtHhf0nhCeKM5>h`iXCNpuvS0{s5+0U`rKO?Nl-o#4 z`NC3C{n?xjON>-_2#2RZY6;3o_lD%W^;@A z)goiRaj}r1p<6;c&!ZVV)rGK_;RuK>$yd-s4>CCg?A)G#IHF5h@M6j(|DY z7)!LMqJ`+wALDs&NtWfPubC6B^H6vh-#y{FPf$Kj&IELmBselT1zO1YjDV|PPXARf z=dx8`sDhLlS3$49rYbN8E--dE^d{;wXn5p)NEHHozBXqLE$8$}K(JkckFxuHG$&Y% z=!CLnu+gp!DrGXK#*KDa+eTkCMg02T&~0slr4wl)?lk>YPVr z;P9zf?Hz)<22_KQ0b1>3&Sakrd)>$@4?!~bg*{j0okLw*#z2n#>i~6!D!zwca*XrXT}FCWGfzs#6vmXv<#8$N|tY#rE-y!Qnftx4r`W%!qN~h z^-%JLbv!8`qnz9hK%bCm!#yzGhExi=@=zgDmJ6&8WD%DHd4x&uaUE5P$fr_&~4Qor9w`^I9y7dIic5S0YtzskyPzSiiF6@O6F=xTZSyi&L$cB#;eZ0 zv6)4zC?Y!3tHC6AhRDvQEe68S101Ov=L9SXg~Fy8GBqy;U!wI9=T!Kps2=w^aP1C3 zqQIB_+y7(Wuu8 zYt*Y8pa%LPca(yli?bwGS7{)@p>!~UPyxa+hggg5z0VNA8BECZDz2-*1Rjh^UWdZn zNhQlg`o*=lSYhs1p}=(4WxmR_%AfJ}{A|3_PptDzGWl}fq&;49piqRSH-o~0V*1ow zHLc2kZ0!QKrve9QxWA_!^*7eYjuia(R^BzoWo6l?(LHBWu>lCxqAIbl1_koSJdi_H zB-O3)2Gn&QPX2hvQg1eQaUOekGptWhOoo6e75+ZyK&BGOrMHdo#v{zgPp|f;cugXi zM-(Hs7>D|*OH*n}5-bUej9!AkDqU56Q?CxaYf8f;M4zDFF$tz%w3cdWl`6G;ZZLkN zWdzC%b{rKjDDM-Y$D3=C$q4&RmM+W&^U|k#1nXwW!@cWf$-`m81^JO9p7OQi;b5Fg z9`2_WAVdMfLKy`KeGV3M1XRbkDwz!CPFtf>~3Jlv-isDeoM#IKCt z8(mDpBv2PpLVk61%D6vngi=y9$`T( zav~qj#F)aBI>S4czAZ33GLev1wutIoSokoWl^_^gdU;Hm0;tIXf>54ioRHA@UM+3p zYrM2EH^egF^s>cEAgHLplhz4}t7vINI+wZ*lM1iz-CPe&G z5D}TX!zBnZ6Zbly((vP;&-`s_4lP=Az(8GCe!1$T?{2ZZU!+wPFOqqn4u`MBX5ixo zD0B~(OFgNwWWJ}i9y$$Dt;0%zUwohl(82i{BS%(`cjQk_1%L61gP}P6K0?E*U&pGW zt{(cR7BTlLM|je>Pi4U)+Y)^l3&7PN zx4-;JVz#nySC-)OCme}7=?7jaOQ;8hF7naC3XGgSA4no3jvT0V)wNPt_b7F^K=nLC zN8dZ*6?5{OG4<;R_~?Y}M=H{6+_Vgj2QiREKlp7W0tTbz4-{ndHC(5?(^8*X%DSP$ zA2gOxRjmBd$3Vu(9*+KeP)Yc%2-QGwnVbsoyCYOS<1~h9-ve6@?y$>GZHy>G5`11P zg;b{@DP@l56poRrg1W9uf&Azxz5S|3(T}yw#mxqOsjm=ksuLO2IaH_TD03EhQMo)K z)p(J=`KEqp4KrF;7dCrkenL;F@r}nu51{rlP8m(bC2>I|U8y%}N?P|I#Wam?SkSoi z8zwbgT3CYB9js`GRBiDUU^z!fi7F-a9CKV~>rh0hWhhgs6B^wVKDq&K@)}t{RA}rz zp|i@}#SeR=UMvHc<`ZrRyn^2k!4(9YI-ntIyz1!Fh|ZYrIJ+v1P%L3$c|n`Mv^P~r z4o)g?09;cWtQ*rq8t-+Xu1S@RG>luV>Ort*7v6Xj7GA}xekKufFa6w4xG3aP##dBF zSZKpT42FO`gBsphQ&UF27eb>_E{f{6*yslvWfhpEg*9>%v1l%S+_6tET2E`dA-VkR zDV#<__eI9h{V64y>WofDep&e>!1L)<9^6!tNe9IRDpn;_*=CV^TS<@|laEshMnOAB z^ZUUar8#+37roM^pQbavDeK3SQr?pKDzYP(Ba&*A`6bq?P*j!KJXIy;Xq1FYVH%Yb z#^_<@N<&vMdl9kf2D#;B(in=@)YQqnL;lo=X#%4Gsva3bR3)TjMijCF!$s73;Syvo zBfYgCmG6WaGsUNp@^0k6v{@TB|5v*pdN!S63&~8itlq+uMW#{8m#jOrngvS|Tt$ttpuccJp{j;}G^n{`i6g13 zKJ$u7g0KaZ1k?+8ILVK^LgO3pnTE3wHZ(X4iQJ;d8Zab0sKR7&;Dt$e6d{@Z#28Bb ziNj>QU+w*ldFC?9X>bVNw5zXo!Ai2@)gR9q2d`&d;5cnnX#DzY_l#>5uQB`&W=Gi67$TvkSEH9I%;tNaa>gcy3<)yozn|>u(KEX%B z(#-@YMtrHQ;+&bAla;-2@Ex%9U)%y{_=euqlBJj@v ziQUWt%!ABB%p*)c^C*s%y?!3Gm+_F zj%B7WCot2P>C6n~G-f8#$(+T^W#%&rnMKS6Oc%3^>1I|jeaw31GUf_q19J^?Ept7y zk-34nk-3GrmAQ?%ow<|Q%-qG?&D_g8z&yx2#5}_EGmkQlF^@CbnJ1a2m}i&)<~gR$ z>}HCo-2O~EGlm(bC%uJ?} zIg6RgT)=cO%b0Fv71PJ8XD(x|U^Xz6B0+nFbs0p>ZT$ma3DjAte?9n2Kw1ZEmDgE@_v$;@XKGK-iCm@cN9S;eepE@Q4| zHZnIbH!`;{cQSV|cQf}g4=@ihk1@|Mg;Ui-JTrwkjhW9ZV=iN^XKrQgV(w)gU>;;1 zVjf}onMaw&n8%sz%#+Mh%rne$Or6=y6!`Ztso&a|c4iDSmKo1XU?wsh%(2V~%rs^? zGlMyenaOlAXEAe``OHFQ5tIIXPs(o@)6J}6`k3|1Wy}@K2Id;(TIPCYBXa|D3v(-T z8*@8zC$pKki@BS*mwAABka>uCgz0AGEXtjFaykUOr6=yjMY@Vjb&yq zbD1t?J#!gz1#>I&B=Z#W3{z*u;NRP&_Hi)NnX{M+m_8=``@9r>Eps>X5c3Gr&pgUJ z&OFIH#XQ42$JCkKOxrA#o}C%PjAte=6PaU~Da;AXbY=!~8q>*~#mr?EGK-iCm}N{i zvx-^IT*h3%T*F+;T+iIV+{oO*+{WC_+{xU<+|As}Jjgu6Ji|;=5FR*=0WBmrk{C~d7RnKJjFc2Jjc|TVz#Pp8#9I(%S>P@rk{C|sWW5lQt3FD>C9Qo1xz1v4Ra%NC-VUFDDxDvn;Dy@(izLlVCFJi z%zEZp<`!l%^C0sW^9)nutN7!YDa>iid}bMQ8FM{zD{~j~5c4=Qz_i`1(n(-WU}iE4 znf1&S%tq!0=62>z<^kqG=27Nx<{9QWrfsguM+`HO>0pj!W-zBQ^O=RrGNzkZ#azK` zV6I_qU~Xh?VeVu$Gj}l$G7mA2Fpo3anJ1a&m^!nY8B?Ij8_SGmrZ6WkGnr0i5px04 z$E;_rVXkGaXKrO~WA0+^X6|MBnMau?nWva%nB7cKsLEku#xoO`iOdPiG-f)}$(+T^ zWiDX4m}Sg*<}&6A=6Yr$a|3fbb0_lv^C0sW^EflWJjb-p<9^9ZWIC8*nd!_7<}_w5 zGoM+=bTg}%YnU6D8<|^}&CFfQL(C)0%y#BU<{4&ysWZEowtH0h?aWwa zJTsB$V5Tr9Fw>bC%uJ?}naj*)7BLqv%b0Gak6F)L!E9izWv*v#U~Xh?Wo~2cWHvK* zGxstNG7mBR%%jZX%y#A}<{9QWrp^>aJpP$6%vfduGm$x#nZitCrZcB8GnuoPxy*cK zA+v~C#cW`1U~XsbW%`*XnL4wZDemR+Fzw7lW*XDUEMhKTx|my;+nC##0p>ZTZalwF zrMr{a%-qe~%RIn5$UMS4$~?t9!wfLR{ah}lotewbXBIN+nah|fm|K|JnA@2yq1m_UpXVj6K^gvcbWh!E2#9OxwfNFins z|0qN*afiS^5e3@toYDaUOc%+QT7-`FhyY_L9w@_}1A9PWC;8v2)6k;1O-zN6bbMP2*C&^FS!~_Zt?j?VPRrrZF z+r&}gTUOCd`2_7UUaL4p@*6DTIPo0nk$53OoFRT>6*}=$gs7r)K%Lo5^0R0c^z#T% zP<)^rcHm+6Sw#$SgH;rg9E>G@R-{NEJ|x6g>9>k>VvS8WiQ^)~EaDuC$R+;5CLHuW zSVsOkEW$^eY!mBYuZmb{5gUpBZV_9E(&QWB(K}9raF}Z4oDlgRSBm@lzpm;>ifnP5c<;#r`Kkixd-xb0b6=ajQk7 z6N{}PgJ`#kX~Zo;WD*NdKH_H)BA58IO}L3iETRzW7_o}{Us&*OJ}Isse_^C>lOJp# zzuP9N$Pca|e;4Y7{NQ@>N87|Q@`H`!A7>LQ$PaEHf1OQiBwma6Ne*ry|1}X}E&0K% zPPsE?t#CGC;Sw%DP8q_cGPbgpJ5P|9zu|ym0tq>!HNFYYxypI?S zdpFUJaZel|L<(`B5EF=lgh(S|UQQ?C=1c~02dfUF3&iLS73f7UWs8yj1wZC z7%xO2aTw-n;#H^*A`Iv*Vgk-Zh{J_&6GsS9MNAaJM;s+YJ#jSVY2r0PtROmsXdsRe zVhu3~_IP5l5bKF!g=i#Ri+UzrC&WhL_2{3(6d|?}$6@{^ju&D(F%|umI05q#@dhDw z5hvoF5AjAJ_7c;CI6#~v#6jX@Ar29z2yujnTl0S6O+p+c-Xg>?VuldMiMI;TPP|Qs zlf457h}oFuiB2J6h%?asL=Ejv z#5$EgoQ3u$=AiwFccT4?v(f&_9qsj z{fQ-Le_|=xpIC_qy33qv_G*1 z?N9Wf{fV_`e_|clpIDFfCoVzz6CXzV6PKd>iObOb#7EHn#7EKo#N}vz;tI4s@rP)C z;*Ze&#K+M7#0IoKaV6THxC-r$_5P~WXn*1wv_J93Xn*3rp#6!DL;jiw4EyP z_8UI2wg3E+A?;7K+XKJ-q~YelV%f|Cn)u^WAGf`|{^J$j?ES=W*TZdo<~BWZncPJt zcYd#ToTg{fdOb@sJxejU9VT~z$sKEQ+u=6nt^4axzR#K5XH4#sCiii;&F}k7&kmW~ z2TbnWz24brdbZ8v-qI^vV=w=jUjAjKcYP+eyH~gcre}pFcdp6pG`Xjl-03Fw1e1HL z$(?9&$D7F9oojMC;WodYVS1Kka;KQw4wE~<AD?IyP{ zx%K}J)qlX`J_WZqAIDA4j+)#@Ozwld-q~$>*4*paHq)~$CijM3;ntd-HJIGXOm1JV zcgjr97MR?Hy~52hJC) z{tQ#tG?P2U^X(dYonOzewCT3#ZF z_52c%G(&ed#$KyJP{^1ukqFh`v82UBA>6q2`z>G3FBW66bVuyiF>QKAu}DJbyDbic zoo=}pHSZ-)#7$29TKF@NifxkRqHWT^V&7ihOtD|(z&0JZnB#%Q*7 zj=fBbouMaZj!j0WVn58P@lMgHAqV}}mJ-;SYH{B0llKx=e+wD$AQ)7IU^Ok-Zz?hLek zJ5HOdiB6GhcU-T>PICqheH-;f-t*`D;1t&{QI zYw|t35fkfh243#-POL+{5$&XRK5b3FJDY>=IPlJfKJPff()qO2;t=h^vF}X8x_zhg z)nY%iqn@6gFG&r}{Xs^k<;j_R@s;3xj73%3K&4GHl2K7{mdJ<lN*Jrw3#=Xn*Ro4iIC1{`qa|9_S^x zW!){kBsZhcaHGc z_wC9VEau{!33%tXHx3rh!XG)y{@OBUzv;i%H+#6>e)vMZ*YKEMRv2Mzm+;&heYoDL|Q(dH4lV8>&(nQh; zuR}YkyBa*2^=wScLA~mL{j9})5RyOZHdmY$`@&CkOa9Bc-8JNem-T_Js{`BgNNwYu zqq;vmuH}BWL)$p>M9rWUVv1&O-ghdn(xF`)NYyFjKX&ZX?GA@F^torm)q#uW_vr)S zyHz9Kx%0<6Fju^0qgpH;T=#M> zWWCtJ>!p$EC05qUfU_3RbwJh26-K=@P_0~vx`}bc;qM`+p}6m;p#fAwt0|Y8dZ>ne z*I|9Zp~Y{$Rm(fQHe$5P_QJ5uqg|0NT!p`{4wRh#0Og2%ZEdqHKnF`!vMez`i0MV$^uox+ASW`ytFhIa25Z){q7g=Ny1 ziU(YqTz~t{TFpYOws(A2+#?Wo4BE@a?G|w5zpKsS5c}Uz){J0(2=#^$ zqn^&X8gaW3w}s=j8FBmik2OQ~gj1JJct8H$JV*4KXFKw|={sv=4`TnmJlFh>^ZZkp zXECOyt8Ks7Zvp=kr133BO5qUgYHg!7xFt0>R;XP^qJBpAQ;ru_E_A)A+Z+0?B{f>F z3KSyEzjb_9-TVH>1uA`SPb|S(+vA&_xyUwBMnPga4!MPdWnJ7oTXRIuG?nH9I|k+*hDh z!e^(m(Mc7v_FGw-4y6R7z@IEm7 zlZyUJI-og#5#iCsW9DhSc&3A9pnFk+Thu(6w;HR)Gn(b;=j0lq=16gUULa!7?V6Z4 z$A6RihCM0msqTrINFD1RrB!<0$m;rQnk&h&v8QX|DTg)* zX3jrEUisYA>O z`^9x5&-P6H-Me_pCQ?rMv*k)794C--%b2SIf9n2BmZ1ynbZvDr^@F?y?G}`SR+Ayx zW6maSu}m#5AOcqF*T<=j zOq9&hbXDN~Zp-F($p`o2a3AS7rsrq=N5`45gT*Yh*3XRQRkM*xnZc#JlMSrWd@K>H^I=IeMPy{;vL%R}Ka(95ptZtcjBZT98G zBOMk8$){GgbR=rWWZ%>CVq~9-)Ec$tSZhh4(hN!n_;r+K;6hE@nB%|Qecc{M`xN&r zT4&2>tRO?oQEikf#{^J>=o(7SlYmWDP=;d1LwQLgo;Qe-LCU;MNq z1?77E;>R5mt9J#*&mD83s2ue%Xty6apVo%9OhrFW(?qgpN(fZyV)KA=*88bE8@1hM z#n2M}F+;e05ZSLLZU8(-7wMRYwmetkzD0<|%;}dc`vPTX-Z5jGG`lP+}4ZIcE z`l#%cSDqd)^ke_6D7j_hrLKp+NJAUkhLYdi{TJD@M!uTHWggv5sacR(SsInvAxnJ~ z_Bn`+q>fD(Z>VoOmA>U&dOtxM*`nSz`fwV`F3=wbUlf}^>OiUBz7_5dI&P_^ImDY3 z?39U4vQEgIUvxbv()Yk(czjs7*0g&0nZ}zae_l-)n!N+ZryXE1>T{ySysU zec^=neH!yKSJ8Mcv}tR#r?pL5%+CkEpjO6Dyh$~YXA_{^&1x&JxH37_7nNMuknH`~ zYnhT#JWk-0{h~m6)G@gZX(i=H~-}HyS3RUt;`!e!~00 z@J}n=lQY+*3!ivfIz)11accdMj;OO%JIB_TcY6Ckky_L`pmU&%Z=a0Mh;2gy_3=wx zD-c^sz-rHSo~YP~_bmgA+~l4140v^qy>ozk`vv*-!yt)n(&m9$xYWlOr$ zmGODI*9JZENQaT*U$zanOe`nQK##T-m}1G`SmHUBpL7`Y*mLgwUtcaa2hLD#HV+Tw zW-!MSIHPiNJ8GF~3hSJnNUH|&dR3r6Z}(0L`f}l$8}!Y9Z!!Av<#b$QPZHH<)yJO1 z_26YRQMD)e#d)2;0RwW;2V-A;`~?%77Q<(;0DRa_B~JjiEFo{fGr zHzwH|Ls~of@m;Q;xPH>_UQEuja;#LG|HykBWt^(T2M+X{QuEbi$7nppXd=dFOj2ZU zj}Xs$ga@I+{~g+7?DuGsH=wK^{sZ+m_C+=Tx+^TPF$R8Gnh@8~w*Vm@`^$pMivH}qi2jCj~;Y94m*QcSs-hBV? z{G0x|*cM2J?zA@T)vT|MAJvb?Ti(F4F>!%kUO1}n&Hq75=i+gr92!{!Zg7hmx>}RG zC#pAPS)s>Ls3wHUxGBMXsZ0CZp$!TwyeQ-@IX*C<`~C0f3$(8ogWCK7+KKjbq4}D2 zb`QEXt&HAu&B|Zs0~_97Y2S3Yx;5tPB-Fq$(_YN1Pg6>xOeu+^PrVLr?9HE6SkfFA zTko&jwDP`{BUWB64H{#^0%x&@B%4BTPtea^DUr)W`_yROOD6JOa%j?sl~J1>bp73R zUvcy%>gSt^`=9+)nT7>+BgJEK5At`tu)(jNsn?z2#xeeXJv9a}=0XU%i_Ff7xmK>>}NoHqsr}5`8uXH-0iS#6A5|*Syy$4Y9v| z1lCp9f^_UfGOvwtuX2laXy2kK>*5C~nr+ObuA`qhTq0$Rf05hrgL0R+@#+tDX$y4Q z)IocOwp+DP?t9%Xcaq!EIm2SfJm#LOkIDbgm8FkKgTCH+_1T_VPQ9CkH1*6&T_az= z&ZWbC02^vvl$Jk7>Sgtf+7F%2K?7UpCw+#rgTJ7hWcx`Y{piMf{o3q#y0!TOSe1-Y zWarpBoe|63x4Y-*maP$|tWp3c{=O^e$T)Bb_Gpk;*n-?A>W-sjGm(bf7UR$|yL zp=rfBE_Jn^p7mdbM-aQ2TL;y_9QE#gKs=QF#x^ zMe0|r2~@(TsC|AZHBgm8^XX_!qU;W`vN&k%DO%%9F>$hg^z0KwBivWEM4@*y zB5ix;Ov@Daz{~=y&2f9;QHM>a!`Fj#xY-SxcG{JAYozbpS!4TqMm!-HE`4LRngCFS~Y0Xy{q0|W#2Sn z^?*(Ht-k!MH650I5vc7BrE=t5nmY@Sv$s$u`fHK0m51`a@(b_y8uUHr(PP@Y75T|i zpoP>mq-dXc$9rQYbuP9{{;Xnr#m1Tc%jI*~H0lpVU+9EYnEC|m$&$3Jz*yKV^?fNw zYt*-2VAiCx22)zF&0ZC>S6>%+OiT4#cTPl&&dLn@tYNAr`E-%dOW#o{zDb@9}av#_XCE?!&(yO`_*j%ges9 z;d#{?Wv_yrRTs;AU~2W$@=0K2_44wstax7iM)|8?XZ6K$ADHT$S~1Bweg6*k8?H+4 z@`|qz_YUtH6|Y82-{0xJ==zynmG(IP(CR*;%!tnRmJQ7z4KegEb%mMneWIN7p4 zzSy_M_McnyYii?Sw0g05ee9?IrE&jrpr+H&|L#CN+j*UI@H+YZ{V!(I``qv8%Jmjn&n#Yv)Smku5U$BoEC*sy-Dyre}U%j zbieIvbj&2kZquT6U>`dqFJK>-clvnDJ9=Vc)P|uyyW(f>=#KUQ_&cTf9eqOkJ9^sI zcl2~H1I#?|jxOM~;g21EV%lvR-qGV5hXj^i$VAOs1Et+*+9+kM($35L>DhArmOa<7 zS-_g#kW_<{DvXthbfVC3SMplS#kS<_IB9WcAA6I%v6DZRdOPMc--*Q=XRg&Pjgi_R zoJszzrOtgwk3p;VJy#)%ewbYMdFl`Qw@qEs;$QtZgC! z4AQnX|1Nq4*;46W{?rQhdo=NEY#?H2;{F%N8d@0}u)+N|cH7||y;#X(;eL?a4hqli zObXBL1`1y(!=Gz-4B^==;C{i7*C0%l3M1ftklhUn5yp_i{Wn9Nhw#-L9_|O(-EarO z8*;e+X2@?ucrS;C`$2X$T!Zk29PTE)%0;0vF;{#*d7D~2q5ziQ&V&M!B{&MBh%CIr z0`0n^*|(4E!rykeVJ9HF@YfxOqtkZT--~lQJzKJ_*`Hl(^Ed+*tF?GtwEevT_Zlf( zEu|5V&W5zfeNal@lu{d{gCK2l+ZIy{))I=r4(Z`2#OrZNX||NcQoN8Bc-BbiYAJP4 zypT3|4oc~pQkqHeLfYoBRmylvDc%N(HxltKc1meBNzXOZAznxe7O#=g)lw=TogIOA z7ax?;H&s|lEpqyPtLNzA>~jsJ*5X{6}QxGqt zO;rb_^i35O(%F!_TpnofU``$Bh z#NhXy(Tma=^(xr&2KpmB4Om06&WSjYWG()^OE}VS8vT2>W&HWp0MB8e)z_HAe2#Cs z#(qw->NNk2Ib;)Dkn|Q#j~;Qpg^^EdbEY1@?%S^0&)kgDmA9}%x~cV3*easrtaoc$ zMa3=95Nyy8!sol!Tr}G)gN`uO^WQF!Iu0`tt!|aPx*5CIZ(2q2)P7eE+861o@6<@I z-+U>Q<{#wBaZdl#djK{LviJ0K{r%hj?6~XNNbH%0XoEbFII+0i|EAZ1Q)RM1Cbd;o zWMEYz3uKD+rFW7x!8<~Wx#i0WOZtS0diMfXx@U{4r)%%G@9BFpoh>IkNuyG*-cTOL z!g@}5oKmds8y483cS=2GkjJ{mH?ybfE!cB1-M*O_uML>Xkx-w*qdiypLJ^JV3F|}?8TEJ@x1$U(UJlEXbei4k@;=cSNmwMuu&V8 z8?B9+Jp@|!(;8{@BU?t?`ENzB(7uNwl~niYmTGr`)PYB~#PgGDVTGTBbD3;y`%J30 z7u}ZRRM*^=Q*K|&keo-HJza1144%E*8L1Vy+BFv*c31@0^HhxP=~S|auYiL+@J(@)Mk%Uh~FS98wdIA^0|&az~_0xM;{ zip}|2YUHcjz+$Qz%H!v zb`9rXG-_>!=gpSSJ&ByR1b&jD&1;F-tZGg)4c=^N8nQW}iRv(t)+kwvJHm47;M^W7 zJ|=S;!MPoPTKv%SXNVHAh0_{t_u>wPwC;t#?mZik)Mq4i$rhio=%;{UG4Hdn54yP~yM*X~&L-)lQp zO?e`9^=|CwD)Dzz+7A3}PwVV=zmcKIT6^ks^u4JikGAOUjV)KmzW3uxv8bPDt*GQV zjM@0Wu%1u6zv*}by|Cnxj$YW=O7*vJ@lQ~HH=FA3QPdahrFV^q6g#gQEY{->)!%EZ zE9wm+wCT@Bqt}a{iNKxu9WTTrMei8!Y~~9CpS5U_a_(6DZ4~O|R;e?NgJiNcnsr9Y zfRNs}qG2?2z%7mM=-cq80b1c2{8@O>5uu_^%&oF+&3W|l4e)ZA|qit z?5jW0d8OTNXpZrL2QHE3_zvn`>6JZQZ?j%0Z9l>MT@^f!>%bfzeKrL>XL8%3ioC!; zyCwNQaPBeH=g^Y8B3Yf|*f*tMhp^9e+o}PZe!KEN^dXIpt{S*$x$okt*H^t!OnHpi z{Fa{BFtudR=H(^JT>a-Zl+OW|I^>?zhdI&@%jcTrDDBoggV2ZUfv$~qE#0P#O z?;%_+ep+$p9#b5zI5gJiv`gM&a=q{!_eSYj;t(bje2Xc3v~gzul(~J z_HDXl6PfgYD|D-Y`jdT<+5_~y?`3h2-8?>U6Y}{n@_Bi?ImK)HAICd@Tt1KVs#mS1&urG06nO{apt?I0g+a^hJ$&Lb#KyQIy$ z{}#KUwZt2@EGu=AU)cxfL@F08mxY##M9YyDM>p4uQ>h1B54oRnMQy&ip`ampb5nzT zbK7^GPfbF*eRV;l@lI=jdq>vWtxvn_+|OlEdVg%iDUw*3_4~HJ=wll;j>!5dCWb7D zI3Yjx=M`&a{N}@gwGmSa8b0<$oV8m|RQz79V7t%{UZOIY+WcwU(i-@4HMjp&+V<`? zwYi2ipU!RGyS@Jk+g|7JLC?`y@++=~eDU1oH@D_})3fxkk)IEzmfw#P-8XT*9D{bJ zv;X+OC+7#F-9t~lYP$_jy1U$8;GWv>j_+;tyDxs~eHG=&K@AmO*xqlee?FXAU6@)u zTAsUhccp)!&RzE-20Ckv4?KUq-MbrO;qqgXS|KxaBDXZn#ZI(zCR&=#n~atY-BA>d zhulRzqqY0*#X9CBYGWbWI5X8R+xQ)B<3F_)EEB1Jl(Ry@sFhi7w*9`-8Z-T?L1N8} zea8#dT4dYCjXHtTY#Iq~;ikcBYCPwy!yT!OTIAExX8FvAdj8g7FR1plZM0%cX9m7$ zcpZJ^hyMS5MO+)z^h=yjKbWO;TBD+$ov5ibl*apkz|R{NRb)D>$r--o=t+^!(P+1A zO7=!=q*L8TTm|lBzBjNo92qOd*ZY^RrQ0yj?Y6dR??cCnX|{F_u(Y6eM6`+VnSq}+ zJc3rAe>&2VclwC|dH(BhI=@>NvAgvM$Ir7SIbXsp{_*%b$+4)-j+W`}dJr}N+msU( zd(PU1#(voD{nc4pgqkM~1Rig&pS4*a8PMHzC&JCfd=ask?w(xZw|B0N$eMwh^5+rz z`G_=xv}es2;vD7ty0uZWZWgKQE@Ph@BsCzsZ}03#su8%Guqo@hw&~cTbay3iDu+9k zuPv^ja=zJV8SwUu#J|4YIbdM)#u)hp0OXCU;F$_D$l}QI@86^s(*TT`!!8*l5|jDzPnL zd2kLJ+%`bg(4YAhK>?+J`iKwQtS^U~p2i2#a8p2o&-PqT*Ad;O`p5L|n$NQP%xBsE z2j{b&=roeDQ@?*c%lsxdp9L1gTy8$g#RlE_X0OcOZ^b;@9)d`EHm(AgP3@? zKQE9yXheJE+7?Y*_x|u#&@U}*Vq8({V$)o76WaPVv~|*%6JC4gpX@XriHTGEYEMF= zVk-6|)}$ZnqIs!U9K5Mx*-T@j()B*}96M-4#EWr%YOP#bQuAhK#DKgRPwdY-eeZx4 ze18xXm3KNPdgJ~f+TISbFyE$8I&p#fdc?%Tm+6&iheG4LP5;FETk0!Gi{;H1>M3;h zMWC<5ps%d$6q{d1PYK;OiEgvXp0c}B&3jLvKaeCYFs7&7y9&O$aTd6*r&`)(|FL?^ z`iJZBN1gw->+v_2{*ijT@q6m=p&OhS* ztff$oT`>z5*6yzHXZB@T-<{(W$&tEc8d5DtoHD{a#l0zOVe5cq_#c49;HmDeA9b$Q ziuTxd+J60(ZrhrVH+Og5t<6kyBBsA~OyE3-e_igx2}DD8*YVDjSt*%UF$jdx>n#7>Paf2=|LEmZahGS!&C$ zoZ=$8+xpDLnbu9?_YA}Hk#3RN?62-9(uU((gReW@#OUkjKyN>7zZfH&*lXA095^#R zQe=P=!M$;jVi(R$Uj!H951nt5jmQTX?alM)O!c)@&5>KuTkQCb^%PBGffS|T!_B8eNZ zdL%^zED_J_$=-9_>`dH>p;lk+6wh{djqMz_NjT_U!KSR6TT|s4^+u&-%(F?>?V@Sq z>}j6m&h(L%4c%R_ox^j6&(7B#aav!b{vxbBUF&*eN*&j0zwd}cOVV2^Uj20J>??Be zwdDxCW%wg#ThXvV-<63rZX7whr_0;(G-~-TpNak2c~#Hb>`@~B%1DupKlR=ikqdv+ z6_G-~?|Usui_N`awqa!($}Kzu?K;Z+K+D4|qg^p<%d!V;S-yStJO8~%OboO}K{mqm zc}IdC6Kt<^zL$`WHv2yn|L(3({7#Pl5aQ2xZP2nUqvL#z3F50)8~%POJ}^$G|DO{N z3uBZ{SJx#7b zo&wi8Ph36iLzTac{KbbMAGA1b_3Xt3tJf`VT6K7F+p0m8O{>>cHZ7f9S>XG$!}NCD z--EvQJ1EB4p19g|o&sN6P>%O0-c^Wq)gZ(-8}Y3}{D|}61N=@Cg{VV_y8qRIw;w_* z4;}V2J=Ba?goE<>9eJy2LR|i(O-t8R4r+-=Zd-b|a%4-}W7#;JX_GmAlJoK%ad7#b z*3;7pd`mjWh8!R8{dN%QX?7^>V&uOV_2Mc+zKtgZt_Mt|XmcG#ofb+7)x$bZY^s39 z>cHPmHP}-hJ2&&!xt@r#gT%;5B6)-B3f*#}WlDUi0QJ_4V6Cn5G_5@BXS5eL6eXH)L7RW(CMW+>+Cu4pQwaQ#fG?r*is!P;$8zpIupimMZZ50Wlf1C;J=f zwZQedd>>_|-bb}uj4~G^uHu*ElXdHm&N|e{deq2z)W~|&$a?h6C(&1*ELgqn$)?qZ zpKM$G?5A`GRgC><^DtPpu1~_(F!Kj*5YJw7on=GBvjbkXK0EMb+p~jSj(j%e<)~)| zza0InHSq0){5=CUUz0k}KX{|PG1eZg*&@phcJ@srWY}$@g*MCD_ z4aI-$KNSBvz2dijPyCnL^QFn%{mj&K-t&>=BnNxGnQWIa_IwF^=d{1w{eaDJD+g{a zSovN1ze`=>BI(34Q{R^Rzqd?#{5P@3kHH>)zufy}elsX@&5S+R`&oHkAA^1UAE3X* z1rA|fuf8pL9C~n*7Qx@g#Ihdz0qeofLk}+Y-}%jswBkRsmef?Pg;s2zIpeAQ)=kYCr9MPkx&PlT+EemQ7ugR<9eLKkwfhHl+M{3T z@H=y)o{Vyyr}V|d-(5yeHqPkd0(V^e1eT$`dNS>);@dBFo%`I^oFCbFK9=x+CR7-y4dy2|Mh+4ME(2s zLvexsIR9PyO0@r({`W%{yVkP>!q`_{i8GJTe&}hv8hs%OC&Mw&GA(;-p2==;ee!tg z@ew)q7vXlOFW`oqDm__#Q?1;7UCbM{XGHrA?mx76-2V^mjK1i;I?LWV+5Mg#bD(6# zS0B8m$AVuRABp>%8)pXG9(R>zvbMvsb*8>g$pmcQ3Ao26zKD_EqQ&wzlIk`$wedvx zrJr$DU~%9}We0v00)GPdUfHHa2HGyH+)0Q`E2hxPofP_Otb>zXui~91`OY&J#0|gqt2IR3h$0K!RD9Pm zRi1H)A(rIFaWiarLoH6#st!1`WUohyIct+&gVX%`7t~grc3ig|cwD!%BkX~=z%W_* zXw4|U@ooIl7JLbxW=W0w>+`xLEppSV#kIw&JFKnvA|AIs&$WtcQ8qb7eyVrC5>bWU z18u=CH{1pO5Tt$6^UY6S&t!Qz9xeU~eh=eNyhwUUzt1t$k?_pwJD=2x#0`%44Z}7( zsoyJxKfSpq{>72c41e)${m|GEP4DA2$osl47S?U7xCa8SG+17^G3jl56PB;hY0rbM z$Y0&p5S@f@E|L7c?#j2{{5IT{o8E>yF7PXS)4puaFSOj2_w_^R!+*6dO9VDGWCl;*;GwCV-yf<=l5{7b|0x-&C+$3A_UYw+0#1NP~+A6VlOXD8VH z=o)l3BdY0Cw0K_E((tRA&x-2~>j`Q5&d*AFUZ0tHSQoCt`m8j|3lW>2*Jt?l>6!Wa z&fiJ5(OeWV5g}p^9MxDM-M(+=w?uDX`vB7Q&S zRpjjDPKyQ^eg$NnKOgs0EfhO`B=+B_eAPC^0g}izr-!{sUlh z=kF|Wfsf7?b$o#QkPbKhbdmfH@?uy1X$ni>o)d9_|2(f@$G#4$gfl3&b*{$SzdwH~ zbh{yEVnjXmU({#zH~(Ef>RbiQWrfrFjAcV2Zo~Lm|E?cQxBMLW%157Y+@o6?adIjx z(~mcNsM`-%u0zkrwS*gPD4Bki~@e0AEu zr2oP=u>RcZg9YyZ#ZlurjvIrwWd7O}fs|Ya&~JAAz#V=4JG%eClloC#wHvjt<{kYA zeDCE?dFdtnFRpj=CQX#By?t_*llcZbsPgLw6f1wr1 zo|Yl|VIkzm=b*U2!{>{%JLE22;CE#XjeSY~ecI45lbb$7-p&IY?9MnF5c8{)|Se{JLc-xU&J*rAu zN#`o{^QYJijlvE`TmCZW#xjJh4*EX4@s@sIEz70U`JWOkUzVL{-C@n=Wx`>90{%VZ zA60!`N9)wT!lG`n!W5oK(yB@i9y`vMs-KFd-{!pcg}jHAi?~&^WP zTt`GQUHxbA1*~Tx)F4JP558AX!cKp3m8m*(A4*}@kvDX&%voc3y1@vqV|mlCmRm)3 zsHwWrGW6?Hpb*5HK^Si)qe5UeMwhg1@uW+&ym%(P zn$AI(&zEwRzLVeDPXlJR_S1m7TFcHDaWA}$J~8d; z6PBw_OlhU-4y(>=fac%}9Djf2fVfqgTz!;8J5#EdRJm&|T6w=NN_fj(e8vPRg7sQh z)_V`=PX}lUS=;A}L+wdr?mqf_i2J%{nCD0yuZoQlUiQ;g+~0_4!C^E%vTn z-=&LzdiVOoi-CIgLL#R+yC~stzxhlo-|RUlk2*%5J#+QhAFe+8-9>iu4jZlg4r^?% zhm^T#iK^>*sH*iJpm8V9254M!kKbPc9n*FKy`&#l)Zj&!>E~Ev!XK~bosG5wt=fz} zA75`>M9+GCe}eB{NicQ-UWXFb74RS2fqmiU{)67dNkN30k?=(v4Gx`RNG!3t`0Id8 zYGwuh;EYe|9+Y&g1Nd-W$^V#duw|8JVt;wOl`(S7Q-}OCFWIDY5q(ybL0Y5h9XS#W zt!Zaf14Wf~RFdFk)(#WYmxlpsiK!&UT%ZDcBkJm?RgefzJMu9jrmf9Ho5omF@ zc>W=l)%9ho+ZEhFoUaa^e}HpG@cdnzmj=)GcvhmOZ(=`O6uk1fhn5)Q%34GboQTxV zlY;&H(uJjn0HfdO^{u|Z=off;fjK~Dx8KM38U2GO*%&NmC7q+E1G?SAmt|x>{@%o2 z4gOxjACEt}KU2F9ov)AeCh^>EVhEA^N)r9VcwbN!56s_yF9h`_Duh%wDsiU3sp3j@ zK=SSPC}M-SO=Q%4@bx0)y}qX}l4{4^71^tR@inupl3~{B5E1-?oxls9R5O)xRzD9U zk$iaf(THw>X!9!2H9G(2U>1GUL!ikZqYdy@rAS>_sO7hPTp2N%f?V@lDUP6@!{sUh z*0dyk7Dj6{d=8RO$6Q#C1Ld4@Q~z8GN~!GS%9=qhq68iEE1NvKd1gZ`JY)BG99VIZ z@660Feglo{j|qYA3|AhovUe^{eN+aU2(_T!v*PgusRly{YbbIg@g0lDEmo#>Ahsfz zAGg57zu_2<*rQ$_dvV3y&*MY+YUOWNoB8kY~*BnC);95l5I?CvNg`OMI4~b18!N~t*pp6V(D*v zl+b=D4_XaHA~8e>(S7ti1@`{|;O&W!wj#Rvv~F%r;y0M>P^S z;Hu54_VjSr$Xit4HI9nej-#Oe;In~vr@?Uwj#}^*IXF@tgU1ovwU}X6e0EgSQyv>v z;=ylEr#yGdQE`TusXi)BYoUAvo7);njmJ*~{n-kBZhmBr+XvM}Zj(1&xgMWZHfGJWf#bIam8+ykVM-+zvJ zV%!2gz1O$*Ty)FN%Nvb|p8nCA40&;uD==1f(H3b*lE-D{kD~5zmwxb|O`t0nFK!SM z)1U+2&yw=mX_>D97@V^~G+jsMJ zSg&ixoO4fJZO3e>9jw%jyUqpTQ0GcPV}<*=Wh`cZC%CGA3cFO-tEC#==t9c8OXmX_3mMW`^@L zHadbC-|PFqdjRpD8F=SA?`9_%6W&Zl4Cfav0^Z65N`-H~w9}q9o{sPr-j6IDpd-D$ zBi;bQ0cdD27K`c@%J{)S1erjD0HqawfTnOPJgr!Gu%$~;SW3yaZX$13Fo}O1>*rSZ zr1$#HopbCx6wiWIyeG0PxAB5Q&o9kh>WCC>^OHmxSrd)19Ny!oH{Rg2ITYi7sLGKv zdOLvcb^vQ{C|^`>y5UKR_d}8L+C10h%%XEl^~|Oebnr73PRS3l)=5eQ15Jv8!`5{O}6|Yps`*$+63c4V;X+l2b7|H%}o4HeM{*sG(|983iy~t z2^`P^{vMo9zZR!UcSjmCn-7kPMt8vPP~N{ghE!5d&pE3fv{qWnvaxT%H{}|B)@^9P zv9^DOpG6~w>Hd|>M+#%FQ2eY&p&rryG-meK+f4mlANr5m9B6B#@FL3X_oq#-k8Y`$ z`Y?9dUf*49k2q8K9XO{NqZV5)pv!z(?j24nE5yR<% z9R<+B{R)3-_!s=?5b&py{|o-q3^dDE{d8`Mh=HfvXrwU0?_GTArr2@;T@>x33IBB; z^#xG!Zrb<#c!5h%^Zy1fFj8NLE9 zS6hj(z$Gswqh`5!eebn}@T`q%xkY3iBBSnfrDE^jBJ&-il%-d~8OU`d+HU9l$w^IY zt&vYj$PyFtuxGV_Yc@@AjkS>$CS8k_HWm?;QNX|Rx!DrnHl!w6S2^=bOPphE^Ww*1 z53i7Ycbsb(D@L2EWq&)qu#_23Og=Z0x(>ULR@$Ai+vI$mGttKGS_gV!J8Q5}#9xEn z$aC;aaXcbmTo~{IPV2_`z00z+lEF@g`m& z9EP@}S=504`<-j*ovFC?WVQmjgB95Eo^X-&$)Sv4RRR38^i(3#tBGH=vU3iyU`LCQN@p}h;bJgl&c-IWH9*L(@RH~|*JR#M}szy)nt8$8^!FlBaxay?h&vgT( z8tST0L-ogAHTRGH=UC3mMx8)eZW~+mJX*r_MH+6Q&vDgphdpL#ZndPXs`EOzF2@s0 zORYucx(6tfB)P|xXIpK-nrm0e=-%^SD`TcHCcVCxRynVACh$Ez;Uc9d<^!h}>m_|g znI#OgJTmcqD;XZpX;7l9M}&7H^0C)J~EIu z*eWbB-xT5B$Rj zsIMvTc?uCHFWVKs4}@2r5)x5er0^6Xp0s7h5W~8XC(kkF9^c-JsX)YN@DS88|-QN?M~d&0!fgE+*g-~cV5L?iQ3t? z2amF}7h8c*EqFyn|Bh#S0i$MwT)9 zvYchv;hUoO#FT4lH5(!}YS%@TMXw!Depo#6xD}LFQ@0n|cmMdcJO|m6Q60>Qz*pyj z5+gq5%5+e1V(f4m7XOCwx40Wte$j1@4{=eRTDB`1tzFi)9~fpwhP`i@h&OM;m35b| zZ^^=V&egAFh^n|n8u0_74u0wk>G6GWf#WGU5ZR~aW1(M&6ikXUHQ~k9j0~9&BYy0mb&sw_YtjyTlDx5`s015Jm2Gc{X#wNB=IZv>iOgGyF?{c`v#6ajkzI$GVCIW zj3H9^J7iY_WY%5pH4UJPEg&0>mCk20z(G43$xV+&5E$M?=Tl=Iur z-Lxcbm-1G!smFKUIbuBJBG3>0=;`q#p2wd2*MKfA8~FoE-gUJzAyn@M-ed$xYHHvG zCggYZYFM0me4EcRSX*~H?L!`pMawS0TSa6RVLu(Fhjus#(b**#e&5T`_r84=I=tM` zXs4NShV!=MucG|bENF~VO}1$30AVrc&YOgNv&lJ7cuC9_l^TQe4f}chzJai*zS^#2 z1_)31@zy=EakFth&PLle$}Mqf^UMb_x;r0ZcGCFlfp^Y?1%}!AB{+zL zs zo9iUmyvO%PNjC5Cl}fUCq|k#kb3IKS%9}u^sIDNPg(4@91-<%)%H<@r)aIN-CGu1% zkv|syo-QLN3sf{UD3RZ&bqHYY_iG%eJo*@9d{F21Gf8$lRJ1%)S{f0R32LUS;{jOJr$?>4Db+GNTwR=R&BO6XafMZjqtf1F zbpcsvnq5~=hU02`enB3NN9+{^S{#)Nn;=Nx{z6@08IG$L<`?GSs9e-ksHN8z>55!H zR9d|#zo-nyBa14E@^Dl>(p03yaoQug`7R(Ut$rkbei@EO9;txw8uu4B&36GYW%c6x zhi9<^j(@h0(N`5xj)my^JUTvR>;sAAVt!uyBTRV@6WjOLFwD@%+F}qY^3HG?_ zXM#@B8d2&R$eM7VM`LbA{QiNS@J71#e+rq#WDT!AAV!e`VvH8P`Hd0qePHxMt=ejx zHL^O^8dV+l3z|+$-%3=Q(SHr9trZqPn^1d|7kREO0=rjWEnP#=NP~`SHgseGfa z3{o4kQX8nZ%kQm>VbAJYS6p2E`xRrJ``;B>VVfT)flgVq$x8J~wb*4s&0hSgF`I7c zn+bil#N}v(c>ft7J@xyb#=*-qVuT7Fu1S)IYbZQi)$ni)3wpS!;NePy7cNh$53Npu zrAk$yb@uo^Jxlb|zZKR{Pgr%h>8BIwYQ0HttE%Hlb$qgQj?HeZvhB8>w6$5|ijxcG z6x$1`igy>BEN&}^vnLnMvD*u)?7It3+S>}_7A6t`7L zQk{WUjY#I%4XX8_Z!zn+4eGbRZEXm9OTIz#R>%g`TMD2J+IW1iCmDvF z3)Wm($FQx6(f##f^urQ*e7&tQUR7}z+BJhU%SOgg8MMf{%BCE>!+OYe+R7Ch3bKle z3RV^GC^%HCY#3g6x*)!Rvl|L~eACZ<<4J}c^C9d(MjYqjNardUHezHMe1?Z$CpLg5 zn;gz=Qm@zSp$G-srm#KCdfBEhZ@5CfDSS`JCiNc0CIX!M{CZ8bdh-aA3bQ5#{ThdU z)lwb{`mSD2M77-1aRQ#LBjMRP@{K-jWP=hmbmcz8DW8EqvEFprtxHJfBe3h1waVIc zEc6-eIwpf3v~QNEJI9za@$W1#=3FNJW{FxHwK!^U)ZnPZQHi7MoGuj{)H&VQ{gxlx zW~?Za6>G8;ngPsWlJc%gg*Ey`s|tuwd!(^>7A=kE?R=tv2;EoGoeaF6!Bt9gV}C2r zhoIkCcs+Nyx$1FFQuVbi3fh&>dS((=ZlfNkyTgU;n8BoCbUpPL1GR58^QS#Z^g%_d zT=JBbRU51)v3AI?m+K&%@Y#t8BbnjsCe@y>_1vb=J!FFn{m87BZ_=Pg!=xTfM~|wi z6HID&Vv}KMRytQpT9E?b2bJ|Gie90Q);S^t4& zHi3O5;Q6gWS@c^I(f07G<466zJKSO0D3|ufvmq2q&AcR@N^;m0;1yxCX6(BS_d?IA ztG8N|4I%CRbh`iS&(6Tr!n0ZNVJ<2!#o<|-b(%91S36s2X(1S!&p;;ykI~ix4}h?W z6srgi06pITZIbBg#@YMV(Vg(Cbms@`$%hUxcD>G9biQ)8BoTIQk| zqqM?jSN2oPj!HeB;))U?d$x$N*0InzLP8Y2=%EPStbvSRHjs_-jgWAGQKG4lmC?Ho z_hLqmo_m9ZmY5Dpd%{6!N0@hsw*F~Pl<=d7lBqm2CAZ^L(Z}t2_RH=^#*OY}uf$d1 z$^!hFz_x{lPwn_i)E6D`OR_uUw={NWkyR+YkpZ4w;LFsriGhXrLBeI|`9t3D@VUw% z8Cm?NI0JvZG2Hw2aQVjYHkN&(kM(>zNa4Lt@s#RQ@3RBf4PpfiYWx~(6k4I^%EPc6 ziN2E;wm~=XOr3IzW;5BK+QMuI-NJ5AZ{arheUXrz^MH4gz=u__LgyuFC90ST9v!>7 z3~MVnmr}woKIzV7*)P!+M#Ou4xs!^>_8R!ir07 z;3}@!t-7FPhGtbS`m`4nyyzsO>C>KO(yo*%A<-*$X$8e)Wp$3IoO}Sb$Kj$3#}PQP zla=F{Dd*g7X$}seSbr@Wah`;cUm(f*G%o)L)^C8`(tXUp$5cg)1ZS`*X(VD_Kyf+H zTkK+c0u)yzQQYM{*K-D<@BQ;cPpR#7oI#a78Jt0dKQYq8*eV*L`6O$mt=PK4w#$0Z zcGk)iClzEC7ZHwOe)G;SX{JX;jW@o>xza$ z3%y0$BGdd84Oxp8&L0PVwv45#8^&3aZP6JfP{Gpkuuj5vXl0#o7>$11=%=xd!n*-( zl3FUSag+TsGFh6D_G{Fzv6zl5Xkx$5@z!k6pBAlf8u9|Q=_{e*2-V+a{r8k{e(w*9 z|LU16t&M^FBuK2Efe)nq6;wVq+3pN_SoBLv)4M$%o zW-!7>hxH8$-0 zR}EL!*uTt=MlHoNr1kZ1aDB1TPH_GDQr@t>UV@hJB~gyG71w*?+M>33P;|*QAK>qq zEl<=_S~BTZ*VfxuThw1s^cBL7Ko2ysz;5smGL6vvZAA}VGjB??@=M9TjhIfko2i_V zwU$zkAIWeTAAz}50koMvmMJ%=HiT|aZ_sQA+Yr7XV#7!17uNN6(2i?);b?}8-%0Hb zF~kg~IpIKC@~9s0n#a5Ds>eH}CUIM1tLfecs$$jAENJFv9($kTD>248VlhxAtXg4R z&yCW~HC?XN|9xRmEBdL!uc{%~jnf*HCTL_tG9l^vxc; z0Z0qIOAjwIW%4LoSMGWdUMxfS7scef!TekB*@!f}2$b_kA@mZ}fD_XsXdLI<%T|3V z_2nrkKix`?Yzq=pj~dOVoU+A>zSqxD9~MH4kkOOT;~{-59@*Bdmcge=aJM3Ow+sP zT8V=<@VY7mG>z)@*&P|9ne~kw5%BIIEi(n3IL6>ey?}H$ zrr;Rg;`a$xILxI<^_nVOvcjbXk0|<#UZM|-Ll`Jyr#qrbk=%Ylm7Lq8Ox88T^YdKH zNTa?Ut7*tN2Q(rJT+qEW5+H!xi3kWIJ4-a4)AL#Qca}KpTo(RjiFzFMIL6}`kE0I9 z0Oy|-s!?{djOf`;UZu_enaPPiv+dhE=%;+Hpm+kb- z=>9VEi|#KnU+H6ka^hC0yw5Rvy_pe_Xb~}1Kspd%OQq7mI#7d5XhXUaw* z*4L!|GvHdO_FRdK1?P3c7ifh@k<_!WI9xCB2Y3RuLMchD5ke&-bBaU$ulI$~(!Q|h z-|h<$!r%PhQRuz^eL<)eoQgi(Iu=}W_%E~sKj)kygxUTdfLbMh=ZfLk-K3nW4UxPO z-@BsVb^Ew##$;$VW2cT3?!5&04i;N(>nb}L%~l}yYfEY~XGefG=Ec$+nL7nG8s!5| zVy@Ej1+wr&Qe4`0Wz76kFzC0J}-oPz8&)U50K9jA)gmQKHpw&s`xbc zsiw0Y4_iUCai?8FF&kWG|KU01;&_UO2Duzkc?_@xOgvV{h|mpK9U%ca$83O{4*8th z5c-x3l6pW!4}*;E_bt4vgk(0U9(rMGkyXdp2X^LqR#atnQOXDqyn;0j*sRn-$fj72#i*iwrmN0oi#6kQIFHu+^`1 zX^ZAra=e_p-4j+CR{t8}@F(&`kUyE>6cvCQ$!=gaX@yZeui92V$HC7&v9M}cVd2ST z+Y9HE{!oaXDMHT_#XYsX=w$H^MRT4?oL}`+;ruxJ_W5({Kg^GNG4bJ(PZd5~X^TV* za81ES!TEG(@c^EA^yNA_V`cnW%W}+F4w@?E+W}1#cKXG~#F7?dwU z7O2;fglBX90IyBeI`wYN+AxZp-59zK_L2Gd|Dm=^vnfJY3(fbDGzD}b`z$j+pD6`= zLxi3HGhm-3l6jNRpk_v)1H-g#{O2 z?Ot6%#zZzFM+#YG+iJN5o(FjxFm7A!5vRq!WQlMwsX9Jy-20eyjQ%g6y%EAcfg|^d zCqnoh$7PS4?JW9#p(-1uF^W1_MtNt~AO;Sw;<)jw7`;e>Cm3B?v+;5FC!XnVG zdkN!*-1$=7E%1s+gax{SSFLA-#y*yhst@q~G=>5igpQ2i5;d2T4GF_p%u=dP`nfjA z?;Cij0=lFG=rdI4pTE0AUmm1-;1fV|&;<<_1KUoRWJPwNg%oG>b+_bC4Bf%a>hZ^a zSr6H-*5m6wS`XQE_0asAdZY&HA?e|7l7EH9dym9CiU)W3%UlZoSUIOeQ8na=L$HFy zA*W2$5>?g7CBWgcs;lCD#nU06sfrLfU|0V7S9P|ObE5M8wS2EbugmwU=TC!zQ#lGV z3He?b1C^sHD8KD^3DQ%zB<+LO0lycP7lB{Oya-_^)lB4R>*e4&7_6dS()w!|aU+E7 zlGJ?=V?`y@U+W)=fkt!gB%ptOnRAEs3+ybz1dg$b3a80HuOm#Kh4eb z*!_J%dB6;b2aJ>YBt+tTf8Hm$pY;j!9zW}oQ1r=5qB>8Dp3&q*;$LlE6#k7tFTDW& z-~YUqBBWm0FU4JeqfHBFs{7@Vf#{iGLAiu__R-cO_qc>m-){@*Uz^n8L0A77_?T0C zd@<`eUTs7CscE_k2z&5Rpl{Q>Ycz{mf1F6mVr9EhNxk8zL}32Lx&YbOxJMGR94z9l zs6T@xJAmOowS@AOpE|h5$fzVxA!W!eTQWRzeZIO2CYx`z(RS7b&n25#=Yu`>*T#ur z`9}!r`&t$s^}LAuO-|Qn+d^Bnj+wB>qcop@jF*ZMpS=+9eY~L!C4n|5ZfL`qU>j&2 zHQI&+!8R;)q?TOY0>-dZYJ<-)PHKa4LVpYHLJLS@$Isf3{cqZk3iQDKHjF_V{5s~= zJ;+O^B(xP1(TZUgnh~>n%MfV3o5}ESP*!+^jQ9J-`ZW^{Anzf?)x6pLRoC5*&1JnS zS-OIdlNCB1;GpJ})hYM~^5tH3K+K&a@i=TK2HTU_5#_8vdgS~w@R`j-M9<95#%RUH zgb~UO`r+J0)dp^O=mzdBvOz8Q#0V+!g>?t^ZXbNvL!3c-@fVb?iZj;)rR8;3F>$H% zI+g#M^LATUeHhKjw0QJjYSF968Ot+YyQY@bn`~nswY0nSykZ}6PC6ol?|POkuE_Zj zct*n?ISo0E<^}cnDquaQo~2r0NgqW+&rD|BiA+K$Y_~18DMGfG$}6|thIkFgpBwKG-s@u$lCdMvdlN)6FX0rdpm|>Og3ND{ zyx)j1Cg}UN)TzFU40|eD=6zZLJx^K#X^-{!K0Bv#aw&*X#t2a)J+ls|;u(73$Bzbn zE+flH8Kzl3dQW6ohO3cjK@Lgm>d~p_EL%;iY zG;|VFH#fr_LnYEbPewVN?wWQ7JF|OvQI+LFlcJUxsVon#4c(+Fk1?pr!)i67RLU*fb)o-$!$a>A2%zB;h)fF;~`b2&OKZcYR<*t+BY!bTrtM(Yk zW5$+dp*Wceksm?1n9XE zj@}w)eH#BRbuz~2X84a;S!7EowT16u%E|g%{&B?kqgP6zD@{N`ofYg8E1s6Qw!j;b z%Ibn=N4tYT?-Z`JbT%OpVg&kTqpDm{tGup%?n3_%<4I%|z1ll_*o_1h5(cfi;|e^m z^fWf(Xs~~p5V!t|{(;SESeX*KJ~ecI)PjZn*~D(t2}7@F>(v$dxZQ}Y-iiK6L;q;r zzN+KFJW89ft}ZP&j~3lz9>q!XC=&B%?v-DgM;gqdIp?B&WgclTk2YVON0GsKl;n>3 z)p>-GcPPslgL;DsGw48XU02f;LvA6Bb ztL+0;{F2|i)fM)q$0W3PB4LrKZLQeCln=7432O2tNqD56I>@MupLRF`7VALv zq!%4U3;d(rY1l=*wp72-%Mx`ZKu%Q7fj<=&+Ol|P@0yN4UU*VLGs8#puI#&ib-s0# z$dobO-OT-tCv6)ms#a85n^pwk#^^4y;G41Vy*lcZ%YE=RIK7yRN*1_KKKmX>5`{n* z#f~aPZv7rRs@cFH8Y9c`{4T0xdcEt)5~}B9$76g0vODT$jde_WO{}P|C6`uWE z7g>6G0VpE;rnp@ZLZ-Oisi;nPv>Mnu;P}9GHFPe8E+$;~3R3wapw0SVd%}g=u8>iD z_U7-dr^#2jj7p+kQ>6wSflm^~1(f7v>Yqiw94^FP`2_rVxbSKaxr18T-no*7QEh4? z4a)1rwTgdC8rPECH9#^CXl8$XTn|g*TJy7UeIDaFLmJIF4m!R&>G%Qx8l$R8z^Fdo z(T}5h|7whBFUHdWezK17?)sH6eOMaPBhr}i=tJ;1i0A|H!I&060t;}|bo8H)xJR?Z zJqGlq&+iP3tz${TV%FS0vUEOSRLj)0A7KOukoXuSwVBazg-#K6G&-)##n=+mu7w@9 z3S7a>M)bXv0!>Z%@4FH^R$N>v+&I;fO0+LRiKZX$6G5hYWV zxqm2KmaU78oyRTHv@x3Kj4ad&7$}XfU>}x|{6jKg#vk=VBE?Fl&nL9DETqSCu!H-2 zZLl0`AvbH^`P?p>6mQZs{iBr=47XhSZ%FVoHh7F62TNt8t4b}UhfA1}l_gmvTKFZc zEaghsl2s+5hb_%2wUlrrKY6&)IF+T1i{?tCSO(-RT+O#T57{mDxGW|)-u1DKO-^<# zwlPzpkEPg{$-T!Cpv$e5tcVHx#YL$+Gnw-KMr6<^ibve@6z}msp23y&OdD6s^s((E zsjK;ZU0mtcS?F)m8cPrOA}WO{O|dSm$>`DpBWY-^r5N~{PXU+G9e8t{7Vma26aRKB z*2YZC%!a;m(B1K(`>&qsOFq*4Q15DymTt-JFa0A=*wxZr36?gCmWGDV?K{xe$u{L=CH0GR(F=<>h8_=rK!=-ZcsjTD^ zsZT#IX5cIET=7w@`9ptn*eW&8j9W50DpY2Q<$K(1c1s)K70 zZMSV^TdNFQgqIEd?GPXk)v=qVHK_K~+M|xiw^6hWMIYCbE3lVUdwz(W#LN0f*{bY8 zA~Oj6GpHQBzYz5%f_jBlI#N`NOg>jgyTT++g3iV7yX{Kgi7rRriFOD4tjb0g)98*` z`%c?i#WAOvVZ~44&uf2-od*6hrcBkxiMhg&OY%PAn4m*c&!jgj@Ijr_11V*z2X!xF z(rfLqvS|%U-i{WWm6ac3`?wC(9$CA8%8#*B2T%G~k?2)rAr-r9D8GdmlZ(T>Oz1#- zEvDs8ATcoOxW4edTw(nsl)y1n$TrtU_GM*DzABR#eD9U3?Rzs=`<*}_xfAU>e7V1U zM=uB3w=wv{I!8z)?MISCTSx0U@Dx{dCsuz<3%;Xr=)(KB-dy4SOA~ojAK7&<`}1s2 z-AUUmYN>^_cD5oz$(FI$+gSJ`j-9Ovl_hI2qRsH4x7(20`!?7d%Ie$wcihqW`#oG= z)N1;b)t+O6xoyN?EdEieDt`xFB(-)0W+@#_?J?S`GuyroM-O=w8uaglNqk8*BA&b$ zM{iM1U>vhtbj(0C8NY9y)UIqP#>Z5=+kV#W@6OmmM{07cs*h=>B_7qP`q-#yIzpy5 zEOf=t5&H5>I<(b(pW})O)&P38>`E;igEBhnR9-IhT=0oUuh@c5*zp8cLEAxae};!< zhw=N~y4+@`@3DQVc4zR(9hcvg*2ACca_m%(lTyR3&1nnen01V4G_P_UvN5JF&~Pgd0y=}Egd&Gra_X<6+XQ5xt8{u_<%B#2n^YsbI>&h z5lfu+8SYfEF5`U<>Y$gEb!ZNP#A8mDOh9{tz!K{|hqn9z*{bd z(7Hu7v(@y-Y@3$N^@VojVvQ>Ln7e0DZ!U=ftO|a8ysJ{=$ooLFuM}BxrO4>B+6c7B zF=kL9={(#uo?nVFOu)Dw&D&*}s4pMHm1l(T4!({6j-k}P@FYJ;A&8p*R3=!BC# z@v@Rir9z?Bb7$*TXAs!1RGv zub%ek;pwO~op47@kGgub$)lYfdG#0dp%k`hh!t2=Pl|s3q|1K)$X>tyZww)S#qVms z8~+df;CfD;z@HB|F4g!uisy6iNA)iE4jDRXC?CVG;MX^h;mmN>w7$W_=U@)420b&v zqsv?uzLl5?-BHM@4KK>!G)9mNmkW%Xj4E`$2dRVlR%%E0NB0raR5z7B?>xom^Aoxu zLDERViLS8fMnnky#hPV3A)3uu1t)-{y9)nKHXkaW>vcRNT8)`2qF9t!_&3J9s)!vk z&K273A2+(NI$K?>_J)wLJaT8%bZZwCG9yg|xxzv*q>pq*RIPMIRPVElJrz;4yO0Sd8VVtvE(Y?W8ZGV9jnjQpBZL5~(%$0G}e`UBjXll^sUIZvwQiUBNXp@6BRsad zeS5vso(KLVb2Wbu`d^xLi%klJ1i}gUuoN{Fc${Y**RmIej1GK!K zP~KgHE6zk&@`sruaQSR#L;k$H(tAn^?Yf4!^R&s7R(V{UM6Xv$^t$9g)Bgr+I=`&9 z<|g&lqu$ZEG}q1w`?74dI0L+@;?J>9t+23O1sCIDj4IdIaI@w_$=J{ewB!DgZ>5%` zg^$%7yEirT{*tPaze{cU_U?cMVI98z%l3VB`RDD^qkSvv?~#GIEWRiQ9my=#J#|m) zYIu|8-LG~rNztx~(i5e#<`LQ4(u_97s?Ex1+g$O_)Po9*msBUky%V|9G|{?<2Yu4W|dn6_ez_?UWR;O z3U+M<_)H}@MfA$iy=s@Cn9&aun23|}Vj3c|65AN&gw!97gu8p$4)@**@J}DWXW>g9 z+r#j=G0}b6t~W(~_e!xoDf~NP(wrhmp{KsLu}O-i z+v=HQIrO>d2ew!Y%@lQDxcyz&nL%e0wWIp+_T!xTQ4F}C^aI;%B)Rt#o20izx)u(J z(k1aO-E<+&e_jjjx@!lr8lH5&R!G-QjfD4LA3`~C(#Pqi3kpAdCJ?i@x1Fe;soUT1 zIgWB*S$)_5JpDS*4>eoPoFWFMoP|&IP6;_<%&Cp79AT^Nw$Hspbu`XoTWi_b5Xp0E zD|2=>RPw8H;!ZNvxj9iM*=lC95_@|B^gRJNQ07%LK1yZMs6BrF)EPMfe8{O+G<5gi zE(176huVn}JYD%`@SFH^9k*LnD}Rf6Uy%(8p`|xtUqD+l2xtv7!fqON8iJU0<-T;# zB%y6*(Gf&|?$?LZjvjn>{9$pw7Tz(VB0hh%H3F8z56uBz=flX7+Hcn~^9tC`jd*+d zS(Gg!#%`c+1>*A%zaNZ~3fRj6-#Y@Y;xhUb^PKoBc%6M{#&`4_&Rl6I8JKW$rT2}4 z(+>nn>m09kf} zb0PG{y+J>|K4~g_xzvUzfgSf|MdQ7`%5Zxnb}bgik2uiYskd5HZg@p8lFG4ll_ThgrPGEOA5$?T!Avh41@;u-uFJ9?#59hqW6qA)(V{@I(+~yYrbAyeIoO zPc{x&;T{#;w3NZHE}n${XCc1X82qLS6ysm5#nB7L6wz<~f6wKGkN%(Dzp(J)fAId` z`ca@Iupzi8HR(ZXX)gt+$>>F6<|C4SfLgL#?xK6EgxYb+spbdS;^@`HT6$H=`aQygqL98a~b4|0O<6m{1F^1B&58^=2~u&vgaAafvN5 zcI}_CW$WbS1lVD3IoK@&ps$GLCpw8CiLcfnlZGjb2lj%St$ZYo+h8BUtfNnsJ7#p; zarfbl;bS@B4ka1!N*|Z79lMoEb2N5o+N$e zruNfuE%K__d^F+>5q;>$gI6u2Cs$-O1OMEBO^HT9j{b(L)Fu`!pq^zf0#T59W+-WH z%^>Ddr9)Q9dS7GbIPNcDDycp{OIKx40%?$~WU9i1=X!`fpe11|hYOsXsp|5D13!@H zY2NyF=-9&q4*mJLr;Pt)eg43y6uxYxwd{yV)v~;<@#alGiyUX|TffAax zXzI$kDKjeRTaQ!j8k_3u4t})|XRF@dx9>+r`VoG(!@@uo{XsV^rtRBQnq7vuC zQ_=0Jh?oYh9T=GUE?>z78NbsBsk3Y>V&;_OFs!y+zU&Lf#g?>t#AIT0Lhe9)W}T;3 zvc%+!K#l=gR?kV=LPpP&clnN;i@nos`vmnZ$d9z**~b~wsa2}eC+>GVD&Y?1f5Zg+ z^Qg@M7v|C|%%#-l`R#owHcIuem({XBuWbY}Cu^qM-%3Pp-w}Fu&Ks`(5tH>Kx!b+n z^L$yL-)KL)0LybFAG4KWc9g+}PBA-{N|+sEi%C*=bBB!#iyk}x>sNMC4Zl3uTrx^| zib;#(Uw}P_=rxj^lnevs7D{pI#ue|djBE~Ic$5@e^ke}Sq7d3QY8`?V8_`X&8pIko z!i1_z?Y5QRNHT!7Fbp+2;d0v2`6}Bz{Q0cA#bMePTlF%(FUg<5e*ydOXBclPzr2Ll zJ*=ywtYB1BfQ|$ZG}N`4w+SLmnT>ewO2`ek9A+tc^B8)6oKsT;6c8tMgz+6+CSW(zEW)nr2$BANWYlUL4q7~~+|?=j0X5(elN zV4#%oinUdkTdtS@7KagbJO9|@K%W?~nK3K2-IW`&mPw#`h-KN)>j%DhOS!gITNbrR zzJ9>kf$MbTpNL1YGk$son(c}**!|MN+UKi7){|i$0x$9bSQ?B#1X|#V!+73{tc%Es=0=CEf zz=vVRk!0~C?!LG4bfZOS z@@*ejhPZ$Muq#a1(sw+-t^pN;C0U-nKcEaH5cxLx{s)#8_dw(* zKa$qsQEWEyA=?I3&lX2&V>graahn-f_KjCQqqrVvA?qp5%rani_>Jawlvb@Zt*NFx zlZ!QFbcl|c_5$f_`ih$NMy{s4NjA{*0(KL|5Ry`H6?5}PJlBG|B6Ia_(zUxOEBrIVOG}=l8x8q&u*KhIbvzD4J$I|7d^rkVUny$*n10~C^D>-sSP1kEnN1-knoNa!* zrt8C{NOmC8*Of&>QR1K#YMXwX8YR76 z^pHv2#7r8F`}TZHl&;C($nn_xMdQO&ib;U9$uIaR1eQAi{P>w1oLgzetfz zX^A4<&^En&wZ>xBK2aQhW8DtpTe5p*qAqJ3mX2hpSH5&G<7n?3!<7-ZB5TO#IEq@b zErHrn-DyqNna7#Q5h?ebsOh?he(!xEGT7(LsEP*kxQwJ^2-PV4(&HmjGCDTmO!+uF zITGh(ju~j>K}SYMvsC)b&c9%^zj2|?OPNUw?)?;J^F*v-VryOmDXs~CfXKv55W}PY8!6r^4ZT?i@SizhioRk`De+f z4tM&2bof02zlL8^9EK?0@B(7eHj`lsi_`ggu&Xg?lZB;ywb&*3HWD(rpyRvly`u{t zJ&)+~_>JlBa=Zrm$FV1fusox#-2sZw?1&3hTbYR_YgFt?kvK_}J95*)U$C=Qo9bGn*q)MKQ>x-nbv=bQ}2hi?f ztkMSb#8lUgt`gL0D4rec)LFph?bKW{~Ue0`Q zf;*APzSa`jywpacJfcOV*6;g+e_Bo(kRlt`Q*B>U&Pg|c{QV=eWvyv5+t#RWwE_D= z@j*^Hyq|WOXLdh@T;gM-uPlEO+-hiK%e0(O_gL_xcM7{<8*EJr?Ii-2Mc?oL;w`~1 zo|xzNS^OC}{|r9A4$uFX#*FWO<45U@T8rm9=GKRDK7$P0GSx6r-OHq2@+o^^-5Pc7XZ$|eiXQ0n?Y_WN z(NYeJHF<}{oe~C`-*;T{xF)8rg80c)cA#x;w5_ZQ1z%oc9_L&yrfI1Jrp5Yv_#AAlueT3n~!5>A|sEB6&af?vgXJZ`g?~(ed^3! zBXC-nG#XzttRiF|Vwnx{Uss z=us20&hJ~~M`ng9Vr+N!*X3EP=^CsN%@&F|U+2L5g65=EX3okGIHJSoS70^go;rpa zRa&OP8*XRgOM~c~_^_Rg(Da3LbKYk|w9Oh=IPVh;$Xd4wu!gIoRSlGLH*4C=bGX-y zx!IZ)XGw8=2-J$C=HJ`i=z1zk(f(-W4)CG32X|kZuRdMkst-BciiyX{fp>XKY#fFa z3UAF+*BI-g!gAORw^`&^btdp@jGi7ts0^?o3bJ5?Ypo*T82tw4`n^rQiH!NtZMMmF z$#=uQzq|K_Go zjzW24Ofqss2TGfLiAq`;l)m4ha>=W=Sy;CW|Gw!C+|S0>UPmcEqSX$Ua>ASKtmcm% zZY{fxDF^Mo!c`(eBeDl9@66e=72o_CaSs|kWXmpO?P{9;y7O;)nU)E*XPxHa{m_*Q zK;rVb-?8cV$84`5iaiBcc{+VBASysSkb-&K>r#decF*i~JpPJhp3864H5}c0pDRxh zar~8bz3i3t3{q&Zcx7zk-YLe41`8-GNzQdK!cc}87F$9~@f%@@8TPH`m9D3`}wH(d(~T%fEEZ>>h-B_>y$bNwsJ}OL_zDJ%@Yrov;bl-`R^h2c!~@ zKThvPq@cuMu)l+ce$_>~mS?Q6G`bmKIrExFpRmJ|3JE%rce-9_AIE;ZSC-5+>25o^ zcb6wUiF1v?y`gw!c>={B7qI@G0Zu`qZ6HtA-e5j)AzK^Pu7M{#Y4Q7ByprMMD&@{3 zYm03X?h(lFxqcdB8qm9~;aAZWpq26KVD}E&N|NUMj3O}l_ykbZ^_{*{$p>JJ3n{Lp z2>edp_VXO@ZisP;>!G$kD;fB^Wxx*7>DzeTRzOGA;Ii6M`S{$!pvud#HI=KZh*T`I z**bl7=kA7X?rp2B7_{cxC-B_dQ$SHJ{JtbOW`!u(7TNgSISD6Bwz=@VVyfB7);R2> zWe)9~!i*jc9zREA4&7h&GLzemEwv4r_W|^<6mR}c;r1TJ5RH8;1D>kXTk*Un1ChO0 zr7uH=f_jRmO^ul;e+Ofj4jZa`bDT|9Sp*+x) zZlg^u{JxJd=&k2G^Ku^qN(I%PzFfB@U&bff!q$-#-W4NQA?NONfL3I_0G_hK@lHE= zDD&$AWp?+IiJx^e7tU;pu^s+Nk$YzE_CAKiSprPI-Fzmuaa}0W7iB@7l+b^O`hyyM zMt9Dgm$DVW-A-`L%ATHc7|0aag&`9sBLelHGvltU_rDzb*aMk47u-*l-k;-j*O#(e zofeO~r~tRZH|td!JAq1(&MP-{ z`rbb$+i04(JUc7iG)+-nihPCd_o{Y{djDM$Z2Cy#QckLJgztu$cUarNQ`tfXLlF}6-M6eT7 zs^snyw@O#K-S@)p{x#@Dm{4vVyRIBMrx?V(hoY2I9-^=CfaZ9Oe+u|7lUHP9GWLCQ zy^MIEKe=!BFR>V}X@Dt)`(yv5j$9+e0eN;m@duybwamJo$Ne=T^K{XI z#lgrwl6VG)B*Pc8yJQoh5kYol!SDqdAzyUdpo6R82VtM2TE>d0c|kN~L>ODgA=|}E z^;<-ho~aDA5@?ODx5AtT#-#_I95h1)x8+msrw9@o03J7x-&1Qx3BJTN4+jw~r#!&mSO(#Xk3RSTEO+?ptGtY*9{b$?D4KQO!T#JJM2 zgXN|iQ8RhTYF$H)D2oST4szG8;YmV1Mm6yq?ADwme!ufX7Baci(fAu=a?#%lT%EZ( zpv0Q-&Sq7+R)s4mUqVN&79K<7!b0RL(I7vI5`QxM5z>Zx&_N3C^w3rk(;D}SLE1`t z`#GSp_TvFw8_)3=&wG#)l1+#!A&K`p^t=c0u_G2o^U7NTc$sRU27Ji~7tjVurtpu} zkGY`_1NzSZ;$MHhwN76*Q1bQsr$95Nz4enw-~L{zdo=2P7(41UYgm7T1sO3K7;LxU z`Fnyb_`>}aZ0=G7?XT273-urHZ|a}nFRi~3Q}cR^E{ZA^Xx(pr(K=$fAk7f3=UUrV zOKp2F*tTb+wo%*`weT9^58jhn&>)!~7z0qZU&Sk(gBBEBo$uGksqP$spZe-}Ib=ulW8KSOU&OjC-jq83J>z1yUCi|KfNJ}|}@WE~-ngM3A^#?@l_Twv)QMW_$jG1`WvG>_n2ed6S+ct&*VHq0z({^}jlu_hm zx^}9v@oo*ZRvn71vP4OFu`Fm^D&(|Z&Qhi#V4Fz-Pv7Z#yY=+q5ds&oHTKK`kJKkS zF4Hos!7O%3(;VpYO zEg#+thlhP*%W{@4inJLaB?W#HQ@1;M5!)UE3~OB~y?U*lRL-aJ3|;frz6TjDSpKyq zwa6hN<8|P5^k?-}y^|zRiKo*yeLs!azzo_S$a8mi{y2E|;@%<6_|MPv22|1X>=k{p34#Q7`4q`^k3(d;yh|4uc-u>eAUVoIfGc8{SIO;klF2 zS%p0VoY3M{dbPs-lkY3(YW~7HTrHHY<}d7jOVhI5cCtthPU5~+Jxch0%zb-YROR;f z-g6%qU_{gbQ3u8giq;62*Ajfo&gR2oE)tkWUwQ z>i$rC<4ig;_!{htTirXZF^12O8#E3wJ-+y!cy5oOy7B0L3ygl&(~5^qd{7+;nS?3; z8UyIHuwKRJb~vUuT{yjy%UZg@+>`hc==*;&%`4_Y@PVr;iG~% z6IWk4I0wIThR(%rPy+q-otlc@m<@AjH%XF%gB{Qi8R_iy|BEnu8;)Zi4qqJEIL70c zh4qh%VVECqe2XI;2g!90$DB!js+xKprO^{c70+f2n}7>6;($iq>b3#7pNVkWjYu!P z76D!g;|8O(8=73O(QS37HeJS;rvWV|JHxEd083OBpl2OubxRIjcc0mVabyqWOf~61 zA0;08+WY_9!Q1@oxj!A=`G;eAf+HpMRJtJ@G!h?%KRI!)hVQZW?(-q&3jy`)sF0MD zy~w|Bc=gl;c^LbsmKa06r?ygP9H6^h=dsaUQ{cq|Dd6G0GH8qP=OSfp1wOb1PcgNf z?VX(-{yB^|B}8pt)1R;w^Uxy$Jszp?dC0k`PqX?#lX9vCCBACDm^94Vty&y8vvvCZ zlQA+hEj8P?5f<7Nwb*s2xii4`&%#b@D6lbyTVhdfs-|9v1Gy}#Z20-4K9*KD(-e{r zlE~`cNm^nKPVluXHU}sEloXukgTA9ncqd6GUen>4PQ2Cw*LsN8df-|Q@mlwUjY(ZC zd$E&Y^IPGO&%(Q0$5lHgyr5zF!d~FuTlgnA7}Dp_AHKt3$9Xi$eg^-q;C}-C-@nz_ zx!-%9hyMY%eg*$1_xJ+f{t^0eZ`ciF+J^I&JFrm3h_I| zc`^V9e|b(;j4&{qH;NGksLd5uC%~&~IKTNOtKW6c+U5=HB+ zmsr}LWV7L?FxuQpgJ-46>PJAH=!@9eo;YJRMCk#xgpox=U&MInS}2|`XUOK!E-W|V z9%3>qLyTjo_uf6v&b$BJlfOAHM5Ld4^G?D!jX{*RZNdHbPX2}t9pVVx_wH}b3x9K- z^qX&&%sYuEs0_JcS!{HMBNj*9e9GJAE#uwt{5B6A=#9luhr@=0p(BG8>8}I*RA-=( zK}l#qdv0I;IZ$v^c#8=zAe3d8ulU22L z_i<by&~IT&kJZ69jfmk@ z%?y!S6!n*wR`=(P7E1)mHsS!}KGHZ#8|_T{wz{h>U-#}WW34Kz{VTDX#SD9yG*X^* zHe>aJwJsCUyK(!DWrtI1?%BIAH5#~4=XduaGTq+y(w2GUx3Xm}YijC;TRpnTrA zC!f{#5XN{?b{Q>u`SXO2*BB&XR+}7k!{>HCVgH!{V2OdP{@O$Wd^gcRom$${;fnE3i zR^G1na;SN$Sv_6S`qon?pBB?<2OTQ6FxtXoaLoM~}CbdBDm_sC;X)vQq^ z#GgB(Lk;M!vBkd4Qz&XD!$z@d1ot6GxpIx9DPP6pn?A+c{?{z?Gph~rJ^4p^^WT2U zFyAuYlYa;HD>kOZeY2?oTC5iLFHIF0^xuN(qVa}Ntg@qZYH z9fu6(S{y+*bT~qB=y7Op48~!c+X!m+JaR5&iTSLsyZ;tYd!p~`)PBWhg~~@Rf`Yzt z`=?&Slgsrk^ii^#K_n-%(G|#+eEIGI`8~r9FZ-CLaR5o2T6--C&}DPmCX*IX?&*<9VdDnFCUagmB|wvhorP_%8+WWDx%IaNf&km{TN#;w%?uy^V(1 zMHoe9<2TH>3BP@e=V$K~LU2FAHv4(zVTM1M-L9NaYvPnA*s#&u43!U}jGt8A{BC2) z@SBoW`Di>jY_FhWst^r;X)$KAM)1H@C0CJ5W$DPqJ;EZB8hEKx+N}3^Ccds^Mz*>+ zLT%#Y`7{zvL~U7{;0s$dVEzb}FugG*T(!)RaB}G88UCScAJ-S+dtYWV4;Psa*Q$X7 z@FT~b>DG`kAGThvPHyx?s8+;u@h##eTe=F$SKr33;#F1jw-ytu3&Q75kG~9ym|UC6 zl`HMZdbEEn(ElsZ<7sTBS|=%0Y-_h{pXLbhYs=Bzc`?ehiu@@Cbv|S8$ybytF)Q+a zK#dXIuUdSOW{mrQF(5OJo=xqr1iu>NKKyEp?Q`~`-rFsEh3>}D$*2e868wf3_u)6x zI2w0*8{1LmeT_@dCjE^2@Y~Gdb z@vaV~O**Ycyci~|j8inwl}hU~@r-MncG78JzmH*ut|rZ^Z=5Ai2pY2tzg@>HOO6r( z$9$TMC{SZQwIBx67%9@KF}f)Dz}VuF)8SS6!IuyQiBM1 zOkZFs|Jv$2i1(BmqB&J*Wzs>s%Yb8^g`G{OTlp)~_q=m8S84gg`HTDIn*%TCfoIw2 zZohRB=a1bC!8xtVTW=BKau8BYx4v>J3JG(+#hr77>gFHzO60fL1q6ty&oEcZOG=&Z zcq!e4uYKWEZm5Zm<<;5!O5);o!AggKV{Ul+;}z|nk}7o7gJ*G5k8XJV#&zt6P^zJ zf1@Rednoxcw4Dz>Mu@21APhD77po$}?VsFdL%@V#_sc!TbH9Ff(S{NX25l|v-(FO1 zIB=0x5PLc=WE^m6%Rg=Xf(6PeFo}G4=4QRK&!AHdZTaHR7W=%kk6bwcO((NLTM!eH z#n`cp*&{~t_2K^oefBoJw&eS#4m*3GPNt$q_eo&ZdHQ9bSS$P5nZD~U5`EfoiY>l8 zMZ?5EreMZVinU5vnN0M%or!buJ7w@c;x!F(9chw7BM3cHRstLcq%Rf8n00@VG28I} z7>=4k8FLs1ha&<*l45%&b6;Lwc0D1rJ6I%*ulFr(v>Dyl!XH~ z2zG6Mb+8dZ@X_&sUql?dg#IjOQL~FLGZDLMC3;p*cDq&a6GY6YN7GIa7Jv^~yxe_j zboEH=bXwe&JMUjFXhhi=>64t?USC z9^%xEmamqSOAD#|OvH*a>eBjhrE9rVURr8mk1+;=#SisI7E#2Vl+PxooMVRo$;9zu z@3{DrwbFjF_~(a1WwxT0Nxg< z3IEX9X_XeS!}r2Y5Lg2b2i8l9M#C!-me#)FI?A`rAuZm=9P24Bm#*p5$=6HDJ9QHL z%En68zl)gl@*+uz1iVOodF&`Ne%l=CQr2Z->&xYlu~Zj%S>9*gw4EtG1KY>ZBHo##Tryf&=xb3n%T!NTcQi|s()IqZPo~x7 zbIvoxzMIb!!uzbDt99WPf1svOJQGCcvjCNrAKI=g^x2%Tr5))fZcT7PV{+biv$SyG z7K&d(t-y}{1}S>Br}tR{kTyr(igKPQTDZlNv#-^6^KWyOwM)u9d5^}shFc*{)aSs5 z?YHSsdFhd^s)NA~F>Fel56Wmc7NDcR4c45IMtc1QO*Vd~I9O zeHx`l`0sxujS_sIY#w=KPhgZ6j{hE!@S+xC4~S8;4*njW3v+BU4Y{aMsi6`U5a5uE zXjo0Oq_WY`sYe7^W{Z2~>CI>eD?@Q@PK4a*@Wx68M!eb;ERr4F$jo$dw zYW^+k8(xGbtw-NN-@UOgg6jr*l1juq?IzCA?1)c$!*0}|h=8@J=*c~`x~f?%qBd#n zTw@|1b;P$kGySucr>BFb)pGFp%64W{de&Fm7FWY!rr(p?re-6{j*7+qIE{__wq|mp zynC+`>W9ZQD&&4YY-%1Z-_)GU{(1ENW_dt7u1SB84~)aV_9Rf~#u)rl56YVB5>}(b@@KyVx17)@2vbfOd=18%Xh77#ja!jPfQN%^V=k%TCEXD+@ zWJZz%n_iDi@;t{HTpvQ?x^lcrql_FFR6Bwj4<8UFVyYc>y&5Ujt8fi-B5Nmme?X7TLRGaXhO)9?W>tco%a|4q4UA!&4ow?etBC1~&=w^hgmFre=E%$MGsfa8@qtc87ur zj@K%v3~{FX_ze!G|39674kao%Uaz3{`iPXqn%0{(!AjfX;;f=Q}_pM)oi#_oNwT=)`lFx4T;d6jF z#%{KRH@jyxUBY@x&9A;0w&0|*+5J`%;@muW2fuc55f}A%NmW$hO71l;B5^nF89`cg z8lyz87iXFout&6Z3vMLUrG zczRBznt$ph{*C1(oru|U%HDrLy>lE;@u#3v8k7oB36$!y_WR?^1s5}VqM_KNb@UX+ z5H*_j&rBe7-*?cg0I@@5-9pi<%0d zvzR?U0C5vFl4(|xpb0I)uPXEhc!5D05~_(}A8m2;n?K9~FC4EPh)`N?>sP`SdQhuF zAh(x1K-)db!iN87DgFapHmo@L`wbdb0js!QiFgReN) zQ7$KAh)W@jm~r=KX%XDl)r@{V{InRz?7PmJW?f~vd3uZKa+;4lV&0)-b#=r%RZ3$r zs}GuYA-P*hWQw}lkGtqJ;(Z#!w%;gRuna!-XoWR0e&bD#?Ctez8N6a@m&x&4zl?>9 zkukHOyAy^JwXWZds76Mw0D!rT%Y{_QXP3y3-;>5X}N zPhYt!7f1!~#+2f$GDgCwfib@==4)Y9(AThn`C8bG|K%~t0zz(J__u8GW|?|Vn?yUZ zO){nkYv-SAgbDXF?kG)$R28)7B4@&t|1uzwwCp_-rO!R zuGRi#UBH>z*@y+lYM9nbHmNI)*==RQfFmK@Whu2xgA7Gq)t3C61*Jq(^W8!9kiETO zsu%VI9RX_B?wB{Qenrj23?2^r#8H*ppE#WRLj(1}U@$JxM zep~%+tWL*%yW(lCm{a8|@|6X$b+VG4u#Sm~XZU|W()sR7dogb?ye#K2?x2ar=b4<& zJ{tG?*+-{+4BE4-v8|V~nL+gXsqU4uC6@NICv_jg=bhm%XODrO$U)OZ$BR~W*pVSy zphMn*aYk3`(=790cqZrNd6d@=j&{T-qc^NMp()s1sQVypGz$zDGq*3Lmou94yRj}+ z^T@RLvF>?0r&%$#0E?H9aNu!5`!$9X)?=k{l%PO)Ld7tsOFvQ585PpJcV(Pu9Vam@RSNy z7$y%_w4AM`fu6D88T~q-pG9%GrZqJwIchs1(%M-=g>|+?)~sPwmA}iKefCJYwE=K@piPlnHijcC~VYjeQvI}sVK+V zw4zdMJr&JFc6u@rsDB&L3oPgb0b(x*$WBiCR5#o5q;8|-JlbNCeE?S1o_y}l;YY{h z>k|=irx_jqBsctA&`WKI{-)p(^%7L2X!m`F9qp6^3$s4-1a>t;A(PwU}4KMqrMuX{-?C$IG(8D?p&v=Z*iRb5R9kr5m#) zQRlK#xCPq&mUoG6?9UX41s4iLAaD}`0KdFXF;)o@i5GzHw}PG(T;FS;H3 z(%P)Yb^E~4<8-fpqnBRqv4d8E^|!Qp37tH@ov16-7DRA@l=9-plivFC0n> z=RQpi<#Z{*&ZsuU{#|W~isSLGJ9f26Dn5x{=3oaa?9pwqZM)iJwol^6USG14YJz!) zqJR>&ur6N}YM=^ZCZe|tt|Cotz|A*=dW;{R#xHfx-RWCc$c+pA!IllIqd3IH(dWZE zehnM7^m@$BaBdEw5i*0O*f(0&x;J+1KDEOHX6BdkTN2rVQ6&A!`VQb z`Qz!O*ZXe!>jmV1F;9z8aOw3vxD$voiFT#wJ9`axMj!gK-&X8~Myv9l0hdHnJx#n) zu@ECnPz7E0+d@}WYo6hr=H>tsyxCoRX)djbOQn3T&X+FG`oRx-AgsX=D;dbKYwCqD z6&{QpNs%vVAeP?)?Tg3%fIPJ7_$}Gwfskk*{{xu;UIa$+K+r~=ONCcxv>_GV1yiP4 z{fjpvf-XFDjM|dTfG6v0bJsiFB`yxDNWxxXn}1cf<8s>-lR5)Z&0n}KiuVwUG)m$c zCt-(aqyH5DFURpvw)E51x1~QIV!Tu#T?c8uc7~29y^vv8xJ8$bQkb%}WeiqDKieQ} zYu5U(`MtU6gb%bUd|`SoDrb-ENYWS%g?&mo8=a9!|8(@uJf9&cmPemY9hey+uw&Bk zD;cvDztSn^a@NKrqi$XhxsDIEe%r#wrbt|(*#a~0jJEr(YASTnB ze)jN%D?#ZOwudq|a~VVzsCp>#e+0JbLI!K-cz9AhzC0!zK3`D|xfnO5j$dm7f^rx| zaM_Ih5Fy4I>3s2gY6j-S4qviEWdzB-$=5p;b&TcVYtZqq>PAP_g^YgnkV}hs^gQl) zKLWCYX1D5|9L_rBH#*?&JPSz0^i0R1X14%u5h<>oPyGfxPsP7^>q5qlSOH(Fp4>Rz zmx+ABPBb!+e?n>GSO*rHGQ_v1W7X6QPnq)>GZ2v_!b8`R=^XFQxQ5a}GOzW~7O~N6 z{u|(pu$|J9W!0ZH%M{@Yx5A@k4)TZs4b8BXIiFD$%or}FMrK~f*pzWKWUKNCXxH!V zgKqm`-Nrs8Do26JQjy+aNX>Nue@;#GsX|A$-~1a!aObM2u&1=*vi~}zriVQ?m(|j5_@$=IPdO_yB!!w9AeM=;3oB1 z#_+FdCUT0GS0{m2UEnegr;Y-r@@^U4IvsqMQ%B)i@zvjR>VQAsR35f6|0$<3da}f# zSX3&0F6etlq||~`x>NZ8PUYRZk@vlvnt*37iyRh@)W~}{^&jHZQMl^i)L}?@IMs;M zLGf-RGPUS)NM{Jy~tpvJs}KZ)_ztWf&Y2Hw?P;Y!l}p^27o{(~iEfkMe#iHh4zR6YwL)wHIyz-UP zs^{IyuOeqT`9&x#`<-*=o`mF>p6rDu2SU2VyUVV8=;YnsBX*r)tVb^OTYG5_&daLb z#2xnFGGlBDfCd5U7Iw_I6Oego24k;w6rTR768x%9G_z8mc^gvVZ_8zuRPSqM0|=$U zua<#Ejm4qGx_U-dQ0=Tt7WM~Zv)Y}IK1RGA>c>gp6`7<`x+W-}&3Y)as~}0w$dnA* z2Y-E9HxoAgICHF-9W%u|J9MJ?bKubMhzmt@dR3QY;d}Co zOwb{h4*AkCi_WDRG7me6hJ#K#EvGBnvu0&(gADEdvQPOh%D(ST*++_H5Ac>9dPtN# zj>;~6X+c&!m3zvD%s(o38Or@5%H12~el|-MP312CgK~d-r`%K?$Z@3HtZ$xT%lcPS zU4KaRU_sdx(uclqd^$7n>BCMctypfT#Hh#YbfU~s$Z7_M)CW8coC%epgc!DkjF(Ljhv#>IpAvjhbDr~IzeN(de3iTQ(+2qcDMbvGHeTSk3J#}L6 zpKkZ+L6bcFhF$xrIpR-9`?6)Qxhr_h%&t56yMDf@T2n&395}l7_Vd^oS-!PwDN}ZS zX3Q*2Em1#HtVJF5o{_JIYQ!EtO|5iIM33JwtH0Ricg#x7lmKlK5x24LMvO%DMDqkQ za5+azG4H{CYMS}Lom!Nk41qXQ-m)yO@++mX%sDXuWs!nIr5a8wi>8FiV)m4!Jnr$o znU|U+RG#(H2bAb^wLeNELy6+-{-y8k_3*_^dx7%L-%(2e#n+{gp$(-kXC0jN9`%q| zwtUR2qfb#U=`EH|*~?SDB9w0hxP!`9hTl};5WGV?vSZf8Oc~00&0E$Lzbk8%Lw1)_ zWZe@3c}c)U#DOcDMSVqPe~&msSu$%0@eFwPpu;~AR}^#bOwU=nGCw5Fk?tVQkx9#N zNBVA7%&eK2Ma~gfutC5v3P%i%SO1C_ayW>mZr5YViSc*pG5(%aZ+kR;k!W9#n@^ zd;P&{RENFAIwXGc)M5F*sl%E(b%?q^9fI$aRF8^TRFB_04avC3eI-<{1mU2#*F6vqm^|l;xLqc7 zvDRLLe%bv*1T>F`E`{FAyPvsC{dtmkn7NfO#g?(7RJbc`mn_0r9Pc*orK@O<$wi1I zGq5y#!}GoCg;ja}1$|33YXjHU3k4Ms<-ne`4cOpU5Xxy+cUcp#{&p(>{a4hjFp)DH znG0d{H#P@2ZI@oGYmrKIoaCg9(T$LD=jO44B=&QN&zER_-}=1}Q>Q7aNoQS3U-0Nq z-$vH=iQX!gukuOLE4mXx-?}cbUure5xRJNBEybp>Kd?h$TMRj7zUkNH+}}CvUPv9 z?7`w{Dxe&DRo}p3WxFcOzkIQYXz+Z$_9V2iRZ$ClMZ2Ur-X~{!P2gJXh6x5})~hH+ z-y4tyC=6Z7w_=wamC>4^i*8Mw8XBGY6{G=6tbQ8;aVM~1D4eY2ioloqsnm2?X{fdw;Req}jt10f-=h?f` zP3FMzq~0@3T3zxyX{`U6eS$=PTBSjZF{vA|VVZ;1O9p%uia6P>O;Vz2Q(D*6`be35 z6XK!%8TwU;vLP)w4J~0K>ltZ3*!4hTs|aVp_cZGR2AO-9RnXf>G;(_-cABS}8O1yA|yt8I6loQQvFMkhH5>w1s}FHHe57 zfH$Q>b4+2plx6ss90s+df)%zebTbiky!+Klz9m?#)%6f{Nq@`fQP@3C66P%{GtM;5 z#jq@*R!Iji1NNdso;vK1>s~=^tdIc3 zObH}r{XoRodkTozF}6I8qVd)XGjV3FP(z+RsiNyTHSm%ra_rcr&70==!PhaIL%A$n zO4)Uif`HPx@k>JA!OW~K?OKLN)wbv7ZAvqyBZ?cSl~cbU-90WZ2m@+I-*Q0a^qA@;|M-hT#F10+M^f+3*YXS3c&(i_xv{-3Q$?IB%(pG%JHE^23 zFwU=dDoQuW%;ZH-$r`o?OV;=ogXbIS#=jDJ)e%tEy)+2c+SlCgHMM4FH*5fglr)=0 zh`?fz$0sZKaUc5^)iGxN%XaYB0Qq`tkpWR%{5Eu-_UKrER%L{3i06O5`>9cg>7yf=jN_mUk%@dk(mR9fW>^ zni~g;bzNVzhf5^K1mimkFFrr7`)YRVY^VPQ#t=|$?TyjGm}a^#Plb41G%Cp3RYKqf z7NeQpYE`pRg)!}hrikJtT?-9ZFLAvu!T6v*H&46vAM<2`5P6gz06v2aj;nzU0H1wn z1Gm)q=SQc{2EVMfotvkE2JcO1@W$lb@Nyp{L*PCmxUUW|KuhBn+Rr0K(R{leqg7zG z4!^y!wfLQb8t^x6oHw&~YxQ>%k6;z)R~*5;Vjj&Qts(1y!?o~s@qw1L9%%bZz73ul zzh1DsfJlT(esR#QB+;A_YB67Sv}RE29ik*KcL}7)e&w6y4Fnn-vmRw4uZlWCCm(jJ z+PQI_--flwEn}xgCxLF3mH+CRtH^60&KgkVP6?g+LF=N z`;9_a0jcYEFiVqhjp$6k-x8CU|GR^Fr2z6R6=f4srL zvnZ&Jq9GIhA;W)W3oHgk>nPH^{%FIRlUv-I>KZjI_o;{9W55$xYIa_ zJl;&2+vm+6W92a0?8FWmJ)rzo^zn(HYgvb!%Yto0P+fGo%Bd+G5_}_dtTQ^puZSHT zo%&9*PSTS4)X)B2UTnBR)@HgJ4A1>(ZU7W{CvWVo$(Y?1@M&yIr#S9oM-R{EBH@I^>ce zZid9i-pop{OAgPaU9uP}WKp$rd z_Gd{)g=W5*H8Zn^AWbaIlmZL?`Wbe_WV0!Bs`Fpy_qn1W;TJ%X@VK>qPxvqCcAIYA;A{I64sP-@3#w`(BK_a#S8y%dLOy#f9>ODlG#)L0P-2QdQ9D( zT8&G^XjbpXc+aQ;@`_CXMMrACbV(JnttuBQDK;IhJ>rr|1M-=N0*a4{DErKyliqb< zB6`nYcqy^a(a{QUl6`ABJHThXZ@wowKu=ig7LGp+4+$o6q$3Jzx(H5FG#%q7oVC_R z)0)mETPMY8PQKo!T(RC)T*kz(dA?J z8mzlaGRJIdK-n&g9q-#1y~mRvf|~|u_V=B2&WQP8^Pq=Woi;zVbsNTpjhGFVbH1e* z%Nr&Dn>_~@?5nIk1xKygp|j&}I08VCZ^2XCU*ikyzJ(8`k2A&f_9^TJT48At{hbg4 zMA$KP+I7CM0YzU6Ne!p9Ukfwqx~yix5N(kUTWlUEJJ*=F;Y%jSv5X2v>sO*9rSi8ckb8^ko^BiL>-xMr`Cr$qDq+ovUS?6%z9XJ z7fj~@O4;>3WzpsG0^d?ik#xOcof2c))wT!Kc~IdscT;1M^EBoiDfF^W?K}?F69WP%Rrek2t9|8SHBU619->$+!@pMMl&nS^bZV`{mk;r6%bQbb-`%@S%MY?`_W8s;q=Jra$Gi;8z&3bA&f7(rnb zrd73=HDP^}UHybf%PRu{>|L;eQ``L#Wup!?%VbaJmYAnogDru<(=EpRo$kH0U3jJJ zihY*#Frv7tMg;|@=|W-a!h_B%e1pS5e(AoGG{Ckw55KUU)jq(LAq*&rl6jz0l}K0R zz$KL3xjy2+{6QKKSB7wA?6A|Peb(Dm`zHD2ziR$CQC{%zBzCoLzO(>Z_@X_D64=}C zNysuw^S(-2Y*w!MFhQOFVWMiyS4lqkz9qYXnzZV$0m9W+(D*=@i8rL@I)cDwzavRwuylkJ`n83hZNi8u_ zd}#*p_GDq#+$o5i$3!f)zm~ulUYoeNS;8zf7h+YQ$UBDkC4QDqP~P*LHd#{uq~c8G z;eqzuwF7u2?u*t{aUp@HYi3|={G?#ecg=!+o=b#1nG{yAnAgTKh#1W@s%4uPSJLci zMNu4I+u@-;C|HK;Ps7`aY;@v->ehx=v;dJrJX*-f99wi9#4>$diui%&Vv~$EB?;g5i~pK$ihW1c_b)a$RgpKO$s$hniS-r()^4kx8hf{VV#{H8P&-eZU4^xMINaCo#CFavsifZFm zBHc9z=O5i*o}+6(X*WuW% zS3NOn14|%voys?GTFg1fU%%XS=^DK@89O0389`?@_)hvfz z=qo`4A0}MGF)ot?QLTK#P=A8s%Mjp`k7Nv5aPgFbWLNl~zQc;|JR-g`;)8%m0e3jt z-^;;%got&iFSFLX;MJPjEizT;H|6$Mvw9zqYNF&5(mgkPO?tG= zs&EBg&~ZS}8@IyJzppVe`v5q_Wm6iqE;=RB`k=bLi`|nBtJ)c`+Ld_GHpFOYQOuC= z)akj;Sq7P>+xpZGC;v&6PlFCJI#$)>UJmV{X1FZ6GX8w3)_y)i7Jfp=tQ!f>e~CY^ zGUFSM(Q^v^+)d5!N?;Z<;e@Hu6_kH@{}4`?-lk)tRMAzo3Awy&Meg4PpN65?nn$*nnjIs!Cbth^_uYwEc-Jz( z)4o(wLtumP7VNkc{Nj#F==aoi{&)Hwc@ud0o)dn2O0nmejz6E8Y#5y>H7v2A)c)tt zY6kQ?3EFIt*kv% zX&A@tvFW)N%}YSL-%Y~2A?zCk-`2iC@G%0DSi3>+)ep5qTKs=UtEW$HfbY%Sy8bJu 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⪙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

  • 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

    o}sERoyoKj91r<_y4spM2~syQ{BT239Op3}f-l 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 Ch7n!> diff --git a/shell/linux-deps/lib/libEGL.so b/shell/linux-deps/lib/libEGL.so deleted file mode 100644 index f9f049b1e10c65fd63deb852983f555c7844c602..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5418 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 diff --git a/shell/linux-deps/lib/libX11.so b/shell/linux-deps/lib/libX11.so deleted file mode 100644 index e4078fd17449553bb49e1cf0bd96d54c33e6c734..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1124632 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 ht@eCipbo6~q7CO+VO|Fhrs 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

    (uJgLTC=xm+Wzq)v

    MYYI;C2@Qd%9il>BHewSQN#SCgx8 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

    #J)5UH%PCKP(lQiuW*(S1AWS_`(k=-JjLvRab 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�c6xw}6bv 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

    c_ay82w7ZvmEO0B9DvTqIhYC&lvI7 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%0AHL~&6< zloX{zX;DU$73D;EQ9)D`l|*GxMHCaq#R+jzoD!$S8F5ye6X(SRaZy|nm&FyaR;&~2 z#RjoaY!aKr7O_=q6WhfOu~Y04yTu-{SL_q}#iTeO4vItKus9-)inSu0NG~#oj3SfB zEV78KBAduAa)_KFm&h&hh`b`7$S)#A0Z~vC5`{$(QB;HqqynB`Rxl$t790uY1ejn? zpcKpt1cF1sfnY(v7pMgL0+~Q4*b71#uuf?a`K;1H|`aDh|c637K^fk&Vacm+OzUqA{1f}kKI2n$vP zhr9qvqWiofu&Y$fBX}n~4KIWS(M{e4FM@{Ab>14!kNVI(o*VU|9#q9U;JHvIs^{r= z2A+|pM|J2HZ=0v!$$2}xU7nWb=6QHto{NW~Jah&Xq08tBx{9u$>*xl$iOSI}bQ?{f zi|7)HN_dhP2`1r71QMY{BoRv_5?msc%u41Y^Aee4L9!@Wk}OMBB&(7&$+~1ivMG^E zwj|q<9m%dlAyG>9B>NJT{*YI_G1K-5u_!hp6@8G+*0$1XD z_&%<}5AZ|$2tUS8Z~|B38eEI(a6N9ojkpOn;}+bC+i*MXz@4}YcjF%1i~DdtPT~PP zh==en9>Jq{43FapJc+09G@ik;cn;6w1-yut@G@S(t2p=yVKW$p@i74={GTT}OoHK< z6r087uz5^|Enth-61I%3V5`^~wvKIJo0uHi!nUy;Y!_2tN^B3?$5hw>c8DEe$Jhx* zU}{W*X)zt9#|)SeGht@Tf>|*eX2%?u6LVp1%!7F`ALhqMEPw^E5EjNFSQLw4aV&u) zu@siZGFTSNVR@{86|oXl#wu79t6_DlfiBzS{AK{Rz+)~br77B$Tp;#ypZVPvW z5n)sq6UK!BVNe(n?g|w`rEpKUFH{K+gonZ-;jvIB)C&zlqtGNY3td9DFvLp>1wvAo z69#x&!i;c5xFJjmQ$oKm%nJ*%!h|r9R_9FBMTa}H=-=_n8)Z+pA}EnwL7=Xac_g7k zp{bp3qh`Edj7d!mU8k_?+iYz#OgcP7rkc8%njZ-e8cQG<^33{E>UnF$R*xurGihx? zn5-t`twcJ`mOWj36OSqt*~O5#LgZCV00yV7&$%QXX`QlRQ- z>s0PSJ?zOv7CbhqtE5!#yPM9edA%v<P((wr)ndTiMTXmC}Bk1edNohY=vM%qiLx_Nu@tyGbA>$A*j4 zEgdD481W{1d?b=8(nZdkJxvZ8X`BUI~L zQIel2W*Z()!&55O8|6ZK%g}Hy*xPD;zN0Q%Gg>}@+x84Q`E3)XS#4@HO_#p9o~Sr< z8m--E$s|%l(7D)|4QXu4PGP{D-8U?C!q&KcKeK2!)rnk&x~*fZo9bpy(A#J!y(=Ma zMx{g5A+NVR-)Naoy(qj|K26VsGBIT*=vs1wy}5j$nr~K&dY8o`@a*RFIwxs!TGHy| zE+Mlf^qGQQQx9jt4!f{}Cl{-E{dS`qb*qgfV?taa4W>lMWeW1DNt!>uNhqn?7$3qz>v$&%W2+ z$i*U^nQGf9?qp*Tt0A|b<<%Ao3x!23?h+Eg&{hj`Zf4E(W((7|JfW&2gBAliL6dCQ z(%CTD$hA_9nXEJ^BAR8Jw%R@^Tk3*3;X5q4><06JBbxM(xqNsW4L$ z6MVhOFAMDEvFd8*u$ePtIx26iy&IkN?KTS$RfccMc2+CZfX3%*+tXg{nr%sItvez~ zy+N-@&LwA)1vB5QuYuFQfmh5MW{UONl0od2o704#U{%LzJ}p*L)V*edMxZZMYXOh> zv?**lQ$qcGG8f)RI0_C&kz9_pJ%y4X)G8jj3x=Y>qc@rtG>)1`y_MPtd&+wrVO|l< z5UF@PvhVR_isqWeqQhhR>V?2!tz+byjAOX((zch780ck&0?f%m^Vc{e8X~Kps8e+HAiA20wM>$2VLaN3 zdQUwrhtwrYu7@NvO&X|4w8!lWbMVfsN{se<2+6#67lV)$A%1o1LKES~vK$>PkM0t5x>X zpvybw$`Tt^G!%;CC9%F{E?C04V!RTWi*4G{enmJOUvYTC8|Br4FSruOX@!M|&Z`bN zrKN@ePn&&-TBYF&WYt?CTRrP8bXIG=a;E5Xi}Ia-#U~|0nSlA&zv`5B%sFK^RhPOC z+p~_%s^4ukAJuh)vc7Cu_G~ou#8Nw%OeLF!a3{6)@b=4YR%=;{XXrBYp)pZCe? zWNAJ&>t2b98V;{BZp#JD{vg>tw$FBQezT@w&RdS$R$n=9usS10ZJUP-%3L$0v{_v~ z=yXC0jh4Zk-l||lokQ=aRRYyDQ@VBRjfa&cdtGj``L=6w>42d^E+uU`zNVTE1b0Hm z?Yy?y$oqFAyShMImN9nZRei&iQWEQ?g4P_0b~4dsNRl@+f^A_v5@=+ru}pHgy;t$r zEBUxLV{TV=T`f)1jFs)VeM_j7Y0Z+^*Q@CDH|E?h?OP)*gUe}j=zMBvx#db!OL3__pYN29-3py0q&HRyMQuvI zt`&q_Mt)IH)P-ASap9!s$el#j9i`?<39FZk$5B^3;j#Pt>a^ZpE*m#ZMgLl0CfGJd zGbiq5*rzw>%+^Y2u6CR&Y4w#-WG`g2L82ISE!DK0)sj7{s$dRbaoxG$Jjv;7>e`&Y5??V{&6;xC6?dj;CzY*|$+co$ zjq7cj<&&C3v!AzV%!X}q%T21o=2~^rsx1Z7<myX24Q_FS|2Mod%>mWl-CS6S?uy@*`v$~m$^uOO%(Wj3PT zY@a%1zO*;)A}tM@UF-1Gi?;BAVXiFl9%O7Kr!N{3nPqNQWH+?nPFR(sJD12W+B=4X z^VE<@gGU-gRX!NZC5#Pc!WG|lsayw^W{lLzLW^!yD^%h;V=cAUVpxsNk*>~)r%o=! z@)eKcFtZU*gcOZ@!tD%~Ry~REL0%csw6$$@QB%~1-34cJy-?{i$X0Bv9c~}AVxbL3 zy?WqrXy(aS*^_JQy*Wv7rz0igoukfT%$O|u(?(x-KO%5$X(J_TX44tVthCbg80pj; zTKKVwb;sOl7sC~QJ)Wr_>8c$^+@ZCB4>Uwn{YUx3{HCK^$d@&hNc$jJO1iyvPsi6N z9$5{J<2-8Q87<({LO2&(M~>i&qf2s*+ zHv>8MqKj`__f#F2F{n*?YI!2RWAJ!w7Mt0SLA5LXx*xSH>WFwHWepiBXhrD6BkE|O zauAtmxXDztpiVk@6{EdwtS1}EC6_;!D^w%9*>G^zAZ;2eOR=4VuDI;hwX@#k*s^`O zwxdnBWO`>UT5{?nx?{D_pw1r|4#K3{Wfj^L*=pTXNo2O1hmo0z#U%{3Tb@FhXvPz| zdLk0sFcd8Uqt0J$OUzOYnTvqMaN8YipQ@9Y1z)JavsCp4Thf{>sGDeH!J5&hGK8Q7WBO6YJ0XA$jy}wJt-#{7X_-;j^67tI+J02akmx? zih{O~G1Eva*cN?p5;uEN^ZtFJo!#$LQ;YhvbKB{6tXp#mnW$ zR@qu!^>4KIvK1nd3#u^->Fc--!#i;wxm-0RTa7(3OsvH^Nw0I+CCMgQYWIq3ryw<- zwDf+3*&d4K3~fciT=AsWYU{~{@z}GG^c7a^D|(SLo0fQa+PV04z*tl!+NKqEtaR!y zwih$=<(ZbUjc56mV%eD`S|P36;f~bmma5o(qBce~`8kKVacbRi$clI{UfRp0GwZQa z*N&!LOt~CETgGTxB2De%l+vut*Yu{0!*b#&*yVnHNn746EYzC`b<0Xv8bs~b7H@Bt zPP3=6J@cx0R@1C5+8icFj33&F&E_>NG$pWTTiaHDp;cY>rL4yhthHeY_-4Xu_H2E{ zXR=uvn=xyuW{u@`0&~rTEo+m<)afPbvX0-%21GSoYunLjCEBa{Bk*Y6s}WY4QLN(W zEM-n~@!W2}-3+P4H9>2`qbM9__H(l~T?dVqTS9BKV2=7Ui}jRewUdmH1&v$lJ+@?= z{7Nfoi5_=Q+iu6)Msr)StkD`RCS-onvDuyn4-NwElgM&rpLB#;;DPyCN7&j+)H=>! z+QWv{-w0hpUJG(n>D;nmNzX+VOL_+x9e0mb2bflC>!xdYKxkN zpR~&@&CZghsxF3{cKV<8w}Vh%@eD%?u;c$8HXxV$VcK$QkC^Nd8wJy zUR$2T<3V38GZQc9w=Bu_POR8ow#^0C%$laBxsnM5q;YRNk=rh>>)i>d@yKq6uDe7}Bn+vqdIzzNU)Y&=c06 zeLlEu*T!8{Ud|P4R}HOMV^}+9%y@M1Mt()tj<)PJL&aODb*eRYvgJuAoyE!lX-V!i zwvq=XV@na^r<#6VXv4mr=)~va=AyX8cc`t$hIwPien|3c`Ao@fY1>_Xjio3vlA4Zt zw`9!A+p-`(>JIw+M`W%T&?Iepu~nU-bgDJA>h)G_H@+5M&1`y>HMPQeyh>nUTRG|% z`eS}&K$TE?4iYmtL25>w2(^q@E|pt0%xI%=eokY~xHj$9Vx*FDE;lSzeJA7&6jsxx zExUQaxS(D%E~@tmf$~aYKd=|5r9^&0y%F`*C5;-fmRUF3icZTxHeXyMrfWW{=6$0?2vWGd~MZbCmh9w!{5y5_nfA@F}zkHo9WzQaNDAD2Fqg0p4Js} z7A4Ld$E+t6Y}*=y%VIC1noa$BW#1V$9E9qrg`!+PYYxQIx@9utt9ciT)snkzP$|-Zo$2YYQ%sBdl3A zI*6i6SP@kO(X_R0Ex8UuVPC|zVq7(@8JCK_ggL)lwB*BTOA9P7LQ$W^->A>!*NuLg z-GH{UIfuue@J3pl6Y|6+v1lS>!eQXGcPvZ6m~YFoYO+>Pow(BQHoexozv?Qc!iC~S zy4{fkoJ1}ssWj5F^}XVL)nw;2Z24xMtddc+bL@;>m@W%ET&5Kyj}0tE8@y{NY6`149XI22wS#tsKf8Hm$p3- zO(7F3xGgKeC^2V_YRrXL#YJRW2Z4m&m))!J98&Lme%pozRvQ(|i9wi42a|4%E?%+L zwC2;&is6)O`Mpsru2qY2%UOqO!zlL4N-E8oPMiamxXfX8J7;T`-ICl!JyCIn4gMP~}?b&@MMhYDC6tZ#oXD8e`kr@kbg2*(u7*rSgf( z7u~EI;w^_YIb%Dlx{K}bV%+8O6m6}=#B4Uy%zBa)GTO;Y?FSVy8*%%*dFM=`QBW1t zB$n6+E`(BTk#<$%&ToPjoBJha0M8x7668TiVcE6LdD{(zh8J1anH;u;q+rw?Ra5R$ zf51_y#q6h+Eu%iNs$O@gv^%!VphK@A8>vnwZg;4IiOu*?NSoHBcWuIu%^&XsvZ89o zE3X^l_C{8xPxBL2+ktj7vu)hb%hL;{ghu6TCw7cm>Dh>^mei=s3R}m92DW|TDtPT= zJFM^mhlzt?qMWvwQ`>1zFy-^)cT+n1t`P?}A|B#UyIMT;u4&fY34>RsNbx%Ax-BUy z=-m4?y&F@Lb$g3Qp`=#lu{b(a(^|3GlvHcYsAHjQiXRXuO*SYG&ej6;bP4r!!s*bw zSLR()o8vP9(sY^^B#P=%#_7?LuG)rsPUChRX&1cnj+szSS1K;mb!4ZKP92!jZMP|9 z;rXHwSzcu=XELF^cqP-e%QJX&y?9)Wn!Uwcy)>oJi=v5+Qtv0zJ|4MS&IJq3qr$rS zw6W=~xYAXRE8NtRi(YZGl*^Qwsc6GX_^du6?C(USl}b32P-nt=vt!AdwrmvF{5rLx zpBPvUepcb66e8@`f&8GwD|iJYBX_FKIk#1J)+A7W<5k44-7Z!PAP=VzlNR z`*nNLUfFdhIRTLw#F(Op=S{zAdtCm@b%o+-X?cj09>Xi7m+~In&uo}sgTrDyn zb*3t-sK+EAy$;r482*8TkCti4gHXO1dFAe8bIHFan5&>VHo zSMs{k#A>S;Eb2FEC8s*zb#1s>sSR}_Lz0T}R%gMV3(b%lorSzwyOU8^^Py%YoXA+c zv8rV)5_9hc)!8z542J7`F`G>jSc+#OJdc4~v7%OYOWi1``Q_uL-4;oBT82)w#dmGH zgXx;qmp`fId<*7mdp~|$DCjbca&a}hQOSD>A%0w5#C#f8f^dbLZC6s&z(U>@kyFJr zR(opJiMO0)p4C^ax{RbK(WuNf+o>eE7&@?q3R$a0>&z$}>1L|1)eJ@>&1P_wSPQ$8 z&5E?OukWOq^$mX^fSFnqm%(k=NiI0oh?qH2UoZ@x+N}UFY#6P41D?ab)&- z=IZO3IYZGwgyuD~7GqUoI3)J0o4O-H)^zwcE2&61x8jv(i=kS}P}}STI;T~I@gTk) zjt7*QjA_RmBu|>!z&b$|PYMN}Kd-85vPIuXtP~8y)FDl%u9xOcJN))S)9E*nt};=W z(QOq&X+DY9=2N~17QnS-ry#D=CIY#3h*SnKoxpdR@}|hVyIc+)n^WbLtfS($Mr^WF zsH_c@%ZtrQ&QC0)b~7g(K^SW+<w_}z) zBfnvd>q3OZ<@dKju~uCll2u}k6X$%rnp^eGXY1N^pRnDoE!5;Xw5-j}1@_aY`rUfa z5jTr`;qqR(;yh@Wy#-r4oo_2L8$>u8C~o+QwzALdH@joakV9Es^Hz#;mXdAVd!YCG zcZz6LooW}3N-46PaR(yViqG6s7v>Ec-hJajm0Uu%Sl3K-YZAdXkjtMD=ej!^JTTnvRGPcr7N-QVmVVO>4SM)R#RAyRP3ct zM1QDXDmlUpy-TlchN8h@wjw7yp`y-dlVv02J%_=Q)sR-AN_1=veOX}J@mSnP_S2%a zupjh!{GQny9`!bMlXE#kxulauec*LLIb_hTTRSzer|Oe{V9N=QDVnH;h?ve$b8Qjv ztj|>|wt@nU+?B|>DxO+0pwul`7CPI}*;cHs3j}Mq%8`E2lGDU3`mDVsAeA;xAe0Xm z3Lc@YQq~p1MVTR&-fXO-G8R=ZmRL@q$*sCTci3>Xmn<7*UlLCQ0(x_`tVrquo0?=c zoL??wEsA2KuwS;2t0~kTSI;(P6Jf_v^B}n0R;3plxCgT)QgU#SoNEP)3inQ>=4%m$ zwPU>@V91seWu4aQ*2}$8T|BXDISRWg%BI*?x72b==CxEk=c#Biz@T6#ELP^6QtM%G zrW0x5{z`DRx>Q-o^8?-rFWt#3SJqoIZo=kNTO!TUdTNbK+tY>lNWhx08;!+4Be&)C zR3mv+Igx0Uau%NEw6^8frq&F5w%Pc6j;~Ir%eO&XM-dNmq2|?WE*Msf+1%uMR_r2I1pB~bB(e- zTHDeclxIBK-or9lx5bt2XnrG{sm?WayfS;-v8{GBboD&A2rPw`%6rLZaW!vqgN+77 zt9{iHZz%27NHU?ZC(I{7cY9VV)9{kju)?sGN3&Hs5mX2DO|a#{wp`X`Okr_yGt4WQ zwCZZKpv-K=joDaU6O@Dl6;~!}FBnsabRtX&T^8?5a^F_A`CUsnZLpJz7Y}l=SjVo5 zdHhF>s#EHB*)Y#~zG7ITzAabVVQEIvqINW`{=b-e^RTAxJ>C-wZMD@_ zTdi8P6_T(czvP#F-xIcwga82oB#;df_Jlpis(>iCA?|vrr`m=cWD7`uB!KLzwzk#Q zw)WJv_SCkfwI}y?&di-VGxyHSedeE;KX`z!JkJk!e&PH1yx#AZlu#0-EQ*MVOb?Yr zQVMy7F3t^4 zEFdQN3JBR{$`GYQ$x26OQDaj|q9QO^X~o_}lw@9ksj###AW55$n3|&CiiG)UT~Rzw zUzn6un3QT1u!>_?V&y#1fi#MiT^yOhDaIGcWk89a zG+E^XEnC9#3sZ9R@_2DhxHv455=u+V$}dVn7Y9Xaa;Qmk8DA74q88?d6-iQzQHnHa zSz&l2+>|d67UzXi)d%vkqeDg1(wykD2u!gsrNAJGfN2m3q7<*#)B^8xPhq@3SK^(J zl%SHz)BUA#RYD9mE4?sUSs;+gvtlz0>Ig%4sxeflknxLXr9N7=lp1zGRuHSrrYA;3 z=E;D#G&NbtPS-0{%EA&-I7KOoD2Pi=6l4hFV5*3s0}+DA;QT04hE5g(S7Dh51efKVU|2nQkn z0T2lY0TCbuq5ugH4a5MkfE0)W;(-J}1|$MWKr$c)6hI09EtUZlpawM1K|T#g2XufQ z$N(~dEFc@m0dj#nzyKJ5e4qd*1d4!SpadudOh6d~nR+2%NH`LK^hWw1eUW}he`EkM z5E+C#fDA?gNF)-41d(VY28l)Dka#2kNko#6WF!SiMbeOTBm>DrvXE>f2gyb9kbGna zG87qx3`a&F1;|LG5E@j7kx|f%JsKHX3S51~LRQk zLZG}+J}6(5AIcvUfC@wfp$?#eQ2+{wLZLtu8ihe&Q8*MHML-czBorA%K~YgO6dlDt zF;OfO8^u9!Q9KkM6@m&yg`vVx5hwvF5+#HNEMim?N`i_;#h_wQQdAr&9+iNSp%PI^ zsAQBJr9h>iQc+5j3Z+JAP+C+PDjlUm=}{S|OjH&s8XVa!8kA; zOaNtIBA5gwgK|&-ra(7RC8z?`pa#@}X<$021NC4AmcQ_xg24NXTg&`dN7%|>(3Tr>~OM~9$8(P8LtbOc&}jzkO5B4}M6g_fYB z(J|0^LyCsR)aV4X44sHhLMNl;Xazb2or+eXRcJM|0MVk;(CKI$T93{^XQH#v+2|Z} zE; zFh~pv17gq^3Pi8JJ8=7A6~$gUQ9@VGI}}CLdFPDZ~_EiZLaaQj7^x27$X?SQr+LMPR+LK3HF@ zAJ!imfDOb3VGm$~u>cl{MPWfK8jHbVu{bOqOTZGbBrF+A!BVj_EFH_hGO;Wy8_U6R zu{aUn~v3C_1Fw-CN>M3jm^R4V)L*DtPz`!Ex;CHi?GGm5^O2fge`-R zV=o*G2gf0B-Z&qeFU}9=j|;#B;(~AoaKShLhs2?9AP$Yg;IKFx4v!tw2)qCvi5KEUcriW- zFTqFSWAL$fDLxJ#k59nM@QL^&d@^2+SKw3dsdyz`g;(P>cr88+pN`kz_4o{YCO!+F zjnBd7;`8tZyb+&|FTfY#i}1zx5_~D%gfD|IZ!ZFj04E>_-UJ_lFTs!CPY56c5`qW^ z2*Ct^fFz&@AOTIl5U>Os0Z$+hhy)UWOrQ{`1R8-(U=WxD7J*IR5V!;$flmk_gc8CC z;e-f+fDlO#5<~>h0ju1~sAjk-bgd{>TK~7K*QV6L8B|$|{6Ep-Z zA&rnu&=K^63_>O$i;zvoA>v)MBoK*25|K=#5UE5Okxpa~nM4+m zP2>={L>`e(3?YUR!-(O;2%>-(NrZ-mL@_anC?Q4@V~DXtDKU;1PfQ@nh>64`Vlq)q zR1i~$sYE4FMN|_tL@hCmm`>CY^~4NfCNYbcP0S(Y67z@#qLG+SEFcyVi-^U<5@IRQ zL@a~QdM^@;1ScU#-XtHAFUgPOPYNIfl7dJFNWoAH5J^IjKoXjSAz?{45}rgL5lJKx znM5H`Ni-6j#2_(AEE1cO289B=$S^XTj39fHeaOCKKe9hLfE-8;A|D_JlL0c4j3R?% zG#Nw2l5u1_nLs9zNn|paLZ*^wWICBaW|CQCHkm`_l6ho4IfNWa4kL$?Bgg`BBw0un zk;UXFvVjv>dArQ|qrJUM|ZBPWuR$jM|mSwT)Ar;?Rq6aTI8LM1hVilq5HlZ2&#Y@NflB>R53M*DxpSGW2muIDK(B7Pfei8sEO1h zYBE($RZt-;i>jomsA{T)s->n;)2TYDo|-|;q-IgGsX5eKY97@h@krcr2A8jVJ$F=$L0i^isLXj~eP#;1kQLTO>Na9RXSK#QaaX(F1K7Da=G-n1B6 zEKN#_qs7w_Xfj$NEs2&)lhYKm6j~}x3BhD)nueyOrP0!9I+~uALCd6N(Xwedv|L&q z%|J8K@@WOMLRt~6m{vk7rI~1DG*7x09Y%-K5p-|558apUNB5@(&;#i~^aJ!@IzUI# zQFM@wreo+>I*yK~6X--biB6_d=u|q5PNy^IOgf9srgP|AI*-n$htNamVf1i%1YJOn zqzmaHx|kkCm(Zi>G4xovlpaTqrzg;5^hA0RJ((`2E9fZ@%%h~M=xVx#uBE5Z)9E_8 zo}NL^q-W8y={fXVdLG?CH`4Rz5S~jfq8HOk=%sWMy^IcptQar`oPl6?Gkh4n3_pfH zBY+Xe2x1&y1Tz2zl7V7?3^W77z%pGDr+EgTkOPXbd`o!C*323^s$q;4*j& zJ|lz?$_QhGGa?uQMkGVX5HZAzD29X)&4^*dGNg<+Mm!^dA!8&mk{HPhIYYrnVWcvY z3>8Do&@i-&G)6i@$Ivq}Ae6XYD8|Hu zG2u)E)0^qT^kw=n{h0yGKxPp005g~gFp*3Y6J(;97$%m9W8#?vCXq>El9?1Hl}TgL znG7bA$zrmZ9442^WAd3H%ur?+Gn^U06fh&1LZ*l*W=1h3%xGo|GnOf3#xdiW2}~I? zk(tCyX3CigW(qTvsbs2{YNm#%Wu`IHnL4JPnZe9tW-+swIm}#U9@D@yGV_@Q%tB@n zvzS@JEM=OQWl+@3iv?rBSqPRl%ZKI5@?-h40$72pAl3m^FbiNIStu6BLbEU|EDOiN zvj{9Ai^L+cC@dijA>hY&aXi_GbIAec66&e|7*nkR8N6zz${u zY$O}S2H9vfhK*(8*myR9O=OeUWHyCOWz*PnHiOM%v)F7lhs|a4*nD;fJCq&94rfQO z1?)(+kS$`1*->l>JDMHCj%7>PaqM_@0$avTWGAtc*>bjmox)CKE7>Zxnyq1L*=g)_ zwvMf5XRtHbS?p{!wEkk}u?=h^JD**^E@T(6i`gaYQnra*#`ffRabO%c2f^{?_;7qV zejI;J04I90@0y6T^w+NI7wwcuoRG#!2Kr2sTH~QE*Z? zsT?Io#ZhxK94#k}lg`m`^qdS%CMS!N&B@{9a`HF^j**kkDc}@xia5ob5>6?{#3|!= za=o}PE}Vh@4fMlCR>c`5L~K zpT-c(p2DIGE;%D=7___Q%zJYJ#=kp8rh5RCZF~5Xg$~W=L_`?`&Y`-=m_L1L7cDrSmVVz!to=85^@5OJtDOdKH=h$F>9u}CZy zM~NlkXmN}@afl6Kqqsm^C{{~K zA(2Et^a1EV6A=>@tBmC&C=(EnOd>kbkXV{j28|#T$=c)`d5|JQVNCT@`Y8{nkSdgl zpdzWrDz-|X5~{?i7*(;VL{+LPQ+cZ4Y9DowI#>;;k!nzlQ{&ZSHCxS9^VFegu{uT_ zrIV#JvH7MKaIa8P!ps9G&BuE!`1LK zVVVd{q(-QT(j;q?8nvcCqtR-$+1ea!fwl-j>dLe}X@P0sX$8XY;ey;85yYxM>CLVYn5p7zRsWn^X~WKwdAp~07rA=6;U&xek6{DP>0 zgu?7X&tk7)b+KQmC(H{5gTY}4m^aJ^<_q(K`NINWfv_Oh0a!2$fFWTh7zjhdFfc3( z2gAb%Fd~cuBf}^#DvSoB!x%6oj0I!EI4~}Z2jjy+V4<)uSU4;KCV)l4gfJ0I42yzE zV9~G`SS(Bmi-X0(5@3OziLfMCGE5GGU~gC|ObJuL)G!T93rmBg!*nn`ECZGa%YtRY za$vczJeUDygyq8uV1=+ESTU>wRthu0yuHFa!#&G9%U}_nG8iOQ23`XC+z|V{_up`H z2U^{B>_>Q!U1YESY6{*C>;N_bn}FAV*MZHz7T^uwO<*gq4d`@Rhg>`I|JZllgIWkW z+)(?${q9gk{ekPD>uVPiN?7mry6*KB>?N;Py%b(zuMgcw`(N>X+4~M+9x;b-Anb^% zh%1P0L>FQhVL_bmZ1OzrdD8Qg=i5NKmku)fP`vheVW8%LK(CEnuX`QxI_y>HRpsRm zwGj9~jRar1mONKH-Mrkrdfbv+j+gGf^w~?FymarSez#9wy6Se@ZQ-Q@UfaCh^t$G@ z$rIRbMT{c)5VsJ@|Kz<@-Wn+Jeb#Fd@d081u?YEut|6`?ZXiBH{2g%#`wj2C z-tT$ea@)V(bN^}2GoEKXn>|}RGrZHh)4lcH2T^-b?|3>uFV8XXE)?DVuja@9`PUm< zFS*=Z9GE>HTyPh{#%&&79zxI$fFu5ed`OW=xh30)$W*cIiH zxT0M#u2`4U73Yd~CAeg+MAug?d7vI<#^tU(?^9!Az8>yY)xBgh8i zQRFdXHq@B#@9u+XMd|Iq!0`%U-%_Pzg? zw>sUs+`HX-+5ql6jp?(Pv5r7~;jU4+C!BEEp4nafgLjX|c z1Rm<`cnh%&@h)OF;vEE3+l<(Pcn|UZe_AR2-AD27Hi{s`f&cVY{JXP)fFL3$2r7b( zVElJ|AOGiT`k#6KG}sKD0pIp)0Vlu@z-!=j@bBPR@Emv^yZ~MVFM*fAE8tb|Z{Rd| z6g&ntg7aW4SO-pmAA&c)4zLsK0=vN;uot`q_JRH209X!IfR$hsSPc$>L!bp521mf# zU=w&8JOQ2rPl4W^qo5V62akXa;2LNHTfsK49sCr$34R2A44T2uzy)v_90#Ys`=A~C zzrO;z+XCeA@!s&43kAKl^%BY*<$-z`^$O}$ z)JD`M)N82MQJYa)P;a2#L~TWFL%oH18?_y^1N9DSCu$dJH|kx~9@GW+MffH7W%w2N zRrufFAHc7{ufzWi{}6ryeiQx?{A0Ko-U@Gnx5GQ&o$xMrH@pYl`+w1Na1dS&uYgy= z2OxV}x0_-A!TlBcEB9CJuinr2|8OsN5GV&KfJ&eWs0M0)L%?C67N`U2fg?Zza1=NO zGy+Y)ao_}S68Ing?OX-^27CZq1Fi#q2R;OD05^e;fR6z)&3XB2czyx3e?0^H91g3y#;0`bY%mQ=3Jg@*P0!zR$ zumY?CYrr~i7q|y}0(=VG2R;Kn2fhFv01tsLfv#<&0DYuw=R4&-9o<+0o2U5`B;dp-7fyyx-$ z|7L51dmuc#AxEPxWNP$>tc`(?v+;mOu*d)SXYyYk1w4?DB@+CPPg3N8gpmbG`Y9xxw6IK4rdOzG%K|zGA*=zG1#; z{>W@Lx0^f6{pJDlklA7$He1aT=1KF6dDXmbeqerReq{dE{Mh^t^Aqz==BMVL&A*s` zHUDOQVg3v9DtolP(z>~IOY57h+gf+E?rq)Q>em|B8q|tz#kAsE$*t^GPAji9q*d4| zX_dArT2ou~tr@M^t$D46R%2^^Ye{QqtEu&1Yej2iYi(;?YeQ>O>xI^ft=C%nT1Q*0 ztrM-2tqZM-t;?-$rbs zw=vpSZJai4TWDK&TSS|nP1q)Bi)oX!CAKBE$=eidsy1y~TARKtyRERTsI8=}w9V93 z-B#1q&}L~HZX0PEZJTJDX`5}EZ(C?vY`fcbukC)@KW+cH{aO3-cDIfV9UdK$uQy zx#LR5)sDY)+~~O3@o|T_qqU>0qrIcEqr0Q0qqn2K!_qO)Ve4>oOm<9lEOab(taRM% zc+l~6$HvZ0ov(Lp?%dk>R_EKDyE=Dw?&;jyxvvw}3GYO7`gR6(qB}92xK4a0p_AUp z=wx^DJB6L1PDy8Ur?gYnDeo-oEb1)nEbpxBtnIApJkoiz^F-&#&QqN&ofkT9bk1}x zbgp#X@BFOui_XWL-*rCeeA?;k{Im0~PLHmayEb;c-nF@Fd)JPxon5=T_IIJX$X(Jd zS(m&^+m+U3=rVSdc2#%Pbk%h=bsg_I)z#8u7$3puDf0Lx<2jttn16JM_pfcebe>0>-(-JT|adF*!5G_FI~^Ne(n0b>v@;6 z>yNHKyIj!CdPBEI_r~t6-P^j~?%v+LqkC_+q&vDhrd!&b&@Jmu>Q3%fcB{HI-D%yr z?#%A&?woEzcVTyVcSUzqcXfA7cSCnm_o?nH-B-JBbep>;x^3N)-FLcYy63tVx>vea zyVtw#b${CZS@(nPN8OLRUvzKn+10bRXMc}xk6%wf54uO#BkGa#NPFZxik{RSRgb=> zyr;J3V$Zdn8$ITp-k!dmfu7NxiJr-xg`U-(`#qoaJm~qV=TXl$Jx_Xm==rJV=bq<1 z+k1EP?&{ssySEqKi|F;~_3icR_3s6Gk-g|%d@sG1(aY*(_i}o}dc%7odWF4`URiHq zZ*s4^SJ8W=_iFF8-W$Ci^?uyj(c9VE-P_aK+dI^2=^gGJ?VaeI>7DJJ?_KC!?7iFj zq<8DBZMU}H+I0(YEASTj7XOy=miE?#TNiI#xpnQ<$G6P4I&ZDqdV1^Gt>=()eM8^N zeZGBueSv+!eLx?+kI+ZzWB2j=sVii z*w@r|yzfL`bKjZ1mcFxn7y7RB-RQg7_i>-OueGnIueYzi&(Sy4_oVNKzNdZ9`d;+? z)#vJS>)+7-YX8RmP5qnuxAyPq-`&5be_ubmAJOmIAJ~uX$Moa+@%@B;dOy2g)F0I^ z>rd>L_bdDL{TcmP{W<-G{iXd!`)~Aj^!N1l_mB2l`^Woj{WJXw{VV;S^?%X-u>W!Y zcl}TLpY}iRclQ6;|5v}qz^;M)1LOh90DXWx5Izt&AR3Sk#0|&>abRiS z?!di)PX|65_jk_YL7 z%t8KO$Y9uD#Gqg>YEUv5Jt!TN4Jrp!gPK9@VA^2zV9uanuyC+yuzIj&@bF;6;ElnX zgC7r?2RjD42Kxsg-Rg0T2l{47Bhz=E`(EqDvv!mzL`YzxN{VhOiIScH~DOSPrOQfoP4X|No#oU)v@ zoUxp>oU>f9T(w-Yd}z60>9BNKx-C7HUW>&tY#FsoSY|ErmIceAWz}-ma^LdI@~h=H z%X7;Mi^uTG!>hRs+`@`Q2KOKHH{CwDL#C_!Dk6jL1h6Bgzr&Ncu?jNX|&!h+)JyQZiCH zVj3wQsUB$q-Esn$c>SOk;Rdfk@b2jkb(l8NE9C!RYl-^Jwd6`)J2#_h`>(@93>j%jodv?a|Ru>!@vX za&&5RW^`fn?&!VIPe<>Mem44O^y|^bqfbVkjs80N`>1o&&FW#@Xx(bvVcl!pXMNB5 zzIDG9W`$e5tv=R3YmhbA3Rsa=tQBu1Sjkqpm2VBPhFQa{5mt#c+A6imtV*lOse8FRXuA-Nrn|Hjix?dvk2t*sihNV|&NmAKO3XJLWeQFcvfxJcb-Y zjiJZ*W5O}fm}E>kCLdFc>Bln0vd0W#rDLYCgJTtAwPST-O=B%%=f^INT^qYTc4N#u z);iWR);rcWHZXR7?6a{4V_%Iu8vB0i$=DBLKaKr7_S@L=G3VHyV=u9}dUdc1bLVSIG_?)bg& z`{Q4XKN$aV{PFmA<3Ef)8~=6u`S`|(trPHxzzJXiJwcwJOzVVo$M zD4#erabco=!ZPvQ#M6nNC!S3_pZH_KHQ{F4VB2ilYTItxYxA}F*#d2V4R0gZNH&U% zZR6PZwh&vWE!-Ai6WF3`5?iz_)+V*Z*%EC@Hn~k+E#3LZ4Yb@ZC}~Gwmq@^VEfVb)b`Bwo9%bo3)^3|f7x6%H~R+r%l237ui7`- zH`}+`ciDH__t^K^;dX@G*B)pOvLCPmcF>NtW9&FP!A`Q%?F>8H&bJHgB72lwVvn}V z?1^@{U2o5_=hzGFMfOsAxxLn2XFp;;YCmN^ZEvw(uwS!Zw|{8AY45Oi+I#H%_5u5# zebjEXkK1kb8T+h#!M3}gB0drZ!J)nR;_-+tjY9z$x^Ua7r{KnUYS)rxa7EQ~IgwDZ^ChRP9vV zRKrx$RLj)asq<48r$(o&Qxj8;smZD7sfDS(iU3w@h!J-Zkwv9X=f~Eu5B2%cc{jlc(j= zifQe%X}Ws4W!f@5JUu!+F+DRqJ3T+WIK4c5clzG+gXt&J&!#ut*?MRDon3eK-|@V| zxWm5_awq(b@Q(CO+?~Wb$~%R3itb#v(|>2>&Z9fu-udp%=9w)sTW7Y2=gb@C3+Kz{Yvvo~ug>3?@0g#Me=z@W z{?Yv7`KR+g&;K(2>->v(w*`-dZ40{=f)>yVm<9X-d4avaS>P>%EC?4Q3(^Jof_@=m zA$!5FP`Y4Rs93nRaDCy%f_b55p?9HgVPIi&!MZT9Fu5?bu&}VWu)MIcu)1)6;j@JY z3y&6_Ec~$W)56n*pBJ7lY*_>rk&Ea>{33CYzQ|Z)EwUFmi{XnAi^4_8qHHm7F?mt3 zs9n@AmM&H=)-GOIyt;U8@y24uV&`J_V(;SMqGfS(@$TZY#pjE!E^S)cx)it+v;-`n zm&i+$CE5~WiN7RUQZAJ*RV-C6)h;zH9bY=VbYbbr(zPY?Qs+|t(!i2s>Gsm-(%91E z($vzOrIn?-OZS%^Eq%T8bm`}%XG_nQ+?F>iyDz`Iym@)c@*B%rm$xs!v%GhC-}3v* z`c-X0tJ_z1tnOSTuToa&tL)YA)ri%|Rne++HEvb5DqmHtYFE=% zb*mYxhE?Ng;cDq>^=i%P;nmvJy49xD>#LKiQ>!zp3#&`3cUSMNe!BYE>Z8@KS0ArF zS$($p>+0{T&Q-Uy4Qn228`rk3ZCiVLZTs4ewY_Wm*WhbGYxp(78hMSr##!U9g{+0G zMXZU|Bx})Y(lyzdW-V({f_4eO=rruB;T+V#5i zhV`cPmi4pi=hrW;QzG-Ag}76AMf_8gQS!B9Q;aqKR>EQRElr>1Cr!9+EN{$6F8;LA zqbjzxwia7I*)V_f&tu;-uAU`{4N)GFbh%Pt(aq<*TQOL-RQJK@s>s*GBhtdSZ{l*3 zijo|P(NwPHiRPg8OqL-3^@3juHx|2!Jxec^XIAD^eqVp`v`%m_`gb)t^Mk@4iW920 z)(H;ZICEDlfGT^#6W>>iKnsc#)uM)-z9(~+vD^4neg~8hY;O{s5}!JK85U)hp^TrF z(@(UVP7rUD-jBN~+nLx0;gq4t1&U;SvGI`cL1~_;)6{TKQsG&7yoOP?=g5l_5zV{{ zcLcu+UKjo>ij?9MRE1VSQ2irqTh?{sq5QS{!zI@%?^L@vKRkKlbb0jO5=5~ZoZY1Z z2YZkE3WuUNvd4)_DVeFCD8E(i&opNz6n%E|y<;yqO--B=&rg&IeuLJ@|4RHL=@kXk z{8b@2#5-m@8E`I1a9o%T;Z~bON5v<^e@nL%Y(24Z>0@!Q{GW|{;Z4O4snbfbwmN+@ ztG425-Kpl6rKVhSu7|P6lu>rG{79YQNNSVlVqHqHUXmp=5f8%ZOGTlIizT~{#GYt4 zX%;L;z9$?Jz9O=UXT=AjvSX{H=aP;m=PS&LIi+5er5;j0Q=icu&Zx=$Is3BVx?$RI z&!{haQusyjZ^azbNl0cyE8kPmT%|s;qj5*m!;|hU_?Gx{kI#=qMnw~)qPSED?dX@k zmBQ3^Xdi1o$_zIa=Fb&UivKLtm6eultiM`MYdF?Caq&^qcTu5|9LXOsi*ZT_5&byn z_Y|CpqsmoXQMYTXX~X&##-{wT0$TB@gYM;5%Nr}csr;+*X_d7GS=&>4z24nL0yS`{=w@@8P_0?tG+P zlq0$?F5kIq7kltLBHMmz`HcEeTH&QWbw_sk-p&V8dO*)e_-BTh(aY#|`&S`<^`@PLw}M zd8w&BGDPGVbx-+*v44woBpgm$NP3~Tn<7&6YrfOm zNfYYqx+f4)b}_Rsdp)-~&)sml;JbqS;)AA5<%Q^Smh4qUUF25d2mrYk)IrH(Eo=bZqEydRk-m9HG_OQuK%9pjIUM_A+csseM zxUKkDrTLh*5HEf%E{NI~`%6l0>TA033|ztWsMtJhP5!af(?rd9dUjSu{mikjv#&S{ z)P=g92J-n=o!>_V#R}r=seh*ZBac%!SZpi)SE;eOu`cf@rs>A%KgAG=W0aT7RK0g% zqf?q5CJGZD7QdfzS8Gf=+iVkF6F(AM2~#*nj{oYR6c zaZAc=>SO6>Lq*YW(ap-T+Jm*pb+0+SPre>G9fgqRq~z+~HK|Q4f)vsHg7)$ak#9ui zi^@g!qqPv!{73AI*zIw=xRY@c2~Dy$5`RuCOPWb8Pgz%erFu{Ez9va?M?0ZShLCKS z-lVV8J2G1Gybb<_O2Y?+LgPVWMd42nZpbU*7Zn$sE^#vrnraWeQXW*^P`;}^@(917 z;Hc+G_{lF@L}%YP_vSg(xf7SBP5F_VBtND|w2Q|-jwXs;cW!p>jsHfm#W|niN_oTi zrgN)voAWK_+s+S~wmWw?-*N7A?sERCez)^o=N{)?XR~^rGbZOf=ljmDn)f>+Q;Sn$ zqdc9B8hKh?rk4|EggN0(gma6@+v(%Xt(}h974PfxbNV|2oPkc3Ajqi^@#CIqww51o z=EWJ3&MBvheofZPCsRsNzfD+A_(&Y=G{pHOzaF1_9hfdU@jwhTPQjTO5=k*&UO)=3Cv4e^gr9=G?qFOSt z2C|+SSwbJgxk1u^C zsEy5x^@-ae>y%-WYLd|@50%|{e^eZ)?Qf`W{`68!LSJ&X98yP$0r5LfLQP#h5?&lX3bVAU(NA=CR9~yo+%0K4b zw7n^+>93}Ulljf}&n)R)$(H8+EmxbDT5!AQQOWtT@*_8;4!K(Omuf`apnorCDkr|- z?UoEdMe%0>vuIYdD&8#lP?4h%YQNCFmrjC9Pv30oI4!-n%dwhwd#MHG5BP(4qG(g^NFE6efNR zDJI_0eV@fDy-+q=qpTaQn@YJ`@qX=e(oRi!#*5sS4OxcD!=E=DirkWTCHb}LKGBs_ zm9b6miZD$yC92SFOK&UfEd91Lt8%G+PviXYTah@?uVSX;Nm3?+iQ814r2i|+zvzAq zthV)Z%DMD&XD-cMIxn`X3v~Ok1By}_nP-|5ZYdBRlogUwXLx4HD*v(CyAjqDdU9B_ zQ~ZH=bH-%$SnX6&rK(LgmPIW!<~@Q!NY0pKCp7#_+$-e42k^G7e=l``T}WN)W`lJRC1DL)vB1ie>-uX}Vdthr9S zr20kElg7xnkojizCWG7%2bJkV4X{U&S~5fjQVN@!A*sOb#D8S;oBSJ(B(oJewF>8< z<|Xlw^82D0QBvC8;t|u&RmSE|BK^cIQEy7#h*rrylnXRBwEB#S+~>Kk7^(~@&M%Gn z(xQX?2kWZlYaiCm9A7y8W%JbeeUh@Qg`5_{A2lBx`=B}Y!sSb6G)}@;ujKp)aNuc+Igtb$at`?;j4y2UP z&-^d)H&=foI$0MXIxU(KPiar-Jqq?0+%`QirJU)#WXs%Eb6vDWVv@X}zNq#|yPSDD z|9HX9sM$M!I zD&17aRpV(t>ZMsfq>a0D62I8 z&e6`}DJOnB$2t!a9uYP}yC1 zwYuSufBnuQe{VuHH(lN${3SBg>5OejzMpa;HA}zfeb>jfbfHeTK>cu8m!CCCbr-cu9R6B?VgJ9~rCW}GVetk|b<|JjY_K8y5}BBj42 zWU5uVZ5hRxrmRPK0mkpD?$^FuCp)se@y*Cp;npZw)X9XK$y+pyMMV|CRoiP`tvggl zXe2dWKl|2&Kux~jd1Of32H8)tr!r0IlJ>9czvVzOkg_M$FCF%3S~~H|g)M@+f}bL5 zgfUP*mA9lx@*p-KP8}bgU`&`vxR9iF=BE^>K2&99T+hVjdP4yf>_K6LsN!4&z4C13 z%_{f$D-GW?{MleQI(YPP)BWRno7v6x&VGAgXVfcVKZyZaeM;go<6Ozt6qzYo)n)p3 zbL{zbrJtAXF_|l^4Nsdj&Vy#ihg_ zPU@1^D?(C=QkqnUH6Ny}=+<=Wy1Tl5z1E2_{9$~n@Oa^B(cPk|(mSSy2d|e?E5<7R zS@rJW$F&3X`XfUPyN@TG`Lu;}*&O4apigd4b*H!MWEnqa?Z{5dZO!|zVYz|Sa$JGa zOUpN$ix3Bzlp&$XfJW$xf(=`B3?m%41cF)s917 z)C%j9>h~SF-=IF)+W1k^iPt<24R--s|~ICq!SNdJ^t5*w3lB{d~S%TJ^nOpQ<-SKm`VSHGkEr?xyd z$&gu+X<9So9{jret;+VAgLNnC_cc8_F?(tML!g)Z_7x|`laAz zp}qRf@qm-}1k(_zULE~}iMRx_E z^4&vE4jb#gI$GFt`~>1u#M!p<+9;7sk~RTpngTL6SDvpS)dkgmRR51=&1HpnK;5Nl zF8kNvEk~)n)vclj)p`U5+y+_{jf|Z%uh0qO<+-oOz$-Zz#~0#FXcjt17P4 zpE&-G;7f6?ZfC~JQ0x;hWjQ+~GWIX&SbS~5$FflwB58wS3)Cf2o4QwtRTZiT>Ge9aes=~k>)V{~ zatrfbHFO!g^A!c7MX|;IC>|(nG?`6`vP%d3Dv(u8)t^-Vqo%pGqrT|~zLD8f)ucb( zd}83lk>(GZZ#1tpyPetC(tLLL+`H#jqROPZ{|kHf0o}yiCwhO>i<>0NHZ6%QcgekX z%iU_DQP*gs(P-4=CU;x5jNHH&8*GX(H9$y03JHYt3WOx2CxrAT0g{mRq>%C?5ozx@ zyZi35dw1X6yYKG3_w0Q*=YM2`nh%HL!~Flh?+5lHPav;$n7VH4PU?H8Z#wkr+Qtg(icvir^~DHZE7p-_^#u_-rol998`?(gURFTCd8B9PuZvO*|W177q8z=U%q#D zB(9mcy4AUjVM(`mE!MvM-MD zSa+NG4aTVJv98VY zVfq5H=VpDn@hA8O)4j-+@DJ$L@In}}SK1fD)!vQmPqc68*xvD%4u03R@I@jX0C#T> zKiU0y_l~e~sB36vxPRos;8HkuY*$z@b8*XZcz1YD7}>Tr{KLL|;r-zQ;c0BTm$$6_yY>=dVDX)*|4($*8<*6sI%SMNF*zBgPC3ZeVLO!Z~Wcdm~1=epRv>j&|`T@&w3lQ-NS zzA$5-4Q_6mdmwyr+k@fQU7Y0|V3hJ%Y}5zXM-E9t}ShK5Tgtk9TZ${N{K({3q8F;a1*cyailVS4bf^_wSNpGG&F+1j%3mxa$4rXr^TgJD0v)`gzxy>HNJ5;B5EVr3TfFn#ysX?S7_vb{^fPP)eZp zp>9o-;Q~xDvCMwkf-AeTphwpCb@0hh^ptC=cG|iTnOU`oyji#K{4V9*UT{&#BPO_> z3Fqo=(*=;5kx?{=K8_y5E@Dg@%XZdY=483gg)g|@aX%Zjd2#PU?dcuQh08jh4`1#o z=`HPjA#Co;?|(6@9(XDIa`;&AxAC&6*JqYz-<|z(Hg8M)7U@FGLSR9%`0Qfm_E*BM zhFQk*;n&(Wh3*Nx7QPU!Q?-?VJ{Kh|p4;sA0Xx;;DkI#m-omhgw8?=A!$e#8ueYfkY;v35_TzkIs8HR!*ET{mEMoS{{9#HuY`Xd{x}>NDhy49E>EZ?KM8*ter)dK z+{T5^!k>q~Uyj`U=kOQdQvY)U&#ix9{V(g+Y*QozNe{s)a!TAaK z;;E&c{oTkXp5?Yc*ZTvD<~v+S*S#ac(UO@zEiu72!9-1w@e$+K#&(!tE<~r$V(Xm! z9+%#IgYPC^WLs@lbI-Lf)VsOwQsCCnq4A63pN!8=wofHb@0fmh`n{Rh`8yW}ckWx7 zCpPml495`#4iU+M?Vjq+*E)m#q_NX8hvryYWjBI1X7_9zd2x2l_7)|mEKr5CufRLe z`*0#C=uPn5)xM_lZGvWetpCB0;@~I54-CW9kJHHP-E$katX_C<;iV<(jUTGn+RLUh zh|$sS{J!&S&(Gnh0YzZ#h+?#6?Be>7Nzvx#<{a~v=dD{l-x}WPU3hhSgEF8z33*gQ zDg`lPXfuu)F_>xAncqeCVtIJ1=ZQ9E`-v{FJCVp*mG!Iodj{kqn@5g~JUy~?taG+z zt7L2Kw(Z*l+eJHmUNSAWEnmNzp%&uHINaeFcrI{iWFUxX9yjko%eo%&FOPC}ZQ1+& zft&3C$G}DsxDz}EnxTHERr@5o2N9#k&>zup>r+^Tz1G?1e8D;38gl*S_INk>?8KP< zsg6%OZsQao?p*L9PuvhGNdoFf$3}=nJIR5bTuQNZ*Hg1_;bS&*% zs@^4EmfrZ1vRU=K>Na(Oo^Nfl-fn-<@fk6Af6WzkUFY8KdDHW&H?FI*%iVpYTiA1Z zU&Ww)*fe}`I5Ds@uxs=pF+lAf+Zg(J`p5?D>=U!Q=f}4sE_5t>xLCRL`qGtsFFP5d zC+DBsZbaB-wdQU7y54kX7jnRQ9BZ?^?s>Z-r!OZ^AKXWTx7x;qTZ*@gZC|wmQbLB0 zEw`c~yKj9Zs8nuMnxOaKvmu|>qy0^%gm)wFTi!t}u6*}51nK!Hk;amC&UZcFztp?2 zUp`6>W(5xiZYk^e;TW^!skoWH$IM*gW&%Vo>w0ugzQ69+)~{++zF9^)>#U zpWFXTzk2M!DamH$ybSzYbB8w1AU3>dCD|GFE=R8OQ)j@n-+j`Jw_)vj+OxW@45kiA zh7H53gNH-p@$bg>PdqTOYUAAOFJbEZa+Yg&zho~MbUgP#p=3*0pR<%ZAaUYP%K>y6Gh_pjj}4Ti4wg1K9N z*#7j=eb#SnQ(b&;S$PBWtmdMw%kq^asm;;${Lr3}-@=kD&u!^kkPsOU@!(V-cl-Js zz8jA_?(X`y`)J=geP;u_(TTBpMwiF-Y-Y~~cW`#gcbBU#A|E@l-8sQ8p(i!NMxzb3 zU9;Wkd^qYNbB61ern>4UJP(BV%yfOLc z)P2xZ!ztub#A`idPaC=~_@~LF>1P)IvN)^yi(5Z(=iFJE9>=y=mmXQV2sUVzb(!#cmZu!gwqNVm(YrpdcH)-lkLEaA1{XeA zyu34M>FHfRslL^2&^=^5;+W~WH+aKV#n$2-&qDF$$J>AISlj=|U^SuM49}jKz25jZ z9FGp#)jhNQZG(TBeRPhu^*glB^;1VMbb9jnS=FvL_5#-$)W5rSc6{A=Dfsbh&H}n{ zVb68y_3BTxJ8V<!%=~y(9p!|6Ou{E^u*lsJifSj z@vg-um9Of*?0$0)*!a_?pO81KD)-Ta4>Ts@Uyvi%xD9hukNHEX)05loa@+~=Er5HU z@iF|UJ=#0uz24W>`S8H=!;eg4PQ5&PbpF?^yhYjKzD3UVRonM$e|M>5Pt-mxXzsTR zUkj*4o*l^D%(t7S2MdtJd4lcTJV!{?mab)g|jv`?nh{GlMhtV)ur~B{H8_go^SW}L1)2(nxC<(PKS9$nF4*Jd)sV9o!Ab~ zBkgB99`C-;|2^S(tqDj1&jf!CcCP<^{I(72wm!Rba<}@%7WGr=FPCrML;=sc>0S3J zKR|Z6XWEB4*7l_jy|*~J{p`k%h+N;Ft#5!wi0I5+#+%`*m6#HIU;Dt(=6cV4y6fvML0?&4!fe?Nm6on|8CtD-Y(z!Wf6V_#aObQK z7L6aaGY6|fx6f&f*^WoNI}tA0)k(SLotCSvYJ_kiCbMm5^S57ZzkcK;;<(Dw^T!uX zEK{#N<2cf_=%6}56-Rr6A$rzo8}QJsz1y!I=?<=0pc`NCt{)d}0v5`bhadxdC%hAn zSrG2E*oJ%F*l9B~o4&Wq;>R4<9E0u;h%8Q4Pf1_V(BS%G6YtI^ET^dJ4eQ;lJsW)rpXh#ma^Wm_km4~MF!H|<20T9q_SlqN>A zL3>S0F;LKWY%hKS*V*aUF1NcnPV^THy&uXQe}BR@b3V z&&BoAdl=XLq715iR*g;LUhN}yeb7e?yUz^IJ+pjvxna*~?F|8q_s3c3+|lK`c8^-` z!0+k5Yv7KV^$Yb&<(ew%Q`Q&SU+BgAH}^M>{5G+Fw-T&chyZoUTQo87IW*68vR&6V zIO*DWY7SbseplSSSB*mmw1L0*-u>qh4>pf|<21Ajx^C)PrXMY8 zY!^-#qn-`zxt(R}_lATM%xkP`wB?&Y9duH=-C%;f$Vud!ZO}W|k?ap|{BTpx>?gAm z3t#SjaL?oFGEY1-geu)Flk%B6KrS(O^l@+8;_tgyyA8W{@7CyVG$I@FXYaB7;2Y^Z zzon(^_9ep}9Sroe&3kuUP=0Stv;Jg5Tz_uA!#~ygQ15TOnS+YKh9DkH9xI(t&#@2O#4fn zG(Y6O+rO>*vtDnXbn@^<+YEEz@WM^okM8bN8LXEux9y}0o|bO8dvWtF5ZnfiYF{^A zGX~-N%<0w=ycK7=+^#>jc{^V2(0BgSxufe+*JlK!^h!@^pQ-Os-}V9X@N=Wrk6jMk zGSN2m#1y!}x}k65;AY?4o!fzB=klvqJU+N+GR3%l?5OFi?W^DWtMwf$X5_4Pl@)D& zjR3jd^3#ID8zN^b_s47Iv^1o`*XHl|ML9&FRv3R(CqPkM}WyQw!cbsrxEBUhS;ut($vp=T(&)J!(~8 zKM-M4xvhbyJlyO(-EQrCwiEA?ckk=lIB*(~Yx+#~mJAX=|*{wU>23sGqer4a}YU%!F_PVW)AK)r09MAh*{q7A84BY(F z{ub2_DyF8SeyqCV_4Uk&H=y@b`*dyk z7xiDjEF==$ZCkeGB-b&mWftP=G0YARnOME>E{9e0A+#Vv<3E=njr-6H;|YV0V!`HjRYj7lTIZH zNkB+M0?1h;CXh`cMdpzhN?U#XU z;y%)gDUXsUz~dy-*{4XBw_YMKrd}hF(%vNPhTbEsKJgJrJNY@Ox$$e#x#1s4+$kY9h!x}z1tO>Nb>vUu%;c*f8~Jp$hpbxcB&%2T zk_8FF-G`C#QDIn}?5OkK5y46yf+g?Wd_)cPajnYyFoRf0RoytxzP zds81ICxsp%XE{!jPXlMkiNI52D)2O!Nj*oNn0}F5K(sNI557)(?l;I6eD9Mvp-W_8 z^2cO+;m_nVu5ZZ`TYe&o9lwx?zi={X2S5?OLZu}4Mp6=iC<+i6LvfVFQ6|#XP$-H- ziUvrb0HIV$^Jx*~0FXynl~_ojhKeatQx#>4q=7;uH&Mi)7E0n31%*LYQ2>sba@)fQ z1-acp;fP%n<>5|B8qiJ2TRlKY{CJdds*>1b6K|v>KE8!Qx@SA(+swU`Gr$4L2L4SH zLDo@9^&9t4R$Y34g5^Czp#qOmj(m2O@(B7eh0QrnIsU`Dl!@3&6d>sXN@($8N+R|d z<-Fi)itX|blvRblP=Is4Q%)yRsMHBM6}X2@O$tR(w~@G1V3ALqeBe5&Dlv)LLQbR7 zIhjHP0?fly$@$x;)0|_}oca5x(D*}Cfd2?JsqqOamUxCrAw5M637@435?`QlNH0;z zt6rrxiZ4)s({ECNtM5|PjhCnhaD@t-{G7Uh|236z@H^@$#!pmI=o*!m_$w9Q{6-C( zBGFn+44M;&paCl@KAJX{%%|m7t)+#gZ=g{R3TO&yI<1H*q5&!(;DD88W7w@BLUlKq}Cgfy<}u>_W3;n%_t1cX`)Jq0kI_^|pQN2gJV)cQUZCv`y-F)`zC{BLze^M6 zy-(Y*{1J^p`h>O+@dfP$@wYVkk3ZAoe1INGq0pD7S#(Zf1U&TVBxZAK@3?nFO5DK$U`VuN(XsR?@G)s6I9?%7HQfUWdBz;=2DXNf+~ z-bV)n2k2(bO>_hQb~@+aF*-BlI32ijl1>8drHe`T)6boKl+F=9PRFRH=>YW%ouBtK zeO1=;bP4HYI*@jrj`7~0qw@FZ>sTMsvAj>{1t-3u@1TB5&u{*T4qf_{4kZ3Y7u1m% z6&wa5i66npqHq`hoyUl)OJEdlxSo-8P{06YQW)1in$3tv%xA31C}tcCl`$xH)H0;p zMh5dzD}#fAjGF*8BQMRsI5cBs@HXNM<8xj{V|@pMT-42&A@?!jLPLyk<_H5w2{HuK z5F;gNiXjotFxG|U7}SOZhH88#0|0h1iqGt0aFY))T-dD)6g|P%OunCC(>}_WSbK&+ zS@#U%=)12lNM#oov;*%lxQXvG(q=wnM7{bsgER9b1AxC_0FmD@4vK$ZFnM7H4fvVC z6#vRN$R#oJ5~)lv#9%^9Hj{TMnkkLo6F*@2%=EIg%xp>$bBdSBtOwGWPm!~T`?Hvw z!+FfmiDG8NOa(KKU&B1YYG4BAnwja>gG?<+%@oJ!nZjl>lgdPyiHkT>R^VkOR(CP& zWdlqxeVF+?Fh;!27*oiaWTw<_WQLfVm_xA(Ovc<2la#p3Y$WYv;E@6pBwWBSH@_1u2g(xunOLJI_7E#G0RDx|y#q7pSi>+2S{t&$0i+B!7CD znK<(iGxpNwOmXa2%Q#Dy;&@hJ)gCTSIiPqOIgo}t5_2gVpb8}%%V+5S*KJ=mS;}K0`7!a z{52>mbQEVn5pLEcavSUTVmAu_x><2RAFJ`;5X-<{&l)#Pv-rS9*23927Mr@2b?WpE z7J1t;@wjDH=+s`;;n0mN66X+W3b={&2I)2yz`ujFaQHZj^VEGT@zIA^sS}U0RGc#` zE^w9wh@T=J_YA9X%?qr&&F5JM{O_+tmG6o7 zAeQGx79hOF;uQbR5=T+k;#-(($*L$e5Q=7RamBOg+%;?fTgRR$7qBf;ne5A_^Vl{{ z5&Iymj14qaumMUHJE@?KeL1n29Rga|tdNwwzysN!*{_D{>>Y(PB0CLP_trjRzVKZxAQp4RSUlSsSR0C|~x zh_jDPjl7Xf3ms-hP2I|lU3DkBHU0z}0Ekt0l08m&fIV~MQ8s7h2{wmvhMjZj9NVjX znaz6kb@s&Wci9~LBAdy)%m!>9v3cT8*b}@zv$657*@?ha_A2>b*!O1q%#LgTB6e_T z5ouWw5zNG>h^EW@h|}+^iEN5gQVFBhGpQ5p-ZQ;=_r_2*$3>5we$eMx@Q|jR0Z~ zM6h1GIf65Pdjx0S-4SBoc*I%YWW@Fj4@ZbUcp_p`-PwrgQ_n__L(fN$$IeFxfC~}X zymun_z@H*GQx_vNuY4R4TKFtt`zu!?$mDM$_V4^TqCG&3^axmySqYrT%IH;*i4$uh z^DZSu@&G}kATKR4@j+4Kuc^h6Kw?Rxz*H5yVe=!=md&H2do znYSV})b}D^nENQQj`K+*>B1M0hXmh5799OC(m(fWByTl2D#WHmQBCY9U{z#PU^PFA zym@sLk9A$tj_Kqm$dM71nw1kp=H^Gu#g|42S}UU_j*6r58O>40xw0ti9#zz#6n#`; z9USG1v_{2>?NKa_D=K46Ta;Mc6-8!tM*(a5qj;V`R0tS};)H@xGhascu<{nge!6aq9O)HMAazN?N!%%2{XqmRq5#@MQALK+QRq9*M*-{? zqio#sQ6~CZQDW*lQ8{BDMa|-$N6`wtjye_kHi{$uKB^A*A?ozLU!xXoqC`KK#*P-V zqoNam=;)cr*k}-29o?F8T{PLB6g`=g7Cl>%9et3R7fqTkj_xe4i9UlhM4zHIN1r20 zqeuPf=nz>O?Z`4k<8*5@iDZkuDbF1}exf6~HRO*zF7At_jSoeqog0g0){RG>N!buB zaLz>oz`tYtv>3e{+8G^LwkJA}crcoL=}0u`=+WpWIme=#Q|^i8EZi5(I{k1oF!N}1 z#;a$dsUJNP9lG*jwCU1?XchE!^a=gtXfE&}@m?QBs}etn766|`lk2{S2B5E^PcgrV z1}NV}1BZTyzL)fKGzt4HTG334VKNypr&N(KiyTf&5}zM)kiRNs3Rn{}c~eqM2oS{d zv}VNANwQ<8;@lWMvmhqpg|e7~p6VFhs=65WP0|=vND;FtO&vog>0#H0I#VU&S;h{3YfD^;!&^PvQsw3MWg<;1K_GI6McJGrgF= zVRBY;LR0HF8?%x*b5I6{1c^A0&J}XZp)!s*RKZbx+sH|nk#c~$lpK7Ip2Iw3;@q5Q z<-GEZn=>VE=K#}PoVui5PV2%TCm$Q-Fl3XQ3GxPxxOg+C1=z}YA$f^&!?pvQOVq<0 zAn6FFKJGTonWVco4^Q6D5djZ#ZsDKe+yq%&TS39a5nkLT)`_HUZC@^NH&lBN;D5hjNy%Qc)Zc1)x34}*YlW(i9E3;l~-_7 z#3Qm$JOKE2EPD~};A}Z>kEo7kOm5+MTIIY`OeHUBjgH3w^gMuWH!`Q8szblMtI4mLcF@=Y2J}Fn|YU;w(;&E@8TWj?ByjS z9^~~fZ|13iqr8`ayLitf-^ZhT`UsCRbc#p6=V=}#`gvX?`6XUz`|G?Z{2g9KNXp z<~TOc8pl4Xh&vdij+<%J$DO;)5=SCi<1Rhzilai_IMo^i{m3Z9WucP0^iGlCq(r@`Cj!FJ4 zZk3)IA6mzZ&&Q+V*R6_;ZxAQM@5io>_mBkf+sv8q>cs4L0QhI?LVkSTbLH{Ux|;Ya ztD53Z@MQ5>x2WT5N6`4DHIDeY3{U)nXYn&Zt%LEt;CTGe$&K;f+_f0bbu7i7 z;_Zpw`1Vcl6Lq)7j~}`-{@~n+_?cTDjHk^!8eeaCGX4d|bMYS}z8qii^qcW;_;Nf` z`APiE%rA(~@h>ki@MZiI`D#3s`EC3}_fPRaC>(!X5s+{vm6ot7#7xMFj!rmjl54s(gXnb7uGsO!egg&31SJH zz0HLD^Z;J0u$N@?P^#Z@3LC_&+7jzO`+I*rV+b9qSlY}Wkp)gsPDNM@D5f%vZ zg+;Ol~5}*3N^y4OuG;lI)x5lk1#J2%oK={L@6SnC|Q&#s>{p~ z6^QahMWRBHSX3*j7uAUxG9i&#L~NXhj3SLlo@p21BB#h9>JdSiy`pqsx`>EtiZX;5 zBH~3vS;8z)t}s`WEzB0>3G+mP%=*j~jAsQCT7hj=K%^CDWd$r*!859aD-1+Dnvy#p-qGdF;Q-&GLy(C zi@ZXw$R%`%h~%=!BlL)TLZ7HxNF1&g_KA9h{lb3Hpm0z$ARG{-3DZO?F@Bv;Cn93c zBEQft>JWB_x`bV#PGP60T$Crs6%+_ch_-K`piEFMu%+Qdjn|RpChEHFX#;6aqOseZ z){{nz6Q+%%4W;#`1=0r7hSNp~rl29cF}*3hIlU#lHC>V}O_!z1(-rApdQUnLYfkS^ zA4nfeA4(ri52O>D6zReAvGi_1mmukXqYy`Iqx>5_ob~@$A#UJ*(un)76XI0=iV>$S z_?r;-|4)c3BaFE6zX@^w&4oDPfcGCt+`lBm1qmN+^nbAshy4#moUQa<6XM4HO(QPp zzfg!<@!^#JZXxb(KHOjXaDT1C75q2w;i?HC?w|W`|DeM){|i2xf$-t9gb?>1^Wpkj ze=WoX2qW&_65?_QBQEz3A+G2TBkn&c#Hk4*?thOESMY}s_ctN#KU0Vs`@@J!`kN3Z zZu*-L_n#)jggDJVG2;Gfgt#P$K$0v;k)%q} zBzO2m?S zNrR+O(j;k?v`AVd5{XnIlgK3s2`C|k7bPl*TB4C?B|3>-Vvramu*4)mBxZ?4f=a9s zOhTk0BzB2I;*_`~Ziz?YmG~rWl6Falq*Kx*@k_cTJ(6BYpQK+hAQ_YpqcxI%WJEG5 z2};H!Nm79{S(+kEm8MD4r5VycE+R^^q}kFOX|6O+nlCMo7D|hx#nKXKskBU5F0GJO zN~@&R(i&;4R4lEN)=L|tjnXD*v$RFpDwRm3QkhgPRY*apQVK~`Qni$b-$`{+z0@Ez zN@1xXrJWZPIorF{UK#lKQ3H(jIBAv`^YE z9gq%6hor;OfOJGUDh*1U`(q$R4%#{nDvMgD)EJv0r%ai5H3S@<{ zB3ZGlL{=&*laSXn@23e!5N!BcDk+sSsGO0`^lgkt`P^OeY zE3q}1My8eN2m#O_Gs<9@NruRXh>Q%CS!Kk4gAAA1We%BB<|2eZkIXCc$=YP?vJP3N ztV`yXb<28Wy|O-8zidD@C>xRu%L1|y*{Cci8zTTVfjn8BB2Sg4$J<%&Mn#jNS<#|sRY(+4g-jt=C={SVsely3z@b8;&?; z$I=xx1+K6w915qxrEn`e3a`SaXj8N+IuxCXE`?vwt>{toD*6=tiUGx-Vn{Kp2q=g_ zM@3LErbq$>U<#NDrh(~T2AByZuUr@hv%qXH2h0WYz#TwHh_&pgRmKF0b4-{CE2IyTKl?7wiN3!2xg(90G^I z05}4Uf{IqD2Z(;^pmIn#OiYlDC`Xk+Vv08j5B!=psdZ+FXV&TpmwMO>V&!= zA~*o`K)p~OF>^Wq4MIcEFcg4Bpiw9YjX_B&fht**qDobzsnS&$s!WwoB~oRnvQ;^% zTveVbUsa$gR28X;RVAuYRhg<>RiUa>RjH~~HL6;bSXHO0S2d^_RZXg9Rg0=sB~eLL zGL>AVP!YrQDoCYLsZ|=)iYTgA83{^n>I!wGx=LM5$fUJuvARzEcRp#;KM_jh|B6v+{6i^4)MmBi533aWLo2oa4_;}z zxCfa)M#ooVojZ6IG^oa^!HB^uTw~WbG)|363)}lqVRxPHr zX>qMx>(Dy2F0GrG1@>xv+IDT5wnN*g?b7;*8f}lZSKFuU*A8e0wL{urZ9qFhsIfuq zm^Mi#&?W0qbg8;DUAitqm$|Z$r_0i16P|3YE>D-QE6^3{igd-g5?!gTOjoX}&{gWH zbk({VU9C>6tJBr%8gz}iCS9|xMc1m6=%hNCPOekvhygVnq*LkCI*m@N)9Lg&gU+af zbtWC6GwUomR7WJ2bT%C^NT+k?oI01zt@G%-I-jmh*RJc(b?UlweqFb&N7t+C)Aj2H zbc4Df-LNj88_|vGhr?cp`ZRsIK0}|mvel{2(r4>)^tt*xeZIaxU#KtA z7wb#(rTQ{`xxPYQsjt#k>udD2da=GvU$1Y_H|m@8E&5iyL@(9L^v!xXq3D8or5@6& z^lH6Euhr}I2E9?Q)5Cg`9?_fi7CoxB>M^}dkL&Gvhu*0tA^>`i-mCZN+w|>vVh~K< zrT6Q*^*#DteV@KxKcFAf59x>X0sV-6R3Frj>5~isL$V>okZMRXq#H5}e{9tnvJBaV z97C=l&ya5@Fccb!48?{LL#d(6P;RI&R2r%b)rJ~FEiqADXQ($c7#a;thGs*Hq17NU zNDVTB+@LUk2BiTqs0?a@#-KIm40?mXU^Ku6lL0Z94Hg4xuo^If&43e9u+!i&xD6hI z*Wfd>8QKjUMEkSL;5T#|dJIHl!_aRSFbo=o48w*RqumfNj2K1@LBp6K$tW-;8&iy_ z#x!HPF~gW?6dFawEMvAY$Czu(Bg$?C#zLdqSY#|VmKaNoWyW%2g|X6DWvn*V8pXys zW4*D#*l27rHXB=vtwxDaYLpojM$o7 zX0#b`quuB*I*l%)+vqWRjXq@;>6{l;!%kFnR-XY4l)7zd3*#$jW?I6^cH zg2pjp5-fm|;S@L(PJ`3ojFnAsI1A2(bKqP!56*`R;6k_vE{03sQn(B*hb!PpxC+jM ztKk~B78b*Ga6Q}rH^NPDGf~TJg(a{QmcepZ0TUS?7=l%>8rHyCSO@E218jt0*aRc6 z8MeSEY=tq{2IH_DcEC>91^2;j*aLfEAKV7F6E(3;xC{2f-Ea@w3-`kV@E|+{55oa? z1RjNh@EDwA5}1-rDW+6Ynkn6sVaibOO(iB*S*fYa zRBoy;Rhp_y)utL#tx0UEGu4|KOpT@{Q?seX)M}ELq$ZiE!z4E;Ohkag1esJOB711k znsg?;$zU>?U=xwcGnq{m6Kb-WFq6%Mo9rfs$!T(#+$N97Yx0@eOzoylQNfS5 zdQE+%e$#+y&@^NkHU&&0rcqPSG-gUd1V}QHf}|p8NIH^%WUd@WK(df*BnQbw@{oL_ z04YR@kYc0+DMiYVa-;&OM5>T#qz0))#7G@dk2D~SNE6bGv>>gB1d$>#M2;vB5K$r! zqC(V&2GJrqL{D@;j0lXF5QOM~SP&GkA{b&raKui?*iOWSxDgNHMSMsb(vA?JT*Qxb zBRxnj(uEKq0b~FfM23)IB!G+{qeu`LBX~`LIoX_IPBo{Q)6E&?%#{Na<}7ozImeu9 z&NJtm3(SS)B6G31#9V4FGnbny%$4RUbG5m~Tx%Aa>&*4$26Lmi$=qyiF}Io}W~o_b zmJ_uv(5y5=W|diO)|j(EoGK+ONFJ2JN zx7aNXi__w=xGf%{isrKri7QKorPD$T%38WDJ(gZepQYb2U>URwS%xhE%ZO#v610pF zq^ST+MpMvKG!0EhGtkVH!zySNnvLe5xo94mj~1YXXc1bBmY}6*8Cs6kq7`T*T7_1l zHK-V^L+jB7v=MDWo6#1u6_ubMDn(_e995u76hc*~8r7g$REO$O18PKJ)Py3a8MUA& zYDF>BhT^Clb)Zhvg}PA>>P3BM8`_R`pq*$J+JpMhZnPKeL;KMIbPydPivIz01YIcz zjiE_afi>BhVokNCS<|f<*36Z|Hr6a_wl&9^Yt6G3So5ug)*@@MwZvL#Ewh$eE3B2) zDr>d1##(C?TkEX#)&^^%waMCSZLzjmB}CO!0RE5eGg z608&}!^*J=tP-ojs<9fZmKd<8!|JgHtPyL%nz0tF6_a36OoquZ1qNbD48l~H8q;7} zOo!<)14hJVFcXGgX3T;)Fch<57-qw8%#JxR7v{!1m>2V5L@=uLdaz!s z59`MUut97H8^!|I2sVlZu`vR57TA()DYjHwnl0UyVar@O++@qLW!rLWxwbr8zOBGk zXe+W6+e&PuwlZ6}t-@AmtFl!S4nnO>Y^$@?+Zt?*wkBJ%t;N=Alh~v-88I8Juz@zE z4YH|hYMa)kv*~Rbo58ly?=aaAo7rZup*E`xv)OF8&2DqpoHm!uO~?vfo6pu}YqxdS zI&EDxzpdNWW9zl`*@)1CZO}Gk8@2^(BQ_#jNLUX7JQ+{HM{U`7DxQX?;~97+F2qH6 z7M_de;rVz0o`Vvu=i3YHh4vzQvAx7zYA>^w+bf7VU6sAsUSqGdi|uvxdV7Pt(cWZl zwzt?@?Gn4xF0;$+3Oi_5+9A8juC{CJTD#7!w;Sw6J8U=E5xd!Lv7>gY9kbi)xZQ4d z*qwHl-EH^Sy>_3y&E9VBuy@*t%(A`P-ed2z_u2dH1NK4tkbRga#*f%X?Lqq(L4XS! z$&M5U0meJh9T|>HhtMH%WI3`OIgVUMo+IB;;3#wyIf@-6j#5XNquf#9sB~00svR|s zT8G$C=csoyI2s*Ij%G)TqtzjCNF6eV+@WxQ4y6Nfs2pmC#-VlS90cLuFgjp|$$>b` z4vPbISRDi*;=mnthr>bS=p1f`$3b+Y9c_+wM~9=+(dFP;m7CDQZmCh1p zsk6*k?yPWDIjfyD&RVC~S?8>GHaHszqoUc_;%s$FoKmOEDR(NIN+(1Z4JxPFsc~wZ zI;Y-ga2lPk)8s^)W~ar8I;~F3X>;OEyVK!xI$chW)9v&+ea<##JJC?=bapxY&TeOq zvzI72^*aZggG9x1*cot+I!ByA=NQ4R3tY*r6j!P%&6V!TaAmF>I&@{ZvRyf@Tvwhe z-&No$bQQUZi3(1stISnS)PyTtRjz7RjjPrrcGVG$%#~(AldIX);%aqCTvDP9BzGxX zpiAk3Tq>8^rEzIpIv0^OaT#4i{MUuJ%r1)yB?_sS%jUvec9+BDbh(I%gU97{`CM%- zBI@DlbalD>u5MQkQFrZk5g}`$LN)9PxJF!~uApm-;Nk`DWOs@?)t%-}cW1aWR}MeA zv)n}4$DQlWbLYDY+=cEUcd@&~UFt4#m%A(6mF_BcwY$b$>lVA~-1Y7TccZ(>-Ry30 zx4I>6saxijyA^KGt#m_fm0RuBxV3JbTkkfwiEN?U}4Pnsv)leu!l)05@N_T+eSJ$asdPl2bvA4uq>Miq@ zdn>$^-YRdkx5iuR6?^Nv_1*?=qqoW1>}~P3dL>?|SMF7KWnR#$^b$FKuiC5eYP~wI z-fQq0y)e-tLcC_L#fy5aUd+2v0JM7@UZ>aPb$dNtuh-{o^R|0Cyq(@IuixA4?eP*J z5pTbDz&q$2@(z0g-VyJpH|QPnCiw)uWM7Ie)tBZ=_htApSB};CvV7UT9AB<4&zJ8j z@D=)se8s*JU#YLmSMICuRr;!Y)xMhlhqbqWYHMv5t=Ec?gd_wAR;5n6E7ZNEEp4em z2=2ilf(7D%xDld2jF7gw?(VMC-Mzc+?()B|_xGK1?|;TP%LI$3n0%&yDP)S6Vy1*y%k07G$?C=G&FaJI%j(C9 zV0FC2nKh6#h&7lsgcZpe${NNR&KkiQ$r{BP%^JfR%NoZT&ziuR$eP5O%!*=7VNGRC zV@0#3vu3bnvSL`XShHDkSaZRC^f=Z$7L^sxqOlTKiL4}6GAo4z)&sKASsAQMRu(Ip z1(G7HTvi?{p9L~RtRhx1tAtg`Vz8Jj7K_a)W0kYOdRbN#i^HmB)v&lM9*fTsu!JlT zOAI?!Q2>}l+1_H_0P_DpsRdlq{(dk%XpdmcNM9ml4!~wYpJCmKo&SvMZ>Fiu~9y_1?ua^6Nb-ao=ir5BSL)=2Fg>E3O zBWfWfQic5AZ@BtQ$kYG6{(try5Gb(c0)<9lP(COu z3Wvg@d{G1x3FU|SpFQrs?oC61)EO!Xm5fS3rJ~YM=_s%!9+i#CK^=j}@Xz0U!3+a4 z1)dB(&W5i-G;l0}Z~wR7@kfw9{08a=4~2)rW8kT96g&%_1Al=M;5$$;{OiBH|G%E$ z|IKkf*tBy9IshTyQ!oUh;KR^C2m@nb0(=zgupz<6pf>0PbR6mg2g3nyDENxHz}?`U za5&r>J_VhG&Oq&H#z=SoJQ$9EN5G@tvG7EAJUk7a2~UU5K^MU0oy*Wg=p0Oi=fanu zL^u^rhST9pm=0&d1#ljG9l8eHgl<4A_ySx3GvF$?3@(AMz&GG)@Fln!z6J4NE-Zj0 zun2ti|NQ$NbQgL6-G`9yX&8pl@I&Y?$Op#3MEEh}3;V%O!RDUl&@-qr90CWzVem(| zE8HDCMi00T{1SQry#^b7&VuuQz(e5v@JM(xJPw`&Pk^K07ZKK5hm&)8qFzhj{|L>w{>8|NEG zhzp1diVKbli3QX3$~aY=E>0h3h%?5Sf}QalhjrDojODeW-XUfl8v1 zse#lGYACfcwF|W?wHq*J{eUNn>@Z{_|8ZgM9&9%7U$Os~uM}Xs+C5jh2-lsmGKB7LMKBc~yDb|6OxfR_tlg1K1r{t0c(0@m=amy* z5MLBu8?T60#@ELi;~nvy_yzHQ#;=aw7QZ8YSNxv%z3~U)+v3l}pNl^qen1-OCX#uoAS`aOm77EN)M2FuR34GRc+ALZUErpg!O9yr; zht_VUihzUS(fGhQNojJLil(O-Xf|3Ct(j)0IcP3g3vCf?F>MKLDQzun9c>G3D{UKX z2W=;9H*Fv75bX%9jdqfDhIWp2k#?DOgLad4kM@xEg!Yv7jP`=|hW3{Bf%b{^nFb{w z6YvSX34{dygusN*gw6?F61pXH2UhEEr}ekdiUcleDlI-Jx1V4{Y0Sg3Z>G!wX`IAD+RfHf)t z&ZzVsTU4D0LXnAzL{*|TQJ2_|Xi02JY)))R^d>GyT#~pnae3m3#MOyw64xhgP28Ti zBXMWq-ozt`#}iK_o=&`*_$={7;_Jjui9Zs5CH_tX|70Ygldws+BtjA~iIf!7VU~t< zn56L?25AZ~M(w_6UWX@2?Jz^x9ZskK*r2*3S&}?Souo}NCYh2fN!BD=Qe%=m>CdD^ zNvo4KB<)SwpL8(kNYb&S6Gb$>e1Jbl+r1sb4u5g@PC`4c1JX@!wpoJ~ZHS3Oig5^FLXfza0(__?y4o zO>K%SMUi4iX-u)FI8$6HEh(Oq))a5bf|RC|r76o&mZz*r*_N_97DVI`i zrQA+=kn$+yamv$_mnm;jKBjz1`I7Q8b=zasZUeir=rs^ zX})QMw1Bk0G)meOb=R~W9fl{O!{`j}a5Ta>mmZFSn3w6$sL(l(}TP1}*SD{X(;!L&nZZE45TPNkhs zyOnl3?M~WXX%EsKr@cyho%S~EUD}7V&uLIPDxHu{OeduWqz9&V>+m-1&Sn6xHIW?# zrrp2H1;!-_n3a6sQ;LCy;dS_u+VuK#bGj|PIo+AwlHQu`O`o5>FnwwIs`T~g8`3wX zZ%*Hqz9W5S`d+Xd|44dU`kD0W={M8wraw%7mi{XJWBRA`pXpEroPo^<0X`)xqjN^r zj2^(d3<6eVN{2I{0Y{Pz97q{39)BB-x(r!{GDDrA&oE|~GeA@@qcNj7V_C-Xj8z${ zGuCFT&)AT$HDgD{u8e&d`!h~uoXNNhDv4J!u4P=$xSR1h<88)=jGq~V%#h4(ncaaa z=?ff5yCE42?8vYVFVgNbGCMrR-v)yXyhXdQ_?M~BWNI_@nWju@rYF;zIX`n@=AW5M zGFN17$lR2h=QD3*Udeow`8M-i=7&r;3zJ363IH~v-EXwpjiJC}j0NUm za)+~+0c=GQ@DpjkSp3UG6af3c2G*h7GSp_(Wy!J>S=uapmNm_yp&vzKMB$X=Db zK6_*KZcrZBn|&nvWcG>d)7j^;&u3rEzLb44`*!xj?C05t988W+4mO9B6PD8@r)$o? z3`0bRR~QVO!U*6J#sh=U?ho3{!AxKasK61V0y9AGZ~?`@4penee?H*-?W|vy(~x7z zY0hcM@#HMbS(>vlXHm|ooV7XYa@OZ;%Q=*DG^Z`+Sk8%@vpMH-&gWdnxtMc1=U&eJ zoF_R?bDrhA$a$IbD(7|1yPWqqpK`wC{K)a4Zk{-4-E{<8q*F9tNfmR?7f)75k>T~9aCEp!{biSD3#=&kgH^hNZ=^kwvQ^!4UR`f2(Z`bGLB`Zf9u`Yrlx`hEIC`aAkZ`WN~S`cFC{*C!XB zOUNbX`sW7Z2If+7gL6Z2!*aXib_0%}-3qkZfWJM!Sit?;iT^A>@#%opR{=6F$`$9< z9xBf#FEB4CuS;Hd2l4L*DE}XT z57^-k!X@ zd57{&=UoE(p0DRU%X^piA@4`t&pc#4Dj%Qkn@`Lq=LhBo=ZAJs`9U2Fek@?`|6=Yl zI#_$`KZHFMaP@YI-pA)D`8V_L=0D7Tmj5FEUH<$0kNIEnzvkl#@CD?8fC5TE zXhFAva6sOB1Mc2V+}la}NWj!519l$wZ)W~4QvNq5&j(DrorH@3`&Jcb3QPs&0!x9T zz**of@Dz9p78Lwhu%uvF!K#9d1-lFO6zm1n%3}q`3r-ZAEI3_ow%}aBrGhJ9oz%mE zrv=XnUKYG5_*n3{;CsRE0=N)Wh%Lkw;tTx>0}CmI!G&RkoeR4ab_aaDFQDp!0ZIRx zn@Y!Vt4Vn;`PNFiZ>VUEZ$YTyZCGIzTyML2a69Ew-p~NK3{yL z_*(JJ;(Nu9ir*B!EB;jcxtLZ$DG4j-TGG8F0x;`#TKzYx9uC;_LSB^ye1mK-i=D>+$mrsQnN zxsnSdmrJgd+$_0O@(>iipOri>c~SDR+NgbV2Fj(j}$K zN>`SyE?rx?wRBtQj?!JFhfCW^&y`*-y;6F=^kM0%($}SLOW&7%Ed5mqF<=Ig;m7c2 z1Ti`>x-!B6SB?M-c^KfwqX9K;C&ulZxSbKl{=EN9V-Z;-7MT^m3S)Kuhx-l$ zymxp9_T=iyPRFY7PIAS4co%DvK!gWY&+Y*Ucp|) z-o)O@-p=05-pfA3Zet&3p9cHJFSBp3Z?W&N@3QZ+AF`jaU$ft^Kd?Wsf3Tr4R9UyO zo@M>YhLw#f8(TKMti6Cby)33|R@t1gxU%>%T3JF_Vp&RAW?2@fspOUAmz9)p+GB@h z4P~}6XW9I+rDdzj)|9O;+gP@&p%04dv!?Yq_nwvAnt5RqidHU%t3}N%_+9 zW#wzi*Osp<-(0?>d{_D5@}uQ#<;Ouq>~{GRuyg%Q`N#6F8VnW5Vis*`%idhx2E9O)rRwPwqRb*GhRuoheR6Mw4 z*_HIll1f3Pv{F^6sWentD_xcD%K4QGE7w-8tK3kz5$qk`Te+`tf90Xd6O|_`FH~Nx zyjFR=@@D0i%3qaGl}{D63Re|a6;joys%usEs@_$9R1K*bQ8lJ&Y}J&isa4aerdP#Q z#Z^(O5~`A_lB?3IGOMzy=vDbuB~{F-va0f`$|_zJze-dkuBxk2R_Ur5s*F{(DtFbg zs?}9%s@7L+s@hYvzv^h!v8t0*m#QvTU9GxP^|0!F)rYEYRo|Va%h}nPAVshlg-KD&^aIh z%qitCIV?^Yr<_yC;c)~UF-OXgaTFXCN6j&E%p4o1iDTzDI4zu3j+Zl^vyiixvxKvP zvy!u#vzfCMbO3g7c60V}4s(uxdhZF&NzNJ0dCmpSWzIFuEzUj8Uz|sr$DF5}51fyj z&!C9;jq@E;gMM?MYPcFz?Ng1f_OI?#-MPAVb>HfU>i+EuZa}eZQ1#&IA=Q!9L#xMD zM^#S))y^5!GppxR&#R8Frd6j@XI1A_7gZNmmsEqeT6I}KpTdKX)^FgEL&*~-B%c_@Guc%&Gy{39?^?J~++ze`yJ3$e&t@>E? z$?CJ!7pkvTlKGtAAAguEx{^)CAXr)P&dcsOeqP zuckj(#xta5RL$6$i8YgICf7vOOskn$6H^mgL#?6Jq|{{Bvh*H~+8HBB|nnwFY{HH&IC)$FL*TeGibf6bwqBQ+;$PS>2Nxl(hp=1$Gs zntL@5Y980TsCiZMy5?=o*BXe6;3Bywt`8T>#d8TAe=7w=QbGvZ6a=USR zar^jQ4`~hWD2Df%k>?ormUQ_&7e1PvZOYyYhSRd-8kn2k{5yH2*yR0{;^KGXDYp2LBHKF8?0?5&s$g z9sfNa5`5x+=6?g#>fd~ffFK|XItjW6x(T`q!UcT<{RI65g9JkbBLpJ_;{_81lLgU& z>4F)8*@8KOI6=H1QIIOg5M&C91*HO}ph_SRhy-Fmt)O0D0Hr{ipi$5yXcjmGZb6G+ zfnb?nxnQMWtzf-ilVF=*r{I9#kl?7GO>kUrMsQJZS#Vu&OK@9oS8!kOQ1DFfT<}ux zR`5meLx2z>g+4-@5HBPM{e?lo&cbfO9>RXYKZJvXLxhpS5yFweF~YIJal&Zfbm2^4 zjBu_nNti556J`ptggHXGuuxbmWC+>98X;d;E0hZ5LX}W0)C=o{W}!vcC~OtZ7yc<+ zCEO_7EZi>KDcmJIB0MHMDLgGaC%hqiB77=*E_@+;EBqk*F8nF{CG-(dMBPQbMEykl zMFT{Chz5xUi-w3IMMFg+L=#1mMNy(DqM4#tQId!*Di9TkN<|D2TU0Kp5^+R4ky4}+ z8AWE1Mbs>Ei&{nVMTok#MO#EWL_0;hM7u=?M2AIfqT`~AqRXNyqHCh- zq8p+oqGzIaq7R~vqA#MaqHm%fqF*9dj1VKmC^1Hi6Z?t@Vv^WT947884j1@nV`dL7XN|7iWkw#aZHPajrODTr4gXv&CiN3UQTK zAQp=yVzpQ!Hi;X>t>XFOCE|7BE#j@>9pathUE;msL*k?2Ht{j>De)Qc1@T4kCGi#U zHSu-vE%77qQ}J{0M=?_3Bf&~=5X?@Jy^9!Z`_ zo=aXz-by}7K1sexzDcmPGSBJE3lT z-Nd>{b(8C+)kW9Mtc$Co)g{zr)MeIX)#cXZ*A>(i))m#U>niIcb+vVMb<(=}x`sMa zow?3Z*IZ|>YpGjMx3F$W-HN)^b(`vT)$Og@S9h?kt?qQ)nYtTwck2GCdsz3R?nT|J zy4Q8@>b}+etov2>yUs_7mExsDDM{)l^_K=pDbiqRS7|qCcWJn^x3sTxpmeY_QaVC9 zQaV~XRys~PK{`nqC5@KSr3KO=DO*}8t&z&4TB%XmB5jo}kuH_4lx~x5m$peyNzX{n zOD{?n01A^_KOM4U|R7 zM#{#?Cdj7CX3A#E=E`WY6dA~M$%Ka;{aYj z990}soKc)roKsv>+)^Yco+zFvJ}JH^zAAnwU?oP0SNbXal|jldmBmVi5(Jr))k?0CuM{gKN|{onv?^`NCS|K~ ziE^28xpIYat#Z9`lX8c0w{nkipYnk6sIpCYQh7#sL3va8Souu(TKPu#R{2i(SvgGg zP5E8a*OR3?>8I8MNIz^qTPE%*8>FQi{o;qJ$pe|Lj)aB|LHCN433)Ky3i@I6uP`lJE>ILd0>ZR&s z>ecG?>W%76>doq{>TT-n>b>fH>iz12>ci@D>htPL>MQE&>YM7j>c7+v)sNL$^*8ko z^-ncQgVy+Hd^IGEpN6an)KD~Gnr@oznjV^7nh4Ec%@EB{%`nYa%{a{j%|y*4O_XMu zX1ZpcCRLNA$<-8S3N_`LN==nUq)}*;8kI(^(P*?9ou*y`(ytnurb%PhI5bX8t7g9D zPt8)zD$Q!m8qIpmX3ZYWUd?_@o93A2xaPFxlIF7Jn&!IZrsj_3zUD8@1I;tdbInW5 zTg`jT7tJ@#Zw;(PYB5@z7O(ZylC@#l0BxX_q7Bt{(stH%(RR~z*G6auX$NZ~wZpU{ zwd1rCv{SUxw9~aQ+F9D!+Bw=-ZM-%~o2*UMrfV~`Ia<25KwGM<)C#mBtyJsKy0mU> zi`J{1uU)2Hq1~a~t=*&Dr#-Gcp*^WRr9G`Zr#-K|puM5Jt$nP0t$m|?tNp0`tc7(L z9Z^Tp`RRgm!Madgn68tqi!NN(SJzJ$p^MZF)eX~))Q#1R(@oMv>89$Y>t^U?>Ed)W zU5YMUm!Zql>_fq#(_g?o&_f_{(_gjb3qxC*|KfS*`Ku^&J z>AUH}^*!~y^?mh!=m+YD=tt^D>nG|b>7(@1^wae-^|SQz^s)K`eX>49pQ_K)XX$hG zh5BNBjh?IL=>>YBUZk(p*XgBtg&Fh7~%}^29QNFq!>~S8HOxF znjzm%U??(_7(m+Ez%kSqxCW7-)}S_M4D|-H!D_G>oCdd{#jwb*-LS)O*l@&f%y7bR z#&Fqi$#BhZ%W%)|#PGuK+VIBk&hXLj+3>~i%kbL(Hy|5u4FL@y4V@bb8%i5k4P^~= z4e|yM{A*}vFgI8lni^UgybbdkmNcwvSkEDaJX*dB#{{oH5auVazmU8MBSK#yn%G5yak& z<;DtQrBPrM8bwCAQDM{>%|@%S$>=h=jUHpGaiMXkak+7|agA}KakFuUai?*gali4P z@sRPT@r?1D@uKmj@rm)3@s07V@w4%(@tg6b5i%i6J|?Wm&qOu_n?g*Xrf#NiQx8)w zQy)`5Q-o=tX^?5KX@qH{X_RTSX`Cs_G{rQ{G}9DkiZ{_r38q9-k|`C`?6XaUCXZ>p zX@O~xX|ZXEX|rjIX`5+}X`gAo>4@pL>4fQ&>8$Cz>4NE!>8|N7(*x5J(<{?k(?`=M z(|6M^6T*x#W6cC}sJXK_!rb3H#5}+}&^*XI+&scO+C14j%^Yo>YtArdne)s==3+C; zTw$&@3(P9B)?9Bkn2lz$xyfudJIqeA+dSXA02Kcgo7b5)m^Yd?nYWmCn@^hem=Br{ znGc(fn%m5m%va1;&DYE~&9}^V%n!}y&7aKA&9BXG%pc6Z%)iYb@nk_;Fcz$ZXdzoD zmS9VWCDhW%(#6uv5^m{Z>1pX@>1XM08EhG18EP3}8D$x58EYA5nP8b{nP!=3iLu04 z5-cf}G)uZA!;)($uoPR^mTHT@BD9DsGK<2ZvZyV3i_v1S*es2fCX2(;YFS`eVp(Qc zWmyecsOv22EgLKwEn6%*ExRncEqg5oEC(%zEf*{oEmthpEY~f!Ee|XYEl(}aEH5lC zEw3!EEpIGuEuSr4E#ECaEszzqqO52u#_D6mS@Bkam23^L23muyq1GuKv* z>jmp2>lN!&>ox05>n-aY>s{+T>tEJ~*2mT-))&@S);HF#*6-HeR>+31VQoa4zl~xG zvURa_wRN*~xAm~~w)L^~v-P(Puno73u#K{fw#~G~*k;+Nws;%OmSjt@rP|VM*|q{( zp{>|fYGc^gwsKpAtJ7GI%J7v3IyJov-yKTE;yKj4B zdu;n^`)vDS`)2!Y`)Pw45sj!uY$L9b*hp&hYYb`(ZVYMc-Z;2%NaN7PVU5EZM>LLa zoZL9Eaa!Z_#+b(0jdL558q*px8*>_S8}l1W8kvpkMv$v)tZb}mR5mIa`AveR+9qX_ zw#m@c&}3}#G_^K)n-(-JX$c== z6PuHpQ<_tobDPVWtD8m5;^x}sx@K9kyjjt#Y}Pefnwy(l&7Nj&^P=X(%}bh>H?L`4 z+q|)PNAvOK^UWKwt~Ot9zSVrY`A+lG=GV<{o4++9>_|J>j}v*w@=P*f-m^*tglY+jrP^+4tD@+V|TJ*$>-~+K<_f+fUk0*-zWg z+Rxc9+OOEJ+OOGf*>BtL+HctJ*&oKb!>C&aO`yKbsTUUcCOPOQ`4 z8RQIhhB!MpJ3G5LyE}V2`#SqM|8Nd<4s#B7j&P22j&+W6j(1LQMmeWAXEqySBKtyLP(v zxc0jCyAHaJxY}H&U1weAU6)*!T~}N;TsK{JT@PFjU5{N)T`yekT<={UU0+?_Tt8jE zU631gBiu+g%8hno-8i?eo8Tt8Np6s@a0k1?+@0NB+~MxN?mygv+{4`?+#}ti-DBP3 z+!Ng~?m6zc?j(1zJH?&h&UWXz^WBB+B6o?K;byv7ZnnG3&2iVbd2YU2;0B3Yx6-Y0 ztKAy6&aHRXyBpjlx7pq3cDX(7R`(M3QulKAD)&0~diMtRR`)jdPWLYN9`|1Ne)my# zoBOo;tow@ls{5Avj{BkevHO|(x%;*Iz5BEKi~FnloBOBxw;O6fwD`98wfMILw}iHY zwRCFf($cM^XG^b^zAgP)B3k;l3}_kJGO}e<%jlMgEmK;iwM4f}Z<*CHyCt?Iu7%o? z(304a+>+Xo(UR4Y-ICLi-%{GbXvu70wv@D#wN$iJwbZomT0||6THdvMZu#2c>p^(@ zJt3Y@PZv*DPdCpHPo!sUr*Y<$2?I@A=^Q<-xZiT76nct>jk! z)_~Ta*5KB#)-J7GTZOHnR&lGeRo<#-Rko^HHLb>0Q)_dpqt)Ho+PbK9S?j9SHLYt~ z*R^hJ-PF3d^+;=5>xtG&t#?`EccOQ)cZzqKH`+Vh zJHtEEo8V3ICVNx7sor#NmN(m5;w|;Ey=C5VZ-uwg%kkEDghQX!(>lpkoPyz(fWMHI_FF5*wBLN)$`}qahwcnAwp%i%C;C1_(z;P244s8a< z|9Vi+7Rb-M3v!M<1dVl`gq+Tc5DI%4-2VSRNa!j=h`b5yYr6-o2P3@?j`txtczr(f zp9T#*0_VXjdJ4V%{RNs#{teFmJ->dF;NQQyff)>D5|~)nkDm&th*@24Gvr}jPy&v2iC2R^wB-~H=0jDqgK_^A7EVa^M9)QwLtPXHrkq0opc zFUW{De}y5&(7PcHV|yVGkNP8!BL*WN=@3Nx$We&4yAu#AYiA-L`7A`KgNle*o{X5< zKLde$l8XQ&5YZ*N6k%Ikg&4Pwk0_a5i=eMiB9hhh2;t;rL=?h-&?-ELT*^X3IC&AG zy2lDckMPw9gwJ{e6uA+xD{4EU_maJcyy!!SW%Of+aQsO`2;v-~T6GnHKwU>DTkayh zi(VpvDDM!x>%JrI`@_h>EqLT>L;$j;dl%&I@IJ_jaRZT2V(y5vVD`A*d+PDAe?s6Hy51WE6y+f_gq?HVV98 z9fgJxP$Qh_C_*J2Wk(jHAh-lolwW~D_2!_?N_nVwNQi>=iBb4zGE}8mgKCR3fc9(y zXv>;WPLdr3eQrfba~7kfKub~UpcN=`;~G>bv<@ZB+k}cjY(bsH?Lv018Dt zjDoR8QRJ?m7mGfF+ONEbB14x@eWI?RsN|a{zbW@o`gu=LxTqH>;*$5Mu$A9Yb1g7> zUk@}|hQpy%hy2h;$RAC^1fwBo2pZ+v8I6Uypu3`apm9(y^sJZ&bf$SQI30;L2aiM- z62_y$drm?JD5s)__l`j$33JiSGZWD$d=oHXmGu-iTg{UYxQG9ol0Tx?Ar9=$HXV(GmV9 z(5TsG&{6pF=+42{&~)N$bd>fU8jpB@Ml?M|_mICt)5&kp(-0rf5b7g3n(`Gq|8Jln z`wfjE`~*iZ6%Yo~360qgVKK821PnwVVW3X_m?$U!gQ5gsrbmTg`a@kX8+Z4^@bQB% zf1rnBmhYU1nZI`iMjSO4BTyt_egtGZYTV&L%C7!>s#MmpjX1{(GiGq>b7=GiPC zpFJgHpShtyK2ryG_6c9s-RD@3K0e#21AW#>BYnC-BYecar}(&(Gkxw-=KAc9i1)b* zC;5;xnLe{t<@@*rGJI~_;`(&jQ|I$tr}MeH(B!i)zR3rX9zbXA86l0pTco3ef~0i_CcV&`os=| zuzl1R?8LnR*ac7!w$r#S*o%f<*khRfSn<%I*t^gOEWT+RwjQ30y+Mk>&iN}I8*WI# z%Kg)@qV6<3sx)B>4ZN;`tc7wop3pNI7#a{fl z3=8wtVpCph$4))82isM57^`5O!bZ$GkHt;7jGcP^Cblc)KK57IODq)n8ryT+N9=>G zzp>u&cpUN#8TV{o2u>Z?6^D?AbS*BlWi#&0i9NXR1qX2V z^N-`^l279{!xwRegc~@8>ppJ7wr4omu-7=D<1g`*kZPfHLXx1=+ni>?O& za`Yx(p*{pi){o%A4kUy^g9+v-!w5c6qX-KgOeCPuQwYR@nFP|%d4zeSL;@xzm4N@9 zM;I1dLRdDSj4)VLL-2+81SnKUP#%{O!bwU3tJFXk2AK#@u$7RS>?D|x9zuBh0zyQm zB?L&il+fFMCE;G^dP3i6TM4wRy@VB{BZT>WCkYX2E)YcD?hv5q_X*g7M}#QdGlI13 z6(M@xI|ADLi7;jT4?=GxL_E|RO&rn5mpG2@PlU{Y#K!$$#2NB##BoqhA~Ccd5wm|F zu_rW`NOleXM0pSF?z-qw|OeeG#$e z%QE6VawQQRRZWD*HADo=BVx5eB0RK~2+fcYQ3wSQdZQs?ed>vj&Paq7T8I#2AtHJ< z5+OtrksRzKPKDgWD6)qL(dHBBh(C!RXe)_O_$ne7m-$aD`w-6Ciw-d3`b`v*C z4-)TH94Cgm&Jd%*&kveb$3)c1mqazJ3WM3osP zMI%t8%qSd5g(s1GhEYh;;b9~Q)rqukTR18FbYIfheSeT5_YEOQp-2)IJ)G2sIF@9_ zPb5V_lSmL^GKqklNAo_9AI8=N4&I@4rYR<~$=25HCqxFMcE;27D!f z|K~_{=r_q9i|{+-@8cKk@9U=y3GkaP>FjrHRxiIrH7%$ntA?M(H9+7kRK5vhLCpiDm*l9{bubD z_({V>e$p;=eyi?l{IF!5ABtS>Hv%&H-Gi)t6lJqtIAr&O!X18)!|g{QxB4BZSmd_? zwcJmuUgH;@xWO-vu+=XRwbM^(+3QCR-|r`nI^>5z9QBLpa>5TvJng4IUhsSR;HF=n z9{2pD$_IYKAG`pM_tI})^jkmNqc46){13mrGMIcl0856kcrsk-M>gAo$#7ICS^XuP zJnw!4Sq2Rtlkh{x@k>ULJHg|~FJx25(2?onDau*oZL4YIfm_na<%{ykQ#7UI#D)qo zVonWsV}Oucf~Y0acdE%L;Rf=2s+l|-)kNO6%thX`brBiSdnq{pUO~R#+DL}NH<2rQ z?jW~8yUDWfedJc@5wf0ef-JpvmW*3>i5xGxP993WO^%4VM7-$$$1hw|_;^ zLjQezm-@pyR{Ik!Z1T?v-3hv+|NTUv_xOib9Pl45Yx9@Io$+6cyyX8P>9#+);J$z8 z!6*LFy=`~OuxH}5z!*zRAgrGoXpcw;bnw#yu~0@JI+z~Vb7)~;)YOtdDV7l!`>i@~Ax01g zzDI%nR#_k-ToH(J>jG(m&4JS}O@R>A9!NI30;fPNfjd--0;fhU3k(lm5$GGYA#gr= zOCYx2&Om9@?m!FrK%lMDu|Vpb^MMfNVjyDS)xaK+Hv=OvcLSxd4+9Soo&~m{UIn7& zzYTAP3&6Gn^n<$hRCuO75 zOPM5HOo`mMih_XGP`YroP#P&aDMb1{N;u&lB?@Ax8q@P|GWT&!%&JC^(nieJu z!cLV0A(vqMasO3SJE^C6IkPSh- zx!Z%txx0fjzmEmo+I}&}TX;JNpZOpttM~IDXu|8Db*n!Ir9t1pa3Xnf@P>gif;%B*2P0bIf{{_QVEV+gV3am9n1Ia*h6Dw{5y7Rw6LwSuN2$5N z*c0O5>MCWh)T{~a2GxT$=s$DS6s*116s&3S1doVX5FCJ76kM=oRj{Ss#$e`?UBTZU zwFR4^P6rnyTn=9H>TYmd!t>xi{`wI7VDryluNo7AfP6w?RD_V8uwMuwIv@nX28IOp z2o0GZ-Z=yXbqPTsx`jaD-9yk&j}WM~Uq~YSN65h7p&_f_Q6b6!<3m*B$srU&bVwvR zCgkAvgpg_5GeV9-IU#g&eh5S_3>g+x8Uh6{L(I~$kVs!nh-@xDBoPvYAfhB8{lO2h zjILVn__`1&q8{`@4d8P&gpm7MLI^?4AyHCC2<+1mGVj{rkluvlA>@cv;7$1JLSX8~ zkZ|gj5Qw}r54594{E=N?K!XVcW7W|S@zoo@TPWoC8H##_45L(F!y$z`E7y%I*2H~h-vZ#drkFxs? zkF2g2_`gd6f`#4^M0U!Vne^}UnKSK7?`L{F(|hleWG0zxhu!Qho86V{E(-|QXet77 zRRl#r6tIAL)r$q>f?ZK82+I6EljUA-`Tg$m{Qfvkk|)U|`)r<>bH3;MdA}y+b_6GG zKOCJ9T$qN(_%8=7JF)$e!o(%J$`g~1Hz#br=}jCze=tF8TbtOnfA_?FPpwa!clC`E z$`>~$EiOkBL}mWlI;+a|ub>mw7}tM^P?e9nCn>gzu};XnW3i4SalWP-iz zixW=qS0@zbKRdyD@%f2!$sbI7Y5NNk`^JAVv3uK#6U6qP!SC?@e%wC!^NG;5Ur&5Z z`-chUfj>`}u6=7_+t=QnaBn|na;$a!#)l zf|In}k;!l4>B(K{+$3jPVRG!^^5iyCb#mLY&B@Dmbtb=c`Re2o+jdTF+p%kM2iiNi zecQgt{!ce1hr`?9xPNl^`!B-VZ%qzWKZc+Ee;=G}1g%MH(Uxfo03eiUG1?rhM~Ac| zjmDz07%V0WW3gCl7Kb%8LS$L9tU1;^Yk`GWTo#YTX9-wBmWU;0Nmy!@hNWfcSbCO$ zWn`IHW|oCzW!YGE7Rhq3oGcg1&GN9kEFa6y3b2AKHk-z#vl(nA8)LKB9QM=*&Z z=h*Y?1vX-H**rF%Eno}TBDR<KG2#U|Klwu|j%d)QvKkL_m%*&%kA zO|c{FC_BcEvlHwjJH<}3Gwduo$Ii10>>|6wF0(7_D!az6vm5LtJHS@b6f_OZKr_-z zG&609zD(ECbhI`df=)CJy+&)%XXvx^Y5E-9PABOOdYta0C+Ij`Mvv06bQq|kMd%i~ zm9C}}^dh}PFF>*_M~87yT9TfnUiZ zTn@%T95zSJ5p#H)DUOmOnK5RZnP4WFDQ23PVP=^*W}aDK7MUexnOR|0nKfpe*YR>I0y1*>8;td2FXCf35*SO@E3ix`V0r}1e5S_SpBV)?2y zr$n->QqJ?5Rd%{_fm`E)zCdW)ej#qjE0v_i!gS`en6ocpIimuk&CA(aDud7%5Q>dy zgI2<~nv2uUf^xp_sH;U*{3=L9pt<<#(G7Aq(cZHY<7 z5_qAilO~sCb`T|e(AS}f?1(N>^Dtk}S~GVf3o0=gv`EC5Cd2b6Lf}h8K%7|6gu$Ai zoKZ{AIj?G4M=c(vqUv-SMdpIDVG;2v(B-K+-D;gAVl*ad&Zs`^T$FSrNoQDIbk;3) zZPwWor=Z-Eak|K|Q|-u!U_=cXK3yk?oR$vw6ic8}WOOa@vQsZ-X|lRSQO_w7_Q9zT zT61EqY{|6Z)Z<$Fnv>xgICc0yAr&)S4iOCmiv`1~njx}VF_(g5fnmXRk!lV|7PDYk zm@H!9$g)`A&AB>q9&~z;%kSj7))WF4W)Im!U|UGQwiwA49VC><#B#-omMJO_OOl#Y z?lRd7`kqV%;zdl~67ws)@NWhPW%?n&&57Y>~~-=Qk>v%O0|@-M$7gaNN@ZzKy1wa_22`?rCD$?G(+pX9V-&|8P4f z`HCb4a?g^XX&D(FLbup0a!cF_p3S<7OWh$gT{$Jf-IVD+JP)S1Aj%?@LFHB`ii8?; z4~8-+(Ylo;ojYO@fT+h2)eKy1%}81e?h*k{1a6aimfJ;D0Y~E!Htklom}hZMi)`+u z&F*%Ss}hlfbUWP+cU&dq#<(uG+bx!O+%+Lj=5=?hLOd*F+ns8aX&^T$3i7UeQ9+mj zZY|fP9!T_(yohqsv}>9f5mOm~GLw#%(@5l28H?M1VRnlw3W|tXXyE6iCShEMak&Pi zjVA5cjrujof;jI^i!9ctDd&y}lJ3-&GC~QHsyRy<3QuWC!p(HFECpRk(vTM1QA5SO zCSR1-!5(4QO71q)pPFuiL}hEaJMKky1J^jp?xMR3D#@~&;puM)Br9&Er-*a;J$R~K zL|~C1i<$0Og>KZqZNgceCA8ofb(}C|(K-h<$%1|!j1mD?gd^3IC#9eE(2>Byu(Opo z_$0`q)o?v^jmX1N@;w=wTs(41grJu2Kr1nLG+>t)JzTZfLzk*N1FaT{P;-KsAj{W* zXR;`^cuXFT+9I44={+5hj!Qx*itTklEy@9^iB0AN&m`#agJ{Cj>UnOkO*l$EH{gl! zQl3?1%rml0;vNN8svcPNqgokK7+)RgW8myp9klp2;Pa*IMPmPP@igm zbJ7I!q~-aicA|H!%I&f?ZyD*dJr5IipqQ%fF-n@!RnLkiVHv=Qz?x^Ipe%_KTqZau z7&s_l{ghXT;2-UWe5K;>v<001As2{1p~%wuHQTZI@S7QsA%@q!H+7ML}WlK}{#z^V1?=-dwP}y=>N?rr6?3LRQ-|RLiR2pzvK>n(E^BS?9&;-nN@LE>5 zxV-6gq86wvDQ;7cFmx|GFQy%M`IaRGrKkBY zDcwhd*uBe!8E1SFq29h=oAoomchPGkR*RnP%UUh?w36d<${aE&GD&6#7aEB#(>@7z zK``ah+qh;9>LHiRjTndr3XI&w2MK1u$5qYy!j_Cg3=+(YQsA3)*o-0{8<+ZmW*o|1 zGF!|j^YP4b9|1y)k*D&> z<320K$UHul)a&cZBpRR3?+eS=Qn!sGG)q8`;Rk(EO~}XahqoM=vx-bZ!{!#{8Wd0? zfl$to=JYfLS5Saht^`SiU5iHU7M2OQoMTV=B0?+9TGuX|Fj6CgY3*3e& zTLv7OkU8(;2$n=SA5Xwjm3=gsnO6dtrUEw2jL{z9tExVNtbt9lrmg!J#EQ(RS(10n z6~ZoW`sS1)uf~ILja$|6@eT9J1!dP)C6IFD*CcGqK7)v^7%4Up`K+pA@T!(gbfa0c z;;Rc+eQP3z0r5PtfsgK|`9W&;N%Tl#)tlr&b>BXcZu|zm?5uUu5o~EUJefKpnDcXN zZcT{40On0xFu&C|~E>${t`a&Zxnt$UkL(^ z!LJ7qhw$tC%N8qmI2M1)ZuYDEZI#V0#z!U&oF+gQt)R!j!|{NP;{_8Z=+BWM5OTu) zgn$AWC$eSZ)Ch(mqe!c#q!N5u+7KrEQrsd*`dK!uG3B3;&I;ICx5z7_%xY8G-xcKi zG+h=XoxH!SOT!YOR2)Q}PeYZGYH0>adlqHSl#frlwzMY5DmA zm1V&=a&~5=0>PqRBGG|Uw$ThKtQCoz<)l2$Tly$opy85++Mvz?~(`0aHLD z_G(C|z*z%qGArpR>;aozsUQq4aDW_8hRaDjfmJi5@CJG&wSlcedS75hC{WFsmjo;$ z{AbE=uoBm}RG_F029|hp!EgW>L*NGWrO`kdbf9D)qR$1Q=ESHmM+Rg*4R9I4LST-_ za#Mk2UOvDTWxx=sfEUyOJ*W{_CR+iXh%4aT*tAZ)C6yS@d zG&#OjT!T8@04^aFa(1wxTY<}?9&e-ztp(`8yky!g6oj~}Aa0yPNmC>+3%*d+HWe)D z=YtL9LNH)3I%Yr|T9H}_FPa98D6C!$2xJD0B1owvTLMu|E(Lo?9K;kjm_)0f8!Dkr z=R^EpOT8l{1(1xgAQ)vpFk0a?Kr!Oz+Ta-FgR9~eC`Mgyj5_Z~MkUKCXhtfg5tjR+Jafs`V|N_EI>Yza;LJfEgA zgO_9p4aANRT~?H`6pGM5W(x&n_K*&lLQ}f7P$05~*hq_uR4tv?q)0!EX8*C+K zC}~mXBI*?jDNlf^w5(baheA?i!N4^JLQ(ayJQ9*9{ZRVz7=0m{7D#QxYwnQhkem=~UO@-yc1!xBH!FA$->m&*{ zl|nF`MzT{QBm>)NIV6XgU`RIdortgse5W;@NV;lSAV`TeYzVu}aiKn}3ww>muux=% z;vg;%$$|#6xTCU!5y8>N&DJgbNn(lm41~=b#Iq)?$*xzEph3x_o!s3TtFW zEhQ7H+~I*`i5rpmz=`sQrKC5!LIlD*O)%USgu#m%X;CYJRf9-d5k_T6bwq(sG)(6u z!(wS7JcHxPcvz++Y}0rEkwh-cC5&93B4=&kawVI{Zs}5GEsH9J*JKiD0fZ@uDj!~u zRlu1V2~*WDoj=m1d_c2U#H}!oP$=D6qo@t_L@TcY@>DlmR+zMUH1emWbxl$$D_ay+ zI<*1{)c^{MG%99T4Kt{Uf=OBJ%SP-SkIEu4ai!9cO4U@P)IqmWtxyLwM!e;$iRbKV zmNoM%)y7r2IcmY7w9e?}sa3&9t_p+gx@e79F&U34%UxCh_*EjRCrAkSpjk<%o@&Kz zMhRT5iOSnb8Aa-))QkqFTFR(R4!%{vuA$%*%BZ3$`WX0H4x!Pgrj$yZ$w>80N-(dq zl!K^RJ!IZ$qqg`dy4goHj4G>4utX3Fk8a-X z0v*c@Mpl5bL;cYMa#lsVY%|C^IF8q?YCfs67|h%jAt0v3Axb7)G5B+M0_3eEzXtYJO}{4KMa;G(Y9Lsn2rCU5lI%#2 zn%36!Gm%w_0|J*+H5=g*(-DQh=~$##ksw;8aNB^QtBkrfET;8U3y~(DCgDc<6oUTb z3N`Y%R1wm^1dU4(3F>V2MYAMg(SXXO7DhDSa@7q)q-4;6+GP^qk*FeJlt-*00XSa# z2y%q^(ug)9zAO>D zy<~NOf|nriyt+N2$!L+=OeYyt7OaH12N z)i|JAs+OieLGwYmbjB8jdZ|;QS4y?s*n&L(Wz&}416G>Lp_H##)3JF|JtmVR6xrAU zsgbr~HPiqztprY*!=8`L>x-bIm19O*E=HHH#Y+6bmY-J9gf)v`rS)S|dPaPtrzK)N zA#PU5m!y10Cq|DKxjA*us221|n$4|S0acBsrp0?8u4x5D@d9{i%S4)=RPaGno7GLl zLpmE+YZ&-y91z#$;xvK@O;m1NBM^bICXVBAtzH1qT3X!G@ZvI~6r?pdv{E(DOf5+{ zMro{LSH#uvu7-f3YOxM4j!;k?8Ehsn*nocqf6W3#RjG(Hgf=Q3juZM2>XNZIhnoPQEec&$hBXCFTbY}Q z^DODO&}LNf)duAXS&H|F+(>KV7UM}{7W6ig(q*c|UGhFr2hEKwuEw4AMx51gC`OXo zys-n48{gQ~FM;IdBNst*t8&|M%F~bM)e_k%*ltW!$UT4?a5bpD(i43n;~n8GrsE{o zTgF>lo;Fu(Ga$YB)lB)^miFeh7)>Y$F8o@Df@BL&8sZ zaUpncqAd+hDI9rlOo_=PPjr>CghZqO6;28LSC>ScD2fR6K&k~DPLrt0O$MpRkeJo# z6GBJIXa*(Dldg8 zO#y^CP`pK}CX2BQ&Rheuxq6}`v2&Y=hN_l`kevjx(*kiW5AvKGAGvdD_GOUgvS82Y z1epA+KPThTk}@+r$rPM5=tcq^E9o&$gF`n9#o3WUhrprhNqNwo)eAf-xt^bt5V)+z z6(n8uv_+WI>G^i8RH3qJ1@3uWfhS6e!KcGPs?&s7d`U8lrcD+TmsEgT7tyka8Pl9u zm7FE*Vgd|1ziA}cQD{+VOzM(VgEq+$THa~fnv$4VqgJa`!n2~C157(VH;^otT%g(c zl1i07=}i)HCm44cvsoDe-!7bF$rtb?J(aZTqDdMVNfyJu}rZ3d|$!fG> zyD8ZW7kuk}O)6oCr$cv;~K9d%U2_ajUmI>@!(D`)gIZ*nn3PLpxX5X~Yu9TYt__BUv z_L+5)uX;} z(Wq9b(n&3mCY2F1CDf*ub-J{Xn6oj=BkRwnHIk;ZF^Uup8#kRCT+LGoh zWZG*5`;TyNao#L)Y$AFs_oYkXoY0@{iUR3X!fr?qT|AghY0K&`sDL487}Lek zG)tTpy6qz$aGsk^FY;611ZF`D%%!KukrLSPmOu&|Ie|j5nyxn-%8?crP)H1oG)LP^ z%eAdECQ`YgTE5&QXv1yy#dJZ~g&WJAv{ShZir|dCpN{dvs*HIxUC=CnDL6>4;H=EN znPuwf!y*i1L7{0a9n-Gp`}##(0>0q%mMl0D2B*Lqq-7iyA5RFzpcs6?wvla<$q*QW z0x$;`GTe+=pwJEox=EQ~nv#Sp<1nc*9t)+#w**2Wqmvs9de8^e8Ii*R;-GcQAhd%? z=yRLFCA5J)Xc3%s2)*DCE}DFqRkCUcgGK1ixQP&0gh6l!Bj6DlGO;a>&|rb+w2c%^ ziPIT@r2vZznGB!o7!7KH(XJp+5uCzoh9+<+OW+meGBxNjSHLVBX@xk^ghq2KT@=^k#9~b7+H_pEX~P^ zLXm}@HL5k%CE)X-I(9ZrhHy?+qnggTl?VsxP@$BV)EJ0|tgKT!57uE>JO|F9MOwAX z5kFfNjs(PkegQ;84nIS1B=DpU3ZfwE67x0EY)x$d|4t80aV2@n2OD;TvmNYRqSVF`o(Pb9a(V&WJQ}`@IPcl4%muk zWySd|TQP}y#C|Q`)KJ)g1Y5{eg9x0(tep$eB0uM`3v+8G5%i@cP?*MZJTYCZ7Am*g z#gVzF$W6fp8qJown6l3*3^{$Ss5+}JW(9V^NMMXw({`_2?66D89Ng>xi*ZWs(l~QA zX~6bRlW|&JwFPo2tsh**Ajpg|V$`mdTB5nSdgL>%ktyg{Cvr%a&aqS(P#PtUk<(ZN zsSz{v3`)n8shsmDr_B{;U6TT@q#&!Arr|`m4uT^obx4b-fQO86)X5Rrppnung6G%; z*Rh>rS$&cLYHq2HQiDvy$}5aTnOtNd432r*QqD_wgncMwuYmT*(khKy9RoJytmS;F ztQpHQ^G>P9A>2|Q8*)y5S;_|ek*A|u80v^-Y$=&o>%ztZmBl_ZeI)S-M|M}a08 z1x+#rl4LyZ5G1!WNiJ?Cvw60v!Od-nk}Xsm*^*|Xypo^d^H3Rj-lS2d^7Gi%s5m03 z=1V+=pvi6JOJr1|Gq2?Xyj5@}n_B{9T3!(?X_xzK2*S+0xsy3JkTjoVbxf)OF^MD7FJXSAgwh8isx183t`-)w-jm?bs^02OQy_L zXoj1>snkL_95wmcByG9xM3l)8w+Y%x{@91)712 zqM%x~)E;mx6NOphGzx-hxonO=ecY#9P|V7MHlsNYmSwoG#9vlsLAY$Ib0A#CwY7rZ zo-RoEMG!A%ZFTT3%Y`W`&Cv$svQ^N^T?NuYxAnli?0|qN;x2)Q>C-J1)(~BzwXA@E z88WRE{7SQ&QB;bU#h!Tp&gN>t;h-DZ=9w)46Duwn7m94qG5KI*&K6tTtYHpxOjePl zo-VRwdKD6PY&}~`A%NPvR)U|Y zDsrRrs2&8(MY}w8*3b+{yh2Mc>goz{vMsWLr&-h5i+ux*(!7zT2^%hCj-tls1YMH? zSu+T}=9aE04;9r~zgWYM6jl5r7@LVAZW=k8CRnOW6$hFM2%BYIt~hPYZ<(7Va5l?O zQBN0x+D>uWHnKKrTSfJHF-J%pBX5&dnpUlVwz&ufC%qKmtri)j0Vte&-BPh&WS3-i z76_d4Teb9@oxf#pE}bdxM+CC z;WU;iVlzmbNa2;TW0sOjA>~_3Zf-znEBU1MQW7c5WT~X`fy`OgdZ5D|6FH#5E)vHy z5fD0sngAG`E~v6cOLbESoX$kaBk`8hC|;uQMRFu|cGYw;T@uA6x8H#oetQd~4B!In&@ zvok>S9k~41FkmGPJ>eCmU!x~Ff_hOP7nn5 zbX3qEiKl+TA&*zw{6u9@J(5q$<^^H8BGOUZOrGZYhdNSGLw2@d8H)T%;G#}dM=I(H_^1ON4NO#eb*(beQD>^G zYLMW7jmicYm9LoH(ouQP*oW;*;G-_uL?EP&d{i8&`zDpFS{2FP5mFUkr26HWDiZR= z^Ac^fVNmLIV5JJ=22fMOVpG+_w^Spz8KhJjsHs_t74%dW=&4+x6YSKmF-Qs&-YVVh z2SqhhRojErDn9^*Dg~A*Pk&ZYtw=HPSxwcfN>}IP8R-4f+-t5}wUNzNnc5i@VJuXA z7O!qiI;EZFE?Wbtm^dl&TZ+|kwNy>;77dl^l98{kR^5tvRbyMLHmj|w8J1C&)Eq;j z>J#>=i?CgE%8<~ut7|%szEfSUCRBN&O{XE2s`DDArdyptbVt9M)Cd(8)oOL6T1SKG zf|*^T3}ryFmPM?Z*skIREJ+>>`~XIcS(6zU+BD+SrfQ6iLNi@!b8YGcN!UJ9o7FF? z1M=D0LM^M9tIepV)fohrP>ZUJTaH29 zE>>7;mReZamJ%|umQ&bkwpvkBmuLxOk}4dvxYAv7f_2~p>!7dn)%@TcI87crDG$~{ zH72Q7)ND2~TuX_l8bcqeE%U9ak%y4b`K+s=L@im1gNqP1X!-eCrj`RG!BNlF%4Aql zuL<;}TD4ZLHEPXTv9?(2a0|6LQ>B(rQc{yOBQhxDhBWun|l3r)lJtDn1C1*I+YRkCF!K!0* zc70GQ8hrYIZnmz~azI#^6VKF+7S<37Yz{#!xrb&2^u^RPWoobxYk|x7KZS zvhLin8+>(7-Cqxa;2_oIZK3+SI$YOTsQL_F&J76sg2Sn7|%|uqsa=mI^ zsrTw}X}_+K=q-aft+7_8H)!0TYE=;uFd8`{)}V8l4V}(T&KOqfERrjs>^+fyWugYZ!I9yOxsu<#q>?l+vT2y%rU{W;Y$3Q+vTT<%^!gRKyrF2=RLVw; zls1TlrlD@YOB;w2eRYbbZ%Ay0hOsg2;8JG=3K9$oTf^RPG<3w0O;0!*ZIcT&-`Q;L zh6i+t0N>vTsR9kAIM|3Z!VRj?=7+Y#3KNPq5{-;9*)R$-jdUZ`XqF?EY$MmmHwukn zqtpls${<=WjJ1Z0*K9NzOs-mFwBR~Ao{;7h5mmd!R5ayHRa4VcHVM!(v`vkuE!Tmfk(3&mO1{HrY?_*3ZP{RM4vaQU zkXsYgMQttFY>4VSJ184Aur`8C2WT5E@HV_nPcx+OfxE#M`kO0iz9iJNYr@Sr0|f?0 ztQl>_!Q)6Zlg&(1D@r%B%^b)a`DU?MZkC#>(n_=1l=ExNdb6o&G@H#s;95SI2ttra2W5QE#9>|zgVq`hEil`x_8b>RU)mk1 z)W&G@tTW()%(kb%2#JX2+Vky&_H?_`LhYnZ0A2_m)DTIV+ZMIOV24QCa?nGRZL>qx zE^Df|s!g=jZ4G!L0*S7zZ!gFVZDZTiHn(kUOIz-+w(F$5O_5}K&FE;mKpb(lt5Uly zZC&ywqAS)Jp1183`oJLxw7b$^+nb(A(YPZ{+c7trTyY0pHGAJhf_6kTQB677oXnWIZ?P*$v z)}Xa%U7Cevr7hATG$swBsc4A7W$+k$hJYbth!|pqgdt_HX&hRbmZW89Q?w7U;A{cV5UcI_}hfB*0U!yHUQeSj{YYgh#9{%yP+{2gPo zSBB%mJGXs!+quKB;d#S%4|fbdzU@5LxvXcfZ(-lWp2EJ0-GSYXJ%~MkJ&Jt+lkK<^ z9j9&3j?qrgE<^uS(f;TA=hNRqzn*>reGh#vOl3{c|M{7-@3H9|`hDA;r+t^UjXw6j zK700ScF;dczm#zf{ay4V-3>EaW%?vcXI%>$8Ar2T|NRkXXlO^BRb`b}J9f}^Jp7-| z`R}p+{&oNJql<@^3@;sCHoSaz#qi4ERl}=?6aUQx2jP22A2No_AvR@sL;cV&G!9Ke^UyN14sApG zkQ_RO&Y^4Q9(sn}p>OCP28O|5Xc+#_?^h!Y(jwSkhz!VxOvsEZ$ck(TZm}T;av~RU zBMyCbO0Sh>*x?VjEZPoPhtPoewKr_lrGLG%#%40;&-3;Hbj z9Qr(Z1bqQLiXKB>L|;OWqc5YcpeN9i=&R@{^fmN#^fY<~J&V49zKOntzKxzk&!g|4 z@1pOae?{L%KR`c3|At;bKSDo7KS4i5FQS*w&(O>0-_a}RRrGW83-n9$EA(sh8}wWB zJM??>8u|nJBYGYE3H=%U<$wJPj*T53J2Cdbv75#=$4-u&8aq99^VpfOTgGl3yKU@4 zW4DjpG4|oHkBohE>|Sp?y>**SM}+!2gV*8duZ%4V-Ju0%h+efJ~#IHu}8+f zF!t!!V`E<&`_kCsV_zA2V(iJWuZ}%6_O-FE|F7@=pO5$d=i`gVFB!jd{Ic=O$FCUQ zK7Qr+RpVEWPmE8FUo-yx@oUFFFn--A{nOAmcbqrQ9~X=Z$DxfhE*_VROULnX*|>aMF|Hg}jT7VQam~1PTsN*CH;fy{ zP2=Wq%eZyiHf|p$#~uI2<8Q;x!QP8qj9ragj=dkI1(`4*D95&AW7tL5W!N>?RWMV? zhdDwS%mVI!IYJK14yv$gVV)3!8A1(q3wfn)EUeo6lJ}YUpKmz2jqY2$PYixP_{y#e z_oWYoklj=k?a{gUTlAEKJ^9l6(Y;{{3Ob-2Q( zI$v8P`+`${*h2va``hCWRPXIRz4+wmk0rJrT0io@O*a-l;kn**DLj4XLJv`YiE$El zr~j1xV&!rOo?qS!HNV$XwYRS=?s;y{$^D59>i9Lc7K2~NhAUY2Z?5@JHnc1Lqxct6 zZ)T@qX!oJ=q4wiD{Rd}nz3|p2Zo4D0Sy|aT?y^Q6PJVUwVjQ~ncf;mv}w>?sE-^!iD-R=vM-b@%1P z_bd(jcdXD>e>o8Cd~N5gyK)eBeemG3>-Qesx8eHWiJOkybmvXk&F`G#oW6RGgq-ny zHu7xr?zU}FzI1ow*E`>H9vJQ_cG@apx4fB<{;#%quM?9_!f z%g^j02hMG-6QNtEh19OpZ!&oK_SUhkv3K{*w{G~tdgIW2>8JPJe)0nEnD<_vw-78f z*4fM5{5NjvcXCf?m%NWWglhY ze*W~5Ycd(T{(fJ-zv%o9W!%`m$s=DV{rs2<_Ew%sf2e<=(m9ztdQX47d0=zT>Q#lt znyXMb@kjSH-h207w*HZw-?;ImjhyGe0d?=oj>nvrxOFa%Z!Ykw_Mw0)l#1_*cN2@r zeDdz(18F={$<}j_>#60sivC-xw!!Ivb*;Sf!o8Ng-?;w#_4In~&_8aRJazQe&+hr= z(O;ao!F^q7Z{|z&)0^tTG3SnQzv8WT`pyAyfU$ml{x77|$#Q0$t1gKJ)P zUcOE1`jF>A&q|CHzoxcP+t+@(tsRK>Y+HYG-MLAU?{WUSXVv?r|2eo(|A*+k5FwDH z^x044{k3nmo?d7{3!r-FZ<93$>Zev943z$Cgv8xhvRp| zKa}`*;l@(9vwQir^^dGC9oje+Bfoy;Bjl>%Q;rGel}@v(;`)&LbMCj@H+x?8T;jdZ zd(h_!+zI@amx@wHsaK*ukN!2f9NQbaIrcBHtK;s3EqOBagVe{lK0UZ%*VwL4?fUdC@9v|!r}wz`+72WS zTyyBo!+$^g^hWns^SEmH@5euKlYR5tQ>Rb=;AYval>1)yUp?o0zZd*#>cx8LaQx`! zZnMH*n#KDMKha-0mbmr#+jQ*<>W$r(bpH|mx5QmHztH-^(M);l)YIf^{!HMpU^rYz zJe9mCcV13f_;lf~)$eujL2Zxb%o)<@_`2sjUp@M2^moy>@~129&N<7@_01DMJ>U#{ zJT{a5jPpL{5!bf-*S)deBcc1LV%(m(BdsX3%jeeyji-+7YF)9+TCVnP%%Z`M_C9{# zf}>|PGj2}6nJ?|U%r;=i7;rO!KY@0l+yx^owh zr<`B*G$X%A9M7a-Ti~nBr`wF~$(228H(kH?&a#HrlIj|e``|)cN?@BLZBh;s|k7j?7y)~bL`xO^e^lfwR z@!lJ&6N8z-ox9H2{rc|BgR%AEdT#yj`tR1CI{c%<&u;$xRK0wNlsk?%oUQ=%CS^)) zPiu0t@-wwZD$3TQo$q!ZU&edy-NoPatKA>mciT~CW#?@d#e;`tZhf==#*Ig)UvG|) zfAIV@zzuyp{1NJ4VrT8V`eWT+9sUrtZU2iaE$5%|x9&+sEc-vOcHy4WuJK4AojY<% zw$@bkt{R-X>)Jz4-&ost>iT;&u5-TW#v`8mYD3tv9sAm`nG>(<`7*_g|1BXS|J8GV zvZlEC_3|%UFSh6V<=r1X;y$){`cl{TJtgmuI*^u@?i*}7`EUMjdJ5i?6gTpd=1hV`wdZ&KcK3CAHuf0~v<_|@>fE?+l)GU)Ryp?7&0CIriF7#hF16=G z{KC|C^XkfbYUws>?HkAT9{;XqBJ@S-xoWgGzjkJIE%>44n=a3R*N#5zcq@YC?pu1f z|NcG0(_eMn6aP)NUOZTSy}DV;)ZbpbeDG4VyK%#@^G?0$y4Fpkj^%!so2)$?dw$T` z`9|(j`~SNCjrF_TKlHRiM`IgtU*g}7XEy)Ed7bOW?j0~o{2R|Nyat%lyvkn)JqD8@ zpP|l+Tokz^G8x$yTaUdMYs7b^_N87(9ZoN$-<5lBZZ5Z&Tg%^BxUM8DeW7xodOx=ubsI1gSTv+I{9w$eDVWifIR7HxW5??1fLDkDM{?f#M_x<-k;Z1A8xg~>HcT; zwGMsu*p3ri|DOVHpZaa;eZ|f4Z=2q=rCqH(uO9sADc=pBJ}Qey94|RO<9L^ENBGCo zFR8D@$>c)%{;W0kyTX~`a`g{Ye)n_T>y~1@S9|=y%ez0d=brud9K_e}z46RZ-o}rQ zz3b%X$;ZhtcQ^Q(;CmvIT}6c4{qFTAkEVfC##X+ye*US{vDf`~d9K=!diMmd*j;Hs zWxbJHI<)%Y&c*@FhWFUTC$2tmbTig@;^ucni_u2*&iq|RUf8Uq&H0JqlY6f^^`*_X z5A3V=GjC8=lCzCycOmzLOXU8U`#YiC5Q(`srOI})*X267KNhYmq|4{lTCMB4FDyQ` z>fiNR@E-?u9=v`1#QHPq*KQm?<~|uZc`$on|GeFgY|h1gl$cC?Gw^{zWc+} zIgu+PKaR3sKjZzG%L;U$aNL=VSY8 z>)$;5=OfD-OB(r@SfkqZ}p z*gD$1v3p_9-}`CrVT@n0f=(U6= z^>|*m$5$japE%9A+2c4b_%?O%u1`l60Fm2~uqFkmVeYlcPio)XwR87(_Z&L#*~8m5 z<~P9k8A9P$D{M@r-G^5Qr}74S^0gP-nnXB^1;XJ zZ?8-C{@nG(^}q7`(qnLVH|{@L3UPP;Bl@fU7mxm1L45d)mgyEn>Hc*o8T6dz&jp@L z-I;zhOO{`%QngPse!KMh{yi&?3>3S*y6c(iZ(65LyzGA}sEmIiyP4Zn`b=5eeQKTQ zd}Rp*u8G5b$_H-*mv>9FMG%PqP;JLiKRL6 zkK}3U#rUHsdF~JSUsTH1FCCDrlgC~^{_WFOl~|4G_RseO_I>K`cGBQ_#&yW|XX;9r zR@fc89Cp)};}6CEn7kx?XYSg3t?q8&U3{stOS*e`_u>s-T>sJf{v)p+x%v3gP3N3? z<(4Pif%KmiugD*$e53u9!=F6S-o&c61TQQ;Tl~k-n@_yZo!kfq&nY~VeygZ;%+`O9 zf8;1@|3d@s301LCF9rS@oTX+5)2(-VUq1HGt)C!CM+7P-O}u=d_jY32Re_ZAURQL)!a1VKPk?7d*`bQDAZQAEV9fC?yJ!;Zac%9Koc znUXrGlQxq{o%G%_GwGRR5-0Kf-RC}Q-Osz;Q{Hpd<676+<+s@^^9P#k_w%{F6-5@E zDcVv>F7IsUZ?tN`3Q@AmU1c2$2y-7ni#-L9VY0kViR*-mH}8GKJDx z{rAQS%6lo%`DnqD0T}aaZ`*qs~#=Ac6cvH|V+Em=x zrIg$)kF5x;4{k`wlecWrZ=8HhJaS4j>lvTA?U?$(k9vInhc?{kOp+Dq%C z#Wf#mzwdp;x!qef=4Nc^yx;gpNore36*Kafr$nbEC(AX85!I+VRNvPA`@oG7uPQ{X zNArf(gOgv*eWY(w)i&%@b!yX8kIM@Ay;{0lD3{SiL%o$vit)kUrqI;tmKhOM^~LCu znWh{r=YGfDv0y5Wk-!A$oCkx_g>_H+4m`DVpn!{x@G zG|HAQv>Ob&y7%<982RJZCalWB)swW?{LO++$z@qcy@j&BC2Ibp#HA^M*&}~CRU(+x zy=+zrv~dtKRdyQ4>`0+j?utWyx#b1fRAIvL4YkgES-IQ)ppWm~p_hD~+pXXT8*ka1pRYJIhZ~q_soS2u2jEK4%B#^TJAzdrc*` zOMO%Ap?NXZDdub4C~~TtPUaK=I>=IRMB+nbM zDk{x_n_7EJ^;ole;KD$*aXZ1Q`$TXK-B$fHeuNxc(5}Ix?hB@p) zOVQ?%Q?fYqlU8rqUsN+@3M+t<&Yk7G$bX(sDj4H$6G@6<#k<5-l3&a3l)tYIZ18Ko zsokMRwf)fs>$LCk?at`^(s*v@wcnHKmW1!^p^8$Bp4%7F-d;iM}cEkerd6 zD;=U^H0!nNbWl%k@BZHAp};XO*0Ko~=C8DT<~q*y;$VrSwnUlI^lP1H!v~uX683;LG6!~+4K{o`!#=P zMB}^X8j3Mxu+}!NfOk#iQTIx*UE`viYzw3lC0FL2DMXS*hS?;bG)2wot-VzCcS0+T zcGQF^pnOO71C-^#dnn>HAMNArtTIfeZ|i$f43Z{Xm8ow`IkW~+1468@ovncqEHjlRyJ5ekuzxp zaM|xwr`nfyeAPu_*s{d=6v?_$M15=hUHNIl9mCIqcgGsWdIX(yKQ&R>RuzfmU5xmO znM#X#u3XkIr0y8I-qbh$9ksIXM{#~f2W2zmDh)&Vnf{D7Db|(ltyo%@pxC7JYJ<9U7X(D!3+$1KOk=S1^gmek8!7;72Fs}C7Y@H2(RLhq{dnppK4 zO_lapo40YxCn*yY^o*?gV0&phByFx7Z(!^G z>u3D`+f|eRO>v_5QUWNUlxRvEC4rJd;ZVRsFN&Ks}(6`aI)3?&UrSGHvNIyZpM!!vGcRZm#rN5y6N&iHL zGprbn3>yZ4;mcS7ykrr;4wl5oWMl!C7mHB_Tw7A$-f98x`D3- zHZnFb_Ag0++#dsJe|1Bc+L2e@fYJg1HnWx!{ydYG}D&p#B^tRGgmSL zm_fjxMF#GyWTp!x9ayj~()qw%RmpVas+dZqo;k)`#r%@_1#>fVEAu<%VWz$M%GfRD z-zCp#o-rRYpE5r%O@K>^%vuIqRMEgj70M#9K4Vc>11veKAGn)pSW4hu8Uk)5Ela^_ zV;NZ;tYfS-tevbcSQ}YKSjSoGSQ}V}Sf8_gVC`jHW<6j%WZAME*&kWYSWj6WSa(?w zz`Atky@l1yo@cAr&Fl&G9D6fc&2D9X&F*BcV_#+e z$iBrs!oJSF&%VHR%z4Ll&iTat$o9y2&!zzD&aIl@oX{LFxDGrx#W^c;%7G21BS)Ll zowF)uBxfM!i=53l-{pLhb0}wT&cU3+IR|o%=lqg$Hs^fKrJQFu?{lEs#TH|h&;@vBsKE1bAlCp~FDj zvzhZF=RD^u=Mv`%=Q8I3=Q`&;=N9KV=L6?GXMyuK=OYKkwdA6?9^5ZW@!Vy=MG^>1 zBeC3bO>E%!pm6iJ9AMuNawXhyu9Vxr)p2LJeCh`3TJCo4QSM{zb#5Q`3im2dX)evP z%k#{$$a4o4jPktnyb$2Z5apHSP37&)`yubAyhC~W^6uqb%6pjiB=2J0hrES66wiw1 z%nRh5$@2xShFD-&_=it{&SUfPcsyV*kODJ79dH>m@C@Q6o|f0j`;xblcbIpKcY=3; zcZPSL_mFp&ca!&k_dD+e?=9~&&n(|OADM5R?~v~WTm{7Z@cani7f8vcXxpd3)_ih|C9wgP>@nu6JajRl(v_7xZl zzAxBYaH8N;!TEx71s4mh75rZCs^HH8E51A5jc>>I;D_?V056^hXmJYA_^<%`EdsoD zDqqf502+JmTnm2{{~-Sm|2Y2)|1|$1{~rGa|0@3)|1SRy|1tjw{}294{%igV{u};Z z{7-ySfdwF$^95D{JAt!+1i0&Pz)+_NvIG>tNoj@sQ73c*mf^LC9 zFevC0%n2q16M|KOb%ITTy@HE^1;Ks6UxJr{8-g9eML;SGg>FJLAd_u`0YVR!QFcHwb34qy^0TNgz>=Ql`whE_&ZNh2cm~dP;B>YO) zBfKNrDZDK_FZ@RMLabmVLhN+#ej1a07U^4(5;h&V}+fC8w*DY zrwY3Z2Mae8ZZ7<}@MPhM!gqzo3lA3_E!hiHii1Gv`}B7ae!CqD!K)qCKM1qD9eB(S_pUqU)lcMJGjvM8`zaq7x!i(KFFYpe=?KA&Z`i{uI%Q zVvDkiJd3GCV@3T%+M*3bilVhe14Ug$^F`kR9#UHLL(!9>14T!R?iHOVI#=|z=tz+> zAQBP94#hrzQv6Kp0ysunKmk?(x{p%qD;_N#F8-qU>taLk-r}pp=Zb$UK32S^_;T@~ z;+MsbiY@fFi|-U~6x}O+Uc5~Fw)jo)tKtvEkoaSC>@7J`va{r3$<>nEC2=JWOP-XxDEYJGU5Ty4S+YdpBOyq_$5#MyD-^I= zfa3z3);}03uB1p(Ea{R|OTLz<0W;Mr>5+UXSuJUod@p$}`9|`GWQXL5WT)i5$y{klAbEPQ2MC!*V0g_y%a9JRC*6+ zgx{CmE`44~l=@2DrQTAE^k`|LR4L7uHUN%>1t^(HX@s<18YATbI;c>}2Mmr*S|;5t z-7GyL-7h^TJum%1`it~2@1*pGbdU6~^egF#vO(!8>5Oz#`i=Ca^sy9H=25mNwUoV= zzLGwYnw4#nE-8B|bu9Z`YFTDqcCgI5%%Lo)3UIG|F0JT3MT{Rn{k)kd4abWS`5{%Qnci z$hOP2$#%%Tm+h4umHi|;FS{lCL-xDuwd}d!4<8vJrLAQ#HY_2qr# zQ{}qy>GEd4D%6z^l^e^Cl)o%LU%s#WQu&YNH_A7cZ!7=a}ZQvUxBJ9su->)1~fn;-~;+AMl0@DwO72aaH_Pd{I=p)#lwo76-O)n zsJL12bH(F|a}_^Ue5klmalhi%ir*@pRV)WHSfils%upi)mGIXs_d#ws%@)3Re4mq zSJzj4R_$876iimfg1Krsm{Ojs9;)6_{jz#v_0H-Y)tjqtRsU3dqxwpW;|73zVmq9j=Ep!_S7Aydrt9QU15w zMDarYLH#J&JzCm||ElshCo1ReYn^so161tvIAOrMRd#r?{!Oqj;cr zr1(v-vSUGkRGKT{N|F+%T%yD)eUu)`FlD$hRhg$ORmzk+rC8abY*scZ`;|S)LFFpt zoN}x3JLN9re&t@}KII%(fGv(h(RD*qkPor0ZZ)0*pe?xskM}xXy zs-d@GZNs+>>l?N-oNYMT@KeKuh94UCHvHIdvf+=0M-5jSJ~q5*FmJSPv}<&0T-NB< zNNyB1<~9l%^BUQW%*Lk1md5VJ*~YILGw0VgZf@MsxT|q@;wkfPBu_?DHy{WKC)Ff@1ov&_cY|=Ctn#P+(n2%YtP3N1gG+k}F(R8QjZqvi2r%f-KU@BXcr3#@6 zQn{+!R7+GLDxxY>MN>7Y;Hqqul`2b>tdgt5s(O_~RjsN~m8&XMv#JTzysA$%qnc9n zsD@Mnssh!d>L=Af)z7Nas&7mRCa1d^+VMIAS;2?=4uD^Yt=iIi`rWKR^_cG zsD0H-)nRHsb&NVoov3E1scN#Crsk*x>SA?{TC6Tt%hj!Fqxy68CiNQi2K8$7I`t0q zcJ(&(X7w)hKJ@|hkLp9}%j$FL>*~AesOjhGSL!$Fx9SgSga)SZ)HrD@HOZPx%?eGR zCQcKgNzv44ax@f8t)^5{siA6$G{c%M4No(m(P*YMyEU6NYc=0$j%oI3HfUm+*J!qA zu4{H`<~3V2mo+yu_cb>)3z}D&I~ucQ%VzIpOtXD+K=aaOi)O24Y;#I;NpnvLTjP7uv=IyoEAZgu%)y`+9GLbXwkQHw17dEmd=*m zmXVgZmf4o6mbEQgTDG_BYT4ZKUCYjvnw}q9j<%d^`L*Rj%bk{oEl*lrx4dt;K7r7} zwN_ett*h2e>#4$J7nYOO-ssMTm&v~AiBZM$|_ zJFK13Zqgd*8@1Q8542abH?&8zSG50N_6$QR-HlDt<&oCx>dSS-RHWsI)QFj_qA@T?pxgtx}Caxx&yjHy4|`Hx>LHd zx+}WNy5qX5x?8&2x<|SXx&_@QorxZ%H`ANzE%nxVwBA`y();Pd^+9^Fo~!5R3-oz< zfxcKT(wFMX^fLVleT`nJZ_qdE`}9Nl4f=Wg9{ooB9sNE1E&VzD8~tnj2mNrXY3qXi zz5b>i(Ry8P(RxK6(i+_A+#1*#&`NHNXr;9#x2|mUYjtULZEbIzYF*zt-@2xCtkt`< zzqPZqyH(x#ZEIbtymeJ;SL?dgH?0nBzqkI<`mxot?Q*MC+rid%t>$gFTVJ(Ww_)47 z+V-`Ew;|dWS}WRo+oId@+S}TcZL+paZIx~MHfdW*+p@N*w#K%Qwv%n5wq0%e+veM@ zw4G|(({{D(OxwY>qiq-4R<~i=7u(*nxwN~sFKb`g?$qws{&yR>y{Mhjp4J}U4(rHl zXSZwHKW{g*54Lx=uWPSpA8DU%|E;~VeWqR6-rR0%KheIs{dD`T_A~9jw%=%f(0;xB zeY<6cLx)wzr}hu+hz@Lrdxw8VTt{{Xo5Jc4bVxdCI)*#ec6{BjzN4q3x8u8xEgeTX zj&^MAIMLy4*wAsI<7UT`jz2nXbzJLs-eKQ~=tOoxou-`&9d?}-oz|W2J1jecJL5XT zI-@%Aoup3pPGP5@v!OGqlhRq=ncG>~S=q_$WOf#HmUWsL)^yHy>N~e|{?xgz^FZgB z&WmFkI*)Yj=sebWv~y4A^UhbDw>xbO)`m}=Z#&<0+8EAt+8LY;P6n(2V+b&W8X^n? zLzE%OkYHdKxCXvKWRMwjhGxT@L2l3(zBSYu^oDW6kYTf7(y+$RXZYN()v({N&2ZRo z#BjlI*>J^h!|>h!>-yX9#_-ti$^h>|by;>fbR~8z>B4vUcKLP1cO`X2b%l0?cV%^b z)+OxXca?M%cU5$ibyaoMcPYD?yIQ*pUEN*7T@ziayT0!FvTI}4magqxySw&v?e99! zb+zky*Nv`6U2nSn>N4$i?go{9-5%Yab>q83yW_ig-Hh&(?zC=ocSU!3x2U_lTi@N* zy{>z8_h9!I-CuT3b+7F{(tWD?Q1{jD-@9LTKkB~U{j%G!=XUqq?swfcyRUVlddz#= zd+u~Q_n>=Rdc1mqdNz#v^!W9}_7HpGd$M|{J(QmGo}3|RlCd2d5+Q?I_atGB(kySJ~mzjvfp z-8<3ynP^k*`rduL+k1EPZtnfA_jvEY-uu1xdaw3=?ETQY&$B`L@3ZZ*?nC!c z<{kP@^*Z)B_euIH`fB>>`gDDheTVvf=-b_Qy6G&?E9>LNk6)OX@5e0NWXu7aDPUBYJYlvRzIyjt)JUp+%N3+?Jw$Q_bd8q`_=ur z{?7jP{lFJ{j2*o_HXS!+P|&;hyEY?kN5x7f35#s|KI%!{lE8r z>bD#)8*m!1A8;FR81NieI^Z#Y8t@qi8i*Q*7)TyS7>FIn8b}{V8K4a04&)Dr28srX z2WAH52i6X38rU-M{lL|M2LpEpej9i`&}n=#U}k(j@L|Bt=w!qgt&K~J&PFRE!5C@` zF-92w8lW0!M!Jzu3>FQF2c?5`gSCS_gI$CA!8L;$2Dc2ZAN+Rk zo59_K2L=xgo*4XT@XX-F!CQlO2CohNJ^1I~+rcG6i-V3s%Z8kW?1uP5xkJfA=|jas zX+xt!aYLCyw4s@yv7zCi>7l%#(?h$4z8`urWIOy}C~0`bu-hF6@UG#D!%tz28 zp(B1HAtRWP$dULF#z@i#Z$vmE8sU$WjgW?_N8}^Q5zR>6h8l#S7jw#3T$M|CfV}h}gvD&fnvA(g1vC*;dvGrqLjcps-KDKr2o3Zc4 zc8={D`(^B>u@hsb#=KUya{tdOQB-xa|aLB76cjftd)Kh?z*4piX2?$R?^L zswZkD>L=jb$06f)P<>=Q@5t>PTiY&IQ4w$_o-)7Z>C;Oy_;H?LQK0(yH78j#!h=r z3h?6r|(Z+n7%U|IrD1z<@Aebry0i?iy4O*)C^(jyF+Xz3|RZ$MGNx=ul=9p(_$dBU>XH|TFd}jCV2h70)tr4;$ksK zJxCkK2>6~x!8N0hFlZVgLo<*yauqoKp9Kl62CrQMUibgbqU~mI?w_%RwuAluB)V@P zSn*D1HT3}W!s|x}vO5N@Jq86GI0d%<9@sCC7jzmN|HpwtXTaM3-7K13g<7aZ zO=DpY^uN!dX&S7jg$Yx&2w~sENMY>f^{{md&9H*kU9d!0AIyq82qP~{!eaZ@z}~60 zz?SuX3tOx_1p9FB6fE+yUtv$z-Gsp&-iNiGehT}u_brSa@(Gr9+thT!BHDD7jahd6pOJSy7+6dF|BXOp!f2NscJffRgCg+$!Te+r=<3dxBQfdmZ%1sSt zYfZfz<)&U}rRjm=YEukGYYIVH({&CVrf^i3DWvT-CBu774^$7D5|JaO2aw~YaA?95 z22FysDN~i-=ccue>rHWu+e{at_L&lbel)%B{|~@W#bc@aIui;Cb)v!=FEX4*zLk0UpYOn}LpavyUE5W-Jpo zvu6?BX6(y;X7UxmW|#NJnYn+RVs_~@!)*Usf!S?|#0>RKh1nr}t(gN-VK#fA#jNK{ zhglw?*Q^k2G<#J)X?B~t%4~jMgPHw~?PgkNhuQkFJ!bxa2h8|ekDE2ko-^AhyliHA z{+1bZ;-1-r|6{Y9?&oGu^(!-@!#gv_rJu|aTww^|0R#dGnIn)|3xpPJg@E8Fgz*mt zgbUFP5%ds?;FuE;kkJ=`d>4qYpoAmZ-;fclf2SjuTbPLBt{jBgRe(StMTlEv6$nR@ zY6R-I91;AL24S~Khd>iL5I+)o5!eJH!T~;lz(8XNwErZ+K7JPA<+=(1kyj)9U|%9o zM>m2G>dgoUy#;}Vwt?(GpgG?o(qVfLBdZP|s>hBYwmv(97;?FU82jlq;+5GW1RnYg z!SQ~9xQTy{_&H$_5q=tJ4$nZDlTo(j^C52LM7z(-p>8kp4-O=A%fS`qBv_z%4m!*{ z9uZ~k1&=XrgOkl)w56CsP>MMmm2M8fGt8I8Q_T_fOmmhU$2`-LZw{L3%^{f3`~V~Z z*NMzWAhEd#RARnof1SD7S!M2r)0yv??loW6GG^X_nm2E}_qF*O^cHjL+uxc8#_u*a znLlXG=s0Fx8*{X@1Bvq5vdX7>v|L!u!v5)Q>9A#5TN zf)bHhC<*E1m4bvy(~%E0(n4KgVaYTk-=yc(m$;QiGXy-{Cz#h zv%N#eg^P2@J6>y%j}zA;A;d-`1-T6gne9NHIkF46wC@mdeb))(oiEQKVa~rIO`wa& zr8n&Y?j(NLU43~RZV4n~yTJ8s00C&E{ zy@4bPuZc7Z8)CKv-iK*1v!8E~zQ5GMHL${hwXxnJeV5w8*-dXDM0HqTzwNU)xG-+P zMa)_x-uuGBt8Jad735|MNV~-XV(+lPdVOcnX0pp-HMG|PO8dbA?RCIH>u|(EOFn7= zw?1j%44twdL%&#fY0p@YKVG(Y)OXh+l=Z}7;`Vck9@Tq`B^HYo$3IzErk_Jw+94b* zpY<)V40H3b#O_{h`9>LTd1F4w@{iY4%d0OqmK}+F%Y;9~mT`SmmT;ds%kmEzOUwbC zWxvQ^c?i{K*?wuvGTCIxa+C54%SrYoOWNHXmdWJrEv#(s^u%QJC=^|4=lCV$Ci-!@0Q;{&n-(5{)R-mR2mt+6n?O zf!SKYP3)|^jyqXZ|MZ!a*D%&fR7SGOa$R9H3I$qeT|=yTredtNuTQoz2~4+Yy3DXT z0*7!? zxtXXah=y9U;-St!d{mjX2xWl8s3WUoC=yhOGV`rN;mnjM3vv_6+gXdkmbRnJv<8%& zR}ac=jS&Th22sZ1F;sfmG)nKV3iYe^I+VZLCX|-64K;-P76oJNLfIMip-jB?qu{F! zp&}XKl04W9{#3w0@s9 zVZHLy8tdORo2`d9-&nU%c3ZE?+Hbw0>A3Z8PtRK~$+>2oe)O)j(e9x&j`@dmNm+@>m3__dTM@ns!rqwoRSglQxUSSgsHQLy1*4ku{+iVUH z4K@(H$0kWQVB_dCVuP-mvVqXkHhO5*CJnaA#tgRB20{MP#`M5?8wmPmV5m(tNNBT- z7i_ByWZZ58k$2cYJHNLnJo|$UCgreAec(wO=&#c@-BFipY|U=iKs|SC&g}WkMvHxF z10kN}3nVFt%g}YYTaK+d@u0w)Zyp+iC-XZIjkV+8#X=Z;LycYU{9(Vhh*OY@w}8 z+q0%z+a-lU+x7&pt?BCu+xgFwww6gM+s6&9wm$qG+o8il;9kSF?a-L5$<`@bh&*j; z%vfccVEEh?e)4PEKGYUlv#-9hHBH!UyBfRS77iV-E$ujJYl1pqTg*OV+lans3xh7% zuDW>(+~>CKLGpdup0wX=O=wSTwWcp@A^1yM2zqG?r@gT)IIv)QM!RT>UIjy2j)RZ5 zJ!tfnYf{;)52#NodE`73efWAo}8$QRt}4N$9vbDta%0gRV~(ps!m?&<;Zt zXg|j~^y;1_w0uP?I^t{(+QNSTO`{E?k%loeB%MNENMDW4fPH~RlfObcYd4^aAM8M1 z>e>rFQum{snMct>ey7k-#~F0;+Dqu$PB+j!&>gfX>H)ga?I{|%`w|^c{SJ-Len5ZW zY+^@RXKn|1A?>uTR(2bk9PQHXxZ9Zrdf8q4*4OTFV1V7AAkuC%Eza(NSF# zv+T6Bbi3|ZuHAa5z;0ju!HQX>_*^qc34Pmha@ZQ&`^UNI$vX#XsWk6 z{&$bv7psTtv}U7rL2c7^5PZf?3(eXgE7#g(`mVS0(QUE2y#9MT6Ve{L?9xMa#-yWm z7SM4!!|u~|Wax~Y9y(_Sft>BUYRALev3t1fH@m`s7j{VPD?14J+Kznaot<>mM?2_C z6MIe{(mpW5#=fS&#om(rnf+aG{S>>-`h-qfqy9)kWE*YFy92v%$Vab*(VpOdNKJEaPRMqEvFHxy`#BCn+B^rd9fb~9R*8eZuFRn*q1wU9Rqmh) zZ+7_8q0`}k`GCW3Ur#t>MbA4pnyqz!5MMaJv|l+~ao^&Qw(om~uxE!H#@_toAgI3J zaG?3R!}k4;90VaR9g-gY1N3(X4BP?Qt zW13l@BN7$jNOg>MgrI0gLvXyKD<{QK=}&QVy3BU8*~fQW$do!7yDJ@`_8Ld%V7=pK z4>gXCPum?kcJw*cE>1d57p-v|`nb{Yhb!MZsto%bhb)gcemZ}~al7XwNA0c~j!iBP z9Z%^0aCEu;r{lsR+({c@;UrA3c0zF-oJ?$8oo;$=PbwdC6t&us1l>O6+*K&h585okL0e&PnJ&XGh|wvmQO+T#_*79NhZ3bF|6V&K}Hd&T#k+ zXKR~X&REnwXF7Di*&aIN3>`S)Ooo1Rh78A?GoX{;q0YbZ_SPlmRMt)BQo}uGBy`_d z2R#Jq{~q!qXUOC+IR5v*o;X8@-@$c%fOG$Gw9r$q_7uF|GqC+v$mkc~_+MFkzUch% zowZBLqNmHJML(Ctg-Dmh#SE9lk6f3<{iR^P!DSKBx*W1^ckzOEx*$+JE=cnM7o78m z3)*B1JdpY?a(fcoa~-(HPLSg+jV%{kZV_*|yoc_&1fm|h*lT}x0pEj5$;T=u3lrVuISsIuBeONu2>(U>$q)zD*_hmO5Psf$~MNiuF)pC+R;*7 zp@|GvI6TW0B4>k#V*h;(EabQ@E|$1{dS36ka7*uswCZq86!p4(7eDM8wJ`5mU-h+X zm-iOemd$%yFa2@UHTCu>S0VSj>)5I*t^*dgU6&O;boF2Lo2#|ObJz90Z(S)DKDnx> z7H->*pxt`HUEGd-z0?g|=jr}@b4&Xa;?`aq=Y(Y$F!S+81xel!Td*Jn8 zA4Dq$+y5hQg&P@Cf^+{t$PM89zX#a}_8Z-9FSfbu`!wjbxVRc*n_ElEez!*pKfCQ; zyymv}?l*AmgWKYB3-{(l7x#C!@b2&42D;x`AiICs55y;0mOBLfCwb0uUu-FJZ&_?~ zfA?LxJ0hvey?N)b`=3#B?g56i?qe<++}}W3-GyI&=RWAL*If(kb5E~5;{N*8X?GlS z*4?D@qWkfLYwqXoJ#bH>J#mL{zq^|yz5ws{!aXbFtvdm>;LbrWx_c2}9?m8R4~unH z9*&T;2lzkBzvV!zqem&^0`~v&++M_bEPn6raqVM_$2%wqTnj=@_E>R@;-NL6fnyLa zx`zqG0Oy(D_@D8I*dFT^g&yy|k$Jq{r0`fY)p~fD=)wB`ATK&R78XZ6-p#J|IQ?<6 z$9|LVJPteU^B}k$_OR3)^GI0tvj=4Piw9D7)&r?M5Av%A-1V}@4{Psw*hBZhd;MRC z@u9~<>2r^;>+d}lWeCs37zfY4{$Aqw{4{oZ>q&;{JkinyPxM`lr~R%r&o4T9JfXY+PpEXrvkNxnX=a@A z)RxVAqM=ourqCL2Ul8qD&-Y6=dqVx&Jx!n;o}U&Ec`h!V1Gx+G3Iz7qVvF5p;DPRc z89%5LQ;s134<8v5kHHbKL?Y3L7)e}4^dWhzTVG z389oAB>-g-p`1`bs3cSostGlOT!JrV888j51jfMt%yNtjcnigtMobB&0#k#n#nxf# zv2v^etHd^78?jAT6;_P}${tJ;Mgv@kshAW@7KVf217jftlY~jeq+`-B3=9(^#0Y?g zFcXuD$-%HOTnr016ALh)xDmJsvoSOb7n_IWVe_#CSWpv&6$0O$2%C&e!KPxk$g#hq-CV#q!pxDUcLI3MPe+Ks^d6oD@Nd zBt?;;Nin2YQXGj)iYFzI5=lvgTy4UNNiFL zDVGFbV^SW8M*CW%QUBnhdM1SB#f840MdNR^~2k^*=n8-N?K z9vCI7F}0W);A*VIh=4N^gTZ3Ffj^Rj3C4tALNQ^Oa7+Xy5)*}q1-8j%;DijqL}Oww z7#tSojl<#aI3FAVN5qkEzBoVJGTd_93fxMZKP~_lhzr66<3ezuxG-EeE&>;ci^4_Y zVsNpzI2;)lk4wNM;*xO5xD;F}E)AEC%fMygvT)fr3XY1S;pjL9j)`O8*ti^AE{=oa z;_`4jTt2P<$Hxh9LR=wEgaZXSI5DmSC&88Cq_{Gi3|Ee;z*XX^aMidPTrI8+C^E6Y zo`wUaG#@+xnA1pjUtm&OhF^|f0ZeNC_yBw$aH|F5L-3)%suqrqz()elS~NZe9}667 zWPCjEt0m%-@X7cTd@4Q-pN`J}7Pc&WHlBi~;%Rs~o`GlLS$H-+2M;QT@c<*igAz%6 z0iKTs$|ZauUW6~g7vshF61)TtMyc^-cp1JNUxBa0SK+JiHFzL5#nX)%7_4Bw(6~$z$2T-4o=V53FXt%2W9j)tw4B1Q6~Wy2XijN1F2t9j z%u$fJpgTD;DKR#H6Pze!tjNiu5ZLlapRgQqL<%E0HI)^S8N^`3agt+eQvw*ZqR&ttxE8|&=3Qj7cij$hCpmTF-K|gYHG%uQxRuGmD zR+rMiiDyVDanb59d{_Z3FDIE<6;&8j!@;EcQ~ZMKIGO1RPHuvd6F_O?tOz7Wc!S~h zlKArUbR9fAQ()=Z{2ixP?D=5vKi4W~LxncK{1;$XN%NukVoP*|zr zh?8mLYC6xK9__>Z2g9@i^eIPVkhq~a{2(G%L(aA+PHIsAH@G4+n2U+yb1A9Kz0HC8t z@j=|WXg-Y;UKAU{jpPRTCvcOvp#gE+h>*J2w5-}l8Y7Wg8sis~%$3EaaHF__q*!h| z=w)8P231+9X}=57j1Ov#3kg?~8~hc)0E*>e zgK1nraJ)aA8{Dbcx@yomVPkkWX0G&{H;UXv6a9T-*>R?dx0Sq_SEGeXjN zxwHt-52XlFMrH6;Mi#R|L+V0uIJC5!Fj{IZXJuRzkHg8Lt%!=1(c&HyqdqzyyfPe+b1}uB2V9*j2HoF2@&0M${yq`R=o(54j~Tx*v?*s< zGB+lc7sqQLV`H<)WL`>!Z(stmDAA9ez+;mWc>!_JNqMPByi#s%dT>NFC5@%_X9RO; zQf?++#`Wi{j0yV;BrhangzmLaGl(lP;m;N6Gws zqn6YB1ByW}JwBv9fto}L3=0$o1PY?r#JFV%Y)(J|i^HM_^T?E7&Wc0~)0+|;9h^o_ zsE7@v73LME5`t<&)mcqsB{_m#NKfVP1I6T;$TZG!Rv|SVw5caj8-h|}GdWp2d>V(^ zoJI-EVU`5?N7I>pnZaS$FmVPZEkC0;pqfTcPUba-S+lBeP;-nB?$cP*@lnL5NewX97Ns20B5-fR4)%q~{h1 ziUl$;fx!@v;&`mIIF=xbS|G@v^92O|uoR|194QFpWj9B#Spq>h74I(rWL*lK4H`tb zfW0F{2?1dz5|n_R&|sz{JT$pXke5!3PfFs)HBj@}m4fgxq-&x{H7@vjl2 zWYq#DPYO&fRf1|kOjMnqUf>V}vZw z5}FHoK{-N2j(<>jZd7KTPzCzq3WWv2yrzO1&_U<&&lWouNu$d^SEKkCn^g@;E$6L_RR;aYFtQKn?g+O~q^Csd>WW#whQ6e12jUJ(OI40aR;9 zsx*|4?*qEEaRFH&{&50&LMSo6DYH(NpV^!lpQTFk&9BVz%V+Xd=7X;8SXIXI{EYO7 zq?ptd`3hDE%`b@^%Hrh(uz5NE4{i4u=0jE((^pLKmsHr5Yh=GME5cOclZ5& z?&o@5JgSuoZt5o(JJ+Jozr0#1-cHKuA>BKE1kI%OU+&g#7Cq|^e;V|65irLBm$B#X+HbcsOIs)p?p ztO>ZCKtBc!y~7ACSY|D5b5_0VGAX+$&fZHcdjQlV&loX#KjoCV)XUgdx@6*~2jG$~ z;4#RSQp+Hn9y6cz^GqhnI+K=}$J2nR)R+_#X`goynNCCL34BH~pI%I3dN)3)hSM$F z6&QFZ&xCOnXnQ)%0xU376 z1>&Ae&nI;0hQpLLr(0f)$!s!$`9)hAMjLr&+LET!(+-K6K<#Nq8cBQ87!db-5;vH1 zjF_!yPa02?X(H`QcS0Z}l_ml)F#8zLc}agDEiSvlX;TmhjC)a2Jgrq56_NBLHm*dC zv%$Qxl!~UCvNTY&g{gsg$t6n7`AS64DTEML&XZG0z=UQv5K^T5Q__mZg-^f|XGT4qHNTwJa607j-R|a#_@7bq@!ax=tlGniiDfBxPGP7lfEX zm9iTaed?4p#feF&(FHE0Bq1j)V;!>^Em8@Lc|(rAG?=Exm40T1_afb*{_|lGD1STWXrn?ni!&V8mxts+NXp6^9wPdh_9#z95zb3 zpa>u(AsSJtG2HI*KxLE(6*V~Qb*h2PH!GWP^3YDg>FWcT*kI|qVM8~;_!os{e?-y| zkNFqTGPINcJb-8!ILNRmW*Sd+WvGgmRGIlnL2@Dqiyd-}HD?|d;@${nQUwSz!6;CA zF;K7(uuzQAHSdDaOVhduA|S!(oTO-4mM_Q&3o0XNg0@S$0f8q7q}(N^M5iEpbbwwk z*!2-QOwZ^MLllU)6m5?X*tlm(W1RfXfgR9 zA_}InBRH_x;I60bqmokXvN)cMDicYe%3(|<3to+fPMRb(3j<{1E|E&kW9j5L!T~5L zlk};~-UJ1>*;LQWA7x=woou0S!d`6322+}C@qCxE%lXPiVU8PB{f^5=$MT;hE z6*?LiD|To>aX@2EiNUM#>lo#jYof>l_LW~XS!{UuMM~M0jxj=M)jg>gN5^cqt}5-( zeV_s_(LVDyV<09OvyG2VGcx5A6ISsUJ~P8iFg3(Vs8uGiXPzo9c?C?<1PowU$Qadg zj82lZLClP{?5V3V?nMS>Cea08=EhWcNlJ?gJt74>%V5GeNnDYU=202rR@v-Mube4~ zri(p-C1#2WhQ=ifMR?^RM#{uxVrE>gWaOk>tYR#xwj<@xm}iU2#)xV`r$f|?R9A-E zq?Va4>X>QeTv5a58L4tXD)*Y8h2mn-pf@lgi;)pVp<+&6KqhmXx9jxVWvD}hBdmsE zYO1N6#uu|r1J!RXHw%=%`CL%5n9~{!;Qdb26{*$pqN)~y{5azj1f(9R zRH2LbCglMOPK9(nqu$0>O~E-!-!kc*g#D5!GeIe_tf*#c%Nl;3q#_iXv*vj{No63j zC1LO>qS~Mb7zrLf<<)8fKFaHhLA04?tf(b~LO*7i5LU@4y~!D%mVA(6-ahRLQ5v1t zIvIeRCbJ);SLFVsoES>$8t$-1=LabpWZb>rCCoxekZSs5YC^?_gqDK1>RZl*sR>WP zlSZNx?3vJO0ujmziIs$-Zq8_>Lbtx+s;X5gnWPCmY#1u0jZ-plOp~CBW-FSIP|~oo zAxTkIUy|~;2Ud$kjMub;QR9}22u)CD^@Op!n5AMAM-6h2k*4(iNl8PPp=wl-s!|Di zGEk;6rldP11Vk5=r+mnycvh#?;+ibAKvGnW(&-CSU6_?m8V#Bz)uCpEd~r@Z;b>8q zi;=fMr=m+4-ASkTK{1Xx6^6#}HoWMrP<+>nuTRCq6Xs=VU;@jFakpWK zDr<#Si>PH+x&~k|N*IudOa_-tAk2zq0|oPVoEI0wMaqddr8hZ3!nAEN9<@!y$Mb}1 z2DB{m1t^Pb;BzV_y`F|w(lFVzvb+XzYlH?r zJSD>AGEohDn~SC^TQSzjF%72=SjAd{koUK94Fd<5`?Y0<1)>eCcaslsLS zYGl&Fw3DVVyD4r`h7cCNq%n`YG zLusCd<0)UR?DXdXrx$p@+`o$K*<|>V+<4mMG;VPnKoITL6sxH9gH!G0E@YbL5j)sYMZEY}_!ghb}kyu8+)w4)gk$g5RFFw+e5&CyI& zh-Hduqt27*`a6cIFrG0uLm9p=2djJtkYph#k%?vG`Zic1j9Q!eY=-BpWpe%muw%QJ zOWBoI3<^cX? zc28vI9phPAZ_*7i0Yx7y$s#x}EA&eOlUbQ&DYFdJS-)ov7XndsMywLgW~aP@>_9Y^ zW%M(kAR*5#WP4!oa!v;WKUQE|%v$90*(f0fx~wc~%Ubmo(3enUtB^V?@M(b}Ysgj& zQu}FN)&z`NX%<%Lvu(9GYt1@=7aI}UvkS7*lB~hUGY7Ltr6bED$ZR0%&7xU@4F|mn zyNJkEP*1ik@@Ko2i)UnRzo#uu7B9K*mvYrgi(>76_uWVv4B+QHRGZMQoW0T|;TyaKEL_%Yp zd4JuO2r(+9l4fSn1Y>h3lwvH&^vtj#nSrEJ{NVq%sl;gU6B9uFk-U8ct@Gt=%mqa{qR zxL9RsOovf=P1ZU&U=o^1P>`u(Ja(FG+r{V>Rr+rTjv6o*iRL zs+eco=CHI4d{$(e(`YmT))t_Jv#d$I$mUfLJ7s}c#>dksSsANhHLTxiRl4+Jaxptb z@{|LOn$>x_=02Ks=m-oIv2s?yX5EOJ)Js^%AZ5LXK}AUF_DPM+H|H3aJ6Sht#+3NH zl2n@5qQn!>v&*QCjT)S8&KWS1fYY|I2G-2ZOG4l+sf#mWv8v?IiVG?aR&+~>Dccn3 zVtoN4E6`ZjG~r-74lSD^1~!Lui4+L~tP%0BY9u1}vrZjC6ijvtSdR0cEXn%VfijKi zd^qc65jN$Saq{#N8iKXUIaW+Y*s>wZa(J9gurp}P6=pFu#YXK6%b965$u5a9Y*GS9 zb#_jL2T*q>&$2Cr#~)&&Y|lusE~8oRH8x?P8!_!56@u{yT8yx3eGSPZ?#aM z5G=3-wcTcj77|#bP$pvqYlJGy!SO<(FcHvO)cFOdp_R)QaX-|Rh=Oyj7&B*0Lsp9- zugt6RdW>hO<%DL58PV5s26Gvy@$w(OiD4prhq6v53Kk}!y<6u=RgO2 zHUk4QUYHR9J6@VW6{qb_$eM$6_PED`z`y|4Ssh|gj`MY6V$j5w=A3dU-gH#lJxAYR zBEV+6e4%25<*BmUK?Kw}2Pg5Gvyz3Z>HBC?_o~Xy|Ij>A+8$p3#ccP?RHDssdYLl`58~xS^aTj>jvD;tW_QN>zB) zBoIDLVy05^MclYnsLlZAldX&i$Nh3brk%6rDs9Z|k0`Shl~nARu#Oq>l~M%&LBIgj zs>&6KyH@duNVpDU&sHTVu2$NWUZn%X&t+hIE`4Bm8W2A4JX?l-CFTSqCk(q!o1Sx3 z#5Y|P*~hE1K=%{?-*Xz8uPy?&6RIv$$1x%BJIe~2BmgA0B59V88mDTqLdmBpQ_ys! z+x7^yWd4(%6J1si33`@=6n>tf?lN1ob2ZI#p^Lr%N-XSxRKJ z+M0fc1Q?a2Sqo-?JZawmb$_-o~$)}*PI-O^cT(J2M0bQf8a)phb> z-UvAq#g7I71b7sL9D*aIADvyLhX%%>GJ-UBlCQlUsJ1oQfs&8=j-8kf?8$(P`=&F{DB@}_1vXrcq{G9e1uikRKs zDYweYDyzt+vEm8U7`jwGt^K-1qyu=dWeRfmm&-+wuVqJo`CHLS!s;beN^UgsDtXsL zWeU@2OEzg$R`uzo#qz4kL)zwjrv+Km#>Y{=s)}hKu|^veV@O=5srGcIRoVYGWe0|F zL(i%8DYXi%(KoJJ^hm04jZ0efo9gDeM}ArrbwWTwsaIXD`h?dB+d&BmlLUY$O4f;b zU#5c*AdZG5UZ9Nn>Yh5IUN-oFBI>T&B_&O?&X-km1HaHy5yyqWdZ;dUoYqB?^*E44 zY2c0KbY)SZK5eV1^L3qqtvH*S5F!X^)e_=Evs3yQs;m*Iv<#^ z*6Y>!lrbi60(UebZq?hMOQqCj^;OI1HdRnO0Q%@@dvvV9YdBQn4Squ_oB(yI1$Drb z3?=mL1|VBxNP}l^Sp8y=&)Yy7SR?Gh8wL_=rO4z4m4Rr?X=yPDT2`}Kevm@PrJ~iw3?Kvm(zo^M~&M>$QY*+k8@&2NbWGl0%2o7rtyQNeA$GB$Hh@TCjiww znIRjfIOOP}-{+s?iqI4{%|#t$d|o@l)gj8B)XZ{L`y7{6b>w_(p5u%ity3fNEO3il zNt^O=F0b3IhPWwp+Y56YuaFaQMzNTaa0AC2k}%0Q1E7fIoPvu4^ggiZV^juIoSM^c zId#fp)N4WUZ(6Mf%|9vUl^Qt{XXcbDN@6u8U<)T9t(;D7=WHCfaNs&ZC+FhaoQFd= zl=E_vMALi@C=;nh| zCBLs6F!?p5ic<~hZ~Bt1RKwIZy(uZ@4Aw^6YimSMrQP0eG@K1rqZb;;tEmc+Xt

    Yz+xURK0saa6C?@$zw>Jy)-Gq&%0$%mMwl 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 diff --git a/shell/linux-deps/lib/libXau.so b/shell/linux-deps/lib/libXau.so deleted file mode 100644 index 92c36acf76ea4cea4a1ed01e2ee1ab79d73ca517..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9636 zcmeHNeRNdSwcmF>!XzdTVvqn4ZxZy4e2gPfNDHmWkX$~3f)rMxrEfAxCd|krna)gT zBD4muZJ6wOuuKRn0ujdPIq#eLicuw4GV4t7w~LY>S~XlL=OtX_w{px9^=R zm+9*2`{(tqoUA>+z0dwQU;CarIcFZO-XIBrKw2@9l@uw5Xc;QcmJk_;%*#lmEa>J? zk*e1mfZa1yGIL!gDSFc_M5a?Jbt7OeC@ZZ;Jj#bYA9|)q$V{v^rRhVUMhn0*X}bF^ zgc>3KL(%*ebsNYE(#pa#vq-A|E(R?D*+F-LxCqZJyLfy~ z&*-IJC8qD(vg*jt!OPRnf4R1J&(}g#kk{$#d5+9FneAt0$mJPwPKNxqjQFh?`n?(YT^aHpGUP92_%~(fLm9HpoJ8oJ z%+TMdGvM(xXXwQYJ?F7j*#7gH0Ax8g!~S@N{`m}9pF<*azs%6TkRcBv{)y9SWjc)PeFhC45Ige950g5 z-fJ0hUxxoq$bUj3ye{nTf;^s%kQ=WW?RL7&_0C%-G?X=rU} zg1tKsXlZq#!>*9GwS@xi79J7DaW(AVFwQ2I*LPjT_BL0bktf5|$UWKG0&lf1OLyApSQlj7HqXGCtu?d^r5YtrMt-KZghoQ2wWcws_UcYd94(UyQNX#(+D6$ zM6+tlH5=ABRy&v4mSN$QV!-=~|BPwWf(pG}WT%nd zMI9IR-j~+1tm+M)==q&E8}*hncAr+|-N0FRA$2n1h4TnwAyF6OeC!**o1o8U#EYzu z5ii^#M!fin8S&hTjM(-UFygteGUEAP%!ud0&WIi_W1LP@&WPuE6(a^!!HE5#iV+*u zTE-iRHZY<;n;2&iZDGV_Qp<<|ZDTAVs$-l()W|rO$ip~~$j6A6kDu{oq7dUPMD2_s z=3|g1hf*|R8OHm0Y{>=F*r^NC#}18ICSSg=?Fk}!_0aFLf8PE3ZOOA2G=7VY-vGXS z%{fWaRp@l(I^M41tvX)R@kKg5U&mW?Jn8t z{0ln%M>_udI{t)?KceHib^Iebem8hyjcNU^s=nGA!gBJt5&xRh_1BMHhgx&=K=7WLFToV!S*V1 zjllz(unE4#aPJz+@BlXL@4&VTw)ul5>9uf$$AWfmON=R4nyB-#JU=n!wTG#s^jmVW z8@!w>Oo-C(#rz66nKzO@Jb$ep@#W-(gh{f5Mae%r4?UBURSC01)+-S?`Jag_X*TKv zyPT{|%&I{@Jj;s=%a1zFk8Jbgjn*pdy+2`>6FD{B zc2U|@MYk7@%#rRdmXjY(yf%IU&ss028}vhrQNd zqt)+48>*AhLt*2AUEx!XccQDk>m|0DcAeF)6f2`tD+!0?WNbp{E0T-@!xtwHt?pV~ z{YrGTXQ|?4xz6j1;x#-@BUiES@OZyDKs}~!n;$bC9!;$s7)@>Hl#_SLyaqJ6x0A7Ei&^IkJfNR=%vZcf7v5-hUwUS)we}>qJ!Om6Jy&487CRJvALa?6`!!nvMx8&BwPDeKHR-x-jzZIg(LhUtf4AWwGxI z8;>1xycvBfm21z(tX*&WGsTwfD2==_N(+Wk`E|ES#xdbjre(v9mm;+(ll^(b`eMpN zOQp9`h52&wfeG%YP>fN;Mmwx#G!NUy~(0T$L-$lH}Tzo;OmB<#N(AQSrgmyLuftZwcaPs?oaA zbKJ2zI(H!NBWlL#?735__&{*X?w6B4iLYFz@|;B<##K$;N8NRD@`d=P6dg;f{bSrH z&VKqq^s*-|*z+SK%E>_d%w?Kkj1=^po7-8P^)|(T$Vx@@Zo;7Y#+N zlCVln)}gj&^vlIX5h`Kp&#|>ju+Hu;L6*K8AGj>v-6@qt<>U|IMvr09yHQ#!N$>s6 zARZh4ammIH&jr})8*xW*mSl$25m@CdibVF0BTM4H#^=}Kr!UKQ)jBFJ8R_A162FSN zh4IeE@J_^jaTf2sCqc-&HHFgN0im>0nl1_bhLSRjtRlWwBJst`!VE*i!1?jblPS}t zlPR+uPspv${MXaclA%{q)FX)fDcTetx58&>e450W^^Gqf&%11t&I}oPd&9+$ei(aad|JOn(Hxd9qMmoZ@5D?B9*<@9 zwhx)4H^$BVS&Gdb8NH3FR^6~7YXUvMtj1m%7qO~8kC~+Muvwb%iy8lW^x_QqI_TMP z)jpJt>PJ*=#TT={{}e_$oGOOzdB|Ah*inpCtSP}e!9MuRmBPFewPvXd`I(FSd?BXh zXZBl!{LHnMAwR8Avyz|o;oFt$6tK#nSb>s(LO8$I7`|$V3LGVb=4P1|B-VrWv)1wGWq4CH6~aE z$$;E84onU&lI#-C_WW4cTs5EmJU%&SmZo>@L*C>nS+hu5!TxoszXkr9cU{*)$>oug zuVS{ZM8y3IrFS8XKuSc!1JL1pbOzGJi1;n&AcbYJ7mWzwJD59sk5RtE)K+fYvUcO< zbzAPo`(fif)ktBw!-j9IAx|s58F#Q8s7F3GfP5@Xm8lt+nt`bqn3{p98JL=ZsTr7> zfvFjont`bqn3{qA?-|&NbMiSLF8EhdIlpJ*bAB9=)0;pXoh$cZI67DE&v3-8+;8J( zTe(lhQMYoY&-bf1o~Mtl%B@B4!?6#Ip#n#QbPh5%a|wtedF2iPM;b(@l{gQ5wh8BcB;=kxrJ;&4=%$(u6nYyw1(Wa?JaG#`Zh0ap}dWxNFGi)3I)9NZ6Vx6a#x&^Sb^w6`CjKD;Hcd(Uo*QaqcqpqfW~wwqvq_I3~yAoMsYX#5%TR!pcT!o9TgmJDX11UOg#5mVLR4$rjh5R3pPwz3{-u> z9{|t$p0bwMAC%wHutB3TpcQQe4lB#&q0EXU#(T`R%il{+u{-dX*|n671e#6c`lkx>zi6j^jneW9Zk^L{T(3aZYTf% diff --git a/shell/linux-deps/lib/libXdmcp.so b/shell/linux-deps/lib/libXdmcp.so deleted file mode 100644 index 30ff01e6102370bc8dfa9e8dcfdbefa2d0b8a017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13680 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 diff --git a/shell/linux-deps/lib/libxcb.so b/shell/linux-deps/lib/libxcb.so deleted file mode 100644 index c35762d16b4662bb78651e56127c9e7a0dc39643..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63052 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%0DB1Z(HLI_#y6Djf7k*3#rOpORl;!@H^liB4}CXE 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%0A2slGJv)A!)S%-@KKKw)p6=Mze;)QCzP3tpF| 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 Date: Sun, 28 Jul 2019 18:28:22 +0200 Subject: [PATCH 156/158] wince: fix wince page lookup --- core/hw/sh4/modules/wince.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/hw/sh4/modules/wince.h b/core/hw/sh4/modules/wince.h index 74bfcc4db..472d6834c 100644 --- a/core/hw/sh4/modules/wince.h +++ b/core/hw/sh4/modules/wince.h @@ -373,7 +373,7 @@ static bool wince_resolve_address(u32 va, TLB_Entry &entry) u32 sz = entry.Data.SZ1 * 2 + entry.Data.SZ0; entry.Address.VPN = (va & mmu_mask[sz]) >> 10; - true; + return true; } } } From 1fffbad9fc5e6ec5ba63259f9a73c78988cd5d21 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Sun, 28 Jul 2019 18:49:59 +0200 Subject: [PATCH 157/158] Fix build warnings. config.h for flac --- core/core.mk | 2 +- core/deps/flac/include/config.h | 10 ++++++ core/deps/zlib/zconf.h | 4 +++ core/hw/sh4/dyna/decoder.cpp | 3 +- core/hw/sh4/dyna/ssa_regalloc.h | 2 +- core/rec-ARM/rec_arm.cpp | 12 +++---- .../reicast-osx.xcodeproj/project.pbxproj | 32 +++---------------- shell/reicast.vcxproj | 16 +++++----- 8 files changed, 35 insertions(+), 46 deletions(-) create mode 100644 core/deps/flac/include/config.h diff --git a/core/core.mk b/core/core.mk index b7970ce95..27370cac2 100755 --- a/core/core.mk +++ b/core/core.mk @@ -126,7 +126,7 @@ endif ifdef CHD5_FLAC RZDCY_CFLAGS += -DCHD5_FLAC -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include - RZDCY_CFLAGS += -DPACKAGE_VERSION=\"1.3.2\" -DFLAC__HAS_OGG=0 -DFLAC__NO_DLL -DHAVE_LROUND -DHAVE_STDINT_H -DHAVE_STDLIB_H -DHAVE_SYS_PARAM_H + RZDCY_CFLAGS += -DHAVE_CONFIG_H RZDCY_MODULES += deps/flac/src/libFLAC/ endif diff --git a/core/deps/flac/include/config.h b/core/deps/flac/include/config.h new file mode 100644 index 000000000..666d63a84 --- /dev/null +++ b/core/deps/flac/include/config.h @@ -0,0 +1,10 @@ +#define PACKAGE_VERSION "1.3.2" +#define FLAC__HAS_OGG 0 +#define FLAC__NO_DLL 1 +#define HAVE_LROUND 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#ifndef _MSC_VER +#define HAVE_SYS_PARAM_H 1 +#endif + diff --git a/core/deps/zlib/zconf.h b/core/deps/zlib/zconf.h index 9987a7755..96a0d222b 100644 --- a/core/deps/zlib/zconf.h +++ b/core/deps/zlib/zconf.h @@ -8,6 +8,10 @@ #ifndef ZCONF_H #define ZCONF_H +#ifndef _MSC_VER +#define HAVE_UNISTD_H 1 +#endif + /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index c1e6a056e..105853fb7 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -273,7 +273,6 @@ sh4dec(i0000_0000_0001_1011) /* sh4dec(i0100_nnnn_0000_0111) { - /* u32 sr_t; ReadMemU32(sr_t,r[n]); if (sh4_exept_raised) @@ -284,7 +283,7 @@ sh4dec(i0100_nnnn_0000_0111) { //FIXME only if interrupts got on .. :P UpdateINTC(); - }* / + } dec_End(0xFFFFFFFF,BET_StaticIntr,false); } */ diff --git a/core/hw/sh4/dyna/ssa_regalloc.h b/core/hw/sh4/dyna/ssa_regalloc.h index f5190457f..5ce49ba39 100644 --- a/core/hw/sh4/dyna/ssa_regalloc.h +++ b/core/hw/sh4/dyna/ssa_regalloc.h @@ -120,7 +120,7 @@ public: AllocDestReg(op->rd); AllocDestReg(op->rd2); } - ssa_printf("%08x %s gregs %ld fregs %ld", block->vaddr + op->guest_offs, op->dissasm().c_str(), host_gregs.size(), host_fregs.size()); + ssa_printf("%08x %s gregs %zd fregs %zd", block->vaddr + op->guest_offs, op->dissasm().c_str(), host_gregs.size(), host_fregs.size()); } void OpEnd(shil_opcode* op) diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index d8dc95aba..8de57daba 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -536,7 +536,7 @@ void ngen_Binary(shil_opcode* op, BinaryOP dtop, BinaryOPImm dtopimm) dtop(reg.mapg(op->rd), rs1, rs2, CC_AL); } -void ngen_fp_bin(shil_opcode* op, const FPBinOP fpop) +void ngen_fp_bin(shil_opcode* op, FPBinOP fpop) { eFSReg rs1 = f0; if (op->rs1.is_imm()) @@ -563,7 +563,7 @@ void ngen_fp_bin(shil_opcode* op, const FPBinOP fpop) fpop(reg.mapfs(op->rd), rs1, rs2, CC_AL); } -void ngen_fp_una(shil_opcode* op, const FPUnOP fpop) +void ngen_fp_una(shil_opcode* op, FPUnOP fpop) { verify(op->rd.is_r32f()); verify(op->rs1.is_r32f()); @@ -894,7 +894,7 @@ u32* ngen_readm_fail_v2(u32* ptrv,u32* regs,u32 fault_addr) if (offs==-1) { - ERROR_LOG(DYNAREC, "%08X : invalid size", ptr[0]); + ERROR_LOG(DYNAREC, "%08X : invalid size", fop); die("can't decode opcode\n"); } @@ -1875,7 +1875,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_fmul: case shop_fdiv: { - const FPBinOP* opcds[]= { VADD_VFP,VSUB_VFP,VMUL_VFP,VDIV_VFP }; + FPBinOP* opcds[] = { VADD_VFP, VSUB_VFP, VMUL_VFP, VDIV_VFP }; ngen_fp_bin(op, opcds[op->op-shop_fadd]); } break; @@ -1883,7 +1883,7 @@ void ngen_compile_opcode(RuntimeBlockInfo* block, shil_opcode* op, bool staging, case shop_fabs: case shop_fneg: { - const FPUnOP* opcds[]= { VABS_VFP,VNEG_VFP}; + FPUnOP* opcds[] = { VABS_VFP, VNEG_VFP }; ngen_fp_una(op, opcds[op->op-shop_fabs]); } break; @@ -2472,7 +2472,7 @@ void ngen_init() BX(LR); } - INFO_LOG(DYNAREC, "readm helpers: up to %08X", EMIT_GET_PTR()); + INFO_LOG(DYNAREC, "readm helpers: up to %p", EMIT_GET_PTR()); emit_SetBaseAddr(); diff --git a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj index 3cf74b978..97dd593e3 100644 --- a/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj +++ b/shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj @@ -2599,13 +2599,7 @@ CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, - "PACKAGE_VERSION=\\\"1.3.2\\\"", - "FLAC__HAS_OGG=0", - FLAC__NO_DLL, - HAVE_LROUND, - HAVE_STDINT_H, - HAVE_STDLIB_H, - HAVE_SYS_PARAM_H, + "HAVE_CONFIG_H=1", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -2656,13 +2650,7 @@ CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, - "PACKAGE_VERSION=\\\"1.3.2\\\"", - "FLAC__HAS_OGG=0", - FLAC__NO_DLL, - HAVE_LROUND, - HAVE_STDINT_H, - HAVE_STDLIB_H, - HAVE_SYS_PARAM_H, + "HAVE_CONFIG_H=1", RELEASE, ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -2821,13 +2809,7 @@ CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, - "PACKAGE_VERSION=\\\"1.3.2\\\"", - "FLAC__HAS_OGG=0", - FLAC__NO_DLL, - HAVE_LROUND, - HAVE_STDINT_H, - HAVE_STDLIB_H, - HAVE_SYS_PARAM_H, + "HAVE_CONFIG_H=1", "${CFLAGS}", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; @@ -2938,13 +2920,7 @@ CHD5_LZMA, _7ZIP_ST, CHD5_FLAC, - "PACKAGE_VERSION=\\\"1.3.2\\\"", - "FLAC__HAS_OGG=0", - FLAC__NO_DLL, - HAVE_LROUND, - HAVE_STDINT_H, - HAVE_STDLIB_H, - HAVE_SYS_PARAM_H, + "HAVE_CONFIG_H=1", RELEASE, "${CFLAGS}", ); diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index 93904ce9a..bd7a9988c 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -713,7 +713,7 @@ Level3 Full - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable @@ -752,7 +752,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Full - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable @@ -791,7 +791,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Full - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable @@ -832,7 +832,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Full - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;NDEBUG;_CONSOLE;X86;RELEASE;TARGET_NAOMI;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include /MP %(AdditionalOptions) AnySuitable @@ -873,7 +873,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Disabled - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false @@ -901,7 +901,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Disabled - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false @@ -929,7 +929,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Disabled - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false @@ -960,7 +960,7 @@ for /f "delims=" %%i in ('date /T') do echo #define BUILD_DATE "%%i" >>$(P Level3 Disabled - WIN32;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) + WIN32;CHD5_FLAC;HAVE_CONFIG_H=1;CHD5_LZMA;_7ZIP_ST;_DEBUG;_CONSOLE;X86;TARGET_NAOMI;%(PreprocessorDefinitions) $(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\rend\gles;$(ProjectDir)..\core\deps;$(ProjectDir)..\core\deps\flac\src\libflac\include;$(ProjectDir)..\core\deps\flac\include true false From 91a753f224398730a93c12e64c34b73f6b07acea Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Tue, 30 Jul 2019 12:40:34 +0200 Subject: [PATCH 158/158] Fix naked functions for GCC --- core/rec-ARM/rec_arm.cpp | 5 ----- core/rec-ARM64/rec_arm64.cpp | 2 +- core/types.h | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index 8de57daba..dd2ad035e 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -269,11 +269,6 @@ struct arm_reg_alloc: RegAlloc arm_reg_alloc reg; -#ifdef naked -#undef naked -#define naked __attribute__((naked)) -#endif - u32 blockno=0; extern "C" void no_update(); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 0ed926849..355b1620d 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -2341,7 +2341,7 @@ void Arm64RegAlloc::Writeback_FPU(u32 reg, eFReg nreg) } -extern "C" void do_sqw_nommu_area_3(u32 dst, u8* sqb) +extern "C" naked void do_sqw_nommu_area_3(u32 dst, u8* sqb) { __asm__ ( diff --git a/core/types.h b/core/types.h index 8ce7eccdc..45f1f3583 100644 --- a/core/types.h +++ b/core/types.h @@ -291,7 +291,7 @@ using namespace std; #if defined(X86) && COMPILER_VC==BUILD_COMPILER #define naked __declspec( naked ) #else -#define naked +#define naked __attribute__((naked)) #endif @@ -781,7 +781,7 @@ void libAICA_Update(u32 cycles); //called every ~1800 cycles, set to 0 if not //GDR s32 libGDR_Init(); -void libGDR_Reset(bool M); +void libGDR_Reset(bool hard); void libGDR_Term(); void libCore_gdrom_disc_change();

    dEfg(u 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 ^P?b5 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 Ii=E!z-Q1VXlUUIGaC<&5$k_1aaB%zYek}$~^ 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 z