os/graphics/graphicsdeviceinterface/gdi/sgdi/PRINTGDI.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.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <gdi.h>
sl@0
    17
#include <f32file.h>
sl@0
    18
#include <s32file.h>
sl@0
    19
#include <bautils.h>
sl@0
    20
#include <barsc.h>
sl@0
    21
#include <barsread.h>
sl@0
    22
#include "GDIPANIC.h"
sl@0
    23
sl@0
    24
_LIT(KPdrExtension,"*.PDR"); // must be capitalized
sl@0
    25
_LIT(KPdlExtension,".PDL"); // must be capitalized
sl@0
    26
_LIT(KUdlExtension,".UDL"); // must be capitalized
sl@0
    27
_LIT(KRscExtension,".RSC");
sl@0
    28
_LIT(KGdiPrintPanic,"GDI - PRINT");
sl@0
    29
sl@0
    30
_LIT(KGDIPanicDesc1, "GDI Pdr internal Panic %S, in file %S @ line %i");
sl@0
    31
_LIT(KGDIPanicDesc2, "Assert condition = \"%S\"");
sl@0
    32
sl@0
    33
enum TPdrStorePanic
sl@0
    34
	{
sl@0
    35
	EPdrModelIndexOutOfRange,
sl@0
    36
	EPdrModelUidNotFound,
sl@0
    37
	EPdrDirectoryIndexOutOfRange,
sl@0
    38
	EPdrFileIndexOutOfRange,
sl@0
    39
	EPdrPrinterDeviceExists,
sl@0
    40
	EPdrPrinterDeviceDoesNotExist,
sl@0
    41
	};
sl@0
    42
sl@0
    43
void Panic(TPdrStorePanic aPanic)
sl@0
    44
	{
sl@0
    45
	User::Panic(KGdiPrintPanic,aPanic);
sl@0
    46
	}
sl@0
    47
	
sl@0
    48
void PanicWithCondAndInfo(TPdrStorePanic aError, const TDesC& aCondition, const TDesC& aFileName, const TDesC& aPanicName, TInt aLine)
sl@0
    49
	{
sl@0
    50
	TBuf<256> buf;
sl@0
    51
	buf.Format(KGDIPanicDesc1, &aPanicName, &aFileName, aLine);
sl@0
    52
	RDebug::Print(buf);
sl@0
    53
sl@0
    54
	buf.Format(KGDIPanicDesc2, &aCondition);
sl@0
    55
	RDebug::Print(buf);
sl@0
    56
	Panic(aError);
sl@0
    57
	}
sl@0
    58
sl@0
    59
//
sl@0
    60
// TPrinterModelEntry
sl@0
    61
//
sl@0
    62
sl@0
    63
sl@0
    64
EXPORT_C void TPrinterModelEntry::InternalizeL(RReadStream& aStream)
sl@0
    65
sl@0
    66
/** Internalises a printer model entry from a read stream. 
sl@0
    67
sl@0
    68
The presence of this function means that the standard templated stream operator>>(), 
sl@0
    69
defined in s32strm.h, is available to internalise objects of this class.
sl@0
    70
sl@0
    71
@param aStream The read stream. */
sl@0
    72
    {
sl@0
    73
	aStream >> iModelName;
sl@0
    74
	iRequiresPrinterPort=aStream.ReadUint8L();
sl@0
    75
	aStream >> iUid;
sl@0
    76
	}
sl@0
    77
sl@0
    78
sl@0
    79
EXPORT_C void TPrinterModelEntry::ExternalizeL(RWriteStream& aStream) const
sl@0
    80
/** Externalises the printer model entry to a write stream.
sl@0
    81
sl@0
    82
The presence of this function means that the standard templated stream operator<<(), 
sl@0
    83
defined in s32strm.h, is available to externalise objects of this class.
sl@0
    84
sl@0
    85
@param aStream The write stream. */
sl@0
    86
	{
sl@0
    87
	aStream << iModelName;
sl@0
    88
	aStream.WriteUint8L((TUint8) iRequiresPrinterPort);
sl@0
    89
	aStream << iUid;
sl@0
    90
	}
sl@0
    91
sl@0
    92
//
sl@0
    93
// TPrinterModelHeader
sl@0
    94
//
sl@0
    95
sl@0
    96
sl@0
    97
EXPORT_C void TPrinterModelHeader::InternalizeL(RReadStream& aStream)
sl@0
    98
/** Internalises a printer model header from a read stream. 
sl@0
    99
sl@0
   100
The presence of this function means that the standard templated stream operator>>(), 
sl@0
   101
defined in s32strm.h, is available to internalise objects of this class.
sl@0
   102
sl@0
   103
@param aStream The read stream. */
sl@0
   104
 	{
sl@0
   105
	aStream >> iEntry;
sl@0
   106
	aStream >> iModelDataStreamId;
sl@0
   107
	}
sl@0
   108
sl@0
   109
sl@0
   110
EXPORT_C void TPrinterModelHeader::ExternalizeL(RWriteStream& aStream) const
sl@0
   111
 
sl@0
   112
/** Externalises the printer model header to a write stream.
sl@0
   113
sl@0
   114
The presence of this function means that the standard templated stream operator<<(), 
sl@0
   115
defined in s32strm.h, is available to externalise objects of this class.
sl@0
   116
@param aStream The write stream. */
sl@0
   117
    {
sl@0
   118
	aStream << iEntry;
sl@0
   119
	aStream << iModelDataStreamId;
sl@0
   120
	}
sl@0
   121
sl@0
   122
//
sl@0
   123
// CPrinterDevice
sl@0
   124
//
sl@0
   125
sl@0
   126
EXPORT_C CPrinterDevice::CPrinterDevice():
sl@0
   127
	CGraphicsDevice(),
sl@0
   128
	iCurrentPageSpecInTwips()
sl@0
   129
/** Standard constructor. */
sl@0
   130
	{}
sl@0
   131
sl@0
   132
sl@0
   133
EXPORT_C CPrinterDevice::~CPrinterDevice()
sl@0
   134
sl@0
   135
