~ubuntu-branches/ubuntu/karmic/libsdl1.2/karmic

« back to all changes in this revision

Viewing changes to src/video/symbian/EKA1/SDL_epocvideo.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-12-05 20:29:43 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071205202943-ryogi07hodn5cdif
Tags: 1.2.12-1ubuntu1
* Merge with Debian; remaining changes:
  - Remove svgalib support.
  - Prefer libgl1-mesa-dev build-dependency over xlibmesa-gl-dev.
  - Build for lpia as for i386.
* Link using -Wl,-Bsymbolic-functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    SDL - Simple DirectMedia Layer
 
3
    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
 
4
 
 
5
    This library is free software; you can redistribute it and/or
 
6
    modify it under the terms of the GNU Library General Public
 
7
    License as published by the Free Software Foundation; either
 
8
    version 2 of the License, or (at your option) any later version.
 
9
 
 
10
    This library is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
    Library General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU Library General Public
 
16
    License along with this library; if not, write to the Free
 
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
    Sam Lantinga
 
20
    slouken@devolution.com
 
21
*/
 
22
 
 
23
/*
 
24
    SDL_epocvideo.cpp
 
25
    Epoc based SDL video driver implementation
 
26
 
 
27
    Thanks to Peter van Sebille, the author of EMame. It is a great example of 
 
28
    low level graphics coding in Epoc.
 
29
 
 
30
    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
 
31
        Assembler routines by Kimmo Kinnunen
 
32
*/
 
33
 
 
34
 
 
35
 
 
36
#include <stdlib.h>
 
37
#include <stdio.h>
 
38
#include <string.h>
 
39
 
 
40
extern "C" {
 
41
#include "SDL_error.h"
 
42
#include "SDL_timer.h"
 
43
#include "SDL_video.h"
 
44
#undef NULL
 
45
#include "SDL_pixels_c.h"
 
46
#include "SDL.h"
 
47
};
 
48
 
 
49
#include "SDL_epocvideo.h"
 
50
#include "SDL_epocevents_c.h"
 
51
 
 
52
#include "sdl_epocruntime.h"
 
53
 
 
54
#include <hal.h>
 
55
#include <coedef.h>
 
56
#include <flogger.h>
 
57
 
 
58
#ifdef SYMBIAN_QUARTZ
 
59
SDL_VideoDevice* _thisDevice;
 
60
#endif
 
61
 
 
62
_LIT(KLibName, "SDL");
 
63
 
 
64
/* For debugging */
 
65
 
 
66
//if old SOS, from 7.x this is public!
 
67
class CLockable : public CFbsBitmap
 
68
    {
 
69
    public:
 
70
        static  CLockable* Lockable(CFbsBitmap* aBmp) {return static_cast<CLockable*>(aBmp);}
 
71
        void Lock() {LockHeap();}
 
72
        void Unlock() {UnlockHeap();}
 
73
    };
 
74
#define LockHeap(x) CLockable::Lockable(x)->Lock()
 
75
#define UnlockHeap(x) CLockable::Lockable(x)->Unlock()
 
76
 
 
77
void RDebug_Print_b(char* error_str, void* param)
 
78
    {
 
79
    TBuf8<128> error8((TUint8*)error_str);
 
80
    TBuf<128> error;
 
81
    error.Copy(error8);
 
82
 
 
83
#ifndef TRACE_TO_FILE
 
84
    if (param) //!! Do not work if the parameter is really 0!!
 
85
        RDebug::Print(error, param);
 
86
    else 
 
87
        RDebug::Print(error);
 
88
#else
 
89
    if (param) //!! Do not work if the parameter is really 0!!
 
90
        RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param);
 
91
    else 
 
92
        RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error);
 
93
#endif
 
94
 
 
95
    }
 
96
 
 
97
extern "C" void RDebug_Print(char* error_str, void* param)
 
98
    {
 
99
    RDebug_Print_b(error_str, param);
 
100
    }
 
101
 
 
102
 
 
103
int Debug_AvailMem2()
 
104
    {
 
105
    //User::CompressAllHeaps();
 
106
    TMemoryInfoV1Buf membuf; 
 
107
    User::LeaveIfError(UserHal::MemoryInfo(membuf));
 
108
    TMemoryInfoV1 minfo = membuf();
 
109
        return(minfo.iFreeRamInBytes);
 
110
    }
 
111
 
 
112
extern "C" int Debug_AvailMem()
 
113
    {
 
114
    return(Debug_AvailMem2());
 
115
    }
 
116
 
 
117
 
 
118
extern "C" {
 
119
 
 
120
/* Initialization/Query functions */
 
121
 
 
122
static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
 
123
static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
 
124
static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
 
125
static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
 
126
                          SDL_Color *colors);
 
127
static void EPOC_VideoQuit(_THIS);
 
128
 
 
129
/* Hardware surface functions */
 
130
 
 
131
static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
 
132
static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
 
133
static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
 
134
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
 
135
static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
 
136
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
 
137
 
 
138
static int EPOC_Available(void);
 
139
static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
 
140
 
 
141
void DrawBackground(_THIS);
 
142
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
 
143
void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
 
144
 
 
145
/* Mouse functions */
 
146
 
 
147
static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
 
148
static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
 
149
static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
 
150
 
 
151
 
 
152
 
 
153
/* !!For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit */
 
154
// TUint16 is enough, but using TUint32 so we can use better instruction selection on ARMI
 
155
static TUint32 EPOC_HWPalette_256_to_Screen[256];
 
156
 
 
157
VideoBootStrap EPOC_bootstrap = {
 
158
        "epoc", "EPOC system",
 
159
    EPOC_Available, EPOC_CreateDevice
 
160
};
 
161
 
 
162
const TUint32 WindowClientHandle = 9210; //!! const
 
163
 
 
164
/* Epoc video driver bootstrap functions */
 
165
 
 
166
static int EPOC_Available(void)
 
167
{
 
168
    return 1; /* Always available */
 
169
}
 
170
 
 
171
static void EPOC_DeleteDevice(SDL_VideoDevice *device)
 
172
{
 
173
        free(device->hidden);
 
174
        free(device);
 
175
}
 
176
 
 
177
static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/)
 
178
{
 
179
        SDL_VideoDevice *device;
 
180
 
 
181
        SDL_TRACE("SDL:EPOC_CreateDevice");
 
182
 
 
183
        /* Allocate all variables that we free on delete */
 
184
        device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
 
185
        if ( device ) {
 
186
                memset(device, 0, (sizeof *device));
 
187
                device->hidden = (struct SDL_PrivateVideoData *)
 
188
                                malloc((sizeof *device->hidden));
 
189
        }
 
190
        if ( (device == NULL) || (device->hidden == NULL) ) {
 
191
                SDL_OutOfMemory();
 
192
                if ( device ) {
 
193
                        free(device);
 
194
                }
 
195
                return(0);
 
196
        }
 
197
        memset(device->hidden, 0, (sizeof *device->hidden));
 
198
 
 
199
        /* Set the function pointers */
 
200
        device->VideoInit = EPOC_VideoInit;
 
201
        device->ListModes = EPOC_ListModes;
 
202
        device->SetVideoMode = EPOC_SetVideoMode;
 
203
        device->SetColors = EPOC_SetColors;
 
204
        device->UpdateRects = NULL;
 
205
        device->VideoQuit = EPOC_VideoQuit;
 
206
        device->AllocHWSurface = EPOC_AllocHWSurface;
 
207
        device->CheckHWBlit = NULL;
 
208
        device->FillHWRect = NULL;
 
209
        device->SetHWColorKey = NULL;
 
210
        device->SetHWAlpha = NULL;
 
211
        device->LockHWSurface = EPOC_LockHWSurface;
 
212
        device->UnlockHWSurface = EPOC_UnlockHWSurface;
 
213
        device->FlipHWSurface = EPOC_FlipHWSurface;
 
214
        device->FreeHWSurface = EPOC_FreeHWSurface;
 
215
        device->SetIcon = NULL;
 
216
        device->SetCaption = NULL;
 
217
        device->GetWMInfo = NULL;
 
218
        device->FreeWMCursor = EPOC_FreeWMCursor;
 
219
        device->CreateWMCursor = EPOC_CreateWMCursor;
 
220
        device->ShowWMCursor = EPOC_ShowWMCursor;
 
221
        device->WarpWMCursor = NULL;
 
222
        device->InitOSKeymap = EPOC_InitOSKeymap;
 
223
        device->PumpEvents = EPOC_PumpEvents;
 
224
        device->free = EPOC_DeleteDevice;
 
225
 
 
226
        return device;
 
227
}
 
