static PyObject* py_set_colorid(PyObject *self, PyObject *args, PyObject *kwargs) { const char *kwnames[] = {"id", "rgb", NULL}; float rgb[3]; int colorid; VMDApp *app; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i(fff):color.set_colorid", (char**) kwnames, &colorid, &rgb[0], &rgb[1], &rgb[2])) return NULL; if (!(app = get_vmdapp())) return NULL; if (colorid >= app->num_regular_colors() || colorid < 0) { PyErr_Format(PyExc_ValueError, "color index '%d' out of range", colorid); return NULL; } app->color_change_rgb(app->color_name(colorid), rgb[0], rgb[1], rgb[2]); Py_INCREF(Py_None); return Py_None; }
static PyObject* py_set_colors(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *newdict, *newtuple, *keys, *vals; const char *kwnames[] = {"colors", NULL}; PyObject *retval = NULL; char *keyname; float rgb[3]; VMDApp *app; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:color.set_colors", (char**) kwnames, &PyDict_Type, &newdict)) return NULL; if (!(app = get_vmdapp())) return NULL; keys = PyDict_Keys(newdict); vals = PyDict_Values(newdict); for (int i=0; i<PyList_Size(keys); i++) { // Get color name from input dictionary keyname = as_charptr(PyList_GetItem(keys, i)); if (PyErr_Occurred()) goto cleanup; // Check this color name actually exists if (app->color_index(keyname) < 0) { PyErr_Format(PyExc_ValueError, "Unknown color '%s'", keyname); goto cleanup; } // Unpack value tuples into 3 floats newtuple = PyList_GetItem(vals, i); if (!PyTuple_Check(newtuple) || PyTuple_Size(newtuple) != 3) { PyErr_SetString(PyExc_ValueError, "color definition must be 3-tuple of floats"); goto cleanup; } for (int j=0; j<3; j++) { rgb[j] = (float)PyFloat_AsDouble(PyTuple_GET_ITEM(newtuple, j)); if (PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "color definition must be floats"); goto cleanup; } } // Finally actually change the color app->color_change_rgb(keyname, rgb[0], rgb[1], rgb[2]); } retval = Py_None; // Getting the keys and values from the dictionary makes a new reference. // We tell Python we're done with it so as to not leak memory. // This needs to happen even if there was a problem setting color, which is // why we don't return NULL from the error checking statements above. cleanup: Py_DECREF(keys); Py_DECREF(vals); Py_XINCREF(retval); return retval; }