symbian-qemu-0.9.1-12/qemu-symbian-svp/python-plugin.c
changeset 1 2fb8b9db1c86
child 36 a587897e3bb2
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #include "Python.h"
       
     2 #include "structmember.h"
       
     3 #include "hw/hw.h"
       
     4 #include "sysemu.h"
       
     5 #include "devtree.h"
       
     6 #include "qemu-char.h"
       
     7 #include "display_state.h"
       
     8 #include "hw/gui.h"
       
     9 #include "hw/fb_render_engine.h"
       
    10 #include "qemu-timer.h"
       
    11 
       
    12 static void qemu_py_die(void)
       
    13 {
       
    14     PyErr_Print();
       
    15     exit(1);
       
    16 }
       
    17 
       
    18 #define qemu_py_assert(x) do { if (!(x)) { qemu_py_die(); } } while (0)
       
    19 
       
    20 static void qemu_py_load_module(const char *name)
       
    21 {
       
    22     PyObject *module;
       
    23     module = PyImport_ImportModule(name);
       
    24     if (!module)
       
    25         qemu_py_die();
       
    26 }
       
    27 
       
    28 static int64_t qemu_py_int64_from_pynum(PyObject *ob)
       
    29 {
       
    30     if (PyInt_Check(ob))
       
    31         return PyInt_AsLong(ob);
       
    32     return PyLong_AsLongLong(ob);
       
    33 }
       
    34 
       
    35 static uint64_t qemu_py_uint64_from_pynum(PyObject *ob)
       
    36 {
       
    37     if (PyInt_Check(ob))
       
    38         return PyInt_AsUnsignedLongMask(ob);
       
    39     return PyLong_AsUnsignedLongLongMask(ob);
       
    40 }
       
    41 
       
    42 typedef struct {
       
    43     PyObject_HEAD
       
    44     PyObject *size;
       
    45     PyObject *readl;
       
    46     PyObject *writel;
       
    47 } qemu_py_ioregion;
       
    48 
       
    49 static void qemu_py_ioregion_dealloc(qemu_py_ioregion *self)
       
    50 {
       
    51     Py_CLEAR(self->size);
       
    52     Py_CLEAR(self->readl);
       
    53     Py_CLEAR(self->writel);
       
    54     self->ob_type->tp_free((PyObject*)self);
       
    55 }
       
    56 
       
    57 static int qemu_py_ioregion_init(qemu_py_ioregion *self, PyObject *args,
       
    58                                  PyObject *kwds)
       
    59 {
       
    60     static char *kwlist[] = {"size", "readl", "writel", NULL};
       
    61     PyObject *obsize;
       
    62     PyObject *readl;
       
    63     PyObject *writel;
       
    64 
       
    65     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist,
       
    66                                      &obsize, &readl, &writel))
       
    67         return -1; 
       
    68 
       
    69     Py_INCREF(obsize);
       
    70     self->size = obsize;
       
    71     Py_INCREF(readl);
       
    72     self->readl = readl;
       
    73     Py_INCREF(writel);
       
    74     self->writel = writel;
       
    75 
       
    76     return 0;
       
    77 }
       
    78 
       
    79 static PyMemberDef qemu_py_ioregion_members[] = {
       
    80     {"size", T_OBJECT, offsetof(qemu_py_ioregion, size), 0,
       
    81      "size"},
       
    82     {"readl", T_OBJECT, offsetof(qemu_py_ioregion, readl), 0,
       
    83      "32-bit read"},
       
    84     {"writel", T_OBJECT, offsetof(qemu_py_ioregion, writel), 0,
       
    85      "32-bit write"},
       
    86     {NULL}  /* Sentinel */
       
    87 };
       
    88 
       
    89 static PyTypeObject qemu_py_ioregionType = {
       
    90     PyObject_HEAD_INIT(NULL)
       
    91     0,                                    /* ob_size */
       
    92     "qemu.ioregion",                      /* tp_name */
       
    93     sizeof(qemu_py_ioregion),             /* tp_basicsize */
       
    94     0,                                    /* tp_itemsize */
       
    95     (destructor)qemu_py_ioregion_dealloc, /* tp_dealloc */
       
    96     0,                                    /* tp_print */
       
    97     0,                                    /* tp_getattr */
       
    98     0,                                    /* tp_setattr */
       
    99     0,                                    /* tp_compare */
       
   100     0,                                    /* tp_repr */
       
   101     0,                                    /* tp_as_number */
       
   102     0,                                    /* tp_as_sequence */
       
   103     0,                                    /* tp_as_mapping */
       
   104     0,                                    /* tp_hash  */
       
   105     0,                                    /* tp_call */
       
   106     0,                                    /* tp_str */
       
   107     0,                                    /* tp_getattro */
       
   108     0,                                    /* tp_setattro */
       
   109     0,                                    /* tp_as_buffer */
       
   110     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
   111     "QEMU IORegion",                      /* tp_doc */
       
   112     0,                                    /* tp_traverse */
       
   113     0,                                    /* tp_clear */
       
   114     0,		                          /* tp_richcompare */
       
   115     0,		                          /* tp_weaklistoffset */
       
   116     0,		                          /* tp_iter */
       
   117     0,		                          /* tp_iternext */
       
   118     0,                                    /* tp_methods */
       
   119     qemu_py_ioregion_members,             /* tp_members */
       
   120     0,                                    /* tp_getset */
       
   121     0,                                    /* tp_base */
       
   122     0,                                    /* tp_dict */
       
   123     0,                                    /* tp_descr_get */
       
   124     0,                                    /* tp_descr_set */
       
   125     0,                                    /* tp_dictoffset */
       
   126     (initproc)qemu_py_ioregion_init,      /* tp_init */
       
   127     0,                                    /* tp_alloc */
       
   128     0,                                    /* tp_new */
       
   129 };
       
   130 
       
   131 typedef struct {
       
   132     PyObject_HEAD
       
   133     QEMUFile *f;
       
   134 } qemu_py_file;
       
   135 
       
   136 static void qemu_py_file_dealloc(qemu_py_file *self)
       
   137 {
       
   138     self->f = NULL;
       
   139     self->ob_type->tp_free((PyObject*)self);
       
   140 }
       
   141 
       
   142 static int qemu_py_file_init(qemu_py_file *self, PyObject *args,
       
   143                              PyObject *kwds)
       
   144 {
       
   145     static char *kwlist[] = {"f", NULL};
       
   146     PyObject *obdata;
       
   147 
       
   148     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obdata))
       
   149         return -1; 
       
   150 
       
   151     self->f = PyCObject_AsVoidPtr(obdata);
       
   152     if (PyErr_Occurred())
       
   153         return -1;
       
   154 
       
   155     return 0;
       
   156 }
       
   157 
       
   158 static PyObject *qemu_py_file_get_u32(qemu_py_file *self, PyObject *args)
       
   159 {
       
   160     uint32_t val;
       
   161 
       
   162     if (self->f) {
       
   163         val = qemu_get_be32(self->f);
       
   164         return PyLong_FromUnsignedLong(val);
       
   165     }
       
   166     Py_RETURN_NONE;
       
   167 }
       
   168 
       
   169 static PyObject *qemu_py_file_put_u32(qemu_py_file *self,
       
   170                                       PyObject *args, PyObject *kwds)
       
   171 {
       
   172     static char *kwlist[] = {"value", NULL};
       
   173     PyObject *obval;
       
   174     uint32_t val;
       
   175 
       
   176     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obval))
       
   177         return NULL;
       
   178 
       
   179     val = qemu_py_uint64_from_pynum(obval);
       
   180     if (PyErr_Occurred())
       
   181         return NULL;
       
   182 
       
   183     if (self->f)
       
   184         qemu_put_be32(self->f, val);
       
   185 
       
   186     Py_RETURN_NONE;
       
   187 }
       
   188 
       
   189 static PyObject *qemu_py_file_get_u64(qemu_py_file *self, PyObject *args)
       
   190 {
       
   191     uint64_t val;
       
   192 
       
   193     if (self->f) {
       
   194         val = qemu_get_be64(self->f);
       
   195         return PyLong_FromUnsignedLongLong(val);
       
   196     }
       
   197     Py_RETURN_NONE;
       
   198 }
       
   199 
       
   200 static PyObject *qemu_py_file_get_s64(qemu_py_file *self, PyObject *args)
       
   201 {
       
   202     int64_t val;
       
   203 
       
   204     if (self->f) {
       
   205         val = qemu_get_be64(self->f);
       
   206         return PyLong_FromLongLong(val);
       
   207     }
       
   208     Py_RETURN_NONE;
       
   209 }
       
   210 
       
   211 static PyObject *qemu_py_file_put_u64(qemu_py_file *self,
       
   212                                       PyObject *args, PyObject *kwds)
       
   213 {
       
   214     static char *kwlist[] = {"value", NULL};
       
   215     PyObject *obval;
       
   216     uint64_t val;
       
   217 
       
   218     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obval))
       
   219         return NULL;
       
   220 
       
   221     val = qemu_py_uint64_from_pynum(obval);
       
   222     if (PyErr_Occurred())
       
   223         return NULL;
       
   224 
       
   225     if (self->f)
       
   226         qemu_put_be64(self->f, val);
       
   227 
       
   228     Py_RETURN_NONE;
       
   229 }
       
   230 
       
   231 static PyObject *qemu_py_file_put_s64(qemu_py_file *self,
       
   232                                       PyObject *args, PyObject *kwds)
       
   233 {
       
   234     static char *kwlist[] = {"value", NULL};
       
   235     PyObject *obval;
       
   236     int64_t val;
       
   237 
       
   238     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obval))
       
   239         return NULL;
       
   240 
       
   241     val = qemu_py_int64_from_pynum(obval);
       
   242     if (PyErr_Occurred())
       
   243         return NULL;
       
   244 
       
   245     if (self->f)
       
   246         qemu_put_be64(self->f, val);
       
   247 
       
   248     Py_RETURN_NONE;
       
   249 }
       
   250 
       
   251 static PyMethodDef qemu_py_file_methods[] = {
       
   252     {"get_u32", (PyCFunction)qemu_py_file_get_u32, METH_NOARGS,
       
   253      "Read unsigned 32-bit value"},
       
   254     {"put_u32", (PyCFunction)qemu_py_file_put_u32, METH_VARARGS|METH_KEYWORDS,
       
   255      "Write unsigned 32-bit value"},
       
   256     {"get_u64", (PyCFunction)qemu_py_file_get_u64, METH_NOARGS,
       
   257      "Read unsigned 64-bit value"},
       
   258     {"put_u64", (PyCFunction)qemu_py_file_put_u64, METH_VARARGS|METH_KEYWORDS,
       
   259      "Write unsigned 64-bit value"},
       
   260     {"get_s64", (PyCFunction)qemu_py_file_get_s64, METH_NOARGS,
       
   261      "Read signed 64-bit value"},
       
   262     {"put_s64", (PyCFunction)qemu_py_file_put_s64, METH_VARARGS|METH_KEYWORDS,
       
   263      "Write signed 64-bit value"},
       
   264     {NULL}  /* Sentinel */
       
   265 };
       
   266 
       
   267 static PyTypeObject qemu_py_fileType = {
       
   268     PyObject_HEAD_INIT(NULL)
       
   269     0,                                    /* ob_size */
       
   270     "qemu.file",                          /* tp_name */
       
   271     sizeof(qemu_py_file),                 /* tp_basicsize */
       
   272     0,                                    /* tp_itemsize */
       
   273     (destructor)qemu_py_file_dealloc,     /* tp_dealloc */
       
   274     0,                                    /* tp_print */
       
   275     0,                                    /* tp_getattr */
       
   276     0,                                    /* tp_setattr */
       
   277     0,                                    /* tp_compare */
       
   278     0,                                    /* tp_repr */
       
   279     0,                                    /* tp_as_number */
       
   280     0,                                    /* tp_as_sequence */
       
   281     0,                                    /* tp_as_mapping */
       
   282     0,                                    /* tp_hash  */
       
   283     0,                                    /* tp_call */
       
   284     0,                                    /* tp_str */
       
   285     0,                                    /* tp_getattro */
       
   286     0,                                    /* tp_setattro */
       
   287     0,                                    /* tp_as_buffer */
       
   288     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
   289     "QEMU File Object",                   /* tp_doc */
       
   290     0,                                    /* tp_traverse */
       
   291     0,                                    /* tp_clear */
       
   292     0,		                          /* tp_richcompare */
       
   293     0,		                          /* tp_weaklistoffset */
       
   294     0,		                          /* tp_iter */
       
   295     0,		                          /* tp_iternext */
       
   296     qemu_py_file_methods,                 /* tp_methods */
       
   297     0,                                    /* tp_members */
       
   298     0,                                    /* tp_getset */
       
   299     0,                                    /* tp_base */
       
   300     0,                                    /* tp_dict */
       
   301     0,                                    /* tp_descr_get */
       
   302     0,                                    /* tp_descr_set */
       
   303     0,                                    /* tp_dictoffset */
       
   304     (initproc)qemu_py_file_init,          /* tp_init */
       
   305     0,                                    /* tp_alloc */
       
   306     0,                                    /* tp_new */
       
   307 };
       
   308 
       
   309 typedef struct {
       
   310     PyObject_HEAD
       
   311     ptimer_state *ptimer;
       
   312 } qemu_py_ptimer;
       
   313 
       
   314 static void qemu_py_ptimer_dealloc(qemu_py_ptimer *self)
       
   315 {
       
   316     self->ptimer = NULL;
       
   317     self->ob_type->tp_free((PyObject*)self);
       
   318 }
       
   319 
       
   320 static void qemu_py_ptimer_tick(void *opaque)
       
   321 {
       
   322     PyObject *fn = opaque;
       
   323     PyObject *obval;
       
   324 
       
   325     obval = PyObject_CallFunctionObjArgs(fn, NULL);
       
   326     qemu_py_assert(obval);
       
   327     Py_DECREF(obval);
       
   328 }
       
   329 
       
   330 static int qemu_py_ptimer_init(qemu_py_ptimer *self, PyObject *args,
       
   331                                PyObject *kwds)
       
   332 {
       
   333     static char *kwlist[] = {"tick", "freq", NULL};
       
   334     PyObject *tick;
       
   335     PyObject *obfreq = NULL;
       
   336     uint64_t freq;
       
   337     QEMUBH *bh;
       
   338 
       
   339     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
       
   340                                      &tick, &obfreq))
       
   341         return -1; 
       
   342 
       
   343     if (!PyCallable_Check(tick)) {
       
   344         PyErr_SetString(PyExc_TypeError, "tick handler must be callable");
       
   345         return -1;
       
   346     }
       
   347     if (obfreq) {
       
   348         freq = qemu_py_uint64_from_pynum(obfreq);
       
   349         if (PyErr_Occurred())
       
   350             return -1;
       
   351     } else {
       
   352         freq = 0;
       
   353     }
       
   354     Py_INCREF(tick);
       
   355     bh = qemu_bh_new(qemu_py_ptimer_tick, tick);
       
   356     self->ptimer = ptimer_init(bh);
       
   357     if (freq)
       
   358         ptimer_set_freq(self->ptimer, freq);
       
   359 
       
   360     return 0;
       
   361 }
       
   362 
       
   363 static PyObject *qemu_py_ptimer_run(qemu_py_ptimer *self,
       
   364                                     PyObject *args, PyObject *kwds)
       
   365 {
       
   366     static char *kwlist[] = {"oneshot", NULL};
       
   367     int oneshot;
       
   368 
       
   369     if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &oneshot))
       
   370         return NULL;
       
   371 
       
   372     ptimer_run(self->ptimer, oneshot != 0);
       
   373     Py_RETURN_NONE;
       
   374 }
       
   375 
       
   376 static PyObject *qemu_py_ptimer_stop(qemu_py_ptimer *self, PyObject *args)
       
   377 {
       
   378     ptimer_stop(self->ptimer);
       
   379     Py_RETURN_NONE;
       
   380 }
       
   381 
       
   382 static PyObject *qemu_py_ptimer_set_limit(qemu_py_ptimer *self,
       
   383                                           PyObject *args, PyObject *kwds)
       
   384 {
       
   385     static char *kwlist[] = {"limit", "reload", NULL};
       
   386     PyObject *oblimit;
       
   387     uint64_t limit;
       
   388     int reload;
       
   389 
       
   390     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, &oblimit,
       
   391                                      &reload))
       
   392         return NULL;
       
   393 
       
   394     limit = qemu_py_uint64_from_pynum(oblimit);
       
   395     if (PyErr_Occurred())
       
   396         return NULL;
       
   397 
       
   398     ptimer_set_limit(self->ptimer, limit, reload != 0);
       
   399 
       
   400     Py_RETURN_NONE;
       
   401 }
       
   402 
       
   403 static PyObject *qemu_py_ptimer_get(qemu_py_ptimer *self,
       
   404                                     PyObject *args, PyObject *kwds)
       
   405 {
       
   406     static char *kwlist[] = {"f", NULL};
       
   407     qemu_py_file *f;
       
   408 
       
   409     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
       
   410                                      &qemu_py_fileType, &f))
       
   411         return NULL;
       
   412 
       
   413     qemu_get_ptimer(f->f, self->ptimer);
       
   414 
       
   415     Py_RETURN_NONE;
       
   416 }
       
   417 
       
   418 static PyObject *qemu_py_ptimer_put(qemu_py_ptimer *self,
       
   419                                     PyObject *args, PyObject *kwds)
       
   420 {
       
   421     static char *kwlist[] = {"f", NULL};
       
   422     qemu_py_file *f;
       
   423 
       
   424     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
       
   425                                      &qemu_py_fileType, &f))
       
   426         return NULL;
       
   427 
       
   428     qemu_put_ptimer(f->f, self->ptimer);
       
   429 
       
   430     Py_RETURN_NONE;
       
   431 }
       
   432 
       
   433 static PyObject *qemu_py_ptimer_get_count(qemu_py_ptimer *self, void *closure)
       
   434 {
       
   435     return PyLong_FromUnsignedLongLong(ptimer_get_count(self->ptimer));
       
   436 }
       
   437 
       
   438 static int qemu_py_ptimer_set_count(qemu_py_ptimer *self, PyObject *obval,
       
   439                                     void *closure)
       
   440 {
       
   441     uint64_t val;
       
   442     if (obval == NULL) {
       
   443         PyErr_SetString(PyExc_TypeError, "Cannot delete ptimer count");
       
   444         return -1;
       
   445     }
       
   446 
       
   447     val = qemu_py_uint64_from_pynum(obval);
       
   448     if (PyErr_Occurred())
       
   449         return -1;
       
   450 
       
   451     ptimer_set_count(self->ptimer, val);
       
   452 
       
   453     return 0;
       
   454 }
       
   455 
       
   456 static PyGetSetDef qemu_py_ptimer_getseters [] = {
       
   457     {"count", (getter)qemu_py_ptimer_get_count,
       
   458      (setter)qemu_py_ptimer_set_count,
       
   459      "current counter value", NULL},
       
   460     {NULL}  /* Sentinel */
       
   461 };
       
   462 
       
   463 static PyMethodDef qemu_py_ptimer_methods[] = {
       
   464     {"run", (PyCFunction)qemu_py_ptimer_run, METH_VARARGS|METH_KEYWORDS,
       
   465      "Start timer"},
       
   466     {"stop", (PyCFunction)qemu_py_ptimer_stop, METH_NOARGS,
       
   467      "Stop timer"},
       
   468     {"set_limit", (PyCFunction)qemu_py_ptimer_set_limit,
       
   469      METH_VARARGS|METH_KEYWORDS,
       
   470      "Set reload value"},
       
   471     {"get", (PyCFunction)qemu_py_ptimer_get, METH_VARARGS|METH_KEYWORDS,
       
   472      "Restore state"},
       
   473     {"put", (PyCFunction)qemu_py_ptimer_put, METH_VARARGS|METH_KEYWORDS,
       
   474      "Save state"},
       
   475     {NULL}  /* Sentinel */
       
   476 };
       
   477 
       
   478 static PyTypeObject qemu_py_ptimerType = {
       
   479     PyObject_HEAD_INIT(NULL)
       
   480     0,                                    /* ob_size */
       
   481     "qemu.ptimer",                        /* tp_name */
       
   482     sizeof(qemu_py_ptimer),               /* tp_basicsize */
       
   483     0,                                    /* tp_itemsize */
       
   484     (destructor)qemu_py_ptimer_dealloc,   /* tp_dealloc */
       
   485     0,                                    /* tp_print */
       
   486     0,                                    /* tp_getattr */
       
   487     0,                                    /* tp_setattr */
       
   488     0,                                    /* tp_compare */
       
   489     0,                                    /* tp_repr */
       
   490     0,                                    /* tp_as_number */
       
   491     0,                                    /* tp_as_sequence */
       
   492     0,                                    /* tp_as_mapping */
       
   493     0,                                    /* tp_hash  */
       
   494     0,                                    /* tp_call */
       
   495     0,                                    /* tp_str */
       
   496     0,                                    /* tp_getattro */
       
   497     0,                                    /* tp_setattro */
       
   498     0,                                    /* tp_as_buffer */
       
   499     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
   500     "QEMU Periodic Timer",                /* tp_doc */
       
   501     0,                                    /* tp_traverse */
       
   502     0,                                    /* tp_clear */
       
   503     0,		                          /* tp_richcompare */
       
   504     0,		                          /* tp_weaklistoffset */
       
   505     0,		                          /* tp_iter */
       
   506     0,		                          /* tp_iternext */
       
   507     qemu_py_ptimer_methods,               /* tp_methods */
       
   508     0,                                    /* tp_members */
       
   509     qemu_py_ptimer_getseters,             /* tp_getset */
       
   510     0,                                    /* tp_base */
       
   511     0,                                    /* tp_dict */
       
   512     0,                                    /* tp_descr_get */
       
   513     0,                                    /* tp_descr_set */
       
   514     0,                                    /* tp_dictoffset */
       
   515     (initproc)qemu_py_ptimer_init,        /* tp_init */
       
   516     0,                                    /* tp_alloc */
       
   517     0,                                    /* tp_new */
       
   518 };
       
   519 
       
   520 typedef struct {
       
   521     PyObject_HEAD
       
   522     render_data *rdata;
       
   523 } qemu_py_palette;
       
   524 
       
   525 static void qemu_py_palette_dealloc(qemu_py_palette *self)
       
   526 {
       
   527     self->rdata = NULL;
       
   528     self->ob_type->tp_free((PyObject*)self);
       
   529 }
       
   530 
       
   531 static int qemu_py_palette_init(qemu_py_palette *self, PyObject *args,
       
   532                                 PyObject *kwds)
       
   533 {
       
   534     static char *kwlist[] = {"rdata", NULL};
       
   535     PyObject *obdata;
       
   536 
       
   537     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obdata))
       
   538         return -1; 
       
   539 
       
   540     self->rdata = PyCObject_AsVoidPtr(obdata);
       
   541     if (PyErr_Occurred())
       
   542         return -1;
       
   543 
       
   544     return 0;
       
   545 }
       
   546 
       
   547 static Py_ssize_t qemu_py_palette_len(PyObject *o)
       
   548 {
       
   549     return 256;
       
   550 }
       
   551 
       
   552 static PyObject *qemu_py_palette_getitem(PyObject *o, Py_ssize_t i)
       
   553 {
       
   554     qemu_py_palette *self = (qemu_py_palette *)o;
       
   555 
       
   556     if (i < 0 || i >= 256) {
       
   557         PyErr_SetString(PyExc_ValueError, "Palette index must be 0-255");
       
   558         return NULL;
       
   559     }
       
   560 
       
   561     return PyLong_FromUnsignedLong(get_palette_value(self->rdata, i));
       
   562 }
       
   563 
       
   564 static int qemu_py_palette_setitem(PyObject *o, Py_ssize_t i, PyObject *obval)
       
   565 {
       
   566     qemu_py_palette *self = (qemu_py_palette *)o;
       
   567     uint32_t val;
       
   568 
       
   569     if (i < 0 || i >= 256) {
       
   570         PyErr_SetString(PyExc_ValueError, "Palette index must be 0-255");
       
   571         return -1;
       
   572     }
       
   573 
       
   574     val = PyLong_AsUnsignedLongMask(obval);
       
   575     if (PyErr_Occurred())
       
   576         return -1;
       
   577     set_palette_value(self->rdata, i, val);
       
   578     return 0;
       
   579 }
       
   580 
       
   581 static PySequenceMethods qemu_py_palette_seq = {
       
   582       .sq_length = qemu_py_palette_len,
       
   583       .sq_item = qemu_py_palette_getitem,
       
   584       .sq_ass_item = qemu_py_palette_setitem
       
   585 };
       
   586 
       
   587 static PyTypeObject qemu_py_paletteType = {
       
   588     PyObject_HEAD_INIT(NULL)
       
   589     0,                                    /* ob_size */
       
   590     "qemu.palette",                       /* tp_name */
       
   591     sizeof(qemu_py_palette),              /* tp_basicsize */
       
   592     0,                                    /* tp_itemsize */
       
   593     (destructor)qemu_py_palette_dealloc,  /* tp_dealloc */
       
   594     0,                                    /* tp_print */
       
   595     0,                                    /* tp_getattr */
       
   596     0,                                    /* tp_setattr */
       
   597     0,                                    /* tp_compare */
       
   598     0,                                    /* tp_repr */
       
   599     0,                                    /* tp_as_number */
       
   600     &qemu_py_palette_seq,                 /* tp_as_sequence */
       
   601     0,                                    /* tp_as_mapping */
       
   602     0,                                    /* tp_hash  */
       
   603     0,                                    /* tp_call */
       
   604     0,                                    /* tp_str */
       
   605     0,                                    /* tp_getattro */
       
   606     0,                                    /* tp_setattro */
       
   607     0,                                    /* tp_as_buffer */
       
   608     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
   609     "QEMU Framebuffer Palette",           /* tp_doc */
       
   610     0,                                    /* tp_traverse */
       
   611     0,                                    /* tp_clear */
       
   612     0,		                          /* tp_richcompare */
       
   613     0,		                          /* tp_weaklistoffset */
       
   614     0,		                          /* tp_iter */
       
   615     0,		                          /* tp_iternext */
       
   616     0,                                    /* tp_methods */
       
   617     0,                                    /* tp_members */
       
   618     0,                                    /* tp_getset */
       
   619     0,                                    /* tp_base */
       
   620     0,                                    /* tp_dict */
       
   621     0,                                    /* tp_descr_get */
       
   622     0,                                    /* tp_descr_set */
       
   623     0,                                    /* tp_dictoffset */
       
   624     (initproc)qemu_py_palette_init,       /* tp_init */
       
   625     0,                                    /* tp_alloc */
       
   626     0,                                    /* tp_new */
       
   627 };
       
   628 
       
   629 typedef struct {
       
   630     PyObject_HEAD
       
   631     render_data *rdata;
       
   632     DisplayState *ds;
       
   633     PyObject *update_cb;
       
   634     PyObject *palette;
       
   635     int need_update;
       
   636 } qemu_py_render;
       
   637 
       
   638 static void qemu_py_render_dealloc(qemu_py_render *self)
       
   639 {
       
   640     if (self->rdata)
       
   641         destroy_render_data(self->rdata);
       
   642     self->rdata = NULL;
       
   643     Py_CLEAR(self->palette);
       
   644     self->ob_type->tp_free((PyObject*)self);
       
   645 }
       
   646 
       
   647 static void qemu_py_update_display(void *opaque)
       
   648 {
       
   649     qemu_py_render *self = opaque;
       
   650     PyObject *obval;
       
   651     PyObject *fn;
       
   652     int do_update;
       
   653 
       
   654     if (nographic || ds_get_bits_per_pixel(self->ds) == 0)
       
   655         return;
       
   656 
       
   657     fn = self->update_cb;
       
   658 
       
   659     if (fn && PyCallable_Check(fn)) {
       
   660         obval = PyObject_CallFunctionObjArgs(fn, NULL);
       
   661         qemu_py_assert(obval);
       
   662         do_update = PyInt_AsLong(obval);
       
   663         qemu_py_assert(!PyErr_Occurred());
       
   664         Py_DECREF(obval);
       
   665 
       
   666         if (!do_update)
       
   667             return;
       
   668     }
       
   669 
       
   670     render(self->ds, self->rdata, self->need_update);
       
   671     self->need_update = 0;
       
   672 }
       
   673 
       
   674 static void qemu_py_invalidate_display(void *opaque)
       
   675 {
       
   676     qemu_py_render *self = opaque;
       
   677     self->need_update = 1;
       
   678 }
       
   679 
       
   680 static int qemu_py_render_init(qemu_py_render *self, PyObject *args,
       
   681                                PyObject *kwds)
       
   682 {
       
   683     static char *kwlist[] = {"name", "width", "height", NULL};
       
   684     int width;
       
   685     int height;
       
   686     char *name;
       
   687     PyObject *ob;
       
   688 
       
   689     if (!PyArg_ParseTupleAndKeywords(args, kwds, "sii", kwlist,
       
   690                                      &name, &width, &height))
       
   691         return -1; 
       
   692 
       
   693     self->ds = gui_get_graphic_console(name,
       
   694                                        qemu_py_update_display,
       
   695                                        qemu_py_invalidate_display,
       
   696                                        NULL, self);
       
   697 
       
   698     if (!self->ds) {
       
   699         PyErr_SetString(PyExc_AssertionError, "Display creation failed");
       
   700         return -1;
       
   701     }
       
   702 
       
   703     if (width && height) {
       
   704         if (!gui_resize_vt(self->ds, width, height)) {
       
   705             /* can't resize */
       
   706             width = height = 0;
       
   707         }
       
   708     }
       
   709     if (!width)
       
   710         width = ds_get_width(self->ds);
       
   711     if (!height)
       
   712         height = ds_get_height(self->ds);
       
   713 
       
   714     self->rdata = create_render_data();
       
   715     set_cols(self->rdata, width);
       
   716     set_rows(self->rdata, height);
       
   717 
       
   718     ob = PyCObject_FromVoidPtr(self->rdata, NULL);
       
   719     if (!ob)
       
   720         return -1;
       
   721     self->palette =
       
   722       PyObject_CallFunctionObjArgs((PyObject *)&qemu_py_paletteType,
       
   723                                    ob, NULL);
       
   724     if (!self->palette)
       
   725         return -1;
       
   726     Py_DECREF(ob);
       
   727     return 0;
       
   728 }
       
   729 
       
   730 static PyObject *qemu_py_render_get(qemu_py_render *self,
       
   731                                     PyObject *args, PyObject *kwds)
       
   732 {
       
   733     static char *kwlist[] = {"f", NULL};
       
   734     qemu_py_file *f;
       
   735 
       
   736     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
       
   737                                      &qemu_py_fileType, &f))
       
   738         return NULL;
       
   739 
       
   740     qemu_get_render_data(f->f, self->rdata);
       
   741 
       
   742     Py_RETURN_NONE;
       
   743 }
       
   744 
       
   745 static PyObject *qemu_py_render_put(qemu_py_render *self,
       
   746                                     PyObject *args, PyObject *kwds)
       
   747 {
       
   748     static char *kwlist[] = {"f", NULL};
       
   749     qemu_py_file *f;
       
   750 
       
   751     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
       
   752                                      &qemu_py_fileType, &f))
       
   753         return NULL;
       
   754 
       
   755     qemu_put_render_data(f->f, self->rdata);
       
   756 
       
   757     Py_RETURN_NONE;
       
   758 }
       
   759 
       
   760 static PyMemberDef qemu_py_render_members[] = {
       
   761     {"update", T_OBJECT, offsetof(qemu_py_render, update_cb), 0,
       
   762      "Display update callback"},
       
   763     {"palette", T_OBJECT, offsetof(qemu_py_render, palette), 0,
       
   764      "palette"},
       
   765     {NULL}  /* Sentinel */
       
   766 };
       
   767 
       
   768 enum {
       
   769     QEMU_PY_FB_BASE,
       
   770     QEMU_PY_FB_WIDTH,
       
   771     QEMU_PY_FB_HEIGHT,
       
   772     QEMU_PY_FB_ORIENTATION,
       
   773     QEMU_PY_FB_BLANK,
       
   774     QEMU_PY_FB_BPP,
       
   775     QEMU_PY_FB_COLOR_ORDER,
       
   776     QEMU_PY_FB_BYTE_ORDER,
       
   777     QEMU_PY_FB_PIXEL_ORDER,
       
   778     QEMU_PY_FB_ROW_PITCH
       
   779 };
       
   780 
       
   781 static PyObject *
       
   782 qemu_py_render_getattr(qemu_py_render *self, void *closure)
       
   783 {
       
   784     /* FIXME: should be target_phys_addr_t?  */
       
   785     uint32_t val;
       
   786     render_data *rdata = self->rdata;
       
   787 
       
   788     switch ((size_t)closure) {
       
   789     case QEMU_PY_FB_BASE:
       
   790         val = get_fb_base_in_target(rdata);
       
   791         break;
       
   792     case QEMU_PY_FB_WIDTH:
       
   793         val = get_cols(rdata);
       
   794         break;
       
   795     case QEMU_PY_FB_HEIGHT:
       
   796         val = get_rows(rdata);
       
   797         break;
       
   798     case QEMU_PY_FB_ORIENTATION:
       
   799         val = get_orientation(rdata);
       
   800         break;
       
   801     case QEMU_PY_FB_BLANK:
       
   802         val = get_blank_mode(rdata);
       
   803         break;
       
   804     case QEMU_PY_FB_BPP:
       
   805         switch (get_src_bpp(rdata)) {
       
   806         case BPP_SRC_1: val = 1; break;
       
   807         case BPP_SRC_2: val = 2; break;
       
   808         case BPP_SRC_4: val = 4; break;
       
   809         case BPP_SRC_8: val = 8; break;
       
   810         case BPP_SRC_15: val = 15; break;
       
   811         case BPP_SRC_16: val = 16; break;
       
   812         case BPP_SRC_24: val = 24; break;
       
   813         case BPP_SRC_32: val = 32; break;
       
   814         default: val = 0; break;
       
   815         }
       
   816         break;
       
   817     case QEMU_PY_FB_COLOR_ORDER:
       
   818         val = get_color_order(rdata);
       
   819         break;
       
   820     case QEMU_PY_FB_BYTE_ORDER:
       
   821         val = get_byte_order(rdata);
       
   822         break;
       
   823     case QEMU_PY_FB_PIXEL_ORDER:
       
   824         val = get_pixel_order(rdata);
       
   825         break;
       
   826     case QEMU_PY_FB_ROW_PITCH:
       
   827         val = get_row_pitch(rdata);
       
   828         break;
       
   829     default:
       
   830         val = -1;
       
   831     }
       
   832     return PyLong_FromUnsignedLong(val);
       
   833 }
       
   834 
       
   835 static int
       
   836 qemu_py_render_setattr(qemu_py_render *self, PyObject *obval, void *closure)
       
   837 {
       
   838     /* FIXME: should be target_phys_addr_t?  */
       
   839     uint32_t val;
       
   840     render_data *rdata = self->rdata;
       
   841 
       
   842     if (obval == NULL) {
       
   843         PyErr_SetString(PyExc_TypeError, "Cannot delete attribute");
       
   844         return -1;
       
   845     }
       
   846 
       
   847     val = PyInt_AsUnsignedLongMask(obval);
       
   848     if (PyErr_Occurred())
       
   849         return -1;
       
   850 
       
   851     switch ((size_t)closure) {
       
   852     case QEMU_PY_FB_BASE:
       
   853         set_fb_base_from_target(rdata, val);
       
   854         break;
       
   855     case QEMU_PY_FB_WIDTH:
       
   856         set_cols(rdata, val);
       
   857         break;
       
   858     case QEMU_PY_FB_HEIGHT:
       
   859         set_rows(rdata, val);
       
   860         break;
       
   861     case QEMU_PY_FB_ORIENTATION:
       
   862         set_orientation(rdata, val);
       
   863         break;
       
   864     case QEMU_PY_FB_BLANK:
       
   865         set_blank_mode(rdata, val);
       
   866         break;
       
   867     case QEMU_PY_FB_BPP:
       
   868         switch (val) {
       
   869         case 1: val = BPP_SRC_1; break;
       
   870         case 2: val = BPP_SRC_2; break;
       
   871         case 4: val = BPP_SRC_4; break;
       
   872         case 8: val = BPP_SRC_8; break;
       
   873         case 15: val = BPP_SRC_15; break;
       
   874         case 16: val = BPP_SRC_16; break;
       
   875         case 24: val = BPP_SRC_24; break;
       
   876         case 32: val = BPP_SRC_32; break;
       
   877         default: val = get_src_bpp(rdata); break;
       
   878         }
       
   879         set_src_bpp(rdata, val);
       
   880         break;
       
   881     case QEMU_PY_FB_COLOR_ORDER:
       
   882         set_color_order(rdata, val);
       
   883         break;
       
   884     case QEMU_PY_FB_BYTE_ORDER:
       
   885         set_byte_order(rdata, val);
       
   886         break;
       
   887     case QEMU_PY_FB_PIXEL_ORDER:
       
   888         set_pixel_order(rdata, val);
       
   889         break;
       
   890     case QEMU_PY_FB_ROW_PITCH:
       
   891         set_row_pitch(rdata, val);
       
   892         break;
       
   893     default:
       
   894         val = -1;
       
   895         break;
       
   896     }
       
   897     return 0;
       
   898 }
       
   899 
       
   900 static PyGetSetDef qemu_py_render_getseters [] = {
       
   901     {"base", (getter)qemu_py_render_getattr,
       
   902              (setter)qemu_py_render_setattr,
       
   903      "base address", (void *)(size_t)QEMU_PY_FB_BASE},
       
   904     {"width", (getter)qemu_py_render_getattr,
       
   905               (setter)qemu_py_render_setattr,
       
   906      "screen width", (void *)(size_t)QEMU_PY_FB_WIDTH},
       
   907     {"height", (getter)qemu_py_render_getattr,
       
   908               (setter)qemu_py_render_setattr,
       
   909      "screen height", (void *)(size_t)QEMU_PY_FB_HEIGHT},
       
   910     {"orientation", (getter)qemu_py_render_getattr,
       
   911               (setter)qemu_py_render_setattr,
       
   912      "screen orientation", (void *)(size_t)QEMU_PY_FB_ORIENTATION},
       
   913     {"blank", (getter)qemu_py_render_getattr,
       
   914               (setter)qemu_py_render_setattr,
       
   915      "blanking mode", (void *)(size_t)QEMU_PY_FB_BLANK},
       
   916     {"bpp", (getter)qemu_py_render_getattr,
       
   917             (setter)qemu_py_render_setattr,
       
   918      "color depth", (void *)(size_t)QEMU_PY_FB_BPP},
       
   919     {"color_order", (getter)qemu_py_render_getattr,
       
   920                     (setter)qemu_py_render_setattr,
       
   921      "color order", (void *)(size_t)QEMU_PY_FB_COLOR_ORDER},
       
   922     {"byte_order", (getter)qemu_py_render_getattr,
       
   923                    (setter)qemu_py_render_setattr,
       
   924      "byte order", (void *)(size_t)QEMU_PY_FB_BYTE_ORDER},
       
   925     {"pixel_order", (getter)qemu_py_render_getattr,
       
   926                     (setter)qemu_py_render_setattr,
       
   927      "pixel packing order", (void *)(size_t)QEMU_PY_FB_PIXEL_ORDER},
       
   928     {"row_pitch", (getter)qemu_py_render_getattr,
       
   929                   (setter)qemu_py_render_setattr,
       
   930      "row pitch", (void *)(size_t)QEMU_PY_FB_ROW_PITCH},
       
   931     {NULL}  /* Sentinel */
       
   932 
       
   933 };
       
   934 
       
   935 static PyMethodDef qemu_py_render_methods[] = {
       
   936     {"get", (PyCFunction)qemu_py_render_get, METH_VARARGS|METH_KEYWORDS,
       
   937      "Restore state"},
       
   938     {"put", (PyCFunction)qemu_py_render_put, METH_VARARGS|METH_KEYWORDS,
       
   939      "Save state"},
       
   940     {NULL}  /* Sentinel */
       
   941 };
       
   942 
       
   943 static PyTypeObject qemu_py_renderType = {
       
   944     PyObject_HEAD_INIT(NULL)
       
   945     0,                                    /* ob_size */
       
   946     "qemu.render",                        /* tp_name */
       
   947     sizeof(qemu_py_render),               /* tp_basicsize */
       
   948     0,                                    /* tp_itemsize */
       
   949     (destructor)qemu_py_render_dealloc,   /* tp_dealloc */
       
   950     0,                                    /* tp_print */
       
   951     0,                                    /* tp_getattr */
       
   952     0,                                    /* tp_setattr */
       
   953     0,                                    /* tp_compare */
       
   954     0,                                    /* tp_repr */
       
   955     0,                                    /* tp_as_number */
       
   956     0,                                    /* tp_as_sequence */
       
   957     0,                                    /* tp_as_mapping */
       
   958     0,                                    /* tp_hash  */
       
   959     0,                                    /* tp_call */
       
   960     0,                                    /* tp_str */
       
   961     0,                                    /* tp_getattro */
       
   962     0,                                    /* tp_setattro */
       
   963     0,                                    /* tp_as_buffer */
       
   964     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
   965     "QEMU Framebuffer Render Engine",     /* tp_doc */
       
   966     0,                                    /* tp_traverse */
       
   967     0,                                    /* tp_clear */
       
   968     0,		                          /* tp_richcompare */
       
   969     0,		                          /* tp_weaklistoffset */
       
   970     0,		                          /* tp_iter */
       
   971     0,		                          /* tp_iternext */
       
   972     qemu_py_render_methods,               /* tp_methods */
       
   973     qemu_py_render_members,               /* tp_members */
       
   974     qemu_py_render_getseters,             /* tp_getset */
       
   975     0,                                    /* tp_base */
       
   976     0,                                    /* tp_dict */
       
   977     0,                                    /* tp_descr_get */
       
   978     0,                                    /* tp_descr_set */
       
   979     0,                                    /* tp_dictoffset */
       
   980     (initproc)qemu_py_render_init,        /* tp_init */
       
   981     0,                                    /* tp_alloc */
       
   982     0,                                    /* tp_new */
       
   983 };
       
   984 
       
   985 
       
   986 typedef struct {
       
   987     PyObject_HEAD
       
   988     CharDriverState *chr;
       
   989     PyObject *can_receive_cb;
       
   990     PyObject *receive_cb;
       
   991     PyObject *event_cb;
       
   992 } qemu_py_chardev;
       
   993 
       
   994 static void qemu_py_chardev_dealloc(qemu_py_chardev *self)
       
   995 {
       
   996     Py_CLEAR(self->can_receive_cb);
       
   997     Py_CLEAR(self->receive_cb);
       
   998     Py_CLEAR(self->event_cb);
       
   999     self->ob_type->tp_free((PyObject*)self);
       
  1000 }
       
  1001 
       
  1002 static int qemu_py_chardev_can_receive(void *opaque)
       
  1003 {
       
  1004     qemu_py_chardev *self = opaque;
       
  1005     PyObject *obval;
       
  1006     int val;
       
  1007 
       
  1008     if (!self->can_receive_cb)
       
  1009         return 0;
       
  1010 
       
  1011     obval = PyObject_CallFunctionObjArgs(self->can_receive_cb, NULL);
       
  1012     qemu_py_assert(obval);
       
  1013     val = PyInt_AsLong(obval);
       
  1014     qemu_py_assert(!PyErr_Occurred());
       
  1015     Py_DECREF(obval);
       
  1016     return val;
       
  1017 }
       
  1018 
       
  1019 static void qemu_py_chardev_receive(void *opaque, const uint8_t *buf, int size)
       
  1020 {
       
  1021     qemu_py_chardev *self = opaque;
       
  1022     PyObject *obval;
       
  1023     PyObject *obbuf;
       
  1024 
       
  1025     if (!self->receive_cb)
       
  1026         return;
       
  1027 
       
  1028     obbuf = PyBuffer_FromMemory((void *)buf, size);
       
  1029     qemu_py_assert(obbuf);
       
  1030     obval = PyObject_CallFunctionObjArgs(self->receive_cb, obbuf, NULL);
       
  1031     Py_DECREF(obbuf);
       
  1032     qemu_py_assert(obval);
       
  1033     Py_DECREF(obval);
       
  1034 }
       
  1035 
       
  1036 static void qemu_py_chardev_event(void *opaque, int event)
       
  1037 {
       
  1038     qemu_py_chardev *self = opaque;
       
  1039     PyObject *obval;
       
  1040     PyObject *obevent;
       
  1041 
       
  1042     if (!self->event_cb)
       
  1043         return;
       
  1044 
       
  1045     obevent = PyInt_FromLong(event);
       
  1046     qemu_py_assert(obevent);
       
  1047     obval = PyObject_CallFunctionObjArgs(self->event_cb, obevent, NULL);
       
  1048     Py_DECREF(obevent);
       
  1049     qemu_py_assert(obval);
       
  1050     Py_DECREF(obval);
       
  1051 }
       
  1052 
       
  1053 static int qemu_py_chardev_init(qemu_py_chardev *self, PyObject *args,
       
  1054                                 PyObject *kwds)
       
  1055 {
       
  1056     static char *kwlist[] = {"chardev", NULL};
       
  1057     PyObject *obchr;
       
  1058 
       
  1059     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obchr))
       
  1060         return -1; 
       
  1061 
       
  1062     self->chr = PyCObject_AsVoidPtr(obchr);
       
  1063     if (PyErr_Occurred())
       
  1064         return -1;
       
  1065 
       
  1066     if (self->chr) {
       
  1067         qemu_chr_add_handlers(self->chr, qemu_py_chardev_can_receive,
       
  1068                               qemu_py_chardev_receive,
       
  1069                               qemu_py_chardev_event, self);
       
  1070     }
       
  1071 
       
  1072     return 0;
       
  1073 }
       
  1074 
       
  1075 static PyObject *qemu_py_chardev_set_handlers(qemu_py_chardev *self,
       
  1076                                               PyObject *args, PyObject *kwds)
       
  1077 {
       
  1078     static char *kwlist[] = {"can_receive", "receive", "event", NULL};
       
  1079     PyObject *obcan_receive;
       
  1080     PyObject *obreceive;
       
  1081     PyObject *obevent = Py_None;
       
  1082 
       
  1083     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
       
  1084                                      &obcan_receive, &obreceive, &obevent))
       
  1085         return NULL;
       
  1086 
       
  1087     if (!self->chr)
       
  1088         Py_RETURN_NONE;
       
  1089 
       
  1090     Py_CLEAR(self->can_receive_cb);
       
  1091     Py_CLEAR(self->receive_cb);
       
  1092     Py_CLEAR(self->event_cb);
       
  1093     if (!PyCallable_Check(obcan_receive)) {
       
  1094         PyErr_SetString(PyExc_TypeError,
       
  1095                         "can_receive handler must be callable");
       
  1096         return NULL;
       
  1097     }
       
  1098     self->can_receive_cb = obcan_receive;
       
  1099     Py_INCREF(obcan_receive);
       
  1100     if (!PyCallable_Check(obreceive)) {
       
  1101         PyErr_SetString(PyExc_TypeError, "receive handler must be callable");
       
  1102         return NULL;
       
  1103     }
       
  1104     self->receive_cb = obreceive;
       
  1105     Py_INCREF(obreceive);
       
  1106     if (obevent != Py_None) {
       
  1107     if (!PyCallable_Check(obreceive)) {
       
  1108         PyErr_SetString(PyExc_TypeError, "event handler must be callable");
       
  1109         return NULL;
       
  1110     }
       
  1111         self->event_cb = obevent;
       
  1112         Py_INCREF(obevent);
       
  1113     }
       
  1114     Py_RETURN_NONE;
       
  1115 }
       
  1116 
       
  1117 static PyObject *qemu_py_chardev_write(qemu_py_chardev *self,
       
  1118                                        PyObject *args, PyObject *kwds)
       
  1119 {
       
  1120     static char *kwlist[] = {"data", NULL};
       
  1121     PyObject *obdata;
       
  1122 
       
  1123     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obdata))
       
  1124         return NULL;
       
  1125 
       
  1126     if (!self->chr)
       
  1127         Py_RETURN_NONE;
       
  1128 
       
  1129     if (PyString_Check(obdata)) {
       
  1130         char *data;
       
  1131         Py_ssize_t len;
       
  1132         if (PyString_AsStringAndSize(obdata, &data, &len) < 0)
       
  1133             return NULL;
       
  1134         qemu_chr_write(self->chr, (uint8_t *)data, len);
       
  1135     } else {
       
  1136         uint8_t ch;
       
  1137         ch = PyInt_AsLong(obdata);
       
  1138         if (PyErr_Occurred())
       
  1139             return NULL;
       
  1140         qemu_chr_write(self->chr, &ch, 1);
       
  1141     }
       
  1142     Py_RETURN_NONE;
       
  1143 }
       
  1144 
       
  1145 static PyMemberDef qemu_py_chardev_members[] = {
       
  1146     {NULL}  /* Sentinel */
       
  1147 };
       
  1148 
       
  1149 static PyMethodDef qemu_py_chardev_methods[] = {
       
  1150     {"set_handlers", (PyCFunction)qemu_py_chardev_set_handlers,
       
  1151       METH_VARARGS|METH_KEYWORDS,
       
  1152      "Set event handlers"},
       
  1153     {"write", (PyCFunction)qemu_py_chardev_write, METH_VARARGS|METH_KEYWORDS,
       
  1154      "Write a byte or string"},
       
  1155     {NULL}  /* Sentinel */
       
  1156 };
       
  1157 
       
  1158 static PyTypeObject qemu_py_chardevType = {
       
  1159     PyObject_HEAD_INIT(NULL)
       
  1160     0,                                    /* ob_size */
       
  1161     "qemu.chardev",                       /* tp_name */
       
  1162     sizeof(qemu_py_chardev),              /* tp_basicsize */
       
  1163     0,                                    /* tp_itemsize */
       
  1164     (destructor)qemu_py_chardev_dealloc,  /* tp_dealloc */
       
  1165     0,                                    /* tp_print */
       
  1166     0,                                    /* tp_getattr */
       
  1167     0,                                    /* tp_setattr */
       
  1168     0,                                    /* tp_compare */
       
  1169     0,                                    /* tp_repr */
       
  1170     0,                                    /* tp_as_number */
       
  1171     0,                                    /* tp_as_sequence */
       
  1172     0,                                    /* tp_as_mapping */
       
  1173     0,                                    /* tp_hash  */
       
  1174     0,                                    /* tp_call */
       
  1175     0,                                    /* tp_str */
       
  1176     0,                                    /* tp_getattro */
       
  1177     0,                                    /* tp_setattro */
       
  1178     0,                                    /* tp_as_buffer */
       
  1179     Py_TPFLAGS_DEFAULT,                   /* tp_flags */
       
  1180     "QEMU Character Device",              /* tp_doc */
       
  1181     0,                                    /* tp_traverse */
       
  1182     0,                                    /* tp_clear */
       
  1183     0,		                          /* tp_richcompare */
       
  1184     0,		                          /* tp_weaklistoffset */
       
  1185     0,		                          /* tp_iter */
       
  1186     0,		                          /* tp_iternext */
       
  1187     qemu_py_chardev_methods,              /* tp_methods */
       
  1188     qemu_py_chardev_members,              /* tp_members */
       
  1189     0,                                    /* tp_getset */
       
  1190     0,                                    /* tp_base */
       
  1191     0,                                    /* tp_dict */
       
  1192     0,                                    /* tp_descr_get */
       
  1193     0,                                    /* tp_descr_set */
       
  1194     0,                                    /* tp_dictoffset */
       
  1195     (initproc)qemu_py_chardev_init,       /* tp_init */
       
  1196     0,                                    /* tp_alloc */
       
  1197     0,                                    /* tp_new */
       
  1198 };
       
  1199 
       
  1200 
       
  1201 typedef struct {
       
  1202     PyObject_HEAD
       
  1203     QEMUDevice *qdev;
       
  1204 } qemu_py_devclass;
       
  1205 
       
  1206 static void qemu_py_devclass_dealloc(qemu_py_devclass *self)
       
  1207 {
       
  1208     self->ob_type->tp_free((PyObject*)self);
       
  1209 }
       
  1210 
       
  1211 static int qemu_py_devclass_init(qemu_py_devclass *self, PyObject *args,
       
  1212                                  PyObject *kwds)
       
  1213 {
       
  1214     static char *kwlist[] = {"qdev", NULL};
       
  1215     PyObject *obqdev;
       
  1216 
       
  1217     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obqdev))
       
  1218         return -1; 
       
  1219 
       
  1220     self->qdev = PyCObject_AsVoidPtr(obqdev);
       
  1221     if (PyErr_Occurred())
       
  1222         return -1;
       
  1223 
       
  1224     return 0;
       
  1225 }
       
  1226 
       
  1227 
       
  1228 /* FIXME: Turn ths into an actual IRQ object?  */
       
  1229 static PyObject *qemu_py_set_irq_level(qemu_py_devclass *self, PyObject *args)
       
  1230 {
       
  1231     int ok;
       
  1232     int irq_num;
       
  1233     int level;
       
  1234 
       
  1235     ok = PyArg_ParseTuple(args, "ii", &irq_num, &level);
       
  1236     if (!ok)
       
  1237       return NULL;
       
  1238 
       
  1239     if (!self->qdev) {
       
  1240         PyErr_SetString(PyExc_ValueError, "device not initialized");
       
  1241         return NULL;
       
  1242     }
       
  1243     qdev_set_irq_level(self->qdev, irq_num, level);
       
  1244 
       
  1245     Py_RETURN_NONE;
       
  1246 }
       
  1247 
       
  1248 /* PyLong_AsUnsignedLongLongMask doesn't seem to work on Int objects.
       
  1249    This wrapper automatically picks the right routine.  */
       
  1250 static target_phys_addr_t qemu_py_physaddr_from_pynum(PyObject *ob)
       
  1251 {
       
  1252     if (PyInt_Check(ob))
       
  1253         return PyInt_AsUnsignedLongMask(ob);
       
  1254     return PyLong_AsUnsignedLongLongMask(ob);
       
  1255 }
       
  1256 
       
  1257 static PyObject *qemu_py_dma_readb(qemu_py_chardev *self, PyObject *args,
       
  1258                                    PyObject *kwds)
       
  1259 {
       
  1260     static char *kwlist[] = {"addr", NULL};
       
  1261     PyObject *obaddr;
       
  1262     target_phys_addr_t addr;
       
  1263 
       
  1264     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obaddr))
       
  1265         return NULL;
       
  1266 
       
  1267     addr = qemu_py_physaddr_from_pynum(obaddr);
       
  1268     if (PyErr_Occurred())
       
  1269         return NULL;
       
  1270 
       
  1271     return PyInt_FromLong(ldub_phys(addr));
       
  1272 }
       
  1273 
       
  1274 static PyObject *qemu_py_dma_writeb(qemu_py_chardev *self, PyObject *args,
       
  1275                                     PyObject *kwds)
       
  1276 {
       
  1277     static char *kwlist[] = {"addr", "value", NULL};
       
  1278     PyObject *obaddr;
       
  1279     PyObject *obval;
       
  1280     target_phys_addr_t addr;
       
  1281     uint8_t val;
       
  1282 
       
  1283     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
       
  1284                                      &obaddr, &obval))
       
  1285         return NULL;
       
  1286 
       
  1287     addr = qemu_py_physaddr_from_pynum(obaddr);
       
  1288     if (PyErr_Occurred())
       
  1289         return NULL;
       
  1290 
       
  1291     val = PyInt_AsLong(obval);
       
  1292     if (PyErr_Occurred())
       
  1293         return NULL;
       
  1294 
       
  1295     stb_phys(addr, val);
       
  1296 
       
  1297     Py_RETURN_NONE;
       
  1298 }
       
  1299 
       
  1300 static PyObject *qemu_py_dma_readl(qemu_py_chardev *self, PyObject *args,
       
  1301                                    PyObject *kwds)
       
  1302 {
       
  1303     static char *kwlist[] = {"addr", NULL};
       
  1304     PyObject *obaddr;
       
  1305     target_phys_addr_t addr;
       
  1306     uint8_t buf[4];
       
  1307     uint32_t val;
       
  1308 
       
  1309     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &obaddr))
       
  1310         return NULL;
       
  1311 
       
  1312     addr = qemu_py_physaddr_from_pynum(obaddr);
       
  1313     if (PyErr_Occurred())
       
  1314         return NULL;
       
  1315 
       
  1316     if (addr & 3) {
       
  1317         cpu_physical_memory_read(addr, buf, 4);
       
  1318         val = ldl_p(buf);
       
  1319     } else {
       
  1320         val = ldl_phys(addr);
       
  1321     }
       
  1322     return PyLong_FromUnsignedLong(val);
       
  1323 }
       
  1324 
       
  1325 static PyObject *qemu_py_dma_writel(qemu_py_chardev *self, PyObject *args,
       
  1326                                     PyObject *kwds)
       
  1327 {
       
  1328     static char *kwlist[] = {"addr", "value", NULL};
       
  1329     PyObject *obaddr;
       
  1330     PyObject *obval;
       
  1331     target_phys_addr_t addr;
       
  1332     uint8_t buf[4];
       
  1333     uint32_t val;
       
  1334 
       
  1335     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist,
       
  1336                                      &obaddr, &obval))
       
  1337         return NULL;
       
  1338 
       
  1339     addr = qemu_py_physaddr_from_pynum(obaddr);
       
  1340     if (PyErr_Occurred())
       
  1341         return NULL;
       
  1342 
       
  1343     val = PyInt_AsLong(obval);
       
  1344     if (PyErr_Occurred())
       
  1345         return NULL;
       
  1346 
       
  1347     if (addr & 3) {
       
  1348         stl_p(buf, val);
       
  1349         cpu_physical_memory_write(addr, buf, 4);
       
  1350     } else {
       
  1351         stl_phys(addr, val);
       
  1352     }
       
  1353 
       
  1354     Py_RETURN_NONE;
       
  1355 }
       
  1356 
       
  1357 static void qemu_py_set_irq_input(void *opaque, int irq, int level)
       
  1358 {
       
  1359     PyObject *fn = opaque;
       
  1360     PyObject *obirq;
       
  1361     PyObject *oblevel;
       
  1362     PyObject *obval;
       
  1363 
       
  1364     obirq = PyInt_FromLong(irq);
       
  1365     qemu_py_assert(obirq);
       
  1366     oblevel = level ? Py_True : Py_False;
       
  1367     Py_INCREF(oblevel);
       
  1368     obval = PyObject_CallFunctionObjArgs(fn, obirq, oblevel, NULL);
       
  1369     qemu_py_assert(obval);
       
  1370     Py_DECREF(obval);
       
  1371     Py_DECREF(obirq);
       
  1372     Py_DECREF(oblevel);
       
  1373 }
       
  1374 
       
  1375 static PyObject *qemu_py_create_interrupts(qemu_py_devclass *self,
       
  1376                                            PyObject *args, PyObject *kwds)
       
  1377 {
       
  1378     static char *kwlist[] = {"callback", "count", NULL};
       
  1379     PyObject *obcallback;
       
  1380     int count;
       
  1381 
       
  1382     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist,
       
  1383                                      &obcallback, &count))
       
  1384         return NULL;
       
  1385 
       
  1386     if (!PyCallable_Check(obcallback)) {
       
  1387         PyErr_SetString(PyExc_TypeError, "irq handler must be callable");
       
  1388         return NULL;
       
  1389     }
       
  1390 
       
  1391     Py_INCREF(obcallback);
       
  1392     qdev_create_interrupts(self->qdev, qemu_py_set_irq_input, obcallback,
       
  1393                            count);
       
  1394 
       
  1395     Py_RETURN_NONE;
       
  1396 }
       
  1397 
       
  1398 static PyObject *qemu_py_dummy_loadsave(qemu_py_devclass *self, PyObject *args)
       
  1399 {
       
  1400     Py_RETURN_NONE;
       
  1401 }
       
  1402 
       
  1403 static PyMemberDef qemu_py_devclass_members[] = {
       
  1404 #if 0
       
  1405     {"irqs", T_INT, offsetof(qemu_py_devclass, num_irqs), 0,
       
  1406      "Number of irqs"},
       
  1407 #endif
       
  1408     {NULL}  /* Sentinel */
       
  1409 };
       
  1410 
       
  1411 static PyMethodDef qemu_py_devclass_methods[] = {
       
  1412     {"set_irq_level", (PyCFunction)qemu_py_set_irq_level, METH_VARARGS,
       
  1413      "Set IRQ state"},
       
  1414     {"create_interrupts", (PyCFunction)qemu_py_create_interrupts,
       
  1415      METH_VARARGS|METH_KEYWORDS,
       
  1416      "Create IRQ inputs"},
       
  1417     {"dma_readb", (PyCFunction)qemu_py_dma_readb, METH_VARARGS|METH_KEYWORDS,
       
  1418      "Read a byte from system memory"},
       
  1419     {"dma_writeb", (PyCFunction)qemu_py_dma_writeb, METH_VARARGS|METH_KEYWORDS,
       
  1420      "Write a byte to system memory"},
       
  1421     {"dma_readl", (PyCFunction)qemu_py_dma_readl, METH_VARARGS|METH_KEYWORDS,
       
  1422      "Read a 32-bit word from system memory"},
       
  1423     {"dma_writel", (PyCFunction)qemu_py_dma_writel, METH_VARARGS|METH_KEYWORDS,
       
  1424      "Write a 32-bit word to system memory"},
       
  1425     {"load", (PyCFunction)qemu_py_dummy_loadsave, METH_VARARGS,
       
  1426      "load snapshot state"},
       
  1427     {"save", (PyCFunction)qemu_py_dummy_loadsave, METH_VARARGS,
       
  1428      "save snapshot state"},
       
  1429     {NULL}  /* Sentinel */
       
  1430 };
       
  1431 
       
  1432 static PyTypeObject qemu_py_devclassType = {
       
  1433     PyObject_HEAD_INIT(NULL)
       
  1434     0,                                    /* ob_size */
       
  1435     "qemu.devclass",                      /* tp_name */
       
  1436     sizeof(qemu_py_devclass),             /* tp_basicsize */
       
  1437     0,                                    /* tp_itemsize */
       
  1438     (destructor)qemu_py_devclass_dealloc, /* tp_dealloc */
       
  1439     0,                                    /* tp_print */
       
  1440     0,                                    /* tp_getattr */
       
  1441     0,                                    /* tp_setattr */
       
  1442     0,                                    /* tp_compare */
       
  1443     0,                                    /* tp_repr */
       
  1444     0,                                    /* tp_as_number */
       
  1445     0,                                    /* tp_as_sequence */
       
  1446     0,                                    /* tp_as_mapping */
       
  1447     0,                                    /* tp_hash  */
       
  1448     0,                                    /* tp_call */
       
  1449     0,                                    /* tp_str */
       
  1450     0,                                    /* tp_getattro */
       
  1451     0,                                    /* tp_setattro */
       
  1452     0,                                    /* tp_as_buffer */
       
  1453     Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,                   /* tp_flags */
       
  1454     "QEMU device class objects",          /* tp_doc */
       
  1455     0,                                    /* tp_traverse */
       
  1456     0,                                    /* tp_clear */
       
  1457     0,		                          /* tp_richcompare */
       
  1458     0,		                          /* tp_weaklistoffset */
       
  1459     0,		                          /* tp_iter */
       
  1460     0,		                          /* tp_iternext */
       
  1461     qemu_py_devclass_methods,             /* tp_methods */
       
  1462     qemu_py_devclass_members,             /* tp_members */
       
  1463     0,                                    /* tp_getset */
       
  1464     0,                                    /* tp_base */
       
  1465     0,                                    /* tp_dict */
       
  1466     0,                                    /* tp_descr_get */
       
  1467     0,                                    /* tp_descr_set */
       
  1468     0,                                    /* tp_dictoffset */
       
  1469     (initproc)qemu_py_devclass_init,      /* tp_init */
       
  1470     0,                                    /* tp_alloc */
       
  1471     0,                                    /* tp_new */
       
  1472 };
       
  1473 
       
  1474 typedef struct
       
  1475 {
       
  1476     PyObject *dev;
       
  1477     int n;
       
  1478     PyObject *region;
       
  1479 } qemu_py_callback_info;
       
  1480 
       
  1481 static uint32_t qemu_py_read(void *opaque, target_phys_addr_t offset)
       
  1482 {
       
  1483     qemu_py_callback_info *info = opaque;
       
  1484     PyObject *r;
       
  1485     PyObject *fn;
       
  1486     PyObject *oboffset;
       
  1487     PyObject *obval;
       
  1488     uint32_t val;
       
  1489 
       
  1490     r = info->region;
       
  1491     qemu_py_assert(r);
       
  1492     fn = PyObject_GetAttrString(r, "readl");
       
  1493     qemu_py_assert(fn);
       
  1494     oboffset = PyInt_FromLong(offset);
       
  1495     obval = PyObject_CallFunctionObjArgs(fn, info->dev, oboffset, NULL);
       
  1496     Py_DECREF(oboffset);
       
  1497     Py_DECREF(fn);
       
  1498     qemu_py_assert(obval);
       
  1499     val = PyLong_AsUnsignedLongMask(obval);
       
  1500     qemu_py_assert(!PyErr_Occurred());
       
  1501     Py_DECREF(obval);
       
  1502     return val;
       
  1503 }
       
  1504 
       
  1505 static void qemu_py_write(void *opaque, target_phys_addr_t offset,
       
  1506                                 uint32_t value)
       
  1507 {
       
  1508     qemu_py_callback_info *info = opaque;
       
  1509     PyObject *r;
       
  1510     PyObject *fn;
       
  1511     PyObject *oboffset;
       
  1512     PyObject *obval;
       
  1513 
       
  1514     r = info->region;
       
  1515     qemu_py_assert(r);
       
  1516     fn = PyObject_GetAttrString(r, "writel");
       
  1517     qemu_py_assert(fn);
       
  1518     oboffset = PyInt_FromLong(offset);
       
  1519     obval = PyLong_FromUnsignedLong(value);
       
  1520     PyObject_CallFunctionObjArgs(fn, info->dev, oboffset, obval, NULL);
       
  1521     Py_DECREF(oboffset);
       
  1522     Py_DECREF(obval);
       
  1523     Py_DECREF(fn);
       
  1524     qemu_py_assert(!PyErr_Occurred());
       
  1525 }
       
  1526 
       
  1527 static CPUReadMemoryFunc *qemu_py_readfn[] = {
       
  1528      qemu_py_read,
       
  1529      qemu_py_read,
       
  1530      qemu_py_read
       
  1531 };
       
  1532 
       
  1533 static CPUWriteMemoryFunc *qemu_py_writefn[] = {
       
  1534      qemu_py_write,
       
  1535      qemu_py_write,
       
  1536      qemu_py_write
       
  1537 };
       
  1538 
       
  1539 static void qemu_py_dev_create(QEMUDevice *dev)
       
  1540 {
       
  1541     PyObject *ob;
       
  1542     PyObject *devclass;
       
  1543     PyObject *regions;
       
  1544     PyObject *obqdev;
       
  1545     qemu_py_devclass *self;
       
  1546     qemu_py_callback_info *callbacks;
       
  1547     Py_ssize_t pos;
       
  1548     PyObject *properties;
       
  1549     PyObject *key;
       
  1550     PyObject *value;
       
  1551     int num_regions;
       
  1552     int i;
       
  1553 
       
  1554     devclass = qdev_get_class_opaque(dev);
       
  1555     obqdev = PyCObject_FromVoidPtr(dev, NULL);
       
  1556     ob = PyObject_CallFunctionObjArgs(devclass, obqdev, NULL);
       
  1557     qemu_py_assert(ob);
       
  1558     Py_DECREF(obqdev);
       
  1559     self = (qemu_py_devclass *)ob;
       
  1560     self->qdev = dev;
       
  1561     qdev_set_opaque(dev, ob);
       
  1562 
       
  1563     value = PyString_FromString(qdev_get_name(dev));
       
  1564     PyObject_SetAttrString(ob, "name", value);
       
  1565 
       
  1566     regions = PyObject_GetAttrString(devclass, "regions");
       
  1567     qemu_py_assert(regions);
       
  1568     num_regions = PyList_Size(regions);
       
  1569     callbacks = qemu_mallocz(num_regions * sizeof(callbacks[0]));
       
  1570     for (i = 0; i < num_regions; i++) {
       
  1571         callbacks[i].dev = ob;
       
  1572         callbacks[i].n = i;
       
  1573         callbacks[i].region = PyList_GetItem(regions, i);
       
  1574         Py_INCREF(callbacks[i].region);
       
  1575         qdev_set_region_opaque(dev, i, &callbacks[i]);
       
  1576     }
       
  1577     Py_DECREF(regions);
       
  1578 
       
  1579     properties = PyObject_GetAttrString(devclass, "properties");
       
  1580     qemu_py_assert(properties);
       
  1581     pos = 0;
       
  1582     while (PyDict_Next(properties, &pos, &key, &value)) {
       
  1583         char *key_name = PyString_AsString(key);
       
  1584         qemu_py_assert(key_name);
       
  1585         if (strcmp(key_name, "chardev") == 0) {
       
  1586             CharDriverState *chr;
       
  1587             PyObject *obchr;
       
  1588             chr = qdev_get_chardev(dev);
       
  1589             obchr = PyCObject_FromVoidPtr(chr, NULL);
       
  1590             qemu_py_assert(obchr);
       
  1591             value =
       
  1592               PyObject_CallFunctionObjArgs((PyObject *)&qemu_py_chardevType,
       
  1593                                            obchr, NULL);
       
  1594             qemu_py_assert(value);
       
  1595             Py_DECREF(obchr);
       
  1596         } else if (PyLong_Check(value) || PyInt_Check(value)) {
       
  1597             long intval;
       
  1598             intval = qdev_get_property_int(dev, key_name);
       
  1599             value = PyInt_FromLong(intval);
       
  1600         } else {
       
  1601             const char *strval;
       
  1602             strval = qdev_get_property_string(dev, key_name);
       
  1603             value = PyString_FromString(strval);
       
  1604         }
       
  1605         if (PyDict_SetItem(properties, key, value) < 0) {
       
  1606             Py_DECREF(value);
       
  1607         }
       
  1608 
       
  1609     }
       
  1610     Py_DECREF(properties);
       
  1611 
       
  1612     PyObject_CallMethod(ob, "create", NULL);
       
  1613     qemu_py_assert(!PyErr_Occurred());
       
  1614 }
       
  1615 
       
  1616 static PyObject *qemu_py_create_file(QEMUFile *f)
       
  1617 {
       
  1618     PyObject *obfile;
       
  1619     PyObject *obarg;
       
  1620 
       
  1621     obarg = PyCObject_FromVoidPtr(f, NULL);
       
  1622     if (!obarg)
       
  1623         return NULL;
       
  1624     obfile = PyObject_CallFunctionObjArgs((PyObject *)&qemu_py_fileType,
       
  1625                                           obarg, NULL);
       
  1626     Py_DECREF(obarg);
       
  1627     return obfile;
       
  1628 }
       
  1629 
       
  1630 static void qemu_py_save(QEMUFile *f, void *opaque)
       
  1631 {
       
  1632     PyObject *self = opaque;
       
  1633     PyObject *obfile;
       
  1634     PyObject *obresult;
       
  1635 
       
  1636 
       
  1637     obfile = qemu_py_create_file(f);
       
  1638     qemu_py_assert(obfile);
       
  1639     obresult = PyObject_CallMethod(self, "save", "O", obfile);
       
  1640     qemu_py_assert(obresult);
       
  1641     Py_DECREF(obfile);
       
  1642     Py_DECREF(obresult);
       
  1643 }
       
  1644 
       
  1645 static int qemu_py_load(QEMUFile *f, void *opaque, int version_id)
       
  1646 {
       
  1647     PyObject *self = opaque;
       
  1648     PyObject *obfile;
       
  1649     PyObject *obresult;
       
  1650 
       
  1651     if (version_id != 1)
       
  1652         return -EINVAL;
       
  1653 
       
  1654     obfile = qemu_py_create_file(f);
       
  1655     qemu_py_assert(obfile);
       
  1656     obresult = PyObject_CallMethod(self, "load", "O", obfile);
       
  1657     /* TODO: Graceful error handling.  */
       
  1658     qemu_py_assert(obresult);
       
  1659     Py_DECREF(obfile);
       
  1660     Py_DECREF(obresult);
       
  1661 
       
  1662     return 0;
       
  1663 }
       
  1664 
       
  1665 static PyObject *qemu_py_register_device(PyObject *self, PyObject *args)
       
  1666 {
       
  1667     int ok;
       
  1668     QEMUDeviceClass *dc;
       
  1669     PyObject *devclass;
       
  1670     PyObject *regions;
       
  1671     PyObject *attr;
       
  1672     PyObject *properties;
       
  1673     Py_ssize_t pos;
       
  1674     PyObject *key;
       
  1675     PyObject *value;
       
  1676     int i;
       
  1677     char *name;
       
  1678     int num_irqs;
       
  1679 
       
  1680     ok = PyArg_ParseTuple(args, "O", &devclass);
       
  1681     if (!ok)
       
  1682         return NULL;
       
  1683 
       
  1684     if (!PyType_Check(devclass)
       
  1685         || !PyObject_IsSubclass(devclass, (PyObject *)&qemu_py_devclassType)) {
       
  1686 
       
  1687         PyErr_SetString(PyExc_TypeError, "Expected qemu.devclass derivative");
       
  1688         return NULL;
       
  1689     }
       
  1690 
       
  1691     Py_INCREF(devclass);
       
  1692 
       
  1693     attr = PyObject_GetAttrString(devclass, "irqs");
       
  1694     if (!attr)
       
  1695         return NULL;
       
  1696     num_irqs = PyInt_AsLong(attr);
       
  1697     if (PyErr_Occurred())
       
  1698         return NULL;
       
  1699     Py_DECREF(attr);
       
  1700 
       
  1701     attr = PyObject_GetAttrString(devclass, "name");
       
  1702     if (!attr)
       
  1703         return NULL;
       
  1704     name = PyString_AsString(attr);
       
  1705     if (PyErr_Occurred())
       
  1706         return NULL;
       
  1707 
       
  1708     dc = qdev_new(name, qemu_py_dev_create, num_irqs);
       
  1709 
       
  1710     Py_DECREF(attr);
       
  1711 
       
  1712     qdev_add_class_opaque(dc, devclass);
       
  1713 
       
  1714     regions = PyObject_GetAttrString(devclass, "regions");
       
  1715     if (!regions)
       
  1716         return NULL;
       
  1717     if (!PyList_Check(regions)) {
       
  1718         PyErr_SetString(PyExc_TypeError, "devclass.regions must be a list");
       
  1719         return NULL;
       
  1720     }
       
  1721     for (i = 0; i < PyList_Size(regions); i++) {
       
  1722         target_phys_addr_t size;
       
  1723         PyObject *r;
       
  1724 
       
  1725         r = PyList_GetItem(regions, i);
       
  1726         if (!r)
       
  1727             return NULL;
       
  1728 
       
  1729         attr = PyObject_GetAttrString(r, "size");
       
  1730         size = PyInt_AsLong(attr);
       
  1731         if (PyErr_Occurred())
       
  1732             return NULL;
       
  1733         qdev_add_registers(dc, qemu_py_readfn, qemu_py_writefn, size);
       
  1734         Py_DECREF(attr);
       
  1735     }
       
  1736     Py_DECREF(regions);
       
  1737 
       
  1738     properties = PyObject_GetAttrString(devclass, "properties");
       
  1739     if (!properties)
       
  1740         return NULL;
       
  1741     if (!PyDict_Check(properties)) {
       
  1742         Py_DECREF(properties);
       
  1743         PyErr_SetString(PyExc_TypeError,
       
  1744                         "qemu.devclass.properties must be a dict");
       
  1745         return NULL;
       
  1746     }
       
  1747     pos = 0;
       
  1748     while (PyDict_Next(properties, &pos, &key, &value)) {
       
  1749         char *key_name = PyString_AsString(key);
       
  1750         if (!key_name)
       
  1751             goto bad_property;
       
  1752         if (strcmp(key_name, "chardev") == 0) {
       
  1753             qdev_add_chardev(dc);
       
  1754         } else if (PyString_Check(value)) {
       
  1755             qdev_add_property_string(dc, key_name, PyString_AsString(value));
       
  1756         } else if (PyLong_Check(value) || PyInt_Check(value)) {
       
  1757             long intval;
       
  1758             intval = PyLong_AsLong(value);
       
  1759             if (PyErr_Occurred())
       
  1760                 goto bad_property;
       
  1761             qdev_add_property_int(dc, key_name, PyLong_AsLong(value));
       
  1762         } else {
       
  1763             PyErr_SetString(PyExc_TypeError,
       
  1764                 "qemu.devclass.properties value must be int or string");
       
  1765         bad_property:
       
  1766             Py_DECREF(properties);
       
  1767             return NULL;
       
  1768         }
       
  1769     }
       
  1770     Py_DECREF(properties);
       
  1771 
       
  1772     /* TODO: Implement savevm versioning.  */
       
  1773     qdev_add_savevm(dc, 1, qemu_py_save, qemu_py_load);
       
  1774 
       
  1775     Py_RETURN_NONE;
       
  1776 }
       
  1777 
       
  1778 static PyObject *qemu_py_get_clock(PyObject *self, PyObject *args)
       
  1779 {
       
  1780     return PyLong_FromUnsignedLongLong((uint64_t)qemu_get_clock(vm_clock));
       
  1781 }
       
  1782 
       
  1783 static PyObject *qemu_py_start_time(PyObject *self, PyObject *args)
       
  1784 {
       
  1785     struct tm tm;
       
  1786     uint64_t t;
       
  1787     qemu_get_timedate(&tm, 0);
       
  1788     t = mktimegm(&tm);
       
  1789     return PyLong_FromUnsignedLongLong(t);
       
  1790 }
       
  1791 
       
  1792 static void qemu_py_keyboard_event(void *opaque, int keycode)
       
  1793 {
       
  1794     PyObject *fn = opaque;
       
  1795     PyObject *obval;
       
  1796     PyObject *obkey;
       
  1797 
       
  1798     obkey = PyInt_FromLong(keycode);
       
  1799     obval = PyObject_CallFunctionObjArgs(fn, obkey, NULL);
       
  1800     qemu_py_assert(obval);
       
  1801     Py_DECREF(obkey);
       
  1802     Py_DECREF(obval);
       
  1803 }
       
  1804 
       
  1805 static PyObject *qemu_py_register_keyboard(PyObject *self, PyObject *args,
       
  1806                                            PyObject *kwds)
       
  1807 {
       
  1808     static char *kwlist[] = {"handler", NULL};
       
  1809     PyObject *fn;
       
  1810 
       
  1811     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &fn))
       
  1812         return NULL; 
       
  1813 
       
  1814     if (!PyCallable_Check(fn)) {
       
  1815         PyErr_SetString(PyExc_TypeError, "keyboard handler must be callable");
       
  1816         return NULL;
       
  1817     }
       
  1818 
       
  1819     Py_INCREF(fn);
       
  1820     gui_register_dev_key_callback(qemu_py_keyboard_event, fn);
       
  1821 
       
  1822     Py_RETURN_NONE;
       
  1823 }
       
  1824 
       
  1825 static void qemu_py_mouse_event(void *opaque, int dx, int dy, int dz,
       
  1826                                 int buttons)
       
  1827 {
       
  1828     PyObject *fn = opaque;
       
  1829     PyObject *obval;
       
  1830     PyObject *obx;
       
  1831     PyObject *oby;
       
  1832     PyObject *obz;
       
  1833     PyObject *obbuttons;
       
  1834 
       
  1835     obx = PyInt_FromLong(dx);
       
  1836     oby = PyInt_FromLong(dy);
       
  1837     obz = PyInt_FromLong(dz);
       
  1838     obbuttons = PyInt_FromLong(buttons);
       
  1839     obval = PyObject_CallFunctionObjArgs(fn, obx, oby, obz, obbuttons, NULL);
       
  1840     qemu_py_assert(obval);
       
  1841     Py_DECREF(obx);
       
  1842     Py_DECREF(oby);
       
  1843     Py_DECREF(obz);
       
  1844     Py_DECREF(obbuttons);
       
  1845     Py_DECREF(obval);
       
  1846 }
       
  1847 
       
  1848 static PyObject *qemu_py_register_mouse(PyObject *self, PyObject *args,
       
  1849                                         PyObject *kwds)
       
  1850 {
       
  1851     static char *kwlist[] = {"handler", "absolute", NULL};
       
  1852     PyObject *fn;
       
  1853     int absolute;
       
  1854 
       
  1855     if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi", kwlist, &fn, &absolute))
       
  1856         return NULL; 
       
  1857 
       
  1858     if (!PyCallable_Check(fn)) {
       
  1859         PyErr_SetString(PyExc_TypeError, "mouse handler must be callable");
       
  1860         return NULL;
       
  1861     }
       
  1862 
       
  1863     Py_INCREF(fn);
       
  1864     gui_register_mouse_event_handler(qemu_py_mouse_event, fn, absolute, "dev");
       
  1865 
       
  1866     Py_RETURN_NONE;
       
  1867 }
       
  1868 
       
  1869 static PyMethodDef qemu_py_methods[] =
       
  1870 {
       
  1871     {"register_device", qemu_py_register_device, METH_VARARGS,
       
  1872      "Register new device class"},
       
  1873     {"get_clock", qemu_py_get_clock, METH_NOARGS,
       
  1874      "Get current virtual time"},
       
  1875     {"start_time", qemu_py_start_time, METH_NOARGS,
       
  1876      "Get VM start time (seconds sice epoch)"},
       
  1877     {"register_keyboard", (PyCFunction)qemu_py_register_keyboard,
       
  1878      METH_VARARGS|METH_KEYWORDS,
       
  1879      "Register keyboard event handler"},
       
  1880     {"register_mouse", (PyCFunction)qemu_py_register_mouse,
       
  1881      METH_VARARGS|METH_KEYWORDS,
       
  1882      "Register mouse event handler"},
       
  1883     {NULL}
       
  1884 };
       
  1885 
       
  1886 static void qemu_py_add_class(PyObject *module, const char *name,
       
  1887                               PyTypeObject *type)
       
  1888 {
       
  1889     if (!type->tp_new)
       
  1890         type->tp_new = PyType_GenericNew;
       
  1891     if (PyType_Ready(type) < 0)
       
  1892         qemu_py_die();
       
  1893     Py_INCREF(type);
       
  1894     PyModule_AddObject(module, name, (PyObject *)type);
       
  1895 }
       
  1896 
       
  1897 static void qemu_py_init_interface(void)
       
  1898 {
       
  1899     PyObject *m;
       
  1900     m = Py_InitModule("qemu", qemu_py_methods);
       
  1901 
       
  1902     /* FIXME: Add default attributes to qemu_py_devclass.  */
       
  1903     qemu_py_add_class(m, "devclass", &qemu_py_devclassType);
       
  1904     qemu_py_add_class(m, "ioregion", &qemu_py_ioregionType);
       
  1905     qemu_py_add_class(m, "chardev", &qemu_py_chardevType);
       
  1906     qemu_py_add_class(m, "render", &qemu_py_renderType);
       
  1907     qemu_py_add_class(m, "palette", &qemu_py_paletteType);
       
  1908     qemu_py_add_class(m, "ptimer", &qemu_py_ptimerType);
       
  1909     qemu_py_add_class(m, "file", &qemu_py_fileType);
       
  1910 }
       
  1911 
       
  1912 #define PLUGIN_INIT_SCRIPT "import sys\nsys.path.insert(0, \"%s/plugins\")"
       
  1913 void qemu_python_init(char *argv0)
       
  1914 {
       
  1915     char *buf;
       
  1916     Py_SetProgramName(argv0);
       
  1917     Py_Initialize();
       
  1918 
       
  1919     /* Nasty hack to look for plugin modules.  */
       
  1920     buf = qemu_mallocz(strlen(bios_dir) + strlen(PLUGIN_INIT_SCRIPT));
       
  1921     sprintf(buf, PLUGIN_INIT_SCRIPT, bios_dir);
       
  1922 #ifdef _WIN32
       
  1923     {
       
  1924         char *p;
       
  1925         /* Windows path separators (backslash) are interpreted as escape
       
  1926            characters in a python string.  Fortunately python also accepts
       
  1927            unix path separators (forward slash), so use those instead.  */
       
  1928         for (p = buf; *p; p++) {
       
  1929             if (*p == '\\')
       
  1930                 *p = '/';
       
  1931         }
       
  1932     }
       
  1933 #endif
       
  1934     PyRun_SimpleString(buf);
       
  1935     qemu_free(buf);
       
  1936 
       
  1937     qemu_py_init_interface();
       
  1938 
       
  1939     qemu_py_load_module("qemu_arm_plugins");
       
  1940 }