regen headers
[p5sagit/p5-mst-13.2.git] / symbian / symbian_utils.cpp
index 16e911c..b3eee0b 100644 (file)
@@ -9,14 +9,21 @@
 #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)
@@ -27,6 +34,43 @@ extern "C" {
         (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. */
@@ -42,30 +86,95 @@ extern "C" {
         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)
@@ -120,10 +229,10 @@ extern "C" {
             return tmsbuf->tms_utime;
         }
     }
-    class CE32ProcessWait : public CActive
+    class CProcessWait : public CActive
     {
     public:
-        CE32ProcessWait() : CActive(EPriorityStandard) {
+        CProcessWait() : CActive(EPriorityStandard) {
           CActiveScheduler::Add(this);
         }
 #ifdef __WINS__
@@ -143,7 +252,6 @@ extern "C" {
       void RunL() {
           CActiveScheduler::Stop();
       }
-      CActiveSchedulerWait iWait;
     };
     class CSpawnIoRedirect : public CBase
     {
@@ -197,7 +305,7 @@ extern "C" {
 #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;