#define SYMBIAN_UTILS_CPP
#include <e32base.h>
#include <e32std.h>
-#include <textresolver.h>
#include <utf.h>
#include <hal.h>
+#include <eikenv.h>
+
#include <string.h>
#include <ctype.h>
+#include "PerlUi.h"
#include "PerlBase.h"
+#include "PerlUtil.h"
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
extern "C" {
EXPORT_C int symbian_sys_init(int *argcp, char ***argvp)
(void)times(&PL_timesbase);
return 0;
}
+ XS(XS_PerlApp_TextQuery) // Can't be made static because of XS().
+ {
+ dXSARGS;
+ if (items != 0)
+ Perl_croak(aTHX_ "PerlApp::TextQuery: no arguments, please");
+ SP -= items;
+ // TODO: parse arguments for title, prompt, and maxsize.
+ // Suggested syntax:
+ // TextQuery(title => ..., prompt => ..., maxsize => ...)
+ // For an example see e.g. universal.c:XS_PerlIO_get_layers().
+ _LIT(KTitle, "Title");
+ _LIT(KPrompt, "Prompt");
+ HBufC* cData = HBufC::New(KPerlUiOneLinerSize);
+ TBool cSuccess = EFalse;
+ if (cData) {
+ TPtr cPtr(cData->Des());
+ if (CPerlUi::TextQueryDialogL(KTitle,
+ KPrompt,
+ cPtr,
+ KPerlUiOneLinerSize)) {
+ ST(0) = sv_2mortal(PerlUtil::newSvPVfromTDesC16(*cData));
+ cSuccess = ETrue;
+ }
+ delete cData;
+ }
+ if (cSuccess)
+ XSRETURN(1);
+ else
+ XSRETURN_UNDEF;
+ }
+ EXPORT_C void init_os_extras(void)
+ {
+ dTHX;
+ char *file = __FILE__;
+ dXSUB_SYS;
+ newXS("PerlApp::TextQuery", XS_PerlApp_TextQuery, file);
+ }
EXPORT_C SSize_t symbian_read_stdin(const int fd, char *b, int n)
{
#ifdef PERL_GLOBAL_STRUCT /* Avoid unused variable warning. */
return ((CPerlBase*)PL_appctx)->ConsoleWrite(fd, b, n);
}
static const char NullErr[] = "";
- EXPORT_C char* symbian_get_error_string(const TInt error)
+ EXPORT_C char* symbian_get_error_string(TInt error)
{
+ // CTextResolver seems to be unreliable, so we roll our own
+ // at least for the basic Symbian errors (this does not cover
+ // the various subsystems).
dTHX;
if (error >= 0)
return strerror(error);
- CTextResolver* textResolver = CTextResolver::NewL();
- CleanupStack::PushL(textResolver);
- TBuf<KErrorResolverMaxTextLength> buf16;
- TBuf8<KErrorResolverMaxTextLength> buf8;
- if (error != KErrNone)
- buf16 = textResolver->ResolveError(error);
- if (buf16.Length()) {
- if (CnvUtfConverter::ConvertFromUnicodeToUtf8(buf8, buf16) !=
- KErrNone) {
- CleanupStack::PopAndDestroy(textResolver);
- return (char*)NullErr;
- }
- }
+ error = -error; // flip
+ const TInt KErrStringMax = 256;
+ typedef struct {
+ const char* kerr;
+ const char* desc;
+ } kerritem;
+ static const kerritem kerrtable[] = {
+ { "None", /* 0 */ "No error"},
+ { "NotFound", /* -1 */ "Unable to find the specified object"},
+ { "General", /* -2 */ "General (unspecified) error"},
+ { "Cancel", /* -3 */ "The operation was cancelled"},
+ { "NoMemory", /* -4 */ "Not enough memory"},
+ { "NotSupported", /* -5 */ "The operation requested is not supported"},
+ { "Argument", /* -6 */ "Bad request"},
+ { "TotalLossOfPrecision",
+ /* -7 */ "Total loss of precision"},
+ { "BadHandle", /* -8 */ "Bad object"},
+ { "Overflow", /* -9 */ "Overflow"},
+ { "Underflow", /* -10 */ "Underflow"},
+ { "AlreadyExists", /* -11 */ "Already exists"},
+ { "PathNotFound", /* -12 */ "Unable to find the specified folder"},
+ { "Died", /* -13 */ "Closed"},
+ { "InUse", /* -14 */
+ "The specified object is currently in use by another program"},
+ { "ServerTerminated", /* -15 */ "Server has closed"},
+ { "ServerBusy", /* -16 */ "Server busy"},
+ { "Completion", /* -17 */ "Completion error"},
+ { "NotReady", /* -18 */ "Not ready"},
+ { "Unknown", /* -19 */ "Unknown error"},
+ { "Corrupt", /* -20 */ "Corrupt"},
+ { "AccessDenied", /* -21 */ "Access denied"},
+ { "Locked", /* -22 */ "Locked"},
+ { "Write", /* -23 */ "Failed to write"},
+ { "DisMounted", /* -24 */ "Wrong disk present"},
+ { "Eof", /* -25 */ "Unexpected end of file"},
+ { "DiskFull", /* -26 */ "Disk full"},
+ { "BadDriver", /* -27 */ "Bad device driver"},
+ { "BadName", /* -28 */ "Bad name"},
+ { "CommsLineFail", /* -29 */ "Comms line failed"},
+ { "CommsFrame", /* -30 */ "Comms frame error"},
+ { "CommsOverrun", /* -31 */ "Comms overrun error"},
+ { "CommsParity", /* -32 */ "Comms parity error"},
+ { "TimedOut", /* -33 */ "Timed out"},
+ { "CouldNotConnect",/* -34 */ "Failed to connect"},
+ { "CouldNotDisconnect",
+ /* -35 */ "Failed to disconnect"},
+ { "Disconnected", /* -36 */ "Disconnected"},
+ { "BadLibraryEntryPoint",
+ /* -37 */ "Bad library entry point"},
+ { "BadDescriptor", /* -38 */ "Bad descriptor"},
+ { "Abort", /* -39 */ "Interrupted"},
+ { "TooBig", /* -40 */ "Too big"},
+ { "DivideByZero", /* -41 */ "Divide by zero"},
+ { "BadPower", /* -42 */ "Batteries too low"},
+ { "DirFull", /* -43 */ "Folder full"},
+ { "KErrHardwareNotAvailable",
+ /* -44 */ "Hardware is not available"},
+ { "SessionClosed", /* -45 */ "Session was closed"},
+ { "PermissionDenied",
+ /* -46 */ "Permission denied"}
+ };
+ const TInt n = sizeof(kerrtable) / sizeof(kerritem *);
+ TBuf8<KErrStringMax> buf8;
+ if (error >= 0 && error < n) {
+ const char *kerr = kerrtable[error].kerr;
+ const char *desc = kerrtable[error].desc;
+ const TPtrC8 kerrp((const unsigned char *)kerr, strlen(kerr));
+ const TPtrC8 descp((const unsigned char *)desc, strlen(desc));
+ TBuf8<KErrStringMax> ckerr;
+ TBuf8<KErrStringMax> cdesc;
+ ckerr.Copy(kerrp);
+ cdesc.Copy(descp);
+ buf8.Format(_L8("K%S (%d) %S"), &ckerr, error, &cdesc);
+
+ } else {
+ buf8.Format(_L8("Symbian error %d"), error);
+ }
SV* sv = Perl_get_sv(aTHX_ "\005", TRUE); /* $^E or ${^OS_ERROR} */
if (!sv)
return (char*)NullErr;
sv_setpv(sv, (const char *)buf8.PtrZ());
- SvUTF8_on(sv);
- CleanupStack::PopAndDestroy(textResolver);
return SvPV_nolen(sv);
}
EXPORT_C void symbian_sleep_usec(const long usec)
return tmsbuf->tms_utime;
}
}
- class CE32ProcessWait : public CActive
+ class CProcessWait : public CActive
{
public:
- CE32ProcessWait() : CActive(EPriorityStandard) {
+ CProcessWait() : CActive(EPriorityStandard) {
CActiveScheduler::Add(this);
}
#ifdef __WINS__
void RunL() {
CActiveScheduler::Stop();
}
- CActiveSchedulerWait iWait;
};
class CSpawnIoRedirect : public CBase
{
#endif
if (error == KErrNone) {
if ((TInt)aFlag & (TInt)ESpawnWait) {
- CE32ProcessWait* w = new CE32ProcessWait();
+ CProcessWait* w = new CProcessWait();
if (w) {
error = w->Wait(proc);
delete w;