228
 
 
229
 
 
230
int GetBpp(TDisplayMode displaymode)
 
231
{
 
232
    /*TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode);
 
233
    TInt bitsPerPixel = 1;
 
234
    for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++);
 
235
    return bitsPerPixel;*/
 
236
    return  TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode);   
 
237
}
 
238
 
 
239
 
 
240
void DisableKeyBlocking(_THIS)
 
241
    {
 
242
    // Disable key blocking
 
243
    TRawEvent event;
 
244
    event.Set((TRawEvent::TType)/*EDisableKeyBlock*/51); // !!EDisableKeyBlock not found in epoc32\include!
 
245
    Private->EPOC_WsSession.SimulateRawEvent(event);
 
246
    }
 
247
 
 
248
void ConstructWindowL(_THIS)
 
249
{
 
250
        TInt    error;
 
251
 
 
252
        SDL_TRACE("SDL:ConstructWindowL");
 
253
        error = Private->EPOC_WsSession.Connect();
 
254
        User::LeaveIfError(error);
 
255
        Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession);
 
256
        User::LeaveIfError(Private->EPOC_WsScreen->Construct());
 
257
        User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc));
 
258
 
 
259
        Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession);
 
260
        User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle));
 
261
        Private->EPOC_WsWindowGroup.SetOrdinalPosition(0);
 
262
 
 
263
        // Set window group name (the same as process name)) !!Gives always "EPOC" in WINS
 
264
        RProcess thisProcess;
 
265
        TParse exeName;
 
266
        exeName.Set(thisProcess.FileName(), NULL, NULL);
 
267
    TBuf<32> winGroupName;
 
268
    winGroupName.Append(0);
 
269
    winGroupName.Append(0);
 
270
    winGroupName.Append(0);// uid
 
271
    winGroupName.Append(0);
 
272
    winGroupName.Append(exeName.Name()); // caption
 
273
    winGroupName.Append(0);
 
274
    winGroupName.Append(0); //doc name
 
275
        Private->EPOC_WsWindowGroup.SetName(winGroupName); 
 
276
 
 
277
        Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession);
 
278
  // Markus, it was:
 
279
  // User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle ));
 
280
  // but SOS 7.0s debug does not accept same window handle twice
 
281
        User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle - 1));
 
282
        Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite);
 
283
    Private->EPOC_WsWindow.Activate();
 
284
        Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels()); 
 
285
        Private->EPOC_WsWindow.SetVisible(ETrue);
 
286
 
 
287
    Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier();
 
288
    Private->EPOC_IsWindowFocused = EFalse;
 
289
 
 
290
    DisableKeyBlocking(_this); //disable key blocking
 
291
}
 
292
 
 
293
int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
 
294
{
 
295
    // !!TODO:handle leave functions!
 
296
 
 
297
    int i;
 
298
 
 
299
        SDL_TRACE("SDL:EPOC_VideoInit");
 
300
 
 
301
        /* Initialize all variables that we clean on shutdown */   
 
302
 
 
303
        for ( i=0; i<SDL_NUMMODES; ++i ) {
 
304
                Private->SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
 
305
                Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0;
 
306
        }
 
307
 
 
308
        /* Modes sorted largest to smallest */
 
309
        Private->SDL_modelist[0]->w = 800; Private->SDL_modelist[0]->h = 250;
 
310
        Private->SDL_modelist[1]->w = 640; Private->SDL_modelist[1]->h = 480;
 
311
        Private->SDL_modelist[2]->w = 480; Private->SDL_modelist[2]->h = 600;
 
312
        Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 400;
 
313
        Private->SDL_modelist[4]->w = 352; Private->SDL_modelist[4]->h = 416;
 
314
        Private->SDL_modelist[5]->w = 416; Private->SDL_modelist[5]->h = 352;
 
315
        Private->SDL_modelist[6]->w = 416; Private->SDL_modelist[6]->h = 312;
 
316
        Private->SDL_modelist[7]->w = 352; Private->SDL_modelist[7]->h = 264;
 
317
        Private->SDL_modelist[8]->w = 800; Private->SDL_modelist[8]->h = 240; //for doom all these..
 
318
        Private->SDL_modelist[9]->w = 640; Private->SDL_modelist[9]->h = 240; 
 
319
        Private->SDL_modelist[10]->w = 480; Private->SDL_modelist[10]->h = 240; 
 
320
        Private->SDL_modelist[11]->w = 640; Private->SDL_modelist[11]->h = 240; 
 
321
        Private->SDL_modelist[12]->w = 352; Private->SDL_modelist[12]->h = 240; 
 
322
        Private->SDL_modelist[13]->w = 416; Private->SDL_modelist[13]->h = 240; 
 
323
        Private->SDL_modelist[14]->w = 416; Private->SDL_modelist[14]->h = 240; 
 
324
        Private->SDL_modelist[15]->w = 352; Private->SDL_modelist[15]->h = 240; 
 
325
    Private->SDL_modelist[16]->w = 640; Private->SDL_modelist[16]->h = 200; 
 
326
        Private->SDL_modelist[17]->w = 320; Private->SDL_modelist[17]->h = 240; //...for doom, currently engine renders no-higher windows :-(, propably should get fixed 
 
327
        Private->SDL_modelist[18]->w = 320; Private->SDL_modelist[18]->h = 200;
 
328
        Private->SDL_modelist[19]->w = 256; Private->SDL_modelist[19]->h = 192;
 
329
        Private->SDL_modelist[20]->w = 176; Private->SDL_modelist[20]->h = 208;
 
330
        Private->SDL_modelist[21]->w = 208; Private->SDL_modelist[21]->h = 176; // Rotated
 
331
        Private->SDL_modelist[22]->w = 160; Private->SDL_modelist[22]->h = 144; 
 
332
 
 
333
    Private->SDL_modelist[23]->w = 640; Private->SDL_modelist[2]->h = 200;  //s80 some new modes 
 
334
    Private->SDL_modelist[24]->w = 640; Private->SDL_modelist[2]->h = 320;  //s90 modes are added
 
335
    Private->SDL_modelist[25]->w = 640; Private->SDL_modelist[2]->h = 240;  //here
 
336
        Private->SDL_modelist[26]->w = 640; Private->SDL_modelist[4]->h = 200;  //now
 
337
 
 
338
        Private->SDL_modelist[27] = NULL;
 
339
 
 
340
    /* Construct Epoc window */
 
341
 
 
342
    ConstructWindowL(_this);
 
343
 
 
344
    /* Initialise Epoc frame buffer */
 
345
 
 
346
    TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode();
 
347
 
 
348
#if !defined(__WINS__) && !defined(TEST_BM_DRAW)
 
349
 
 
350
    TScreenInfoV01 screenInfo;
 
351
        TPckg<TScreenInfoV01> sInfo(screenInfo);
 
352
        UserSvr::ScreenInfo(sInfo);
 
353
 
 
354
        Private->EPOC_ScreenSize                = screenInfo.iScreenSize; 
 
355
        Private->EPOC_DisplayMode               = displayMode;
 
356
    Private->EPOC_HasFrameBuffer        = screenInfo.iScreenAddressValid;
 
357
        Private->EPOC_FrameBuffer               = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL;
 
358
        Private->EPOC_BytesPerPixel         = ((GetBpp(displayMode)-1) / 8) + 1;
 
359
        
 
360
    Private->EPOC_BytesPerScanLine      = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel;
 
361
        Private->EPOC_BytesPerScreen    = Private->EPOC_BytesPerScanLine * Private->EPOC_ScreenSize.iHeight;
 
362
 
 
363
    SDL_TRACE1("Screen width %d", screenInfo.iScreenSize.iWidth);
 
364
    SDL_TRACE1("Screen height %d", screenInfo.iScreenSize.iHeight);
 
365
    SDL_TRACE1("Screen dmode %d", displayMode);
 
366
    SDL_TRACE1("Screen valid %d", screenInfo.iScreenAddressValid);
 
367
 
 
368
    SDL_TRACE1("bpp %d", Private->EPOC_BytesPerPixel);
 
369
    SDL_TRACE1("bpsl %d", Private->EPOC_BytesPerScanLine);
 
370
    SDL_TRACE1("bps %d", Private->EPOC_BytesPerScreen);
 
371
 
 
372
 
 
373
    /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the 
 
374
     * beginning of the frame buffer. E.g. Series 7 and Netbook.
 
375
     * In 12 bpp machines the table has 16 entries.
 
376
         */
 
377
        if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8)
 
