⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e32module.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
* ====================================================================
*  e32module.cpp  
*  
*  Basic EPOC facilities for Python
*
*  Implements currently (13.12.2006) following Python classes / methods:
*
*  Ao_lock -- Symbian active object -based synchronization
*    Ao_lock()
*    wait()
*    signal()
*
*  Ao_timer -- Symbian active object -based timer
*    Ao_timer()
*    after()
*    cancel()
*
*  ao_yield()
*
*  ao_sleep(float [,callable])
*
*  callable ao_callgate(callable)
*
*  file_copy(unicode_string OR string, unicode_string OR string)
*
*  start_server(unicode_string OR string)
*
*  start_exe(unicode_string OR string, unicode_string OR string [,int])
*
*  [unicode_string] drive_list()
*
*  bool is_ui_thread()
*
*  set_home_time(time)
*
*  bool in_emulator()
*     
*  reset_inactivity()
*
*  int inactivity()
*
* Copyright (c) 2005-2007 Nokia Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/

#include <e32std.h>
#include <e32def.h>
#include <e32uid.h>   // e32_uidcrc_app()
#include <eikapp.h>
#include <f32file.h>
#include <bautils.h>  // e32_file_copy()
#include <apmstd.h>
#include <hal.h>      // e32_clock()
#include "Python.h"
#include "symbian_python_ext_util.h"
#include "CSPyInterpreter.h" // e32_stdo(), e32_mem_info()

#ifdef EKA2
#include <tz.h>
#endif 

#ifdef WITH_DLC
#include "dlc.h"    
#endif

//MAX_TIME(in seconds) is max integer where (2147*10exp6< 2exp31)
//This restriction is needed to avoid overflow at
//RTimer.After(TTimeIntervalMicroSeconds32) 
#define MAX_TIME 2147

/*
 *
 * Utilities for e32.start_server() and e32.start_exe()
 *
 */