/** Destructor.
sl@0
   136
It frees all resources owned by the object, prior to its destruction. */
sl@0
   137
	{
sl@0
   138
	delete iControl;
sl@0
   139
	}
sl@0
   140
sl@0
   141
sl@0
   142
EXPORT_C void CPrinterDevice::SelectPageSpecInTwips(const TPageSpec& aPageSpecInTwips)
sl@0
   143
/** Sets the page specification in twips.
sl@0
   144
@param  aPageSpec The page specification in twips. */	
sl@0
   145
    {
sl@0
   146
	iCurrentPageSpecInTwips=aPageSpecInTwips;
sl@0
   147
	}
sl@0
   148
sl@0
   149
sl@0
   150
EXPORT_C TRect CPrinterDevice::PrintablePageInPixels() const
sl@0
   151
/** Gets the dimensions of the area to which the printer device can print.
sl@0
   152
sl@0
   153
These dimensions are normally less than those returned by TPageSpec::OrientedPageSize() 
sl@0
   154
because a margin exists between the boundary of the printable page and the 
sl@0
   155
absolute extent of the page.
sl@0
   156
sl@0
   157
@return The dimensions of the printer device area in pixels, respecting the 
sl@0
   158
page orientation */
sl@0
   159
	{
sl@0
   160
	return TRect(SizeInPixels());
sl@0
   161
	}
sl@0
   162
sl@0
   163
sl@0
   164
EXPORT_C void CPrinterDevice::DeleteControl()
sl@0
   165
 /** Deletes the printer control owned by this object.
sl@0
   166
sl@0
   167
The function sets the iControl member to NULL. */
sl@0
   168
    {
sl@0
   169
	delete iControl;
sl@0
   170
	iControl=NULL;
sl@0
   171
	}
sl@0
   172
sl@0
   173
sl@0
   174
EXPORT_C void CPrinterDevice::RestorePropertiesL()
sl@0
   175
/** Restores printer properties. */	
sl@0
   176
    {
sl@0
   177
	_LIT(KSystemIniFileNameSpec,"Z:\\System\\System.ini");
sl@0
   178
sl@0
   179
	RFs fs;
sl@0
   180
	User::LeaveIfError(fs.Connect());
sl@0
   181
	CleanupClosePushL(fs);
sl@0
   182
	
sl@0
   183
	TDriveUnit drive(static_cast<TUint>(RFs::GetSystemDrive()));
sl@0
   184
	TParse systemIniFileName;
sl@0
   185
	systemIniFileName.Set(drive.Name(), &KSystemIniFileNameSpec, NULL);
sl@0
   186
	
sl@0
   187
	TUint atts = 0;
sl@0
   188
	TInt ret = fs.Att(systemIniFileName.FullName(), atts);
sl@0
   189
	if (ret == KErrNone)
sl@0
   190
		{
sl@0
   191
		CDictionaryStore* dictionarystore = NULL;
sl@0
   192
		TRAPD(err,dictionarystore = CDictionaryFileStore::SystemL(fs));
sl@0
   193
		if (err == KErrNone)
sl@0
   194
			{
sl@0
   195
			CleanupStack::PushL(dictionarystore);
sl@0
   196
			if (dictionarystore->IsPresentL(Model().iUid))
sl@0
   197
				{
sl@0
   198
				RDictionaryReadStream stream;
sl@0
   199
				stream.OpenLC(*dictionarystore,Model().iUid);
sl@0
   200
				InternalizePropertiesL(stream);
sl@0
   201
				CleanupStack::PopAndDestroy(); // stream
sl@0
   202
				}
sl@0
   203
			CleanupStack::PopAndDestroy(); // dictionarystore
sl@0
   204
			}
sl@0
   205
		}
sl@0
   206
	CleanupStack::PopAndDestroy(); // fs
sl@0
   207
	}
sl@0
   208
sl@0
   209
sl@0
   210
EXPORT_C void CPrinterDevice::StorePropertiesL() const
sl@0
   211
/**  Stores the printer properties. */
sl@0
   212
    {
sl@0
   213
	RFs fs;
sl@0
   214
	User::LeaveIfError(fs.Connect());
sl@0
   215
	CleanupClosePushL(fs);
sl@0
   216
	CDictionaryStore* dictionarystore = CDictionaryFileStore::SystemLC(fs);
sl@0
   217
	RDictionaryWriteStream stream;
sl@0
   218
	stream.AssignLC(*dictionarystore,Model().iUid);
sl@0
   219
	ExternalizePropertiesL(stream);
sl@0
   220
	stream.CommitL();
sl@0
   221
	CleanupStack::PopAndDestroy(); // stream
sl@0
   222
	dictionarystore->CommitL();
sl@0
   223
	CleanupStack::PopAndDestroy(2); // dictionarystore, fs
sl@0
   224
	}
sl@0
   225
sl@0
   226
//
sl@0
   227
// CPrinterControl
sl@0
   228
//
sl@0
   229
sl@0
   230
sl@0
   231
EXPORT_C CPrinterControl::~CPrinterControl()
sl@0
   232
/**  Destructor.
sl@0
   233
sl@0
   234
It frees all resources owned by the object, prior to its destruction. */
sl@0
   235
 {
sl@0
   236
	delete iPrinterPort;
sl@0
   237
	}
sl@0
   238
sl@0
   239
EXPORT_C CPrinterControl::CPrinterControl(CPrinterPort* aPrinterPort):
sl@0
   240
	CBase(),
sl@0
   241
	iState(ENotPrinting),
sl@0
   242
	iPrinterPort(aPrinterPort)
sl@0
   243
	{}
sl@0
   244
sl@0
   245
//
sl@0
   246
// TPageSpec
sl@0
   247
//
sl@0
   248
sl@0
   249
sl@0
   250
EXPORT_C TPageSpec::TPageSpec():
sl@0
   251
	iPortraitPageSize(TSize(0,0)),
sl@0
   252
	iOrientation(EPortrait)
sl@0
   253