378
        {
 
379
                Private->EPOC_FrameBuffer += 512;
 
380
        }
 
381
        else
 
382
        {
 
383
        Private->EPOC_FrameBuffer += 32;
 
384
        }
 
385
        /*if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12)
 
386
                Private->EPOC_FrameBuffer += 16 * 2;
 
387
    if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 16)
 
388
                Private->EPOC_FrameBuffer += 16 * 2;
 
389
    */
 
390
#else /* defined __WINS__ */
 
391
    
 
392
    /* Create bitmap, device and context for screen drawing */
 
393
    Private->EPOC_ScreenSize        = Private->EPOC_WsScreen->SizeInPixels();
 
394
 
 
395
        Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession);
 
396
        Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode);
 
397
 
 
398
        Private->EPOC_DisplayMode           = displayMode;
 
399
    Private->EPOC_HasFrameBuffer    = ETrue;
 
400
    Private->EPOC_FrameBuffer       = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */
 
401
        Private->EPOC_BytesPerPixel         = ((GetBpp(displayMode)-1) / 8) + 1;
 
402
        Private->EPOC_BytesPerScanLine  = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel;
 
403
 
 
404
#endif /* __WINS__ */
 
405
 
 
406
#ifndef SYMBIAN_CRYSTAL
 
407
        // Get draw device for updating the screen
 
408
        TScreenInfoV01 screenInfo2;
 
409
    
 
410
    Epoc_Runtime::GetScreenInfo(screenInfo2);
 
411
 
 
412
        TRAPD(status, Private->EPOC_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode));
 
413
        User::LeaveIfError(status);
 
414
#endif
 
415
 
 
416
    /* The "best" video format should be returned to caller. */
 
417
 
 
418
    vformat->BitsPerPixel       = /*!!GetBpp(displayMode) */ 8;
 
419
    vformat->BytesPerPixel      = /*!!Private->EPOC_BytesPerPixel*/ 1;
 
420
 
 
421
    /* Activate events for me */
 
422
 
 
423
        Private->EPOC_WsEventStatus = KRequestPending;
 
424
        Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
 
425
 
 
426
    SDL_TRACE("SDL:WsEventStatus");
 
427
    User::WaitForRequest(Private->EPOC_WsEventStatus); //Markus: I added this and ...
 
428
 
 
429
        Private->EPOC_RedrawEventStatus = KRequestPending;
 
430
        Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus);
 
431
    
 
432
    SDL_TRACE("SDL:RedrawEventStatus");
 
433
    User::WaitForRequest(Private->EPOC_RedrawEventStatus); //...this, if not catches a stray event is risen
 
434
                                                           //if there are active objects used, or confucing
 
435
                                                           //actions with User::WaitForAnyRequest
 
436
    Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0); 
 
437
 
 
438
    Private->EPOC_ScreenOffset = TPoint(0, 0);
 
439
 
 
440
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
441
        LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap
 
442
#endif
 
443
 
 
444
    SDL_TRACE("SDL:DrawBackground");
 
445
        DrawBackground(_this); // Clear screen
 
446
 
 
447
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
448
        UnlockHeap(Private->EPOC_Bitmap); // Unlock bitmap heap
 
449
#endif
 
450
    //!! TODO: error handling
 
451
    //if (ret != KErrNone)
 
452
    //    return(-1);
 
453
    //else
 
454
            return(0);
 
455
}
 
456
 
 
457
 
 
458
SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 /*flags*/)
 
459
{
 
460
    if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8)
 
461
        return Private->SDL_modelist;
 
462
    return NULL;
 
463
}
 
464
 
 
465
int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
 
466
{
 
467
        if ((firstcolor+ncolors) > 256)
 
468
                return -1;
 
469
//    SDL_TRACE1("colors %d", (TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode)));
 
470
    if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 4096)
 
471
        {
 
472
        // Set 12 bit palette
 
473
        for(int i = firstcolor; i < ncolors; i++)
 
474
            {
 
475
                // 4k value: 0000 rrrr gggg bbbb
 
476
                TUint32 color4K  = (colors[i].r & 0x0000f0) << 4;
 
477
                color4K                 |= (colors[i].g & 0x0000f0);      
 
478
                color4K                 |= (colors[i].b & 0x0000f0) >> 4;
 
479
            EPOC_HWPalette_256_to_Screen[i] = color4K;
 
480
            }
 
481
        }
 
482
    else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 65536)
 
483
        {
 
484
        for(int i = firstcolor; i < ncolors; i++)
 
485
            {
 
486
                        // 64k-colour displays effectively support RGB values
 
487
                        // with 5 bits allocated to red, 6 to green and 5 to blue
 
488
                        // 64k value: rrrr rggg gggb bbbb
 
489
                TUint32 color64K = (colors[i].r & 0x0000f8) << 8;
 
490
                color64K                |= (colors[i].g & 0x0000fc) << 3;
 
491
                color64K                |= (colors[i].b & 0x0000f8) >> 3;
 
492
            EPOC_HWPalette_256_to_Screen[i] = color64K;
 
493
            }
 
494
        }
 
495
    else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 16777216)
 
496
        {
 
497
        for(int i = firstcolor; i < ncolors; i++)
 
498
            {
 
499
                        // 16M-colour
 
500
            //0000 0000 rrrr rrrr gggg gggg bbbb bbbb
 
501
                TUint32 color16M = colors[i].r << 16;
 
502
                color16M                |= colors[i].g << 8;
 
503
                color16M                |= colors[i].b;
 
504
            EPOC_HWPalette_256_to_Screen[i] = color16M;
 
505
            }
 
506
        }
 
507
    else
 
508
        {
 
509
        return -2;
 
510
        }
 
511
        return(0);
 
512
}
 
513
 
 
514
 
 
515
SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
 
516
                                int width, int height, int bpp, Uint32 /*flags*/)
 
517
{
 
518
        SDL_TRACE("SDL:EPOC_SetVideoMode");
 
519
    /* Check parameters */
 
520
#ifdef SYMBIAN_CRYSTAL
 
521
   if (! (bpp == 8 || bpp == 12 || bpp == 16) &&
 
522
                 (
 
523
                  (width == 640 && height == 200) ||
 
524
          (width == 640 && height == 400) || 
 
525
          (width == 640 && height == 480) || 
 
526
          (width == 320 && height == 200) || 
 
527
          (width == 320 && height == 240)
 
528
                 )) {
 
529
                SDL_SetError("Requested video mode is not supported");
 
530
        return NULL;
 
531
    }
 
532
#else // SYMBIAN_SERIES60
 
533
   if (! (bpp == 8 || bpp == 12 || bpp == 16) &&
 
534
                 (
 
535
                  (width == 320 && height == 200) || 
 
536
          (width == 320 && height == 240) ||
 
537
                  (width == 256 && height == 192) ||  
 
538
                  (width == 176 && height == 208) || 
 
539
                  (width == 208 && height == 176) || // Rotated
 
540
                  (width == 160 && height == 144)    
 
541
                 )) {
 
542
                SDL_SetError("Requested video mode is not supported");
 
543
        return NULL;
 
544
    }
 
545
#endif
 
546
 
 
547
    if (current && current->pixels) {
 
548
        free(current->pixels);
 
549
        current->pixels = NULL;
 
550
    }
 
551
        if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
 
552
                return(NULL);
 
553
        }
 
554
 
 
555
    /* Set up the new mode framebuffer */
 
556
    if (bpp == 8) 
 
557
            current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE); 
 
558
    else // 12 bpp, 16 bpp
 
559
            current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC); 
 
560
        current->w = width;
 
561
        current->h = height;
 
562
    int numBytesPerPixel = ((bpp-1)>>3) + 1;   
 
563
        current->pitch = numBytesPerPixel * width; // Number of bytes in scanline 
 
564
        current->pixels = malloc(width * height * numBytesPerPixel);
 
565
        memset(current->pixels, 0, width * height * numBytesPerPixel);
 
566
 
 
567
        /* Set the blit function */
 
568
        _this->UpdateRects = EPOC_DirectUpdate;
 
569
 
 
570
    /*
 
571
     *  Logic for getting suitable screen dimensions, offset, scaling and orientation
 
572
     */
 
573
 
 
574
        int w = current->w;
 
575
        int h = current->h;
 
576
        
 
577
        // Rotate, if the screen does not fit horizontally and it is landscape screen
 
578
/*
 
579
        if ((width>Private->EPOC_ScreenSize.iWidth) &&  (width>height)) {
 
580
                Private->EPOC_ScreenOrientation = CFbsBitGc::EGraphicsOrientationRotated270;
 
581
                w = current->h; 
 
582
                h = current->w; 
 
583
        }
 
584
*/
 
585
        // Get nearest stepwise scale values for width and height. The smallest supported scaled screen is 1/2.
 
586
        TInt scaleValue = 0;
 
587
        Private->EPOC_ScreenXScaleValue = 1;
 
588
        Private->EPOC_ScreenYScaleValue = 1;
 
589
        if (w > Private->EPOC_ScreenSize.iWidth) {
 
590
                // Find the biggest scale value that result the width that fits in the screen HW
 
591
                for (scaleValue = 2; scaleValue++;) {
 
592
                        TInt scaledWidth = (w * (scaleValue-1))/scaleValue;
 
593
                        if (scaledWidth > Private->EPOC_ScreenSize.iWidth)
 
594
                                break;
 
595
                }
 
596
                Private->EPOC_ScreenXScaleValue = Max(2, scaleValue - 1);
 
597
                w = (w * (Private->EPOC_ScreenXScaleValue-1))/Private->EPOC_ScreenXScaleValue;
 
598
        }
 
599
        if (h > Private->EPOC_ScreenSize.iHeight) {
 
600
                // Find the biggest scale value that result the height that fits in the screen HW
 
601
                for (scaleValue = 2; scaleValue++;) {
 
602
                        TInt scaledHeight = (h * (scaleValue-1))/scaleValue;
 
603
                        if (scaledHeight > Private->EPOC_ScreenSize.iHeight)
 
604
                                break;
 
605
                }
 
606
                Private->EPOC_ScreenYScaleValue = Max(2, scaleValue - 1);
 
607
                h = (h * (Private->EPOC_ScreenYScaleValue-1))/Private->EPOC_ScreenYScaleValue;
 
608
        }
 
609
 
 
610
    /* Centralize game window on device screen  */
 
611
    Private->EPOC_ScreenOffset.iX = (Private->EPOC_ScreenSize.iWidth - w) / 2;
 
612
        if (Private->EPOC_ScreenOffset.iX < 0)
 
613
                Private->EPOC_ScreenOffset.iX = 0;
 
614
    Private->EPOC_ScreenOffset.iY = (Private->EPOC_ScreenSize.iHeight - h) / 2;
 
615
        if (Private->EPOC_ScreenOffset.iY < 0)
 
616
                Private->EPOC_ScreenOffset.iY = 0;
 
617
 
 
618
 
 
619
    SDL_TRACE1("View width %d", w);
 
620
    SDL_TRACE1("View height %d", h);
 
621
    SDL_TRACE1("View bmode %d", bpp);
 
622
    SDL_TRACE1("View s %d", scaleValue);
 
623
    SDL_TRACE1("View x %d", Private->EPOC_ScreenOffset.iX);
 
624
    SDL_TRACE1("View y %d", Private->EPOC_ScreenOffset.iY);
 
625
 
 
626
        /* We're done */
 
627
        return(current);
 
628
}
 
629
 
 
630
 
 
631
void RedrawWindowL(_THIS)
 
632
{
 
633
 
 
634
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
635
            LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap
 
636
            Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
 
637
#endif
 
638
 
 
639
    int w = _this->screen->w;
 
640
    int h = _this->screen->h;
 
641
        if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
 
642
                w = _this->screen->h;
 
643
                h = _this->screen->w;
 
644
        }
 
645
    if ((w < Private->EPOC_ScreenSize.iWidth)
 
646
        || (h < Private->EPOC_ScreenSize.iHeight)) {
 
647
                DrawBackground(_this);
 
648
    }
 
649
 
 
650
    /* Tell the system that something has been drawn */
 
651
        TRect  rect = TRect(Private->EPOC_WsWindow.Size());
 
652
        Private->EPOC_WsWindow.Invalidate(rect);
 
653
 
 
654
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
655
        Private->EPOC_WsWindow.BeginRedraw(rect);
 
656
        Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
 
657
        Private->EPOC_WsWindow.EndRedraw();
 
658
        Private->EPOC_WindowGc->Deactivate();
 
659
    UnlockHeap(Private->EPOC_Bitmap);; // Unlock bitmap heap
 
660
        Private->EPOC_WsSession.Flush();
 
661
#endif
 
662
 
 
663
    /* Draw current buffer */
 
664
    SDL_Rect fullScreen;
 
665
    fullScreen.x = 0;
 
666
    fullScreen.y = 0;
 
667
    fullScreen.w = _this->screen->w;
 
668
    fullScreen.h = _this->screen->h;
 
669
    EPOC_DirectUpdate(_this, 1, &fullScreen);
 
670
}
 
671
 
 
672
 
 
673
void DrawBackground(_THIS)
 
674
{
 
675
        /* Draw background */
 
676
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
677
        //warning heap is not locked! - a function calling must ensure that it's ok
 
678
    TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
 
679
#else
 
680
    TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
 
681
#endif
 
682
        // Draw black background
 
683
        Mem::FillZ(screenBuffer, Private->EPOC_BytesPerScreen);
 
684
 
 
685
#if 0
 
686
    for (int y = 0; y < Private->EPOC_ScreenSize.iHeight; y++) {
 
687
                for (int x = 0; x < Private->EPOC_ScreenSize.iWidth; x++) {
 
688
#ifdef SYMBIAN_CRYSTAL
 
689
                        const TUint16 color = 0; // ((x+y)>>1) & 0xf; /* Draw blue stripes pattern, because in e.g. 320x200 mode there is a big background area*/
 
690
#else // SYMBIAN_SERIES60
 
691
            const TUint16 color = 0; /* Draw black background */
 
692
#endif
 
693
            *screenBuffer++ = color;
 
694
                }
 
695
        }
 
696
#endif
 
697
}
 
698
 
 
699
 
 
700
/* We don't actually allow hardware surfaces other than the main one */
 
701
static int EPOC_AllocHWSurface(_THIS, SDL_Surface* /*surface*/)
 
702
{
 
703
        return(-1);
 
704
}
 
705
static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
 
706
{
 
707
        return;
 
708
}
 
709
 
 
710
static int EPOC_LockHWSurface(_THIS, SDL_Surface* /*surface*/)
 
711
{
 
712
        return(0);
 
713
}
 
714
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
 
715
{
 
716
        return;
 
717
}
 
718
 
 
719
static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
 
720
{
 
721
        return(0);
 
722
}
 
723
 
 
724
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
 
725
{
 
726
    //TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup();//these are async services
 
727
   // if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) {              //for that cannot be called from
 
728
                                                                            //SDL threads ???
 
729
    if (!Private->EPOC_IsWindowFocused)
 
730
        {
 
731
        /* Force focus window to redraw again for cleaning away SDL screen graphics */
 
732
/*
 
733
        TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition();
 
734
        Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt);
 
735
        TRect  rect = TRect(Private->EPOC_WsWindow.Size());
 
736
        Private->EPOC_WsWindow.Invalidate(rect);
 
737
        Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal);
 
738
       */ /* If this is not the topmost window, wait here! Sleep for 1 second to give cpu time to 
 
739
           multitasking and poll for being the topmost window.
 
740
        */
 
741
    //    if (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID) {
 
742
           
 
743
                   /* !!TODO: Could call GetRedraw() etc. for WsSession and redraw the screen if needed. That might be 
 
744
                      needed if a small dialog comes in front of Game screen.
 
745
                   */
 
746
           // while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID)
 
747
        
 
748
        SDL_PauseAudio(1);
 
749
        SDL_Delay(1000);
 
750
        return;
 
751
      //  }
 
752
 
 
753
    //    RedrawWindowL(_this);  
 
754
    }
 
755
 
 
756
    SDL_PauseAudio(0);
 
757
 
 
758
        // if we are not focused, do not draw
 
759
//      if (!Private->EPOC_IsWindowFocused)
 
760
//              return;
 
761
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
762
        TBitmapUtil lock(Private->EPOC_Bitmap); 
 
763
    lock.Begin(TPoint(0,0)); // Lock bitmap heap
 
764
        Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
 
765
    TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
 
766
#else
 
767
    TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
 
768
#endif
 
769
 
 
770
        if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270)
 
771
                DirectDrawRotated(_this, numrects, rects, screenBuffer);
 
772
        else
 
773
                DirectDraw(_this, numrects, rects, screenBuffer);
 
774
    
 
775
   
 
776
#if defined(__WINS__) || defined(TEST_BM_DRAW)
 
777
 
 
778
        TRect  rect = TRect(Private->EPOC_WsWindow.Size());
 
779
        Private->EPOC_WsWindow.Invalidate(rect);
 
780
        Private->EPOC_WsWindow.BeginRedraw(rect);
 
781
        Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
 
782
        Private->EPOC_WsWindow.EndRedraw();
 
783
        Private->EPOC_WindowGc->Deactivate();
 
784
    lock.End(); // Unlock bitmap heap
 
785
        Private->EPOC_WsSession.Flush();
 
786
#else
 
787
#ifndef SYMBIAN_CRYSTAL
 
788
        // This is not needed in Crystal. What is the performance penalty in SERIES60?
 
789
    TRect  rect2 = TRect(Private->EPOC_WsWindow.Size());
 
790
    
 
791
    Private->EPOC_DrawDevice->UpdateRegion(rect2); // Should we update rects parameter area only??
 
792
    Private->EPOC_DrawDevice->Update();
 
793
#endif
 
794
#endif
 
795
 
 
796
    /* Update virtual cursor. !!Do not yet work properly
 
797
    Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition());
 
798
    */
 
799
 
 
800
    /*static int foo = 1;
 
801
 
 
802
        for ( int i=0; i < numrects; ++i ) {
 
803
        const SDL_Rect& currentRect = rects[i];
 
804
        SDL_Rect rect2;
 
805
        rect2.x = currentRect.x;
 
806
        rect2.y = currentRect.y;
 
807
        rect2.w = currentRect.w;
 
808
        rect2.h = currentRect.h;
 
809
 
 
810
        if (rect2.w <= 0 || rect2.h <= 0) 
 
811
            continue;
 
812
 
 
813
    
 
814
    foo++;
 
815
    if((foo % 200) == 0)
 
816
        {
 
817
        SDL_TRACE1("foo %d", foo);
 
818
        CFbsBitmap* b = new (ELeave) CFbsBitmap;
 
819
        SDL_TRACE1("bee %d", (int)b);
 
820
        int e = b->Create(TSize(currentRect.w, currentRect.h), Private->EPOC_DisplayMode);
 
821
        
 
822
        SDL_TRACE1("err %d", e);
 
823
        if(e != KErrNone)
 
824
            User::Panic(_L("damn"), e);
 
825
 
 
826
        TBitmapUtil u(b);
 
827
        u.Begin(TPoint(0, 0));
 
828
        TUint32* d = b->DataAddress();
 
829
        
 
830
        SDL_TRACE1("addr %d", (int)d);
 
831
 
 
832
        for(TInt o = 0; o < currentRect.h; o++)
 
833
            for(TInt p = 0; p < currentRect.w; p++)
 
834
                {
 
835
                u.SetPos(TPoint(p, o));
 
836
                u.SetPixel(0xFFFF);
 
837
                }
 
838
 
 
839
        SDL_TRACE1("w %d", (int)currentRect.w);
 
840
        SDL_TRACE1("h %d", (int)currentRect.h);
 
841
 
 
842
        SDL_TRACE1("addr %d", (int)Private->EPOC_DisplayMode);
 
843
 
 
844
        
 
845
        const TUint f = (TUint)Private->EPOC_FrameBuffer;
 
846
        const TUint y = (TUint)Private->EPOC_BytesPerScreen;
 
847
 
 
848
        
 
849
        SDL_TRACE1("frame %u", f);
 
850
        SDL_TRACE1("bytes %u", y);
 
851
 
 
852
        Mem::Copy(d, Private->EPOC_FrameBuffer, Private->EPOC_BytesPerScreen);
 
853
 
 
854
        SDL_TRACE("kopied");
 
855
 
 
856
        u.End();
 
857
        TBuf<32> name;
 
858
        name.Format(_L("C:\\nokia\\images\\doom%d.mbm"), (foo / 200));
 
859
        e= b->Save(name);
 
860
        if(e != KErrNone)
 
861
            User::Panic(_L("damned"), e);
 
862
        delete b;
 
863
            }}*/
 
864
}
 
865
 
 
866
 
 
867
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
 
868
{
 
869
        TInt i;
 
870
 
 
871
    const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;   
 
872
    const TPoint fixedOffset = Private->EPOC_ScreenOffset;   
 
873
    const TInt screenW = _this->screen->w;
 
874
    const TInt screenH = _this->screen->h;
 
875
    const TInt sourceScanlineLength = screenW;
 
876
    const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
 
877
 
 
878
        /* Render the rectangles in the list */
 
879
 
 
880
        for ( i=0; i < numrects; ++i ) {
 
881
        const SDL_Rect& currentRect = rects[i];
 
882
        SDL_Rect rect2;
 
883
        rect2.x = currentRect.x;
 
884
        rect2.y = currentRect.y;
 
885
        rect2.w = currentRect.w;
 
886
        rect2.h = currentRect.h;
 
887
 
 
888
        if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
 
889
            continue;
 
890
 
 
891
        /* All variables are measured in pixels */
 
892
 
 
893
        /* Check rects validity, i.e. upper and lower bounds */
 
894
        TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
 
895
        TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
 
896
        if (maxX < 0 || maxY < 0) /* sanity check */
 
897
            continue;
 
898
                /* Clip from bottom */
 
899
        maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1); 
 
900
                /* TODO: Clip from the right side */
 
901
 
 
902
        const TInt sourceRectWidth = maxX - rect2.x + 1;
 
903
        const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
 
904
        const TInt sourceRectHeight = maxY - rect2.y + 1;
 
905
        const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
 
906
                const TUint skipValue = 1; // no skip
 
907
 
 
908
        TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY +rect2.y) * targetScanlineLength;   
 
909
        
 
910
        // Nokia7650 native mode: 12 bpp --> 12 bpp
 
911
        //
 
912
 
 
913
        switch (_this->screen->format->BitsPerPixel)
 
914
                        {
 
915
                case 12:
 
916
                        {
 
917
                        TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
 
918
                        TUint16* screenMemory = screenBuffer + targetStartOffset;
 
919
                        if (skipValue == 1)
 
920
                                {
 
921
                                for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
922
                                        {
 
923
                                        Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
 
924
                                        }
 
925
                                        bitmapLine += sourceScanlineLength;
 
926
                                        screenMemory += targetScanlineLength;
 
927
                                }
 
928
                        else
 
929
                                {
 
930
                                for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
931
                                        {
 
932
                                        //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case.
 
933
                                        TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */
 
934
                                        TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
935
                                        for(TInt x = 0 ; x < sourceRectWidth ; x++)
 
936
                                                {                                       
 
937
                                                __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt));
 
938
                                                __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
 
939
                                                __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
 
940
                                                __ASSERT_DEBUG(bitmapLine >=  (TUint16*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
 
941
                    
 
942
                                                *screenMemoryLinePos++ = *bitmapPos;
 
943
                                                bitmapPos+=skipValue;
 
944
                                                }
 
945
                                        bitmapLine += sourceScanlineLength;
 
946
                                        screenMemory += targetScanlineLength;
 
947
                                        }
 
948
                                }
 
949
                        }
 
950
                        break;
 
951
        // 256 color paletted mode: 8 bpp  --> 12 bpp
 
952
        //
 
953
                default:
 
954
                        {
 
955
            if(Private->EPOC_BytesPerPixel <= 2)
 
956
                {
 
957
                            TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
 
958
                TUint16* screenMemory = screenBuffer + targetStartOffset;
 
959
                                    for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
960
                                            {
 
961
                                            TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
 
962
                                            TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
963
                                            /* Convert each pixel from 256 palette to 4k color values */
 
964
                                            for(TInt x = 0 ; x < sourceRectWidth ; x++)
 
965
                                                    {
 
966
                                                    __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
 
967
                                                    __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
 
968
                                                    __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
 
969
                                                    __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));               
 
970
                                                    *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++];
 
971
    //                                          bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip
 
972
                                                    }
 
973
                                            bitmapLine += sourceScanlineLength;
 
974
                                            screenMemory += targetScanlineLength;
 
975
                                            }
 
976
                }
 
977
            else
 
978
                {
 
979
                TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
 
980
                TUint32* screenMemory = reinterpret_cast<TUint32*>(screenBuffer + targetStartOffset);
 
981
                                    for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
982
                                            {
 
983
                                            TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
 
984
                                            TUint32* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
985
                                            /* Convert each pixel from 256 palette to 4k color values */
 
986
                                            for(TInt x = 0 ; x < sourceRectWidth ; x++)
 
987
                                                    {
 
988
                                                    __ASSERT_DEBUG(screenMemoryLinePos < (reinterpret_cast<TUint32*>(screenBuffer) + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
 
989
                                                    __ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast<TUint32*>(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt));
 
990
                                                    __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
 
991
                                                    __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));               
 
992
                                                    *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos++];
 
993
    //                                          bitmapPos+=skipValue; //TODO: optimize: separate loops for 1, 2 and n skip
 
994
                                                    }
 
995
                                            bitmapLine += sourceScanlineLength;
 
996
                                            screenMemory += targetScanlineLength;
 
997
                                            }
 
998
                }
 
999
                        }
 
1000
                } // switch
 
1001
        } // for
 
1002
}
 
1003
 
 
1004
/*
 
1005
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
 
1006
{
 
1007
        TInt i;
 
1008
    const TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;   
 
1009
    const TPoint fixedOffset = Private->EPOC_ScreenOffset;   
 
1010
    const TInt screenW = _this->screen->w;
 
1011
    const TInt screenH = _this->screen->h;
 
1012
    const TInt sourceScanlineLength = screenW;
 
1013
    const TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
 
1014
 
 
1015
        /* Render the rectangles in the list */
 
1016
 
 
1017
/*      for ( i=0; i < numrects; ++i ) {
 
1018
        const SDL_Rect& currentRect = rects[i];
 
1019
        SDL_Rect rect2;
 
1020
        rect2.x = currentRect.x;
 
1021
        rect2.y = currentRect.y;
 
1022
        rect2.w = currentRect.w;
 
1023
        rect2.h = currentRect.h;
 
1024
 
 
1025
        if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
 
1026
/*            continue;
 
1027
 
 
1028
        /* All variables are measured in pixels */
 
1029
 
 
1030
        /* Check rects validity, i.e. upper and lower bounds */
 
1031
/*        TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
 
1032
        TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
 
1033
        if (maxX < 0 || maxY < 0) /* sanity check */
 
1034
/*            continue;
 
1035
                /* Clip from bottom */
 
1036
/*        maxY = Min(maxY, Private->EPOC_ScreenSize.iHeight-1); 
 
1037
                /* TODO: Clip from the right side */
 
1038
 
 
1039
/*              TInt sourceRectWidth = maxX - rect2.x + 1;
 
1040
        const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
 
1041
        const TInt sourceRectHeight = maxY - rect2.y + 1;
 
1042
        const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
 
1043
                const TUint skipValue = Private->EPOC_ScreenXScaleValue; //1; // no skip
 
1044
 
 
1045
                const TInt targetStartOffset = // = (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) ;
 
1046
                        (skipValue > 1 ? 
 
1047
                        (fixedOffset.iX + (rect2.x / skipValue) + (fixedOffset.iY + rect2.y) * targetScanlineLength ) : 
 
1048
                        (fixedOffset.iX +  rect2.x              + (fixedOffset.iY + rect2.y) * targetScanlineLength ));
 
1049
 
 
1050
                __ASSERT_DEBUG(skipValue >= 1, User::Panic(KLibName, KErrArgument));
 
1051
 
 
1052
        // Nokia7650 native mode: 12 bpp --> 12 bpp
 
1053
        //
 
1054
        switch (_this->screen->format->BitsPerPixel)
 
1055
                        {
 
1056
                case 12:
 
1057
                        {
 
1058
                        TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
 
1059
                        TUint16* screenMemory = screenBuffer + targetStartOffset;
 
1060
                        if (skipValue == 1)
 
1061
                                {
 
1062
                                for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
1063
                                        {
 
1064
                                        Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
 
1065
                                        }
 
1066
                                        bitmapLine += sourceScanlineLength;
 
1067
                                        screenMemory += targetScanlineLength;
 
1068
                                }
 
1069
                        else
 
1070
                                {
 
1071
                                for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
1072
                                        {
 
1073
                                        //TODO: optimize: separate loops for 1, 2 and n skip. Mem::Copy() can be used in unscaled case.
 
1074
                                        TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */
 
1075
/*                                      TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
1076
/*                                      for(TInt x = 0 ; x < sourceRectWidth ; x++)
 
1077
                                                {                                       
 
1078
                                                __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt));
 
1079
                                                __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
 
1080
                                                __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
 
1081
                                                __ASSERT_DEBUG(bitmapLine >=  (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
 
1082
                    
 
1083
                                                *screenMemoryLinePos++ = *bitmapPos;
 
1084
                                                bitmapPos+=skipValue;
 
1085
                                                }
 
1086
                                        bitmapLine += sourceScanlineLength;
 
1087
                                        screenMemory += targetScanlineLength;
 
1088
                                        }
 
1089
                                }
 
1090
                        }
 
1091
                        break;
 
1092
        // 256 color paletted mode: 8 bpp  --> 12 bpp
 
1093
        //
 
1094
                default:
 
1095
                        {
 
1096
                        TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
 
1097
            TUint16* screenMemory = screenBuffer + targetStartOffset;
 
1098
                        if (skipValue > 1)
 
1099
                                sourceRectWidth /= skipValue;
 
1100
#if defined __MARM_ARMI__
 
1101
                        __asm volatile("
 
1102
                                mov             %4, %4, lsl #1  @ targetScanLineLength is in pixels, we need it in bytes
 
1103
                        1:
 
1104
                                mov             r6, %0                  @ bitmapLine
 
1105
                                mov             r7, %2                  @ screenMemory
 
1106
                                mov             r8, %6                  @ sourceRectWidth
 
1107
                        2:
 
1108
                                ldrb    r4, [%0], %7                    @ r4 = *bitmapPos; bitmapPos += skipValue
 
1109
                                ldr             r5, [%1, r4, lsl #2]    @ only 16 lower bits actually used
 
1110
                                subs    r8, r8, #1                              @ x--
 
1111
                                strh    r5, [%2], #2                    @ *screenMemoryLinePos++ = r4
 
1112
                                bne             2b
 
1113
 
 
1114
                                add             %0, r6, %3              @ bitmapLine += sourceScanlineLength
 
1115
                                add             %2, r7, %4              @ screenMemory += targetScanlineLength
 
1116
                                subs    %5, %5, #1              @ sourceRectHeight--
 
1117
                                bne             1b
 
1118
                                "
 
1119
                                : // no output
 
1120
                                //              %0                                                              %1                                                      %2                                              %3                                                      %4                                              %5                                                      %6                                      %7
 
1121
                                : "r" (bitmapLine), "r" (&EPOC_HWPalette_256_to_Screen[0]), "r" (screenMemory), "r" (sourceScanlineLength), "r" (targetScanlineLength), "r" (sourceRectHeight), "r" (sourceRectWidth), "r" (skipValue)
 
1122
                                : "r4", "r5", "r6", "r7", "r8"
 
1123
                        );
 
1124
#else
 
1125
                        for(TInt y = 0 ; y < sourceRectHeight ; y++)
 
1126
                                {
 
1127
                                TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
 
1128
/*                              TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
1129
                                /* Convert each pixel from 256 palette to 4k color values */
 
1130
/*                              for (TInt x = 0 ; x < sourceRectWidth ; x++)
 
1131
                                        {
 
1132
                                        //__ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt));
 
1133
                                        //__ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
 
1134
                                        //__ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
 
1135
                                        //__ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
 
1136
            
 
1137
                                        *screenMemoryLinePos++ = EPOC_HWPalette_256_to_Screen[*bitmapPos];
 
1138
                                        bitmapPos += skipValue;
 
1139
                                        }
 
1140
                                bitmapLine += sourceScanlineLength;
 
1141
                                screenMemory += targetScanlineLength;
 
1142
                                }
 
1143
//#endif
 
1144
                        }
 
1145
                } // switch
 
1146
        } // for
 
1147
}
 
1148
*/
 
1149
 
 
1150
void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
 