class CE32ProcessWait : public CActive
{
public:
  CE32ProcessWait():CActive(EPriorityStandard) {
    CActiveScheduler::Add(this);
  }
#if defined(__WINS__) && !defined(EKA2)  
  TInt Wait(RThread& aProcess) {
#else
  TInt Wait(RProcess& aProcess) {
#endif
    aProcess.Logon(iStatus);
    aProcess.Resume();
    SetActive();
#ifdef HAVE_ACTIVESCHEDULERWAIT   
    iWait.Start();
#else
    CActiveScheduler::Start();
#endif
    return iStatus.Int();
  }

  private:
  void DoCancel() {;}
  void RunL() {
#ifdef HAVE_ACTIVESCHEDULERWAIT
    iWait.AsyncStop();
#else
    CActiveScheduler::Stop();
#endif
  }
#ifdef HAVE_ACTIVESCHEDULERWAIT
  CActiveSchedulerWait iWait;
#endif
};

static TInt ProcessLaunch(const TDesC& aFileName, const TDesC& aCommand,
                     TInt aWaitFlag=0)
{
  TInt error;
  Py_BEGIN_ALLOW_THREADS
#if defined(__WINS__) && !defined(EKA2)
  RThread proc;
  RLibrary lib;
  HBufC* pcommand = aCommand.Alloc();
  error = lib.Load(aFileName);
  if (error == KErrNone) {
    TThreadFunction func = (TThreadFunction)(lib.Lookup(1));
    error = proc.Create(_L(""), func, 0x1000, (TAny*) pcommand, &lib,
                        RThread().Heap(), 0x1000, 0x100000, EOwnerProcess);
    lib.Close();
  }
  else
    delete pcommand;
#else
  RProcess proc;
  error = proc.Create(aFileName, aCommand);
#endif
  if (error == KErrNone)
    if (aWaitFlag) {
      CE32ProcessWait* w = new CE32ProcessWait();
      if (w) {
        error = w->Wait(proc);
        delete w;
      }
      else
        error = KErrNoMemory;
    }
    else
      proc.Resume();
  proc.Close();
  Py_END_ALLOW_THREADS
  return error;
}

/*
 *
 * Implementation of e32.start_server()
 *
 */
extern "C" PyObject *
e32_start_server(PyObject* /*self*/, PyObject* args)
{
  PyObject* it;

  if (!PyArg_ParseTuple(args, "O", &it))
    return NULL;

  PyObject* fn = PyUnicode_FromObject(it);
  if (!fn)
    return NULL;

  TPtrC name(PyUnicode_AsUnicode(fn), PyUnicode_GetSize(fn));
  TParse p;
  p.Set(name, NULL, NULL);
  
  if (!(p.Ext().CompareF(_L(".py")) == 0)) {
    Py_DECREF(fn);
    PyErr_SetString(PyExc_TypeError, "Python script name expected");
    return NULL;
  }
  
  TInt error;
  RFs rfs;
  
  if ((error = rfs.Connect()) == KErrNone) {
    TBool f_exists;
    f_exists = BaflUtils::FileExists(rfs, name);
    rfs.Close();
    if (!f_exists){
      Py_DECREF(fn);
      return SPyErr_SetFromSymbianOSErr(KErrNotFound);
    }
  }  
  
  error =
#if defined(__WINS__) && !defined(EKA2)
    ProcessLaunch(_L("\\system\\programs\\Python_launcher.dll"), name);
#else
    ProcessLaunch(_L("python_launcher.exe"), name);
#endif

  Py_DECREF(fn);
  
  RETURN_ERROR_OR_PYNONE(error);
}


/*
 *
 * Implementation of e32.start_exe()
 *
 */

extern "C" PyObject *
e32_start_exe(PyObject* /*self*/, PyObject* args)
{
  PyObject *it0, *it1;
  int wait_flag = 0;

  if (!PyArg_ParseTuple(args, "OO|i", &it0, &it1, &wait_flag))
    return NULL;

  PyObject* n = PyUnicode_FromObject(it0);
  if (!n)
    return NULL;
  
  TPtrC name(PyUnicode_AsUnicode(n), PyUnicode_GetSize(n));
  TParse p;
  p.Set(name, NULL, NULL);
  
#if defined(__WINS__) && !defined(EKA2)
  if (!(p.Ext().CompareF(_L(".dll")) == 0)) {
#else
  if (!(p.Ext().CompareF(_L(".exe")) == 0)) {
#endif
    Py_DECREF(n);
    PyErr_SetString(PyExc_TypeError, "Executable expected");
    return NULL;
  }
  
  PyObject* a = PyUnicode_FromObject(it1);
  if (!a) {
    Py_DECREF(n);
    return NULL;
  }

  TInt error = ProcessLaunch(name,
                             TPtrC(PyUnicode_AsUnicode(a),
                                   PyUnicode_GetSize(a)),
                             wait_flag);

  Py_DECREF(n);
  Py_DECREF(a);
  
  if (wait_flag && (error >= 0))
    return Py_BuildValue("i", error);
  else
    RETURN_ERROR_OR_PYNONE(error);
}

/*
 *
 * Implementation of e32.drive_list()
 *
 */

extern "C" PyObject *
e32_drive_list(PyObject* /*self*/)
{
  TInt error;
  RFs rfs;
  
  if ((error = rfs.Connect()) != KErrNone)
    return SPyErr_SetFromSymbianOSErr(error);

  PyObject* r;
  TDriveList l;

  error = rfs.DriveList(l);
  
  if (error == KErrNone) {
    if (r = PyList_New(0)) {
      for (int i = 0; i < KMaxDrives; i++) {
        if (l[i]) {
          char d[2];
          d[0] = 'A'+i; d[1] = ':';
          
          PyObject* v = PyUnicode_Decode(d, 2, NULL, NULL); 
          if ((v == NULL) || (PyList_Append(r, v) != 0)) {
            Py_XDECREF(v);
            Py_DECREF(r);
            r = NULL;
            break;
          }
          Py_DECREF(v);
        }
      }
    }
  }
  else
    r = SPyErr_SetFromSymbianOSErr(error);

  rfs.Close();

  return r;
}

/*
 *
 * Implementation of e32.file_copy()
 *
 */

extern "C" PyObject *
e32_file_copy(PyObject* /*self*/, PyObject* args)
{
  PyObject *it0, *it1;

  if (!PyArg_ParseTuple(args, "OO", &it0, &it1))
    return NULL;

  PyObject *t, *s;

  if (!((t = PyUnicode_FromObject(it0)) &&
        (s = PyUnicode_FromObject(it1)))) {
    Py_XDECREF(t);
    return NULL;
  }

  TPtrC target(PyUnicode_AsUnicode(t), PyUnicode_GetSize(t));
  TPtrC source(PyUnicode_AsUnicode(s), PyUnicode_GetSize(s));
  
  TInt error;
  RFs rfs;
  
  if ((error = rfs.Connect()) == KErrNone) {
    error = BaflUtils::CopyFile(rfs, source, target);
    rfs.Close();
  }

  Py_DECREF(t); Py_DECREF(s);

  RETURN_ERROR_OR_PYNONE(error);
}

/*
 *
 * Implementation of e32.Ao_lock
 *
 */

#define Ao_lock_type ((PYTHON_GLOBALS->tobj).t_Ao)

#ifndef EKA2
class Ao_lock : public CActive {
#else
NONSHARABLE_CLASS(Ao_lock) : public CActive {
#endif
public:
  Ao_lock();
  TInt Signal(TUint aTid);
  void Wait();
private:
  void RunL();
  void DoCancel() {;}
  TRequestStatus* iPst;
#ifdef HAVE_ACTIVESCHEDULERWAIT
  CActiveSchedulerWait iWait;
#endif
};

Ao_lock::Ao_lock():CActive(0)
{
  iStatus = KErrCancel;
  iPst = &iStatus;
  CActiveScheduler::Add(this);
}

void Ao_lock::Wait()
{
  if (iStatus != KErrNone) {
    iStatus = KRequestPending;
    iPst = &iStatus;
    SetActive();

    Py_BEGIN_ALLOW_THREADS
#ifdef HAVE_ACTIVESCHEDULERWAIT   
    iWait.Start();
#else
    CActiveScheduler::Start();
#endif
    Py_END_ALLOW_THREADS
  }
  iStatus = KErrCancel;
  return;
}

TInt Ao_lock::Signal(TUint aTid)
{
  TInt error = KErrNone;

  if (iStatus != KRequestPending) {
    iStatus = KErrNone;
    return error;
  }
  RThread t;
  error = t.Open(aTid);
  if (error == KErrNone) {
    //iStatus = KErrNone; // Doing this will panic the 3.0 emulator with E32USER-CBase 46 "Stray signal".
    t.RequestComplete(iPst, 0);
    t.Close();
  }
  return error;
}

void Ao_lock::RunL()
{
#ifdef HAVE_ACTIVESCHEDULERWAIT
  iWait.AsyncStop();
#else
  CActiveScheduler::Stop();
#endif
}

struct Ao_lock_object {
  PyObject_VAR_HEAD
  Ao_lock* ob_data;
  unsigned int ob_tid;
};

extern "C" PyObject *
new_e32_ao_object(PyObject* /*self*/)
{
  if (!CActiveScheduler::Current()) {
    PyErr_SetString(PyExc_AssertionError, "no ao scheduler");
    return NULL;
  }

  Ao_lock_object *op = PyObject_New(Ao_lock_object, &Ao_lock_type);
  if (op == NULL)
    return PyErr_NoMemory();

  op->ob_data = new Ao_lock();
  if (op->ob_data == NULL) {
    PyObject_Del(op);
    return PyErr_NoMemory();
  }
  op->ob_tid = RThread().Id();
  return (PyObject *) op;
}

extern "C" PyObject *
ao_wait(Ao_lock_object *self, PyObject* /*args*/)
{
  if ((TUint)RThread().Id() != self->ob_tid) {
    PyErr_SetString(PyExc_AssertionError,
                    "Ao_lock.wait must be called from lock creator thread");
    return NULL;
  }
  if (self->ob_data->iStatus == KRequestPending) {
    PyErr_SetString(PyExc_AssertionError, "wait() called on Ao_lock while another wait() on the same lock is in progress");
    return NULL;
  }
  self->ob_data->Wait(); 
  Py_INCREF(Py_None);
  return Py_None;
}

extern "C" PyObject *
ao_signal(Ao_lock_object *self, PyObject* /*args*/)
{
  TInt error = self->ob_data->Signal(self->ob_tid);
  RETURN_ERROR_OR_PYNONE(error);
}

extern "C" {

  static void
  ao_dealloc(Ao_lock_object *op)
  {
    if ((TUint)RThread().Id() == op->ob_tid) {
      delete op->ob_data;
      op->ob_data = NULL;
    }
    PyObject_Del(op);
  }
  
  static const PyMethodDef ao_methods[] = {
    {"wait", (PyCFunction)ao_wait, METH_NOARGS},
    {"signal", (PyCFunction)ao_signal, METH_NOARGS},
    {NULL,              NULL}           /* sentinel */
  };

  static PyObject *
  ao_getattr(Ao_lock_object *p, char *name)
  {
    return Py_FindMethod((PyMethodDef*)ao_methods,
                         (PyObject *)p, name);
  }

  static const PyTypeObject c_Ao_lock_type = {
    PyObject_HEAD_INIT(NULL)
    0,
    "e32.Ao_lock",
    sizeof(Ao_lock_object),
    0,
    /* methods */
    (destructor)ao_dealloc,             /* tp_dealloc */
    0,                                  /* tp_print */
    (getattrfunc)ao_getattr,            /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_compare */
    0,                                  /* tp_repr */
    0,                                  /* tp_as _number*/
    0,                                  /* tp_as _sequence*/
    0,                                  /* tp_as _mapping*/
    0,                                  /* tp_hash */
  };
} /* extern "C" */

/*
 *
 * Implementation of e32.ao_yield
 *
 */

class CE32AoYield : public CActive
{
 public:
  CE32AoYield():CActive(EPriorityStandard) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -