1 module allegro5.internal.da5; 2 3 /* 4 * Issue: MinGW 4.5 and below has a bizzare calling convention when 5 * returning structs. ColorWrapper takes care of the difference in 6 * calling convention. If this wrapper is necessary, then D programs 7 * that use DAllegro5 should link against allegro_color even when they 8 * never call any allegro_color function. 9 * 10 * The following toolchains (to compile Allegro DLLs) are free of this issue: 11 * - MSVC, 12 * - maybe MinGW 4.6. 13 * ColorWrapper resolves to a mere binding on all systems that don't 14 * need the caretaking, and allegro_color needs not be linked against 15 * then unless you call a function from allegro_color. 16 * 17 * ColorWrapper is private to DAllegro5. Call ColorWrapper in DAllegro5 18 * outside any "nothrow @nogc extern (C)" because ColorWrapper will 19 * insert attributes itself. 20 */ 21 char[] ColorWrapper( 22 in char[] prefix, in char[] func, in char[] arg_decls, in char[] arg_names) 23 { 24 static if (NeedsMinGW4CallingConvention) 25 { 26 // Implement a new D function to wrap Allegro's C function, 27 // fixing the calling convention (see comment for ColorWrapper above). 28 return 29 `nothrow @nogc ALLEGRO_COLOR ` ~ func ~ `(` ~ arg_decls ~ `) 30 { 31 auto ret = ` ~ prefix ~ func ~ `(` ~ arg_names ~ `); 32 asm nothrow @nogc 33 { 34 sub ESP, 4; 35 } 36 return ret; 37 }`; 38 } 39 else 40 { 41 // Declare function as a normal C binding. 42 return 43 `nothrow @nogc extern (C) 44 ALLEGRO_COLOR ` ~ func ~ `(` ~ arg_decls ~ `);`; 45 } 46 } 47 48 bool NeedsMinGW4CallingConvention() pure nothrow @nogc 49 { 50 version(ALLEGRO_MINGW_4_5) 51 { 52 return true; 53 } 54 else 55 { 56 return false; 57 } 58 }