os/graphics/graphicsdeviceinterface/bitgdi/bitgdi_switch/bitgdiswitch.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // For the Winscw Emulator only, selects between GCE and non-GCE version of Bit Gdi.
    15 // The default is the non-GCE based version.
    16 // To select the GCE version do one of:
    17 // 1. Add a line to the epoc.ini file in \epoc32\data like this:
    18 // symbian_graphics_use_gce ON
    19 // or
    20 // 2. Start epoc.exe with these parameters, (the "--" IS necessary):
    21 // -Dsymbian_graphics_use_gce=ON --
    22 // or
    23 // 3. epoc.exe can be told to switch to a different initialisation file than epoc.ini, with the -M parameter.
    24 // Progress chaining to the real Bitgdi is logged in epocwind.out.
    25 // 
    26 //
    27 
    28 
    29 
    30 #include <emulator.h>
    31 
    32 #include <e32svr.h>
    33 #include <u32hal.h>
    34 
    35 
    36 extern "C" {
    37 
    38 #include "bitgdi_stubs.h"
    39 
    40 FARPROC vector[MAX_ORDINAL+1];
    41 
    42 
    43 #ifdef _DEBUG
    44 void Stop(char* aErrorMessage)
    45 #else
    46 void Stop(char* /*aErrorMessage*/)
    47 #endif
    48 	{
    49 	int err = GetLastError();
    50 #ifdef _DEBUG
    51 	RDebug::Printf("%s, (last error = %i)", aErrorMessage, err);
    52 #endif
    53 	_asm int 3;
    54 	}
    55 
    56 void fill_vector(HINSTANCE aDll)
    57 	{
    58 	int i;
    59 	FARPROC address = NULL;
    60 	for (i=1;i<=MAX_ORDINAL;i++)
    61 		{
    62 		address = GetProcAddress(aDll, (LPCSTR)i);
    63 		if (address == NULL)
    64 			{
    65 			Stop("... has too few exported functions");
    66 			}
    67 		vector[i] = address;
    68 		}
    69 
    70 	address = GetProcAddress(aDll, (LPCSTR)i);
    71 	if (address != NULL)
    72 		{
    73 		Stop("... has too many exported functions");
    74 		}
    75 	vector[0] = (FARPROC)1;		// initialised
    76 	}
    77 
    78 // redirects DLL calls to GCE or non-GCE implementation
    79 void init_vector()
    80 	{
    81 	// ask HAL which configuration to use
    82 	TBool gce = EFalse;
    83 	UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty,  (TAny*)"symbian_graphics_use_gce",  &gce);
    84 	const char* library = gce ? "bitgdi_gce.dll" : "bitgdi_nongce.dll";
    85 
    86 #ifdef _DEBUG
    87 	RDebug::Printf("Redirecting bitgdi.dll to \"%s\" ...\n", library);
    88 #endif
    89 
    90 	Emulator::Escape();		// prevent deadlock between EKA2 scheduler and MS kernel
    91 	// try to load selected DLL
    92 	HINSTANCE instance = LoadLibraryA(library);
    93 	Emulator::Reenter();
    94 
    95 	if (instance == NULL)
    96 		{
    97 		Stop("... unable to load");
    98 		}
    99 	else
   100 		{
   101 		fill_vector(instance);
   102 #ifdef _DEBUG
   103 		RDebug::Printf("... DLL loaded successfully");
   104 #endif
   105 		}
   106 	}
   107 
   108 __declspec(naked) void common_dispatch()
   109 	{
   110 	_asm cmp	dword ptr vector,0		// initialised?
   111 	_asm je  	do_init_vector
   112 call_though_vector:
   113 	_asm jmp	[vector+eax*4]
   114 
   115 do_init_vector:
   116 	_asm push	eax
   117 	_asm push	ecx
   118 	_asm push	edx
   119 	_asm call	init_vector
   120 	_asm pop	edx
   121 	_asm pop 	ecx
   122 	_asm pop 	eax
   123 	_asm jmp	call_though_vector
   124 	}
   125 
   126 }