/** Default constructor. 
sl@0
   254
sl@0
   255
Initialises the page orientation to portrait and the page height and width 
sl@0
   256
to zero. */
sl@0
   257
	{}
sl@0
   258
sl@0
   259
sl@0
   260
EXPORT_C TPageSpec::TPageSpec(TPageOrientation anOrientation,const TSize& aSize):
sl@0
   261
	iPortraitPageSize(aSize),
sl@0
   262
	iOrientation(anOrientation)
sl@0
   263
/** Constructor with page orientation and size. 
sl@0
   264
sl@0
   265
@param aOrientation Specifies the page orientation. 
sl@0
   266
@param aSize Specifies the page size. */
sl@0
   267
 	{}
sl@0
   268
sl@0
   269
sl@0
   270
EXPORT_C void TPageSpec::InternalizeL(RReadStream& aStream)
sl@0
   271
/** Internalises a page specification object from a read stream. 
sl@0
   272
sl@0
   273
The presence of this function means that the standard templated stream operator>>(), 
sl@0
   274
defined in s32strm.h, is available to internalise objects of this class.
sl@0
   275
sl@0
   276
@param aStream The read stream. */
sl@0
   277
 	{
sl@0
   278
	iPortraitPageSize.iWidth = aStream.ReadInt32L();
sl@0
   279
	iPortraitPageSize.iHeight = aStream.ReadInt32L();
sl@0
   280
	iOrientation=(TPageSpec::TPageOrientation)aStream.ReadInt8L();
sl@0
   281
	}
sl@0
   282
sl@0
   283
sl@0
   284
EXPORT_C void TPageSpec::ExternalizeL(RWriteStream& aStream) const
sl@0
   285
/** Externalises the page specification object to a write stream.
sl@0
   286
sl@0
   287
The presence of this function means that the standard templated stream operator<<(), 
sl@0
   288
defined in s32strm.h, is available to externalise objects of this class.
sl@0
   289
@param aStream The write stream. */
sl@0
   290
 	{
sl@0
   291
	aStream.WriteInt32L(iPortraitPageSize.iWidth);
sl@0
   292
	aStream.WriteInt32L(iPortraitPageSize.iHeight);
sl@0
   293
	aStream.WriteInt8L(iOrientation);
sl@0
   294
	}
sl@0
   295
sl@0
   296
sl@0
   297
EXPORT_C TSize TPageSpec::OrientedPageSize()const
sl@0
   298
/** Gets the oriented page size.
sl@0
   299
sl@0
   300
The oriented page size is the absolute width and height of the page, respecting 
sl@0
   301
the page orientation.
sl@0
   302
@return The oriented page size (in pixels or twips). */
sl@0
   303
  	{
sl@0
   304
	if(iOrientation==EPortrait)
sl@0
   305
		return(iPortraitPageSize);
sl@0
   306
	return(TSize(iPortraitPageSize.iHeight,iPortraitPageSize.iWidth));
sl@0
   307
	}
sl@0
   308
sl@0
   309
sl@0
   310
EXPORT_C TBool TPageSpec::operator==(const TPageSpec& aPageSpec) const
sl@0
   311
/** Equality operator. 
sl@0
   312
sl@0
   313
This operator compares page specifications for equality. Two page specifications 
sl@0
   314
are equal if both their orientations and portrait page sizes are equal.
sl@0
   315
sl@0
   316
@param aPageSpec Page specification to be compared.
sl@0
   317
@return ETrue, if the page specifications are equal; EFalse, otherwise. */
sl@0
   318
   {
sl@0
   319
	return(iPortraitPageSize==aPageSpec.iPortraitPageSize &&
sl@0
   320
		iOrientation==aPageSpec.iOrientation);
sl@0
   321
	}
sl@0
   322
sl@0
   323
 
sl@0
   324
EXPORT_C TBool TPageSpec::operator!=(const TPageSpec& aPageSpec) const
sl@0
   325
/** Inequality operator.
sl@0
   326
sl@0
   327
This operator compares two page specifications for inequality. Two page specifications 
sl@0
   328
are unequal if one or both of their orientations and portrait page sizes differ.
sl@0
   329
sl@0
   330
@param aPageSpec Page specification to be compared.
sl@0
   331
@return ETrue, if the page specifications differ; EFalse, otherwise. */
sl@0
   332
	{
sl@0
   333
	return(!(*this==aPageSpec));
sl@0
   334
	}
sl@0
   335
sl@0
   336
sl@0
   337
// TMargins
sl@0
   338
sl@0
   339
EXPORT_C void TMargins::InternalizeL(RReadStream& aStream)
sl@0
   340
/** Internalises a set of margins from a read stream.
sl@0
   341
sl@0
   342
The presence of this function means that the standard templated stream operator>>() 
sl@0
   343
is available to internalise objects of this class.
sl@0
   344
sl@0
   345
@param aStream Stream from which the object is internalised. */
sl@0
   346
	{
sl@0
   347
	iLeft = aStream.ReadInt32L();
sl@0
   348
	iRight = aStream.ReadInt32L();
sl@0
   349
	iTop = aStream.ReadInt32L();
sl@0
   350
	iBottom = aStream.ReadInt32L();
sl@0
   351
	}
sl@0
   352
sl@0
   353
EXPORT_C void TMargins::ExternalizeL(RWriteStream& aStream) const
sl@0
   354
/** Externalises a set of margins to a write stream.
sl@0
   355
sl@0
   356
The presence of this function means that the standard templated stream operator<<() 
sl@0
   357
is available to externalise objects of this class.
sl@0
   358
sl@0
   359
@param aStream Stream to which the object is externalised. */
sl@0
   360
	{
sl@0
   361
	aStream.WriteInt32L(iLeft);
sl@0
   362
	aStream.WriteInt32L(iRight);
sl@0
   363
	aStream.WriteInt32L(iTop);
sl@0
   364
	aStream.WriteInt32L(iBottom);
sl@0
   365
	}
sl@0
   366
sl@0
   367
EXPORT_C TBool TMargins::operator==(const TMargins& aMargins) const
sl@0
   368
/** Tests margins for equality.
sl@0
   369
sl@0
   370
@param aMargins The margin to be compared with this margin. 
sl@0
   371
@return ETrue, if the margins are equal; EFalse, otherwise. */
sl@0
   372
	{
sl@0
   373
	return(iLeft==aMargins.iLeft && iRight==aMargins.iRight &&
sl@0
   374
		iTop==aMargins.iTop && iBottom==aMargins.iBottom);
sl@0
   375
	}
sl@0
   376
sl@0
   377
EXPORT_C TBool TMargins::operator!=(const TMargins& aMargins) const
sl@0
   378
/** Tests margins for inequality.
sl@0
   379
sl@0
   380
@param aMargins The margin to be compared with this margin. 
sl@0
   381
@return ETrue, if the margins are unequal; EFalse, otherwise. */
sl@0
   382
	{
sl@0
   383
	return(!(*this==aMargins));
sl@0
   384
	}
sl@0
   385
sl@0
   386
//
sl@0
   387
// CPrinterDriverUI
sl@0
   388
//
sl@0
   389
sl@0
   390
EXPORT_C CPrinterDriverUI::CPrinterDriverUI()
sl@0
   391
	{
sl@0
   392
	__DECLARE_NAME(_S("CPrinterDriverUI"));
sl@0
   393
	}
sl@0
   394
sl@0
   395
sl@0
   396
EXPORT_C TBool CPrinterDriverUI::BeforePrintL()
sl@0
   397
 /** Provides an opportunity for a dialog to be put up before printing begins.
sl@0
   398
sl@0
   399
@return ETrue, if printing is to continue; EFalse, if printing is to be cancelled. 
sl@0
   400
The default implementation returns ETrue. */
sl@0
   401
  	{
sl@0
   402
	return ETrue;
sl@0
   403
	}
sl@0
   404
sl@0
   405
sl@0
   406
EXPORT_C void CPrinterDriverUI::AfterPrintL()
sl@0
   407
 /** Provides an opportunity for a dialog to be put up after printing is complete.
sl@0
   408
The default implementation is empty. */
sl@0
   409
	{
sl@0
   410
	}
sl@0
   411
sl@0
   412
sl@0
   413
EXPORT_C void CPrinterDriverUI::SetPropertiesL()
sl@0
   414
/** Provides an opportunity for a dialog to be put up to capture or change printer 
sl@0
   415
properties.
sl@0
   416
The default implementation is empty. */
sl@0
   417
	{
sl@0
   418
	}
sl@0
   419
sl@0
   420
sl@0
   421
EXPORT_C TBool CPrinterDriverUI::CanSetProperties()
sl@0
   422
/** Tests whether printer properties can be set.
sl@0
   423
sl@0
   424
@return ETrue, if printer properties can be set; EFalse, otherwise. The default 
sl@0
   425
implementation returns EFalse. */
sl@0
   426
    {
sl@0
   427
	return EFalse;
sl@0
   428
	}
sl@0
   429
sl@0
   430
//
sl@0
   431
// CPrinterDriver
sl@0
   432
//
sl@0
   433
sl@0
   434
sl@0
   435
EXPORT_C CPrinterDriver* CPrinterDriver::NewL()
sl@0
   436
/** Constructs, and returns a pointer to a new instance for accessing a printer 
sl@0
   437
specification data store.
sl@0
   438
sl@0
   439
@return Pointer to the object for accessing a printer specification data store. */
sl@0
   440
	{
sl@0
   441
	CPrinterDriver* printerdriver=new(ELeave) CPrinterDriver;
sl@0
   442
	CleanupStack::PushL(printerdriver);
sl@0
   443
	User::LeaveIfError(printerdriver->iFs.Connect());
sl@0
   444
	CleanupStack::Pop();
sl@0
   445
	return printerdriver;
sl@0
   446
	}
sl@0
   447
sl@0
   448
sl@0
   449
EXPORT_C CPrinterDriver::~CPrinterDriver()
sl@0
   450
/** Destructor.
sl@0
   451
sl@0
   452
It frees all resources owned by the object, prior to its destruction. In particular, 
sl@0
   453
it closes the printer specification data store and any open session with the file server.  */	
sl@0
   454
    {
sl@0
   455
	Close();
sl@0
   456
	iFs.Close();
sl@0
   457
	}
sl@0
   458
sl@0
   459
sl@0
   460
EXPORT_C void CPrinterDriver::OpenPdrL(const TDesC &aName)
sl@0
   461
/**  Opens the specified printer specification data store.
sl@0
   462
sl@0
   463
@return  The name of the printer specification data store. This must be a 
sl@0
   464
valid printer specification data store,otherwise the function leaves with
sl@0
   465
KErrNotSupported. */	
sl@0
   466
    {
sl@0
   467
	Close();
sl@0
   468
	TRAPD(ret,DoOpenPdrL(aName));
sl@0
   469
	if (ret!=KErrNone)
sl@0
   470
		{
sl@0
   471
		Close();
sl@0
   472
		User::Leave(ret);
sl@0
   473
		}
sl@0
   474
	}
sl@0
   475
sl@0
   476
EXPORT_C void CPrinterDriver::Close()
sl@0
   477
/** Closes the printer specification data store and frees resources.
sl@0
   478
sl@0
   479
An open session with the file server remains open. */
sl@0
   480
	{
sl@0
   481
	delete iPdrStore,
sl@0
   482
	iPdrStore=NULL;
sl@0
   483
	iNumModels=0;
sl@0
   484
	delete[] iModelList;
sl@0
   485
	iModelList=NULL;
sl@0
   486
	DeletePrinterDevice();
sl@0
   487
	}
sl@0
   488
sl@0
   489
sl@0
   490
EXPORT_C TInt CPrinterDriver::NumModels() const
sl@0
   491
 /** Gets the number of printer models defined by the printer specification.
sl@0
   492
sl@0
   493
@return The number of printer models. */
sl@0
   494
 	{
sl@0
   495
	return iNumModels;
sl@0
   496
	}
sl@0
   497
sl@0
   498
sl@0
   499
EXPORT_C TPrinterModelEntry CPrinterDriver::Model(TInt aNum) const
sl@0
   500
/** Gets the specified printer model.
sl@0
   501
sl@0
   502
@param aNum An index into the list of printer models defined in the printer 
sl@0
   503
specification data.
sl@0
   504
@return Model specific information. */
sl@0
   505
 	{
sl@0
   506
	GDI_ASSERT_DEBUG(aNum>=0,EPdrModelIndexOutOfRange);
sl@0
   507
	GDI_ASSERT_DEBUG(aNum<iNumModels,EPdrModelIndexOutOfRange);
sl@0
   508
	return iModelList[aNum].iEntry;
sl@0
   509
	}
sl@0
   510
sl@0
   511
sl@0
   512
EXPORT_C CPrinterDevice* CPrinterDriver::CreatePrinterDeviceL(TUid aModelUid)
sl@0
   513
/** Creates the physical graphics device to be used for printing.
sl@0
   514
sl@0
   515
@param aModelUid The UID of a specific model which is defined in the printer 
sl@0
   516
specification data.
sl@0
   517
@return The physical graphics device to be used for printing.  */	
sl@0
   518
    {
sl@0
   519
	GDI_ASSERT_DEBUG(!iPrinterDevice,EPdrPrinterDeviceExists);
sl@0
   520
	TRAPD(ret,DoCreatePrinterDeviceL(aModelUid));
sl@0
   521
	if (ret!=KErrNone)
sl@0
   522
		{
sl@0
   523
		DeletePrinterDevice();
sl@0
   524
		User::Leave(ret);
sl@0
   525
		}
sl@0
   526
	return iPrinterDevice;
sl@0
   527
	}
sl@0
   528
sl@0
   529
void CPrinterDriver::LoadLibraryL(RLibrary& aLibrary,const TDesC& aExt,TUid aUid2)
sl@0
   530
	{
sl@0
   531
	TFileName filename=iPdlName;
sl@0
   532
	filename.Append(aExt);
sl@0
   533
sl@0
   534
	User::LeaveIfError(aLibrary.Load(filename));
sl@0
   535
	TUidType type=aLibrary.Type();
sl@0
   536
	if (type[1]!=aUid2 && type[2]!=iPdlUid)
sl@0
   537
		{
sl@0
   538
		aLibrary.Close();
sl@0
   539
		User::Leave(KErrNotSupported);
sl@0
   540
		}
sl@0
   541
	if (type[1]!=aUid2)
sl@0
   542
		{
sl@0
   543
		aLibrary.Close();
sl@0
   544
		User::Leave(KErrNotFound);
sl@0
   545
		}
sl@0
   546
	}
sl@0
   547
sl@0
   548
sl@0
   549
EXPORT_C CPrinterDriverUI* CPrinterDriver::CreatePrinterDriverUIL()
sl@0
   550
/** Constructs a printer specific user interface.
sl@0
   551
sl@0
   552
The user interface object is optional, but if it exists, it is implemented 
sl@0
   553
as part of a UDL (i.e. a UI DLL).
sl@0
   554
sl@0
   555
@return A pointer to the printer specific user interface, or NULL if there is 
sl@0
   556
none. */
sl@0
   557
    {
sl@0
   558
	GDI_ASSERT_DEBUG(iPrinterDevice,EPdrPrinterDeviceDoesNotExist);
sl@0
   559
	if (iUdlLibrary.Handle()==0)
sl@0
   560
		{
sl@0
   561
		TRAPD(ret,LoadLibraryL(iUdlLibrary,KUdlExtension,TUid::Uid(KUdlUidVal)));
sl@0
   562
		if (ret==KErrNotFound)
sl@0
   563
			return NULL;
sl@0
   564
		else
sl@0
   565
			User::LeaveIfError(ret);
sl@0
   566
		}
sl@0
   567
	TLibraryFunction f = iUdlLibrary.Lookup(1);
sl@0
   568
	CPrinterDriverUI* printerdriverui=(CPrinterDriverUI*)((*f)());
sl@0
   569
	CleanupStack::PushL(printerdriverui);
sl@0
   570
	User::LeaveIfError(printerdriverui->SetPrinterDevice(iPrinterDevice));
sl@0
   571
	CleanupStack::Pop();
sl@0
   572
	return printerdriverui;
sl@0
   573
	}
sl@0
   574
sl@0
   575
CPrinterDriver::CPrinterDriver()
sl@0
   576
	{}
sl@0
   577
sl@0
   578
void CPrinterDriver::DeletePrinterDevice()
sl@0
   579
	{
sl@0
   580
	iUdlLibrary.Close();
sl@0
   581
	delete iPrinterDevice;
sl@0
   582
	iPrinterDevice=NULL;
sl@0
   583
	iPdlLibrary.Close();
sl@0
   584
	}
sl@0
   585
sl@0
   586
void CPrinterDriver::DoOpenPdrL(const TDesC &aName)
sl@0
   587
	{
sl@0
   588
	Close();
sl@0
   589
	iPdrStore=CDirectFileStore::OpenL(iFs,aName,EFileStream|EFileRead|EFileShareReadersOnly);
sl@0
   590
	if (iPdrStore->Type()[1]!=TUid::Uid(KPdrStoreFileUidVal))
sl@0
   591
		User::Leave(KErrNotSupported);
sl@0
   592
	TStreamId headerid = iPdrStore->Root();
sl@0
   593
	RStoreReadStream stream;
sl@0
   594
	stream.OpenLC(*iPdrStore,headerid);
sl@0
   595
		stream >> iPdlName;
sl@0
   596
	stream >> iPdlUid;
sl@0
   597
	iNumModels = stream.ReadInt32L();
sl@0
   598
	iModelList = new(ELeave) TPrinterModelHeader[iNumModels];
sl@0
   599
	for (TInt i=0; i<iNumModels; i++)
sl@0
   600
		iModelList[i].InternalizeL(stream);
sl@0
   601
	CleanupStack::PopAndDestroy();
sl@0
   602
	}
sl@0
   603
sl@0
   604
void CPrinterDriver::DoCreatePrinterDeviceL(TUid aModelUid)
sl@0
   605
	{
sl@0
   606
	if (!iPdlName.Length())
sl@0
   607
		User::Leave(KErrGeneral); // !! find a better error number
sl@0
   608
	LoadLibraryL(iPdlLibrary,KPdlExtension,TUid::Uid(KPdlUidVal));
sl@0
   609
	TLibraryFunction f = iPdlLibrary.Lookup(1);
sl@0
   610
	iPrinterDevice=(CPrinterDevice*)((*f)());
sl@0
   611
	TInt i;
sl@0
   612
	for (i=0; (i<iNumModels) && (aModelUid!=iModelList[i].iEntry.iUid); i++)
sl@0
   613
		{
sl@0
   614
		}
sl@0
   615
	GDI_ASSERT_DEBUG(i<iNumModels,EPdrModelUidNotFound);
sl@0
   616
	User::LeaveIfError(iPrinterDevice->SetModel(iModelList[i],*iPdrStore));
sl@0
   617
	iPrinterDevice->RestorePropertiesL();
sl@0
   618
	}
sl@0
   619
sl@0
   620
//
sl@0
   621
// CPdrModelList
sl@0
   622
//
sl@0
   623
sl@0
   624
sl@0
   625
EXPORT_C CPdrModelList* CPdrModelList::NewL()
sl@0
   626
/** Constructs, and returns a pointer to a new instance of the printer model 
sl@0
   627
list interface.
sl@0
   628
@return Pointer to the new printer model list interface object. */
sl@0
   629
    {
sl@0
   630
	CPdrModelList* modellist=new(ELeave) CPdrModelList();
sl@0
   631
	CleanupStack::PushL(modellist);
sl@0
   632
	modellist->ConstructL();
sl@0
   633
	CleanupStack::Pop();
sl@0
   634
	return modellist;
sl@0
   635
	}
sl@0
   636
sl@0
   637
sl@0
   638
EXPORT_C CPdrModelList::~CPdrModelList()
sl@0
   639
/** Virtual destructor.
sl@0
   640
Frees resources owned by the object, prior to its destruction. */
sl@0
   641
	{
sl@0
   642
	delete iModelArray;
sl@0
   643
	delete iFileArray;
sl@0
   644
	if (iDirectoryArray)
sl@0
   645
		{// delete all the HBufC's
sl@0
   646
		for (TInt i=iDirectoryArray->Count()-1 ; i>=0 ; i--)
sl@0
   647
			delete (*iDirectoryArray)[i];
sl@0
   648
		delete iDirectoryArray;
sl@0
   649
		}
sl@0
   650
	iFileServer.Close();
sl@0
   651
	}
sl@0
   652
sl@0
   653
sl@0
   654
EXPORT_C TInt CPdrModelList::ModelCount() const
sl@0
   655
/** Gets the number of printer models in the printer model list.
sl@0
   656
@return The number of printer models. */
sl@0
   657
    {
sl@0
   658
	return iModelArray->Count();
sl@0
   659
	}
sl@0
   660
sl@0
   661
sl@0
   662
EXPORT_C const TPrinterModelEntry CPdrModelList::operator [] (TInt anIndex)
sl@0
   663
/** Gets printer model name.
sl@0
   664
sl@0
   665
This is the name of the printer model at the specified index within the list 
sl@0
   666
of printer models.
sl@0
   667
sl@0
   668
@param anIndex The index of the printer model within the array of printer 
sl@0
   669
models. Note that this number must be between zero and ModelCount(). 
sl@0
   670
sl@0
   671
@return Name of printer model, up to 32 characters long */
sl@0
   672
 	{
sl@0
   673
	GDI_ASSERT_DEBUG(anIndex>=0,EPdrModelIndexOutOfRange);
sl@0
   674
	GDI_ASSERT_DEBUG(anIndex<iModelArray->Count(),EPdrModelIndexOutOfRange);
sl@0
   675
sl@0
   676
	return (*iModelArray)[anIndex].iEntry;
sl@0
   677
	}
sl@0
   678
sl@0
   679
sl@0
   680
EXPORT_C TInt CPdrModelList::UidToNum(TUid aModelUid) const
sl@0
   681
/** Gets a printer model's index within the model list from its UID.
sl@0
   682
sl@0
   683
@param aModelUid The UID of the printer model.
sl@0
   684
@return The index of the printer model within the array of printer models if 
sl@0
   685
found; KErrNotFound, otherwise. */
sl@0
   686
    {
sl@0
   687
	TInt i,count=iModelArray->Count();
sl@0
   688
	for (i=0; (i<count) && (aModelUid!=(*iModelArray)[i].iEntry.iUid); i++)
sl@0
   689
		{
sl@0
   690
		}
sl@0
   691
sl@0
   692
	if (i==count)
sl@0
   693
		i=KErrNotFound;
sl@0
   694
sl@0
   695
	return i;
sl@0
   696
	}
sl@0
   697
sl@0
   698
sl@0
   699
EXPORT_C void CPdrModelList::AddDirectoryL(const TDesC& aDir)
sl@0
   700
/** Adds a directory to the list of directories to be scanned for printer models.
sl@0
   701
sl@0
   702
@param aDir The directory to be added to the list. */
sl@0
   703
	{
sl@0
   704
	HBufC* buf = HBufC::NewL(aDir.Length());
sl@0
   705
	CleanupStack::PushL(buf);
sl@0
   706
	*buf = aDir;
sl@0
   707
	iDirectoryArray->AppendL(buf);
sl@0
   708
	CleanupStack::Pop(); //buf
sl@0
   709
	}
sl@0
   710
sl@0
   711
LOCAL_C void DereferenceAndDeleteHBufC8(TAny* aPointerToPointerToHBufC8)
sl@0
   712
	{
sl@0
   713
	delete *STATIC_CAST(HBufC8**, aPointerToPointerToHBufC8);
sl@0
   714
	}
sl@0
   715
sl@0
   716
sl@0
   717
EXPORT_C CPrinterModelList* CPdrModelList::ScanForModelsL()
sl@0
   718
/** Scans through through the list of directories for all .pdr files and generates 
sl@0
   719
a list of printer models.
sl@0
   720
sl@0
   721
@return The list of model names. */
sl@0
   722
	{
sl@0
   723
	iModelArray->Reset();
sl@0
   724
	iFileArray->Reset();
sl@0
   725
	// check that there is at least one directory to parse?
sl@0
   726
	// get a list of *.pdr files in all directories specified (using AddDirectory())
sl@0
   727
	for (TInt index=iDirectoryArray->Count()-1 ; index>=0 ; index--)
sl@0
   728
		ScanDirectoryL(index);
sl@0
   729
 	// then go through the files one at a time, adding all models to the list
sl@0
   730
	TParse* parser = new(ELeave) TParse;
sl@0
   731
	CleanupStack::PushL(parser);
sl@0
   732
	TFileName* nameOfLoadedResourceFile=new(ELeave) TFileName;
sl@0
   733
	CleanupStack::PushL(nameOfLoadedResourceFile);
sl@0
   734
	TFileName* tempFileName=new(ELeave) TFileName;
sl@0
   735
	CleanupStack::PushL(tempFileName);
sl@0
   736
	RResourceFile resourceFile;
sl@0
   737
	CleanupClosePushL(resourceFile);
sl@0
   738
	HBufC8* resource=NULL;
sl@0
   739
	CleanupStack::PushL(TCleanupItem(DereferenceAndDeleteHBufC8, &resource));
sl@0
   740
	for (TInt fileNum=iFileArray->Count()-1 ; fileNum>=0 ; fileNum--)
sl@0
   741
		ListModelsL(fileNum, *parser, *nameOfLoadedResourceFile, *tempFileName, resourceFile, resource);
sl@0
   742
	CleanupStack::PopAndDestroy(5); // resource, resourceFile, tempFileName, nameOfLoadedResourceFile and parser
sl@0
   743
	// return a handle to the array of model names
sl@0
   744
	return this;
sl@0
   745
	}
sl@0
   746
sl@0
   747
sl@0
   748
EXPORT_C CPrinterDriver* CPdrModelList::CreatePrinterDriverL(TInt anIndex)
sl@0
   749
/** Creates an object for accessing the specified store that contains printer specification 
sl@0
   750
data.
sl@0
   751
sl@0
   752
@param anIndex An index into a list of files containing printer specification 
sl@0
   753
data. The files are the complete set of .pdr files found in the directories 
sl@0
   754
known to this object.
sl@0
   755
@return A pointer to the object representing the store containing the printer 
sl@0
   756
specification data. */
sl@0
   757
 	{
sl@0
   758
	GDI_ASSERT_DEBUG(anIndex>=0,EPdrModelIndexOutOfRange);
sl@0
   759
	GDI_ASSERT_DEBUG(anIndex<iModelArray->Count(),EPdrModelIndexOutOfRange);
sl@0
   760
sl@0
   761
	CPrinterDriver* driver = CPrinterDriver::NewL();
sl@0
   762
	CleanupStack::PushL(driver);
sl@0
   763
	HBufC* file = NewPathBufL(*((*iModelArray)[anIndex].iFile));
sl@0
   764
	CleanupStack::PushL(file);
sl@0
   765
	driver->OpenPdrL(*file);
sl@0
   766
	driver->CreatePrinterDeviceL((*iModelArray)[anIndex].iEntry.iUid);
sl@0
   767
	CleanupStack::PopAndDestroy();
sl@0
   768
	CleanupStack::Pop();
sl@0
   769
	return driver;
sl@0
   770
	}
sl@0
   771
sl@0
   772
 
sl@0
   773
 CPdrModelList::CPdrModelList():
sl@0
   774
	iModelArray(NULL),
sl@0
   775
	iFileArray(NULL),
sl@0
   776
	iDirectoryArray(NULL)
sl@0
   777
	{
sl@0
   778
	}
sl@0
   779
 
sl@0
   780
 void CPdrModelList::ConstructL()
sl@0
   781
	{
sl@0
   782
	__DECLARE_NAME(_S("CPdrModelList"));
sl@0
   783
	iModelArray = new(ELeave) CArrayFixSeg<TModelEntry>(5);
sl@0
   784
	iFileArray = new(ELeave) CArrayFixFlat<TFileEntry>(5);
sl@0
   785
	iDirectoryArray = new(ELeave) CArrayFixFlat<HBufC*>(1);
sl@0
   786
	User::LeaveIfError(iFileServer.Connect());
sl@0
   787
	}
sl@0
   788
sl@0
   789
void CPdrModelList::ScanDirectoryL(TInt aDirIndex)
sl@0
   790
/** Scans the given directory, parsing all files found
sl@0
   791
 If a file is of the correct type it is appended to the file list*/
sl@0
   792
	{
sl@0
   793
	GDI_ASSERT_DEBUG(aDirIndex>=0,EPdrDirectoryIndexOutOfRange);
sl@0
   794
	GDI_ASSERT_DEBUG(aDirIndex<iDirectoryArray->Count(),EPdrDirectoryIndexOutOfRange);
sl@0
   795
sl@0
   796
	TDesC* dir = (*iDirectoryArray)[aDirIndex];
sl@0
   797
	TParse path;
sl@0
   798
	path.Set(KPdrExtension,dir,NULL);
sl@0
   799
	CDir* fileList;
sl@0
   800
	TInt ret = iFileServer.GetDir(path.FullName(),KEntryAttNormal,ESortByName,fileList);
sl@0
   801
	if (ret == KErrNone)
sl@0
   802
		{
sl@0
   803
		CleanupStack::PushL(fileList);
sl@0
   804
		for (TInt i=fileList->Count()-1 ; i>=0 ; i--) 
sl@0
   805
			{
sl@0
   806
			TFileEntry& entry = iFileArray->ExtendL();
sl@0
   807
			entry.iFileName = (*fileList)[i].iName;
sl@0
   808
			entry.iDirectory = dir;
sl@0
   809
			}
sl@0
   810
		CleanupStack::PopAndDestroy(); // fileList
sl@0
   811
		}
sl@0
   812
	else if (ret == KErrNoMemory) // Ignore errors other than KErrNoMemory
sl@0
   813
		User::LeaveNoMemory();
sl@0
   814
	}
sl@0
   815
sl@0
   816
void CPdrModelList::ListModelsL(TInt aFileIndex, TParse& aParser, TFileName& aNameOfLoadedResourceFile, TFileName& aTempFileName, RResourceFile& aResourceFile, HBufC8*& aResource)
sl@0
   817
/** given a pdr file list all the models it contains in the model array */
sl@0
   818
	{
sl@0
   819
	GDI_ASSERT_DEBUG(aFileIndex>=0,EPdrFileIndexOutOfRange);
sl@0
   820
	GDI_ASSERT_DEBUG(aFileIndex<iFileArray->Count(),EPdrFileIndexOutOfRange);
sl@0
   821
sl@0
   822
	CPrinterDriver* driver = CPrinterDriver::NewL() ;
sl@0
   823
	CleanupStack::PushL(driver);
sl@0
   824
	// open the file
sl@0
   825
	HBufC* fullPath = NewPathBufL((*iFileArray)[aFileIndex]);
sl@0
   826
	TRAPD(ret,driver->OpenPdrL(*fullPath));
sl@0
   827
	delete fullPath;
sl@0
   828
	if ((ret!=KErrNone) && (ret!=KErrNotSupported))
sl@0
   829
		User::Leave(ret);
sl@0
   830
	// get info on the models one by one and insert them into the array
sl@0
   831
	if (ret==KErrNone)
sl@0
   832
		{
sl@0
   833
		TModelEntry modelentry;
sl@0
   834
		modelentry.iFile = &(*iFileArray)[aFileIndex]; // set the file pointer for the entry
sl@0
   835
		const TInt numberOfModels = driver->NumModels();
sl@0
   836
		for (TInt i=0 ; i<numberOfModels ; i++)
sl@0
   837
			{
sl@0
   838
			modelentry.iEntry=driver->Model(i);
sl@0
   839
			if (UidToNum(modelentry.iEntry.iUid)==KErrNotFound)
sl@0
   840
				{
sl@0
   841
				User::LeaveIfError(aParser.SetNoWild(KRscExtension, &modelentry.iFile->iFileName, modelentry.iFile->iDirectory));
sl@0
   842
				aTempFileName=aParser.FullName();
sl@0
   843
				BaflUtils::NearestLanguageFile(iFileServer, aTempFileName);
sl@0
   844
				if (aNameOfLoadedResourceFile.CompareF(aTempFileName)!=0)
sl@0
   845
					{
sl@0
   846
					if (!BaflUtils::FileExists(iFileServer, aTempFileName))
sl@0
   847
						{
sl@0
   848
						iModelArray->AppendL(modelentry); // no resource file found, so reverting to old behaviour (i.e. where the model-name is set from the PDR file)
sl@0
   849
						continue;
sl@0
   850
						}
sl@0
   851
					aNameOfLoadedResourceFile=KNullDesC;
sl@0
   852
					aResourceFile.OpenL(iFileServer, aTempFileName);
sl@0
   853
					HBufC8* resource=aResourceFile.AllocReadL(aResourceFile.Offset()+2); // read the first resource after the RSS_SIGNATURE resource
sl@0
   854
					delete aResource;
sl@0
   855
					aResource=resource;
sl@0
   856
					aNameOfLoadedResourceFile=aTempFileName;
sl@0
   857
					}
sl@0
   858
				TResourceReader resourceReader;
sl@0
   859
				resourceReader.SetBuffer(aResource);
sl@0
   860
				for (TInt j=resourceReader.ReadUint16()-1; ; --j)
sl@0
   861
					{
sl@0
   862
					if (j<0)
sl@0
   863
						{
sl@0
   864
						iModelArray->AppendL(modelentry); // no matching uid found in the resource file, so reverting to old behaviour (i.e. where the model-name is set from the PDR file)
sl@0
   865
						break;
sl@0
   866
						}
sl@0
   867
					TInt uid=resourceReader.ReadInt32();
sl@0
   868
					TPtrC name=resourceReader.ReadTPtrC();
sl@0
   869
					if (uid==modelentry.iEntry.iUid.iUid)
sl@0
   870
						{
sl@0
   871
						if (name.Length()>0)
sl@0
   872
							{
sl@0
   873
							modelentry.iEntry.iModelName=name;
sl@0
   874
							iModelArray->AppendL(modelentry);
sl@0
   875
							}
sl@0
   876
						break;
sl@0
   877
						}
sl@0
   878
					}
sl@0
   879
				}
sl@0
   880
			}
sl@0
   881
		}
sl@0
   882
	CleanupStack::PopAndDestroy(); // driver
sl@0
   883
	}
sl@0
   884
sl@0
   885
sl@0
   886
HBufC* CPdrModelList::NewPathBufL(const TFileEntry& aFileEntry)  
sl@0
   887
/** Create a buf of the right length and... 
sl@0
   888
 set its contents to the full filename of model aModel */
sl@0
   889
	{
sl@0
   890
	// Create a buf of the right length
sl@0
   891
	HBufC* buf = HBufC::NewL(aFileEntry.iFileName.Length()+aFileEntry.iDirectory->Length());
sl@0
   892
	// Insert the file path
sl@0
   893
	TPtr filePtr = buf->Des();
sl@0
   894
	filePtr.Append(*aFileEntry.iDirectory);
sl@0
   895
	filePtr.Append(aFileEntry.iFileName);
sl@0
   896
	return buf;
sl@0
   897
	}
sl@0
   898
sl@0
   899
// !!!!
sl@0
   900
// Retained for binary compatibility only: remove if we make a binary incompatible release
sl@0
   901
//
sl@0
   902
sl@0
   903
IMPORT_C void GDI_Reserved();
sl@0
   904
EXPORT_C void GDI_Reserved()
sl@0
   905
	{}
sl@0
   906