1151
{
 
1152
        TInt i;
 
1153
//    TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;   
 
1154
    TPoint fixedScreenOffset = Private->EPOC_ScreenOffset;   
 
1155
    TInt bufferW = _this->screen->w;
 
1156
    TInt bufferH = _this->screen->h;
 
1157
    TInt ScreenW = Private->EPOC_ScreenSize.iWidth;
 
1158
//    TInt ScreenH = Private->EPOC_ScreenSize.iWidth;
 
1159
    TInt sourceW = bufferW;
 
1160
    TInt sourceH = bufferH;
 
1161
    TInt targetW = ScreenW - fixedScreenOffset.iX * 2;
 
1162
//    TInt targetH = ScreenH - fixedScreenOffset.iY * 2;
 
1163
        TInt sourceScanlineLength = bufferW;
 
1164
    TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
 
1165
 
 
1166
        /* Render the rectangles in the list */
 
1167
 
 
1168
        for ( i=0; i < numrects; ++i ) {
 
1169
        SDL_Rect rect2;
 
1170
        const SDL_Rect& currentRect = rects[i];
 
1171
        rect2.x = currentRect.x;
 
1172
        rect2.y = currentRect.y;
 
1173
        rect2.w = currentRect.w;
 
1174
        rect2.h = currentRect.h;
 
1175
 
 
1176
        if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
 
1177
            continue;
 
1178
 
 
1179
        /* All variables are measured in pixels */
 
1180
 
 
1181
        /* Check rects validity, i.e. upper and lower bounds */
 
1182
        TInt maxX = Min(sourceW - 1, rect2.x + rect2.w - 1);
 
1183
        TInt maxY = Min(sourceH - 1, rect2.y + rect2.h - 1);
 
1184
        if (maxX < 0 || maxY < 0) /* sanity check */
 
1185
            continue;
 
1186
                /* Clip from bottom */
 
1187
        //maxX = Min(maxX, Private->EPOC_ScreenSize.iHeight-1); 
 
1188
                /* TODO: Clip from the right side */
 
1189
 
 
1190
        TInt sourceRectWidth = maxX - rect2.x + 1;
 
1191
//        TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
 
1192
        TInt sourceRectHeight = maxY - rect2.y + 1;
 
1193
        TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
 
1194
        TInt targetStartOffset = fixedScreenOffset.iX + (targetW-1 - rect2.y) + (fixedScreenOffset.iY +rect2.x) * targetScanlineLength;   
 
1195
        
 
1196
        // Nokia7650 native mode: 12 bpp --> 12 bpp
 
1197
        if (_this->screen->format->BitsPerPixel == 12) { 
 
1198
            
 
1199
            /* !!TODO: not yet implemented
 
1200
 
 
1201
                TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
 
1202
            TUint16* screenMemory = screenBuffer + targetStartOffset;
 
1203
            for(TInt y = 0 ; y < sourceRectHeight ; y++) {
 
1204
                                //TODO: optimize: separate loops for 1, 2 and n skip
 
1205
                        //Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
 
1206
                TUint16* bitmapPos = bitmapLine; // 2 bytes per pixel 
 
1207
                TUint16* screenMemoryLinePos = screenMemory; // 2 bytes per pixel 
 
1208
                                for(TInt x = 0 ; x < sourceRectWidth ; x++) {
 
1209
 
 
1210
                                        __ASSERT_DEBUG(screenMemory < (screenBuffer + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), User::Panic(KLibName, KErrCorrupt));
 
1211
                                        __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
 
1212
                                        __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
 
1213
                                        __ASSERT_DEBUG(bitmapLine >=  (TUint16*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
 
1214
                    
 
1215
                      *screenMemoryLinePos = *bitmapPos;
 
1216
                    bitmapPos++;
 
1217
                    screenMemoryLinePos += targetScanlineLength;
 
1218
                }
 
1219
                        bitmapLine += sourceScanlineLength;
 
1220
                        screenMemory--;
 
1221
            }
 
1222
 
 
1223
            */
 
1224
        }
 
1225
        // 256 color paletted mode: 8 bpp  --> 12 bpp
 
1226
        else { 
 
1227
                TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
 
1228
            TUint16* screenMemory = screenBuffer + targetStartOffset;
 
1229
                        TInt screenXScaleValue = Private->EPOC_ScreenXScaleValue;
 
1230
                        TInt debug_ycount=0;
 
1231
            for(TInt y = 0 ; y < sourceRectHeight ; y++) {
 
1232
                                if(--screenXScaleValue) {
 
1233
                                        TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
 
1234
                                        TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
 
1235
                                        TInt screenYScaleValue = Private->EPOC_ScreenYScaleValue;
 
1236
                                        TInt debug_xcount=0;
 
1237
                                        /* Convert each pixel from 256 palette to 4k color values */
 
1238
                                        for(TInt x = 0 ; x < sourceRectWidth ; x++) {
 
1239
                                                if(--screenYScaleValue) {
 
1240
                                                        
 
1241
                            __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), User::Panic(KLibName, KErrCorrupt));
 
1242
                                                        __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(KLibName, KErrCorrupt));
 
1243
                                                        __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + (_this->screen->w * _this->screen->h)), User::Panic(KLibName, KErrCorrupt));
 
1244
                                                        __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, User::Panic(KLibName, KErrCorrupt));
 
1245
                                                        
 
1246
                            *screenMemoryLinePos = TUint16(EPOC_HWPalette_256_to_Screen[*bitmapPos]);
 
1247
                                                        screenMemoryLinePos += targetScanlineLength; debug_xcount++;
 
1248
                                                }
 
1249
                                                else
 
1250
                                                        screenYScaleValue = Private->EPOC_ScreenYScaleValue;
 
1251
                                                bitmapPos++; 
 
1252
                                        }
 
1253
                                        screenMemory--; debug_ycount++;
 
1254
                                } // endif
 
1255
                                else
 
1256
                                        screenXScaleValue = Private->EPOC_ScreenXScaleValue;
 
1257
                                bitmapLine += sourceScanlineLength;
 
1258
             }
 
1259
            }
 
1260
    }    
 
1261
}
 
1262
 
 
1263
 
 
1264
/* Note:  If we are terminated, this could be called in the middle of
 
1265
   another SDL video routine -- notably UpdateRects.
 
1266
*/
 
1267
void EPOC_VideoQuit(_THIS)
 
1268
{
 
1269
        int i;
 
1270
 
 
1271
        /* Free video mode lists */
 
1272
        for ( i=0; i<SDL_NUMMODES; ++i ) {
 
1273
                if ( Private->SDL_modelist[i] != NULL ) {
 
1274
                        free(Private->SDL_modelist[i]);
 
1275
                        Private->SDL_modelist[i] = NULL;
 
1276
                }
 
1277
        }
 
1278
        
 
1279
    if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) {
 
1280
                /* Direct screen access, no memory buffer */
 
1281
                _this->screen->pixels = NULL;
 
1282
        }
 
1283
 
 
1284
    if (_this->screen && _this->screen->pixels) {
 
1285
        free(_this->screen->pixels);
 
1286
        _this->screen->pixels = NULL;
 
1287
    }
 
1288
 
 
1289
    /* Free Epoc resources */
 
1290
 
 
1291
    /* Disable events for me */
 
1292
        if (Private->EPOC_WsEventStatus != KRequestPending)
 
1293
                Private->EPOC_WsSession.EventReadyCancel();
 
1294
        if (Private->EPOC_RedrawEventStatus != KRequestPending)
 
1295
                Private->EPOC_WsSession.RedrawReadyCancel();
 
1296
 
 
1297
        #if defined(__WINS__) || defined(TEST_BM_DRAW)
 
1298
        delete Private->EPOC_Bitmap;
 
1299
        Private->EPOC_Bitmap = NULL;
 
1300
        #else
 
1301
    #endif
 
1302
 
 
1303
#ifndef SYMBIAN_CRYSTAL
 
1304
        free(Private->EPOC_DrawDevice);
 
1305
#endif
 
1306
 
 
1307
        if (Private->EPOC_WsWindow.WsHandle())
 
1308
                Private->EPOC_WsWindow.Close();
 
1309
 
 
1310
        if (Private->EPOC_WsWindowGroup.WsHandle())
 
1311
                Private->EPOC_WsWindowGroup.Close();
 
1312
 
 
1313
        delete Private->EPOC_WindowGc;
 
1314
        Private->EPOC_WindowGc = NULL;
 
1315
 
 
1316
        delete Private->EPOC_WsScreen;
 
1317
        Private->EPOC_WsScreen = NULL;
 
1318
 
 
1319
        if (Private->EPOC_WsSession.WsHandle())
 
1320
                Private->EPOC_WsSession.Close();
 
1321
}
 
1322
 
 
1323
 
 
1324
WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
 
1325
{
 
1326
        return (WMcursor *) 9210; // it's ok to return something unuseful but true
 
1327
}
 
1328
 
 
1329
void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
 
1330
{
 
1331
    /* Disable virtual cursor */
 
1332
    HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
 
1333
    Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
 
1334
}
 
1335
 
 
1336
int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
 
1337
{
 
1338
 
 
1339
    if (cursor ==  (WMcursor *)9210) {
 
1340
        /* Enable virtual cursor */
 
1341
            Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal);
 
1342
        if (isCursorVisible)
 
1343
                HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
 
1344
        else
 
1345
            Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
 
1346
    }
 
1347
    else {
 
1348
        /* Disable virtual cursor */
 
1349
        HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
 
1350
        Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
 
1351
    }
 
1352
 
 
1353
        return(1);
 
1354
}
 
1355
 
 
1356
}; // extern "C"