os/graphics/graphicsdeviceinterface/screendriver/scdv_switch/scdvswitch.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 Screen Driver.
    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 Scdv 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 "scdv_stubs.h"
    39 
    40 FARPROC vector[MAX_ORDINAL+1];
    41 
    42 #ifdef _DEBUG
    43 void Stop(char* aErrorMessage)
    44 #else
    45 void Stop(char* /*aErrorMessage*/)
    46 #endif
    47 	{
    48 	int err = GetLastError();
    49 #ifdef _DEBUG
    50 	RDebug::Printf("%S, (last error = %i)", aErrorMessage, err);
    51 #endif
    52 	_asm int 3;
    53 	}
    54 
    55 void fill_vector(HINSTANCE aDll)
    56 	{
    57 	int i;
    58 	FARPROC address = NULL;
    59 	for (i=1;i<=MAX_ORDINAL;i++)
    60 		{
    61 		address = GetProcAddress(aDll, (LPCSTR)i);
    62 		if (address == NULL)
    63 			{
    64 			Stop("... has too few exported functions");
    65 			}
    66 		vector[i] = address;
    67 		}
    68 
    69 	address = GetProcAddress(aDll, (LPCSTR)i);
    70 	if (address != NULL)
    71 		{
    72 		Stop("... has too many exported functions");
    73 		}
    74 	vector[0] = (FARPROC)1;		// initialised
    75 	}
    76 
    77 // redirects DLL calls to GCE or non-GCE implementation
    78 void init_vector()
    79 	{
    80 	// ask HAL which configuration to use
    81 	TBool gce = EFalse;
    82 	UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty,  (TAny*)"symbian_graphics_use_gce",  &gce);
    83 	const char* library = gce ? "_generic_scdv.dll" : "_wins_scdv.dll";
    84 
    85 #ifdef _DEBUG
    86 	RDebug::Printf("Redirecting scdv.dll to \"%s\" ...\n", library);
    87 #endif
    88   	
    89 	Emulator::Escape();		// prevent deadlock between EKA2 scheduler and MS kernel
    90 	// try to load selected DLL
    91 	HINSTANCE instance = LoadLibraryA(library);
    92 	Emulator::Reenter();
    93 
    94 	if (instance == NULL)
    95 		{
    96 		Stop("... unable to load");
    97 		}
    98 	else
    99 		{
   100 		fill_vector(instance);
   101 #ifdef _DEBUG
   102 		RDebug::Printf("... DLL loaded successfully");
   103 #endif
   104 		}
   105 	}
   106 
   107 __declspec(naked) void common_dispatch()
   108 	{
   109 	_asm cmp	dword ptr vector,0		// initialised?
   110 	_asm je  	do_init_vector
   111 call_though_vector:
   112 	_asm jmp	[vector+eax*4]
   113 
   114 do_init_vector:
   115 	_asm push	eax
   116 	_asm push	ecx
   117 	_asm push	edx
   118 	_asm call	init_vector
   119 	_asm pop	edx
   120 	_asm pop 	ecx
   121 	_asm pop 	eax
   122 	_asm jmp	call_though_vector
   123 	}
   124 
   125 }