diff -r b685c59de105 -r fe49e33862e2 widgettools/wrtwidgetpreinstaller/src/installwidgets.pl --- a/widgettools/wrtwidgetpreinstaller/src/installwidgets.pl Thu Aug 19 09:43:47 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2156 +0,0 @@ -# -# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -use strict; -use warnings; -use File::Spec::Functions; -use Getopt::Long; -use Pod::Usage; - -# Version of the script - just use the date -$main::VERSION = '12-July-2010'; - -# New getopt::long provides this - but old version doesn't? -sub version - { - print sprintf("$0: $main::VERSION\n$^X: %vd\nos: $^O", $^V); - exit; - } - -# Get arguments -my ( $help, $version, $verbose, $debug, $epocroot, $l10n ); -GetOptions( "help" => \$help, "version|ver" => \$version, - "verbose|v" => \$verbose, "debug" => \$debug, - "epocroot|e=s" => \$epocroot, "localization|l=s" => \$l10n ) - or pod2usage('Invalid parameters'); - -# Handle help and version -pod2usage({ verbose => 1, exitval => 0}) if $help; -version() if $version; - -# Interpret arguments -$verbose = 1 if $debug; -$verbose = $verbose ? '-v' : ''; -$epocroot = $ENV{EPOCROOT} if !$epocroot; - -# Interpret localization l10n argument - -# There are two modes. In one mode you specify the location of a -# lproj.xml file and the code computes l10n files for all languages so -# that runtime locale selection should work. In the other mode you -# specify a language code (example, fr for French) and the code -# computes l10n just for that language. -$l10n = '' if !$l10n; -my $lproj = ''; -if ($l10n =~ /lproj\.xml$/i) - { - $lproj = $l10n; - $l10n = ''; - } - -my ($configini, @unnecessary) = @ARGV; - -if ($configini) - { - # There shouldn't be any need for any other arguments - pod2usage('Unnecessary arguments supplied.') if @unnecessary; - - # Now do the installation - my $installer = WidgetInstaller->new('verbose' => $verbose, 'debug' => $debug, 'epocroot' => $epocroot, 'lproj' => $lproj, 'l10n' => $l10n); - $installer->installConfig($configini); - } -else - { - pod2usage('Missing config.ini argument.'); - } - -# *** -# Package for installing Widgets -# - -package WidgetInstaller; - -use File::Spec::Functions; -use File::Path; -use File::Basename; -use Unicode::String qw(utf8 utf16); -use File::Temp qw/tempdir/; -use File::Copy; -use XML::Parser; -use Data::Dumper; -use XML::Simple; - -# CONSTANTS -use constant ICON_SIZES => "88,32,24"; # Size of icons to generate in the MBM file -#use constant INTERNAL_UID_LOWER => 0x2000DAD2; # Lower UID bound for midlets installed to internal drives and rom -#use constant EXTERNAL_UID_LOWER => 0x2000DCC6; # Lower UID bound for midlets installed to removable cards -use constant INTERNAL_UID_LOWER_WRT => 0x2000DAD2; # Lower UID bound for WRT widgets installed to internal drives and rom -use constant INTERNAL_UID_LOWER_CWRT => 0x2000DBCC; # Lower UID bound for CWRT widgets installed to internal drives and rom -use constant EXTERNAL_UID_LOWER_WRT => 0x2000DCC6; # Lower UID bound for WRT widgets installed to removable cards -use constant EXTERNAL_UID_LOWER_CWRT => 0x2000DDC0; # Lower UID bound for CWRT widgets installed to removable cards -use constant WIDGET_UI_UID => 0x10282822; # UID of the widget app -use constant CWRT_WIDGET_UI_UID => 0x200267C0; # UID of the cwrt widget app -use constant SWIDGET_UI_UID => 0x102829A0; # UID of the securewidget app -use constant CWRT_WIDGET_UI_NON_NOKIA_UID => 0x200267D6; # UID of the cwrt widget app - -# Folder paths -use constant DESTINATION => 'private/10003a3f/import/apps/NonNative/Resource'; -use constant ROM_DEST => 'epoc32/release/winscw/udeb/Z/'; -use constant DRIVE_DEST => 'epoc32/winscw/%s'; -use constant WIDGET_REGISTRY => 'private/10282f06/WidgetEntryStore.xml'; -use constant CWRT_WIDGET_REGISTRY => 'private/10282f06/CWRTWidgetEntryStore.xml'; -use constant CWRT_WEBAPP_REGISTRY => 'private/200267D9/webapp_registry.db'; -use constant CWRT_ACCESS_POLICY_PATH => 'browser_access_policy.xml'; -use constant WIDGET_NAME => 'en-gb/widget/name'; -use constant WIDGET_PROCESSUID => 'processUid'; -use constant WIDGET_ID => 'widget/id'; -use constant WIDGET_VERSION => 'widget/version'; -use constant WIDGET_CONTENT => 'widget/content'; -use constant WIDGET_FEATURE => 'widget/feature/'; -use constant WIDGET_FEATURE_PARAM => '/param/'; -use constant WIDGET_ACCESS => 'widget/access/'; -use constant WIDGET_HEIGHT => 'widget/height'; -use constant WIDGET_WIDTH => 'widget/width'; -use constant WIDGET_NOKIA_SHAREDLIB => 'widget/NOKIA:sharedlibrary'; -use constant WIDGET_NOKIA_SHAREDLIB_FOLDER => 'widget/NOKIA:sharedlibrary/NOKIA:folder'; -use constant WIDGET_NOKIA_SHAREDLIB_WIDGET => 'widget/NOKIA:sharedlibrary/NOKIA:widget'; -use constant WIDGET_NOKIA_SHAREDLIB_ICON => 'widget/NOKIA:sharedlibrary/NOKIA:icon'; -use constant KEY_VALUE_SEPERATOR => ','; -use constant KEY_VALUE_PAIR_SEPERATOR => ';'; -use constant KEY_ATTR_SEPERATOR => ':'; - -our $w3c_widget = 0 ; -our $hashval; -our $non_nokia_widget = 0; -our ($isSharedLibrary, $sharedFolderName ,$isSharedWidget, $isSharedIcon)= (0,'',0,0); -our (@staticUidWrtIntList,@staticUidCwrtIntList,@staticUidWrtExtList,@staticUidCwrtExtList) = ({},{},{},{}); -our $isSecureWidget = 0; - -# Create a new object -sub new - { - my $invocant = shift; - my $self = bless({}, ref $invocant || $invocant); - - my %args = @_; - $self->{'args'} = \%args; - $self->{'args'}->{'verbose'} = $self->{'args'}->{'verbose'} ? '-v' : ''; - - $self->{'installedFiles'} = (); - $self->{'freeuidwrtint'} = INTERNAL_UID_LOWER_WRT; - $self->{'freeuidwrtext'} = EXTERNAL_UID_LOWER_WRT; - $self->{'freeuidcwrtint'} = INTERNAL_UID_LOWER_CWRT; - $self->{'freeuidcwrtext'} = EXTERNAL_UID_LOWER_CWRT; - $self->{'langmapping'} = $self->getLangMapping($self->{'args'}->{'lproj'}) unless $self->{'args'}->{'l10n'}; - - #Check if localisation argument is land number ID; If true, get the lang Name using langmapping file - Widget_lproj.xml - if ($l10n =~ /\d+$/) - { - print "\nLANG ID given as localisation argument :: $l10n \n"; - $self->{'langmapping'} = $self->getLangMapping(); - - if($self->{'langmapping'}) - { - # Iterate through all the languages we know about - for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++) - { - my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] ); - if($l10n == $langid) - { - print "Setting argument to LangName - $langname \n"; - $self->{'args'}->{'l10n'} = lc($langname); - last; - } - } - } - } - - return $self; - } - -# Gets the language mapping from the Widget_lproj.xml file -sub getLangMapping - { - my ( $self, $lproj ) = @_; - - # Get the LPROJ file which specifies lang id mappings - if (!$lproj) - { - (my $EPOCROOT = $ENV{EPOCROOT}) =~ s/[\/\\]+$//; - $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/winscw/c/private/10282f06/Widget_lproj.xml"); - $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/winscw/c/private/10282f06/Widget_lproj.xml") if !-e $lproj; - $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj; - $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj; - $lproj = WidgetInstaller::fixFilename("${epocroot}S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj; - $lproj = WidgetInstaller::fixFilename("$EPOCROOT/S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj; - $lproj = WidgetInstaller::findCmd('Widget_lproj.xml') if !-e $lproj; - $lproj = WidgetInstaller::findCmd('internal/Widget_lproj.xml') if !-e $lproj; - undef $lproj if !-e $lproj; - - # Display a warning if localisation can't be performed - warn "WARNING: Can't find Widget_lproj.xml - localisation is disabled.\n" if !$lproj; - } - - # Load the mapping file - if ($lproj) - { - die "Can't find $lproj file." if !-e $lproj; - print "Localisation support enabled using config: $lproj\n" if $verbose; - my $mapping = XMLin($lproj); - print "Found ", scalar(@{ $mapping->{'LangID'} }), " language mappings.\n" if $verbose; - return $mapping; - } - } - -# Install Widgets listed in config file -# Format is as follows where "drive-z" specifies widgets for drive z: etc... -# Comments are okay - they start with a # character -# If the file doesn't exist as given then EPOCROOT is prepended to the filename to try and find it -# -# You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename -# This will set the BlanketPermissionGranted attribute in the registry. -# Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated. -# -# You can specify commands to run before exit after a [run-commands] or [homescreen-processor] -# -# [drive-z] -# \path\widget1.wgz -# widget2.wdgt.zip [HomeScreen] -# -# [drive-e] -# widget3.wgz -# -# [run-commands] -# dostuff.pl -# - -sub installConfig - { - my ( $self, $file ) = @_; - $self->{'installedFiles'} = (); - - my ( %installData, $sectionName ); - open CONFIG, $file or die "Failed to open config file $file: $!"; - - # Loop for gathering STATIC UIDs allocated for widgets in config INI file - while(my $line = ) - { - # Ignore comments - $line =~ s/\#.*$//; - - if ($line =~ /^\[([^\]]+)\]/) - { - $sectionName = lc $1; - next; - } - - # Process sections after this point - next if !$sectionName; - chomp $line; - - # Have we found a list of widgets? - if ($sectionName =~ /^drive-([a-z])/) - { - my $drive = uc($1); - #Assuming Static UID given in ini are within int/ext/wgt/wgz specified ranges - # Add Static UID to the respective list - if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i) - { - if ($3) - { - my $uid = hex($3); - - if ($drive =~ /^[zcZC]/) - { - if(($uid >= INTERNAL_UID_LOWER_WRT) && ($uid < INTERNAL_UID_LOWER_CWRT)) - { - push(@staticUidWrtIntList,$uid) ; - } - else - { - push(@staticUidCwrtIntList,$uid); - } - } - else - { - if(($uid >= EXTERNAL_UID_LOWER_WRT) && ($uid < EXTERNAL_UID_LOWER_CWRT)) - { - push(@staticUidWrtExtList,$uid) ; - } - else - { - push(@staticUidCwrtExtList,$uid) ; - } - } - } - } - } - } - close CONFIG; - @staticUidWrtIntList = sort(@staticUidWrtIntList); - print "SORTED WRT INTERNAL STATIC UID @staticUidWrtIntList \n"; - @staticUidCwrtIntList = sort(@staticUidCwrtIntList); - print "SORTED CWRT INTERNAL STATIC UID @staticUidCwrtIntList \n"; - @staticUidWrtExtList = sort(@staticUidWrtExtList); - print "SORTED WRT EXTERNAL STATIC UID @staticUidWrtExtList \n"; - @staticUidCwrtExtList = sort(@staticUidCwrtExtList); - print "SORTED CWRT EXTERNAL STATIC UID @staticUidCwrtExtList \n"; - - open CONFIG, $file or die "Failed to open config file $file: $!"; - # Main loop which reads the config INI line by line and installs widgets[wgz/wgt] in respective drives - while(my $line = ) - { - # Ignore comments - $line =~ s/\#.*$//; - - if ($line =~ /^\[([^\]]+)\]/) - { - $sectionName = lc $1; - - # Remember destination if any specified - if ($sectionName =~ /^drive-([a-z])=(.+)$/) - { - $self->{'destination'}->{uc($1)} = $2; - } - next; - } - - # Process sections after this point - next if !$sectionName; - chomp $line; - - # Have we found a list of widgets? - if ($sectionName =~ /^drive-([a-z])/) - { - my $drive = uc($1); - - # Add to the list of Widget files - if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i) - { - my $widget = $1; - $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget; - die "Can't find widget $widget" if !-e $widget; - $self->{'homescreen'}{lc $widget} = 1 if $2; # Intended for the homescreen? - $self->{'staticUID'}{lc $widget} = hex($3) if $3; - $self->{'secure'}{lc $widget} = 0; - $self->{'operator'}{lc $widget} = 1 if $4; - print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'}; - push @{ $installData{"$drive:"} }, $widget; - } - elsif ($line =~ /^(.+?\.(?:wdgt\.zip|wgz))\s*(\[Secure\])?\s*(0x[a-fA-F0-9]{8})?\s*$/i) - { - my $widget = $1; - $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget; - die "Can't find widget $widget" if !-e $widget; - $self->{'secure'}{lc $widget} = 1 if $2; # Intended for a secure widget handling? - $self->{'staticUID'}{lc $widget} = hex($3) if $3; - print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'}; - push @{ $installData{"$drive:"} }, $widget; - } - else - { - my $widget = $1; - $self->{'secure'}{lc $widget} = 0; - } - } - # Retrieve the command to execute before exit - elsif ($sectionName =~ /^(run-commands|homescreen-processor)$/i && $line) - { - push @{ $self->{'exitcmds'} }, $line; - } - } - close CONFIG; - - # Now intall the widgets for each drive specified in the config file - foreach my $drive ( keys %installData ) - { - $self->installFiles($drive, $installData{$drive} ); - $self->makeIBY($drive); - $self->makeIBY($drive, 'localised') unless $self->{'args'}->{'l10n'}; - } - - # Exit commands at the end of the process - if ($self->{'exitcmds'}) - { - foreach my $cmd ( @{ $self->{'exitcmds'} } ) - { - print "Executing: $cmd\n" if $self->{'args'}->{'verbose'}; - warn "WARNING: error running $cmd" if system($cmd) != 0; - } - } - } - -# *** -# Installs files to a drive -# -sub installFiles - { - my ( $self, $drive, $fileList ) = @_; - my $startsrc ; - my $iconsrc ; - - $isSharedLibrary = 0; - $isSharedWidget = 0; - $isSharedIcon = 0; - $sharedFolderName =''; - $isSecureWidget = 0; - - print "Installing files for drive $drive\n" if $self->{'args'}->{'verbose'}; - - # Unregister any existing widgets as otherwise when the registry is rewritten their icons will appear in the emulator but they won't work - $self->unregisterWidgets($drive); - - print "\n INSTALLING FILES FOR DRIVE $drive \n"; - # Process each widget in turn - my ( @installedProps ); - my ( @installedCWRTProps ); - foreach my $filename ( @$fileList ) - { - # Check the file exists - die "Can't find $filename" if !-e $filename; - - # Create a temporary folder - print "\nInstalling $filename\n"; - my $tempdir = tempdir ( DIR => '.', CLEANUP => !$self->{args}->{'debug'}); - - # Prefer to use 7zip rather than unzip because it's better behaved wrt Unicode - if (findCmd('7z.exe')) - { - $self->un7zipWidget($filename, $tempdir); - } - else - { - $self->unzipWidget($filename, $tempdir); - } - my $widgetdata ; - - $isSharedLibrary = 0; - $isSharedWidget = 0; - $isSharedIcon = 0; - $sharedFolderName =''; - - my ( $root, $extracted, $size ) = $self->getFiles($tempdir); - die "No files extracted from $filename" if !@$extracted; - - if ($self->{'operator'}{lc $filename}) - { - print "\n NON NOKIA WGT \n"; - $non_nokia_widget = 1; - } - else - { - print "\n NOKIA WGT \n"; - $non_nokia_widget = 0; - } - - - if (($filename =~ /.wgz/ )&& (my $plist = catfile($tempdir, $root, 'Info.plist'))) - { - print ("S60 widget \n"); - - $w3c_widget = 0; - # Parse the XML file into a hash - $widgetdata = parsePList($plist); - } - elsif (($filename =~ /.wgt/ ) && ( my $confxml = catfile($tempdir, $root, 'config.xml'))) - { - print (" W3C widget \n"); - - # Parse the XML file into a hash - $widgetdata = parseConfXml($confxml,$self->{'args'}->{'l10n'}); - $w3c_widget = 1; - } - else - { - die "Can't find $root/Info.plist , $root/config.xml file"; - } - - if ($self->{'secure'}{lc $filename}){ - $isSecureWidget = 1; - } else { - $isSecureWidget = 0; - } - - if( $w3c_widget ) - { - if( $widgetdata->{'MainHTML'} ) - { - $startsrc = $widgetdata->{'MainHTML'}; - } - else - { - $startsrc = 'index.html'; - } - if( $widgetdata->{'IconPath'} ) - { - $iconsrc = $widgetdata->{'IconPath'}; - } - else - { - $iconsrc = 'icon.png'; - } - - if($non_nokia_widget) - { - $widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_NON_NOKIA_UID; - } - else - { - $widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_UID; - } - - $widgetdata->{'MimeType'} = "application/widget"; - } - - print "Identifier: $widgetdata->{'BundleIdentifier'}\n" if $self->{args}->{'verbose'}; - - # Set widget package properties - $widgetdata->{'FileName'} = $filename; - $widgetdata->{'FileSize'} = $size; - - # Load the language translations for BundleDisplayName - if ($self->{'args'}->{'l10n'}) - { - my $localised = $self->getLocalisedStringByLangCode(catfile($tempdir, $root), 'DisplayName', $self->{'args'}->{'l10n'}); - $widgetdata->{'BundleDisplayName'} = $localised if $localised; - } - else - { - $widgetdata->{'LocBundleDisplayName'} = $self->getLocalisedStrings(catfile($tempdir, $root), 'DisplayName'); - } - - # Fix up some of the fields - $widgetdata->{'BundleName'} = $widgetdata->{'BundleDisplayName'} if !$widgetdata->{'BundleName'}; - $widgetdata->{'AllowNetworkAccess'} = $widgetdata->{'AllowFullAccess'} if !$widgetdata->{'AllowNetworkAccess'}; - $widgetdata->{'DriveName'} = $drive; - - if( $w3c_widget ) - { - $widgetdata->{'PropertyListVersion'} = 4; - my $widget_uid; - - if($non_nokia_widget) - { - $widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID; - } - else - { - $widget_uid = CWRT_WIDGET_UI_UID; - } - - if($isSharedLibrary) - { - #In case of NOKIA:sharedlibrary, the extracted widget contents and data source are stored under private\\..\lib\\ - $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7","lib",$sharedFolderName); - $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" ,"lib" ,$sharedFolderName); - } - else - { - $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7", hashpjw($widgetdata->{'BundleIdentifier'})); - $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" , hashpjw($widgetdata->{'BundleIdentifier'})); - } - $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$startsrc"; - $widgetdata->{'AllowNetworkAccess'} = 1; - - } - else - { - $widgetdata->{'PropertyListVersion'} = 1; - $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\', $widgetdata->{'DriveName'}, WIDGET_UI_UID, $widgetdata->{'BundleIdentifier'}); - $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$root\\$widgetdata->{'MainHTML'}"; - $widgetdata->{'IconPath'} = "$widgetdata->{'BasePath'}$root\\"; - } - - $widgetdata->{'BlanketPermissionGranted'} = 0 if( ! $widgetdata->{'BlanketPermissionGranted'} ); - $widgetdata->{'MiniViewEnabled'} = 0 if( ! $widgetdata->{'MiniViewEnabled'} ); - - # Indicate that the widget was pre-installed - $widgetdata->{'PreInstalled'} = 1; - - # Set BlanketPermissionGranted flag if Widget is listed as a homescreen widget in the INI file - # Error if MiniViewEnabled isn't set - if ($self->{'homescreen'}{lc $filename}) - { - $widgetdata->{'BlanketPermissionGranted'} = 1; - die "ERROR: $filename - MiniViewEnabled not set for homescreen widget" if !$widgetdata->{'MiniViewEnabled'}; - } - - # Defining UID - if($self->{'staticUID'}{lc $filename}) - { - print "Using Static UID from INI file\n"; - $widgetdata->{'Uid'} = $self->{'staticUID'}{lc $filename}; - } - else - { - # Find the next free UID to use - $widgetdata->{'Uid'} = $self->findfreeUid($widgetdata); - } - print sprintf("Using UID for midlet: 0x%08X\n", $widgetdata->{'Uid'}) if $self->{args}->{'verbose'}; - - # Make sure the destination exists - my $dest = $self->regFileName($drive); - mkpath $dest; - - my $icon; - if($w3c_widget) - { - my $locate = $self->{'args'}->{'l10n'}; - my $seperator ='-'; - my $position = -1; - my $found = 0 ; - if ($self->{'args'}->{'l10n'}) - { - do - { - my $searchdir = '.\\'.$tempdir.'\\locales\\'.$locate; - if( opendir(DIR, $searchdir)) - { - my @files = grep(/$iconsrc$/,readdir(DIR)); - closedir(DIR); - if(@files) - { - $iconsrc = 'locales\\'.$locate.'\\'.$iconsrc ; - $found = 1; - } - } - if(($position = rindex($locate,$seperator)) > 0 ) - { - $locate = substr($locate,0,$position); - } - } while (!$found && $position > 0); - } - if ($iconsrc) - { - $icon = catfile($tempdir, $root, $iconsrc); - } - - if(-e $icon) - { - $widgetdata->{'DBIconPath'}= "$widgetdata->{'BasePath'}$iconsrc"; - print "Icon found -- $widgetdata->{'DBIconPath'} \n"; - } - else - { - $icon = findCmd('default_widget_icon.png'); - print "default_widget_icon.png used \n"; - $widgetdata->{'DBIconPath'}= ":/resource/default_widget_icon.png"; - } - } - else - { - $icon = catfile($tempdir, $root, 'Icon.png'); - die "ERROR: Widget bundle must include an Icon.png file in $root directory.\n" unless -e $icon; - } - - # Create the MBM file icon - in case of sharedlibrary, create only if NOKIA:widget is true - my $mbm; - - print("\nIs shared library - $isSharedLibrary \nIs sharedlib widget - $isSharedWidget \nIs Secure WGZ - $self->{'secure'}{lc $filename}\n"); - - if( ((!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget)) && (!$self->{'secure'}{lc $filename})) - { - print "Creating mbm !!!\n"; - die "ERROR: Can't find PNG2MBM command in PATH." if !(my $cmd = findCmd('png2mbm.exe')); - $mbm = $self->regFileName($drive, sprintf("[%08x].mbm", $widgetdata->{'Uid'})); - print "Generating: $mbm\n"; - die "Failed to create MBM $mbm " if system("$cmd $self->{args}->{'verbose'} -in \"$icon\" -out $mbm -sizes ".ICON_SIZES) != 0; - - # Add the mbm to the list of files - $self->addToRomList($drive, $mbm); - - # Create the INI file which defines the registry info - my $ini = catfile($tempdir, 'reg.ini'); - $self->makeIni($widgetdata, $ini); - unlink 'debug.ini'; copy($ini, 'debug.ini') if $debug; - print "Generated INI file: $ini\n" if $self->{args}->{'verbose'}; - - # Generate the registry files - die "ERROR: Can't find WidgetRegFiles.exe command in PATH." if !($cmd = findCmd('WidgetRegFiles.exe')); - die "Failed to generate registry files" if system("$cmd $ini") != 0; - my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $widgetdata->{'Uid'})), catfile($dest, sprintf("%08x_loc.rsc", $widgetdata->{'Uid'})) ); - die "Failed to generate REG file: $!" if !-e $reg; - $self->addToRomList($drive, $reg); - die "Failed to generate LOC file: $!" if !-e $loc; - if ($self->{'args'}->{'l10n'}) - { - $self->addToRomList($drive, $loc); - } - else - { - $self->addToRomList($drive, $loc, 'localised'); - } - } - - # Create install folder - my $dir = $self->installDir($drive, $widgetdata->{'BundleIdentifier'}); - mkpath $dir; - - # Now copy the widget files to the right place - print "Install Directory: $dir\n"; - foreach my $widgetfile ( @$extracted ) - { - my ( $sourceFile, $destFile ) = ( catfile($tempdir, $widgetfile), catfile($dir, $widgetfile) ); - print "Copying $sourceFile to $destFile\n" if $self->{args}->{'debug'}; - - # Create the directory if it doesn't exist already - my $dir = dirname($destFile); - if (!-d $dir) - { - mkpath ($dir) or die "Failed to create $dir $!"; - } - unlink $destFile; - if (!copy($sourceFile, $destFile)) - { - warn "WARNING: Failed to copy $sourceFile to $destFile: $!"; - } - #else - { - $self->addToRomList($drive, $destFile); - } - } - - # Copy the MBM file into the widget install directory - # because native installation does and uses it after - # installation to manage UID consistency. - if( (!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget)) - { - my $mbmName = sprintf("[%08x].mbm", $widgetdata->{'Uid'}); - my $destFile; - if($w3c_widget) - { - my $dataDir; - - my $widget_uid; - - if($non_nokia_widget) - { - $widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID; - } - else - { - $widget_uid = CWRT_WIDGET_UI_UID; - } - - # NOKIA:sharedlibrary check - if($isSharedWidget) - { - $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName)); - } - else - { - #in case of WGT copy .mbm to \epoc32\winscw\C\private\200267c0\data\hash\ - $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval)); - } - mkpath $dataDir; - $destFile = catfile($dataDir,$mbmName); - } - else - { - $destFile = catfile($dir, $root, $mbmName); - } - # Exclude securewidget from making a mbm file - if (!$self->{'secure'}{lc $filename}){ - print "Copying $mbm to $destFile\n" if $self->{args}->{'debug'}; - copy $mbm, $destFile or die "Failed to copy $mbm to $destFile: $!"; - $self->addToRomList($drive, $destFile); - } - } - - # Remember the data for the registry - if( $w3c_widget ) - { - push @installedCWRTProps, $widgetdata; - } - else - { - if (!$self->{'secure'}{lc $filename}){ - push @installedProps, $widgetdata; - } - } - - if (!$debug) - { - # Perl v5.6 can't delete files with unicode in their name on Windows - if ($] < 5.008 && $^O =~ /MSWin32/) - { - system("rmdir /s /q $tempdir"); - } - else - { - rmtree $tempdir; - } - } - #Generate the secsession for .wgt widgets - if( $w3c_widget ) - { - $self->addToRomList($drive, $self->makeSecSession($drive)); - } - } - - my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY); - $self->addToRomList($drive, $cwrtdbPath); - - # Generate the registry and IBY file - $self->addToRomList($drive, $self->makeRegistry($drive, \@installedProps, 0)); - $self->addToRomList($drive, $self->makeRegistry($drive, \@installedCWRTProps, 1)); - - - print "\n\n %%%%% WIDGET PRE-INSTALLATION completed for Drive $drive %%%%% \n\n"; - } - -sub un7zipWidget - { - my ( $self, $filename, $tempdir ) = @_; - - # Unzip the file - die "Can't find 7z.exe tool on PATH." if !findCmd('7z.exe'); - die "Failed to extract widget contents using 7zip: $!" if (system("7z x -aoa -o$tempdir \"$filename\" >nul 2>&1") != 0); - } - -sub unzipWidget - { - my ( $self, $filename, $tempdir ) = @_; - - # Unzip the file - die "Can't find unzip.exe tool on PATH." if !findCmd('unzip.exe'); - die "Failed to extract widget contents using zip: $!" if (system("unzip.exe \"$filename\" -d $tempdir >nul 2>&1") != 0); - } - -# Recursively get list of files in a folder -sub getFiles - { - my ( $self, $tempdir ) = @_; - - my $root = '.'; - my @extracted; - my $size =0; - - my @dirs = '.'; - foreach my $dir ( @dirs ) - { - opendir DIR, catfile($tempdir, $dir) or die "Failed to opendir $dir: $!"; - foreach ( grep !/^\.{1,2}$/, readdir DIR ) - { - my $name = catfile($dir, $_); - my $fullname = catfile($tempdir, $name); - if (-d $fullname) - { - push @dirs, $name; - } - else - { - # Remember total size for later - if (-e $fullname) - { - push @extracted, $name; - print "Extracted: $name\n" if $self->{args}->{'debug'}; - $size += -s $fullname; - - # Get root - if ($name =~ /info.plist$/i && $name =~ /^([^\/\\]+)[\/\\]/) - { - $root = $1; - } - } - else - { - warn "WARNING: Failed to find extracted file $fullname"; - } - } - } - closedir DIR; - } - - return ( $root, \@extracted, $size ); - } - -## see http://www.loc.gov/standards/iso639-2/php/code_list.php -## see http://www.loc.gov/standards/iso639-2/faq.html#2 -sub getLocalisedStringByLangCode - { - my ( $self, $dir, $strName, $langCode ) = @_; - my $localised; - - # Generate the name of the file containing localised strings for this language - my $locfile = catfile($dir, "$langCode.lproj", "InfoPlist.strings"); - if (-e $locfile) - { - # Open the file - print "Found $langCode language translations in $locfile\n" if $verbose; - open LOC, $locfile or die "Failed to open $locfile: $!"; - - # Get the byte order mark from the start of the file - my $bom; - $bom = unpack("S", $bom) if (read(LOC, $bom, 2) == 2); - if ($bom) - { - if ($bom == 0xEFBB) - { - # Skip utf8 bom - seek LOC, 3, 0; - } - elsif ($bom != 0xFFFE && $bom != 0xFEFF) - { - seek LOC, 0, 0; - undef $bom; - } - } - else - { - # go back to start of file if no bom - seek LOC, 0, 0; - undef $bom; - } - - while(my $line = ) - { - # Do unicode conversion - my $ustr; - if ($bom) - { - $ustr = utf16($line); - $ustr->byteswap if $bom != 0xFFFE; - } - else - { - $ustr = utf8($line); - } - - # Find the string we're looking for - if ($ustr->utf8 =~ /(?:^|\s)$strName\s*=\s*\"([^\"]*)\"/) - { - print "\t...$strName => $1\n" if $debug; - $localised = utf8($1); - } - } - close LOC; - } - return $localised; - } - -# Get localised version of strings if they exist -sub getLocalisedStrings - { - my ( $self, $dir, $strName ) = @_; - return if (!$self->{'langmapping'}); - - # Iterate through all the languages we know about - my %result; - for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++) - { - my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] ); - - my $localised = $self->getLocalisedStringByLangCode($dir, $strName, $langname); - $result{$langid} = $localised if $localised; - } - - return \%result if keys %result; - } - -# Find and execute a command -sub findCmd - { - my $cmd = shift; - return fixFilename("./$cmd") if -e $cmd; - - # PATH separator differs on Windows and Linux - my $sep = $^O =~ /MSWin32/ ? ';' : ':'; - - # Search each entry in the PATH - my @paths = split /$sep/, $ENV{PATH}; - push @paths, dirname($0); - foreach my $path ( @paths ) - { - my $fullcmd = fixFilename(catfile($path, $cmd)); - return $fullcmd if -e $fullcmd; - } - } - -# Make INI file describing widget - this is passed to widgetregfiles.exe -sub makeIni - { - my ( $self, $data, $file ) = @_; - open INI, ">$file" or die "Failed to open $file for writing: $!"; - binmode INI, ":utf8" if $] >= 5.008; - - # Get directory where mbm should go - my $dir = $self->regFileName($data->{'DriveName'}); - - print INI "[app_registration_info]\n"; - print INI sprintf("uid=%08x\n", $data->{'Uid'}); - print INI "app_file=$data->{'MainHTML'}\n"; - print INI "caption=$data->{'BundleDisplayName'}\n"; - print INI "drive_name=$data->{'DriveName'}\n"; - print INI "results_dir=$dir\n"; - - if( $w3c_widget ) - { - print INI "app_type=200267DC\n"; - print " WGT Widget:: app_type added to ini of widgetregfiles.exe \n" if $debug; - } - - - # Add language stuff if we have the mapping - if ($data->{'LocBundleDisplayName'}) - { - my @langList; - foreach my $langid ( sort { $a <=> $b } keys %{ $data->{'LocBundleDisplayName'} } ) - { - my $symid = sprintf("%02d", $langid); - push @langList, $symid; - print INI "caption$symid=", $data->{'LocBundleDisplayName'}->{$langid}->utf8, "\n"; - } - print INI "languages=", join(' ', @langList), "\n"; - } - - close INI; - convert2Unicode($file); - } - - sub findfreeUid - { - my ( $self, $data ) = @_; - my $appfile = lc $data->{'MainHTML'}; - my $uid; - my $size; - if($w3c_widget) #CWRT Widget - { - # pick the next free CWRT Internal UID - if(isInternal($data->{'DriveName'})) - { - print "\nInternal CWRT UID"; - $size = scalar @staticUidCwrtIntList; - print " Static UID :: @staticUidCwrtIntList Length -- $size \n" if($size); - for(my $i=0; $i<$size; $i++) - { - #skip looping if freeUid found - if( $self->{'freeuidcwrtint'} lt $staticUidCwrtIntList[$i] ) {last}; - - if($self->{'freeuidcwrtint'} == $staticUidCwrtIntList[$i]) - { - $self->{'freeuidcwrtint'}++; - } - } - $uid = $self->{'freeuidcwrtint'}++; # Assign and then set next free UID - } - else - { - # pick the next free CWRT External UID - print "\nExternal CWRT UID "; - $size = scalar @staticUidCwrtExtList; - print "Static UID :: @staticUidCwrtExtList Length -- $size \n"; - - for(my $i=0; $i<$size; $i++) - { - if( $self->{'freeuidcwrtext'} lt $staticUidCwrtExtList[$i] ) {last}; - - if($self->{'freeuidcwrtext'} == $staticUidCwrtExtList[$i]) - { - $self->{'freeuidcwrtext'}++; - } - } - $uid = $self->{'freeuidcwrtext'}++; # Assign and then set next free UID - } - } - else #WRT widget - { - # pick the next free WRT Internal UID - if(isInternal($data->{'DriveName'})) - { - # pick the next free CWRT Internal UID - if(isInternal($data->{'DriveName'})) - { - print "\nInternal WRT UID "; - $size = scalar @staticUidWrtIntList; - print " STATIC UID :: @staticUidWrtIntList Length -- $size\n"; - - for(my $i=0; $i<$size; $i++) - { - if( $self->{'freeuidwrtint'} lt $staticUidWrtIntList[$i] ) {last}; - - if($self->{'freeuidwrtint'} == $staticUidWrtIntList[$i]) - { - $self->{'freeuidwrtint'}++; - } - } - $uid = $self->{'freeuidwrtint'}++; # Assign and then set next free UID - } - } - else - { - # pick the next free WRT External UID - print "\nExternal WRT UID "; - $size = scalar @staticUidWrtExtList; - print "STATIC UID :: @staticUidWrtExtList Length -- $size\n"; - - for(my $i=0; $i<$size; $i++) - { - if( $self->{'freeuidwrtext'} lt $staticUidWrtExtList[$i] ) {last}; - - if($self->{'freeuidwrtext'} == $staticUidWrtExtList[$i]) - { - $self->{'freeuidwrtext'}++; - } - } - $uid = $self->{'freeuidwrtext'}++; # Assign and then set next free UID - } - } - print sprintf("Generated UID: hex->0x%08X dec->$uid\n \n",$uid); - return $uid; - } - -# Fix slash problems in a filename -sub fixFilename - { - my $filename = shift; - $filename =~ s/([\\\/])[\\\/]/$1/g; - return catfile(split(/[\\\/]/, $filename)); - } - -# Get install location -sub destLocation - { - my ( $self, $drive ) = @_; - my $letter = uc(substr($drive, 0, 1)); - - # Was any destination location specified in the config file? - if ($self->{destination} && $self->{destination}->{$letter}) - { - return catfile($self->{'args'}->{'epocroot'}, $self->{destination}->{$letter}); - } - - # No destination specified - use emulator location - return catfile($self->{'args'}->{'epocroot'}, $letter eq 'Z' ? ROM_DEST : sprintf(DRIVE_DEST, $letter)); - } - -# Get the destination for REG/LOC/MBM file -sub regFileName - { - my ( $self, $drive, $filename ) = @_; - my $result = catfile($self->destLocation($drive), DESTINATION, $filename); - return fixFilename($result); - } - -# Widget install directory -sub installDir - { - my ( $self, $drive, $id ) = @_; - my $result ; - $hashval = hashpjw($id); - if( $w3c_widget ) - { - my $widget_uid; - if($non_nokia_widget) - { - $widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID; - } - else - { - $widget_uid = CWRT_WIDGET_UI_UID; - } - if($isSharedLibrary) - { - $result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", "lib",$sharedFolderName); - } - else - { - $result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", $hashval); - } - } - else - { - if ($isSecureWidget){ - print "Installing secure WGZ Widget\n"; - $result = catfile($self->destLocation($drive), 'private', sprintf("%08x", SWIDGET_UI_UID), $id); - } else { - print "Installing WGZ Widget\n"; - $result = catfile($self->destLocation($drive), 'private', sprintf("%08x", WIDGET_UI_UID), $id); - } - } - return fixFilename($result); - } - -# Determines whether a drive should be considered internal or not -sub isInternal - { - my $drive = shift; - die "Invalid drive format: $drive" if $drive !~ /^[a-zA-Z]:/; - return 1 if $drive =~ /^[zcZC]/; - } - -# Parse these awful PLIST files -sub parsePList - { - my $file = shift; - - # Create parser object - our ($key, $val, $plisthash ) = ('', '', {}); - my $parser = new XML::Parser; - $parser->setHandlers('Doctype' => \&docT, 'Start' => \&startH, 'End' => \&endH, 'Char' => \&dataH); - - # Parse the file - open XML, $file or die "Couldn't open $file"; - - # Skip the UTF8 BOM - perl 5.6 can't handle it - my $bom; - read XML, $bom, 3; - $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom))); - print "Testing the following for BOM: $bom\n" if $debug; - seek(XML, 0, 0) if $bom ne 'EFBBBF'; - - $parser->parse(*XML); - close XML; - - # Check required fields exist - die "Widget MainHTML unknown" if !$plisthash->{'MainHTML'}; - die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'}; - die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'}; - - # Return result - return $plisthash; - - # Called on a start tag - sub startH - { - my ($p, $el, %atts) = @_; - undef $key if ($el =~ /^key$/i); - $val = ''; - } - - # Receives document type - sub docT - { - my ($expat, $name, $sysid, $pubid, $internal ) = @_; - die "PLIST format looks wrong!" if lc($name) ne 'plist'; - $plisthash->{'NokiaWidget'} = ( $pubid =~ m[^-//Nokia//DTD PLIST]i ) ? 1 : 0; - } - - # Receives character data - sub dataH - { - my ($p, $s) = @_; - $val .= $s; - } - - # Called on an end tag - sub endH - { - my ($p, $el) = @_; - if ($el =~ /^key$/i) - { - $key = $val; - } - elsif ($key) - { - $val = 1 if $el =~ /^true$/i; - $val = 0 if $el =~ /^false$/i; - - # Fix stuff so it's in the correct format - $key =~ s/^CF//; - $key = 'BundleIdentifier' if $key =~ /^Identifier$/i; - $key = 'BundleDisplayName' if $key =~ /^DisplayName$/i; - $key = 'BundleVersion' if $key =~ /^Version$/i; - - $plisthash->{$key} = $val; - undef $key; - } - $val = '' - } - } - - -sub parseConfXml - { - my ( $file , $language ) = @_; - - our ($key, $val, $plisthash, $localizationValue,$localizationIconValue, $lang,$langIcon) = ('', '', {}, '','', {},{}); - our ($featureCount, $paramCount, $accessCount) = (1,1,1); - our ($attributeMap, $featureMap, $featureParamMap, $accessMap)=('','','',''); - - # Create parser object - my $parser = new XML::Parser; - $parser->setHandlers( 'Start' => \&startC, 'End' => \&endC, 'Char' => \&dataC); - - # Parse the file - open XML,$file or die "Couldn't open $file"; - # Skip the UTF8 BOM - perl 5.6 can't handle it - my $bom; - read XML, $bom, 3; - $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom))); - print "Testing the following for BOM: $bom\n" if $debug; - seek(XML, 0, 0) if $bom ne 'EFBBBF'; - $plisthash->{'NokiaWidget'} = 2 ; - $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1" ; - - $parser->parse(*XML); - close XML; - - if( $language ) - { - if($lang->{$language}) - { - $plisthash->{'BundleDisplayName'} = $lang->{$language}; - } - if($langIcon->{$language}) - { - $plisthash->{'IconPath'} = $langIcon->{$language}; - } - } - die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'}; - die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'}; - - $attributeMap = $attributeMap.WIDGET_NAME.KEY_VALUE_SEPERATOR.$plisthash->{'BundleDisplayName'}.KEY_VALUE_PAIR_SEPERATOR; - - if($non_nokia_widget) - { - $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267D6".KEY_VALUE_PAIR_SEPERATOR; - } - else - { - $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267C0".KEY_VALUE_PAIR_SEPERATOR; - } - - if($attributeMap) - { - $plisthash->{'AttributeList'} = $attributeMap; - print "\nAttributeList::$plisthash->{'AttributeList'}\n" - } - - # Return result - return $plisthash; - - # Called on a start tag - sub startC - { - my ($p, $el, %atts) = @_; - - if($el eq "widget") - { - if ( $atts{"id"} ) - { - $plisthash->{'BundleIdentifier'} = $atts{"id"}; - $attributeMap = $attributeMap.WIDGET_ID.KEY_VALUE_SEPERATOR.$atts{"id"}.KEY_VALUE_PAIR_SEPERATOR; - - } - if ( $atts{"version"} ) - { - $plisthash->{'BundleVersion'} = $atts{"version"}; - $attributeMap = $attributeMap.WIDGET_VERSION.KEY_VALUE_SEPERATOR.$atts{"version"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ( $atts{"viewmodes"} && $atts{"viewmodes"} eq "all" ) - { - $plisthash->{'MiniViewEnabled'} = 1; - } - $attributeMap = $attributeMap.WIDGET_HEIGHT.KEY_VALUE_SEPERATOR.$atts{"height"}.KEY_VALUE_PAIR_SEPERATOR; - $attributeMap = $attributeMap.WIDGET_WIDTH.KEY_VALUE_SEPERATOR.$atts{"width"}.KEY_VALUE_PAIR_SEPERATOR; - } - elsif ($el eq "icon") - { - if ( $atts{"xml:lang"} ) - { - $localizationIconValue = lc($atts{"xml:lang"}) ; - } - if ( $atts{"src"} ) - { - $plisthash->{'IconPath'} = $atts{"src"}; - } - } - elsif ($el eq "content") - { - $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR; - if ( $atts{"src"} ) - { - $plisthash->{'MainHTML'} = $atts{"src"}; - $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_ATTR_SEPERATOR."src".KEY_VALUE_SEPERATOR.$atts{"src"}.KEY_VALUE_PAIR_SEPERATOR; - } - } - elsif ($el eq "name") - { - if ( $atts{"xml:lang"} ) - { - $localizationValue = lc($atts{"xml:lang"}) ; - } - } - elsif ($el eq "feature") - { - $featureMap = WIDGET_FEATURE . $featureCount; - $attributeMap = $attributeMap.$featureMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR; - - if ( $atts{"name"} ) - { - $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR; - my $jilFeature = "http://jil.org/jil"; - if($atts{"name"}=~ m/^$jilFeature/i) - { - $plisthash->{'WidgetPackagingFormat'} = "jil"; - } - } - if ( $atts{"required"} ) - { - $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."required".KEY_VALUE_SEPERATOR.$atts{"required"}.KEY_VALUE_PAIR_SEPERATOR; - } - } - elsif($el eq "param") - { - $featureParamMap = $featureMap. WIDGET_FEATURE_PARAM . $paramCount; - $attributeMap = $attributeMap.$featureParamMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR; - if ($atts{"name"}) - { - $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ($atts{"value"}) - { - $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."value".KEY_VALUE_SEPERATOR.$atts{"value"}.KEY_VALUE_PAIR_SEPERATOR; - } - } - elsif ($el eq "access" || $el eq "jil:access") - { - $accessMap = WIDGET_ACCESS . $accessCount; - $attributeMap = $attributeMap.$accessMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR; - - if ( $atts{"network"} ) - { - $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."network".KEY_VALUE_SEPERATOR.$atts{"network"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ( $atts{"remotescripts"} ) - { - $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."remotescripts".KEY_VALUE_SEPERATOR.$atts{"remotescripts"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ( $atts{"localfs"} ) - { - $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."localfs".KEY_VALUE_SEPERATOR.$atts{"localfs"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ( $atts{"origin"} ) - { - $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."origin".KEY_VALUE_SEPERATOR.$atts{"origin"}.KEY_VALUE_PAIR_SEPERATOR; - } - if ( $atts{"subdomains"} ) - { - $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."subdomains".KEY_VALUE_SEPERATOR.$atts{"subdomains"}.KEY_VALUE_PAIR_SEPERATOR; - } - } - elsif ($el eq "NOKIA:sharedlibrary") - { - print " \n\n ^^^^^^^^^^^^^^^^^^^^^^^NOKIA:sharedlibrary ^^^^^^^^^^^^^^^^^^^^ \n\n"; - $isSharedLibrary = 1; - $plisthash->{'WidgetPackagingFormat'} = "shared-library"; - $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR; - } - $val = ''; - } - -sub docC{} -# Receives character data - sub dataC - { - my ($p, $s) = @_; - $val .= $s; - } - - # Called on an end tag - sub endC - { - my ($p, $el) = @_; - if ($el eq "name") - { - if( $localizationValue ) - { - chomp($val); - $lang->{$localizationValue} = $val; - $localizationValue = ''; - } - else - { - chomp($val); - $plisthash->{'BundleDisplayName'} = $val; - } - } - elsif ($el eq "icon") - { - if( $localizationIconValue ) - { - $langIcon->{$localizationIconValue} = $plisthash->{'IconPath'}; - print "\n %%%%%%%%%%% $localizationIconValue :: $plisthash->{'IconPath'}%%%%%%%%%%%%%\n"; - $localizationIconValue = ''; - } - } - elsif($el eq "feature") - { - $featureCount++; - $paramCount = 0; - } - elsif($el eq "param") - { - $paramCount++; - } - elsif($el eq "access" || $el eq "jil:access") - { - $accessCount++; - } - elsif ($el eq "NOKIA:folder") - { - chomp($val); - $sharedFolderName = $val; - $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_FOLDER.KEY_VALUE_SEPERATOR.$sharedFolderName.KEY_VALUE_PAIR_SEPERATOR; - } - elsif ($el eq "NOKIA:widget") - { - chomp($val); - if( lc($val) eq "true" ) - { - $isSharedWidget = 1; - $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1"; - } - $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_WIDGET.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR; - } - elsif ($el eq "NOKIA:icon") - { - chomp($val); - if( lc($val) eq "true" ) - { - $isSharedIcon = 1; - } - $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_ICON.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR; - } - $val = '' - } - - } - - -# Stores the details of files to be added to "rom" -sub addToRomList - { - my ( $self, $drive, $file, $localised ) = @_; - $file = fixFilename($file); - - # All files should be under epoc32 somewhere - need to drop a bit of the path for the rom destination - my $localpath = $self->destLocation($drive); - - my $dest = fixFilename($file); - $dest =~ s/^\Q$localpath\E//i; - - # Add the file to the list for the rom - # It may be localised - in which it'll be put in a different IBY file - $localised = $localised ? '_rsc' : ''; - $self->{"installedFiles${localised}"}->{$drive}->{$file} = $dest; - } - -# Make the IBY file -sub makeIBY - { - my ( $self, $drive, $localised ) = @_; - - # Generate the file name for the IBY file - $localised = $localised ? '_rsc' : ''; - my $name = $drive =~ /^[zZ]/ ? "preinstalledwidgets${localised}.iby" : sprintf("preinstalledwidgets_drive%s${localised}.iby", substr($drive, 0, 1)); - my $iby = fixFilename(catfile($self->{'args'}->{'epocroot'}, 'epoc32', 'rom', 'include', $name)); - print "Generating: $iby\n"; - - mkpath dirname($iby); - open IBY, ">$iby" or die "Failed to open $iby for writing: $!"; - $name =~ s/\./_/g; $name = uc($name); - print IBY "// GENERATED FILE: EDIT WITH CARE\n\#ifndef __${name}__\n\#define __${name}__\n\n"; - foreach my $file ( sort keys %{ $self->{"installedFiles${localised}"}->{$drive} } ) - { - my $dest = $self->{"installedFiles${localised}"}->{$drive}->{$file}; - - # Quote filenames as they may contain spaces! - print IBY "data=\"$file\"\t\"$dest\"\n"; - } - print IBY "\#endif\n"; - close IBY; - } - -# Unregister (with Apparc) existing Widgets -sub unregisterWidgets -{ - my ( $self, $drive ) = @_; - - my $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY)); - # If the WRT registry already exists, remove apparc registry info for those widgets - # This should avoid problems with unregistered widget icons in the emulator? - if (-e $registry) - { - print("\n UNREGISTERING WGZ WIDGETS \n"); - - my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } ); - foreach my $entry ( @{ $ref->{entry} } ) - { - my $uid = $entry->{prop}->{Uid}->{val}->{content}; - - print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose; - my $dest = $self->regFileName($drive); - my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid)); - my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) ); - unlink $mbm, $reg, $loc; - - # We also have to delete the widget directory otherwise it'll be re-registered - my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content}; - $w3c_widget = 0; - my $dir = $self->installDir($drive, $id); - rmtree $dir; - } - } - - $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY)); - - # If the CWRT registry already exists, remove apparc registry info for those widgets - # This should avoid problems with unregistered widget icons in the emulator? - if (-e $registry) - { - print("\n UNREGISTERING WGT WIDGETS \n"); - - my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } ); - foreach my $entry ( @{ $ref->{entry} } ) - { - my $uid = $entry->{prop}->{Uid}->{val}->{content}; - - print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose; - my $dest = $self->regFileName($drive); - my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid)); - my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) ); - unlink $mbm, $reg, $loc; - - # We also have to delete the widget directory otherwise it'll be re-registered - my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content}; - print " Unregistering $id "; - my $basepath = $entry->{prop}->{BasePath}->{val}->{content}; - $w3c_widget = 1; - my $sharedLib = "lib"; #BasePath will have lib only if the widget is shared Library - - if($basepath =~ m/$sharedLib/) - { - $isSharedLibrary = 1; - } - - if($basepath =~ m/\\200267d6\\/i) - { - $non_nokia_widget = 1; - } - #sharedFolderName TBD - my $dir = $self->installDir($drive, $id); - rmtree $dir; - - print("BasePath:$basepath \nIs Non-Nokia? $non_nokia_widget Is SharedLibrary? $isSharedLibrary \nDirectory:$dir \n"); - - $dir =~ s/widgets_21D_4C7/data/; - rmtree $dir; - } - } - #delete CWRT webapp DB if exists - my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY); - if($cwrtdbPath) - { - print "Deleting CWRT_WEBAPP_REGISTRY \n"; - rmtree $cwrtdbPath; - } - } - -# Make the registry -sub makeRegistry - { - my ($self, $drive, $installed, $w3c) = @_; - - my ($registry); - if($w3c) - { - $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY)); - } - else - { - $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY)); - } - - print "\nGenerating: $registry\n"; - - # Write the file - mkpath dirname($registry); - open OUT, ">$registry" or die "Failed to open WidgetEntryStore.xml: $!"; - - print OUT "\n\n"; - binmode OUT, ":utf8" if $] >= 5.008; - foreach my $pList ( @$installed ) - { - $self->dumpPList(\*OUT, $pList, $w3c); - } - print OUT "\n"; - close OUT; - - # Convert the file to unicode - convert2Unicode($registry); - - # Return the generated file - return $registry; - } - -# Converts a file to Unicode -sub convert2Unicode - { - my $file = shift; - - my @lines; - open IN, $file or die "Failed to open $file: $!"; - binmode IN; - while() - { - my $u = utf8($_); - $u->byteswap; - push @lines, $u->utf16; - } - close IN; - - open OUT, ">$file" or die "Failed to open $file for writing: $!"; - binmode OUT; - print OUT pack("CC", 0xff, 0xfe); - print OUT @lines; - close OUT; - } - -sub hashpjw { - my $s = shift; - my $hashval = 0; - my $g; - - for ( split //, $s ) { - $hashval = ( $hashval << 4 ) + ord $_; - - if ($g = $hashval & 0xf0000000) { - $hashval ^= $g >> 23; - } - $hashval &= ~$g; - } - #print "$hashval \n"; - return $hashval; -} - -# Dumps a single PList hash object -sub dumpPList - { - my ($self, $fh, $data, $w3c) = @_; - my @regProperties = ( - [ 'PropertyListVersion', 'int' ], - [ 'BundleIdentifier', 'string' ], - [ 'BundleName', 'string' ], - [ 'BundleDisplayName', 'string' ], - [ 'MainHTML', 'string' ], - [ 'BundleVersion', 'string' ], - # [ 'Height', 'int' ], - # [ 'Width', 'int' ], - [ 'AllowNetworkAccess', 'int' ], - [ 'DriveName', 'string' ], - [ 'BasePath', 'string' ], - [ 'IconPath', 'string' ], - [ 'FileSize', 'int' ], - [ 'Uid', 'int' ], - [ 'NokiaWidget', 'int' ], - [ 'MiniViewEnabled', 'int' ], - [ 'ProcessUid', 'int' ], - [ 'MimeType', 'string'], - [ 'WidgetPackagingFormat', 'string'], - [ 'DBIconPath', 'string'], - [ 'AttributeList', 'string'], - [ 'BlanketPermissionGranted', 'int' ], - [ 'PreInstalled', 'int' ], - ); - - print $fh "\n"; - my $encodeddata = {}; - foreach my $prop ( @regProperties ) - { - my ( $key, $type ) = @$prop; - if($key ne "DBIconPath" && $key ne "WidgetPackagingFormat" && $key ne "AttributeList" && $key ne "BlanketPermissionGranted" && $key ne "PreInstalled") - { - print $fh "$key$data->{$key}$type\n" if defined $data->{$key}; - } - - if( $w3c ) - { - $encodeddata->{$key} = encodeChar($data->{$key}) if defined $data->{$key}; - } - else - { - if($key eq "BlanketPermissionGranted" || $key eq "PreInstalled") - { - print $fh "$key$data->{$key}$type\n" if defined $data->{$key}; - } - } - } - print $fh "\n"; - print "\n Is a w3c widget? -- $w3c\n"; - if( $w3c ) - { - my $dbPath = fixFilename(catfile($self->destLocation('C'), CWRT_WEBAPP_REGISTRY)); - mkpath dirname($dbPath); - die "ERROR: Can't find CWRTWebAppRegistry.exe in PATH" if !(my $cmd = findCmd('CWRTWebAppRegistry.exe')); - my $regCmd; - - if($encodeddata->{'AttributeList'}) - { - print "\n AttributeList argument sent to DB\n"; - $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'} $encodeddata->{'AttributeList'}"; - } - else - { - print "\n AttributeList argument not sent to DB\n"; - $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'}"; - } - print "\n regCmd : $regCmd \n\n"; - system($regCmd); - } - } - -#encode the space character -sub encodeChar - { - my ($encoded) = @_; - - $encoded =~ s/%/%10/g; - $encoded =~ s/\s/%40/g; - $encoded =~ s/\'/%apos/g; - $encoded =~ s/&/%amp/g; - $encoded =~ s//%gt/g; - $encoded =~ s/\"/%quot/g; - return $encoded; - } - - -# Make secssion -sub makeSecSession - { - my ($self, $drive) = @_; - my $secSession; - my $widget_uid; - if($non_nokia_widget) - { - $widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID; - } - else - { - $widget_uid = CWRT_WIDGET_UI_UID; - } - - if($isSharedLibrary) - { - $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName,"secsession")); - } - else - { - $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval,"secsession")); - } - print "\nGenerating: $secSession\n\n"; - - # Write the file - mkpath dirname($secSession); - open OUT, ">$secSession" or die "Failed to open SecSession.xml: $!"; - - print OUT "\n\n"; - if($non_nokia_widget) - { - print OUT "\n"; - } - else - { - print OUT "\n"; - } - - if(CWRT_ACCESS_POLICY_PATH) { - my $accesspolicypath = findCmd(CWRT_ACCESS_POLICY_PATH); - # Copy Secsession capabilities from browser_access_policy.xml if it exists - if (-e $accesspolicypath) { - print "Browser Access Policy File exists :: ",$accesspolicypath,"\n" ; - my $accesspolicy = XMLin($accesspolicypath, keyattr => {domain => 'name'}, forcearray =>['domain'] ); - my $domainName; - - if($non_nokia_widget) - { - $domainName = $accesspolicy->{domain}->{Operator}; - } - else - { - $domainName = $accesspolicy->{domain}->{TrustedWidgets}; - } - - my $xml = XMLout($domainName, keeproot => 1); - print OUT $xml; - } - #browser_access_policy.xml does not exist in the path - else { - print "\n Browser Access policy file '$accesspolicypath' does not exist in the given path\n"; - if(!$non_nokia_widget) - { - print OUT " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"; - } - } - } - #Access policy path not defined - else { - print "\n Browser Access policy path not defined \n"; - if(!$non_nokia_widget) - { - print OUT " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"; - } - } - - print OUT "\n"; - print OUT "\n"; - close OUT; - - # Return the generated file - return $secSession; - } -__END__ - -=head1 NAME - -installwidgets.pl - A script for generating all the files needed to install Widgets - -=head1 SYNOPSIS - -installwidgets.pl [-h] [-ver] [-v] [-debug] [-e ] [-l ] config.ini - - Options: - -help|h Show this help - -version|ver Show version number - -verbose|v Show verbose output - -debug Show debug output - -epocroot|e Override value of EPOCROOT - -localization|l lproj_dir - -A script for generating all the files needed to preinstall Widgets. - - Example: - perl installwidgets.pl -l fr config.ini Install widgets listed in config.ini using French localization - - Author: - peter.harper@sosco.com - -=head1 DESCRIPTION - -This tool can be used to pre-generate all the files needed to install Widgets. The tool and its dependencies can be placed anywhere on your PATH. -It generates the results in the epoc32 folder - in the appropriate locations for the emulator. -It finds the epoc32 folder using the EPOCROOT environment variable which can be overridden via the -e command line option. - -=head2 CONFIG FILE - -The preferred way to run the tool is via a configuration INI file. -You can list the widgets to install on each drive. You can specify the exact location of the Widget, otherwise it will try and find the Widget via EPOCROOT. - -You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename -This will set the BlanketPermissionGranted attribute in the registry. -Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated. - - # Widgets to be pre-installed for the ROM - [drive-z] - \somepath\foo.wgz - \somepath\bar.wgz - - # Widgets for the internal disk - [drive-c] - \somepath\widget1.wdgt.zip [HomeScreen] - - # Widgets for the removable disk - [drive-e] - \somepath\widget2.wdgt.zip - - # Commands to run at the end - [run-commands] - dostuff.pl - domorestuff.exe - -=head2 DEPENDENCIES - -The tool has some dependencies which must exist for it to work. - -=over - -=item 1 - -png2mbm.pl - A script to generate an MBM file from a PNG - -=item 2 - -WidgetRegFiles.exe - an EXE which can generate Symbian REG and LOC files for registering non-native Widget apps. -This tool is built with "SymPort" a native tools port of basic Symbian OS services. - -=item 3 - -7z/unzip - For extracting files from the Widget archive. -7Zip will be used in preference to unzip if it's found on your path because it handles Unicode a better. - -=item 4 - -GD.pm - Perl support for the GD graphics library for PNG support, see http://www.libgd.org . - -=back - -=head3 INSTALLING GD - -You can install GD automatically with a simple command - however the command you need to use differs depending on the version of Perl you have installed. -At the time of writing Symbian requires Perl version 5.6 - although in my experience Perl 5.8 works okay. To find out which version of Perl you have type "perl -v" on the command line. - -To install the GD library: - -=over - -=item * - -For Perl v5.6: "ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/GD.ppd " - -=item * - -For Perl v5.8: "ppm install http://theoryx5.uwinnipeg.ca/ppms/GD.ppd " - -=back - -=head2 WIDGET INSTALL PROCESS - -Here's a detailed breakdown of what the script does. - -=over - -=item 1 - -It gets the lists of Widgets from the config.ini file passed on the command line. -This process is repeated for all Widgets and all drives listed in the config file. - -=item 2 - -Any existing Widgets listed in "private\10282f06\WidgetEntryStore.xml" are deleted from the epoc32 tree. -This ensures that there are no problems when testing Widgets in the emulator. - -=item 3 - -All the compressed files in the Widget are extracted to a temporary folder. - -=item 4 - -The details for the Widget are loaded from its "Info.plist" file. - -=item 5 - -A UID is chosen for the widget. This differs depending on whether installation is for an internal drive (z: or c:) or an external drive (e: etc). - -=item 5 - -A Symbian MBM file is generated from the "Icon.png" file supplied by the Widgets. -Three different sized icons are generated "88x88", "32x32" and "24x24". -The MBM file is placed in "private/10003a3f/import/apps/NonNative/Resource/[].mbm". - -=item 6 - -"WidgetRegFiles.exe" is executed to generate REG and LOC resource files used to register the Widget as an app in Symbian OS. -These files are placed in "private/10003a3f/import/apps/NonNative/Resource". - -=item 7 - -All the widgets files are copied to a folder under "private\10282822". -The Widget's bundle identifier is used to create a unique folder under here for the Widget. - -=item 8 - -The Widget registry is generated in "private\10282f06\WidgetEntryStore.xml" - -=item 9 - -If Widgets are being preinstalled for ROM an IBY file is created in "epoc32\rom\include\preinstalledwidgets.iby". -A separate IBY file is generated for the localised parts of a Widget "epoc32\rom\include\preinstalledwidgets_rsc.iby". -Separate IBY files (per drive) are generated for Widgets preinstalled to UDA, e.g. preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby. -These IBY files can be used to add all the Widgets to ROM, ROFS or UDA. - -=back - -=head3 INSTALLING ON HARDWARE USING iMaker - -=over - -=item 1 - -Create the following folder structure at the root level. - -X:\variants\content - -=item 2 - -Copy the files specified in the generated ibys (preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby) to X:\variants\content. Preserve the dir structure. (Note, this step will be automated in the future) - -For example if you want the following file on UDA (User Disk Area, C drive on phone) at the following location C:\private\10282f06\WidgetEntryStore.xml - -Drop the file under X:\variants\content\private\10282f06\WidgetEntryStore.xml - -=item 3 - -Run the foll command to generate UDA - -B -X:\epoc32\tools>imaker -f /epoc32/rom/s60_makefiles/image_conf_sp_rnd_gadget.mk VARIANT_DIR=/variants variantuda - -B -Y:\epoc32\tools>imaker -f /epoc32/rom/config/ncp52/tube/image_conf_tube_ui.mk VARIANT_DIR=/variants variantuda - -=item 4 - -Flash the fpsx file generated under X:\epoc32\rombuild\gadget\uda for Gadget and Y:\epoc32\rombuild\tube\uda for Tube to your device. - -Note: More info on iMaker tool at: L - -=back - -=head3 LOCALISATION - -Widget handles localization by providing localized resources in various language project directories(lproj_dir), one level deep than the root directory. In order to specify a language variant for pre-installing widget, you need to provide the language project directory name, e.g. 'en' for english, 'fr' for French. - -A list of Nokia supported languages can be found in Widget_lproj.xml or at L. If the widget does not provide the localized resource for the variant you specified, the default resources in widget's home directory will be used instead. - -=head3 NOTES - -=over - -=item 1 - -The location of the private folder is in the appropriate place for the files to appear in the emulator. -This is different depending on the intended destination drive (see -dd command line option) for the Widget. -e.g. "epoc32/release/winscw/udeb/z/", "epoc32/winscw/c" or "epoc32/winscw/e" - -=item 2 - -Files are extracted to epoc32 on the current drive relative to the EPOCROOT environment variable or the value given for -epocroot (-e) on the command line. - -=item 3 - -A different IBY file is generated for each drive. - -=over - -=item * - -Z: - \epoc32\rom\include\preinstalledwidgets.iby - -=item * - -C: - \epoc32\rom\include\preinstalledwidgets_driveC.iby - -=item * - -E: - \epoc32\rom\include\preinstalledwidgets_driveE.iby - -=back - -There are separate resource files for localised resources e.g. preinstalledwidgets_rsc.iby. - -=cut