/**************************************************************************** * misc_python.cpp - Misc Functions for python api * * Copyright (C) 2003 Hans Karlsson * Copyright (C) 2003-2004 Adam Geitgey * Copyright (C) 2004 Petri Damstén * Copyright (C) 2004, 2005 Luke Kenneth Casson Leighton * * This file is part of SuperKaramba. * * SuperKaramba is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * SuperKaramba is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SuperKaramba; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ****************************************************************************/ #ifdef _XOPEN_SOURCE #undef _XOPEN_SOURCE #endif #include #include #include #include #include #include "kdebug.h" #include "karamba.h" #include "karambaapp.h" #include "themefile.h" #include "themelocale.h" #include "meter.h" #include "meter_python.h" #include "misc_python.h" /* now a method we need to expose to Python */ long acceptDrops(long widget) { karamba* currTheme = (karamba*)widget; currTheme->setAcceptDrops(true); return 1; } PyObject* py_accept_drops(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", acceptDrops(widget)); } // Runs a command, returns 0 if it could not start command PyObject* py_run_command(PyObject*, PyObject* args) { char* name; char* command; char* icon; PyObject *lst; if (!PyArg_ParseTuple(args, (char*)"sssO:run", &name, &command, &icon, &lst) || lst == NULL || !PyList_Check(lst)) return NULL; TQString n; TQString c; TQString i; n.setAscii(name); c.setAscii(command); i.setAscii(icon); KService svc(n, c, i); KURL::List l; for (int i = 0; i < PyList_Size(lst); i++) { l.append(PyString2TQString(PyList_GetItem(lst, i))); } KRun::run(svc, l); return Py_BuildValue("l", 1); } // Runs a command, returns 0 if it could not start command PyObject* py_execute_command(PyObject *, PyObject* args) { PyObject* s; if (!PyArg_ParseTuple(args, (char*)"O:execute", &s)) return NULL; return Py_BuildValue((char*)"l", KRun::runCommand(PyString2TQString(s))); } // Runs a command, returns 0 if it could not start command PyObject* py_execute_command_interactive(PyObject *, PyObject* args) { long widget; //if (!PyArg_ParseTuple(args, (char*)"ls", &widget, &command)) // return NULL; int numLines; /* how many lines we passed for parsing */ TQString line; /* pointer to the line as a string */ PyObject * listObj; /* the list of strings */ PyObject * strObj; /* one string in the list */ /* the O! parses for a Python object (listObj) checked to be of type PyList_Type */ if (! PyArg_ParseTuple(args, (char*)"lO!", &widget, &PyList_Type, &listObj)) return NULL; if (!checkKaramba(widget)) return NULL; karamba* currTheme = (karamba*)widget; currTheme->currProcess = new TDEProcess; /* get the number of lines passed to us */ numLines = PyList_Size(listObj); /* should raise an error here. */ if (numLines < 0) return NULL; /* Not a list */ /* iterate over items of the list, grabbing strings, and parsing for numbers */ for (int i=0; icurrProcess) << line; } TQApplication::connect(currTheme->currProcess, TQT_SIGNAL(processExited(TDEProcess *)), currTheme, TQT_SLOT(processExited(TDEProcess *))); TQApplication::connect(currTheme->currProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), currTheme, TQT_SLOT(receivedStdout(TDEProcess *, char *, int))); currTheme->currProcess->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout); return Py_BuildValue((char*)"l", (int)(currTheme->currProcess->pid())); } long attachClickArea(long widget, long meter, TQString LeftButton, TQString MiddleButton, TQString RightButton) { karamba* currTheme = (karamba*) widget; Meter* currMeter = (Meter*) meter; // Look if currMeter has an ClickArea attached. bool meterAlreadyClickable = currTheme->clickList->containsRef(currMeter); // if currMeter is of type ImageLabel* if (ImageLabel* image = dynamic_cast(currMeter)) { image -> attachClickArea(LeftButton, MiddleButton, RightButton); if (!meterAlreadyClickable) { //tqWarning("attachClickArea : meter is image"); currTheme -> clickList -> append(image); } } // else if currMeter is of type TextLabel* else if (TextLabel* text = dynamic_cast(currMeter)) { text -> attachClickArea(LeftButton, MiddleButton, RightButton); if (!meterAlreadyClickable) { //tqWarning("attachClickArea : meter is text"); currTheme -> clickList -> append(text); } } else { //The given meter does not support attached clickAreas. tqWarning("The given meter is not of type image or text"); return 0; } return 1; } PyObject* py_attach_clickArea(PyObject*, PyObject* args, PyObject* dict) { long widget; long meter; char* LeftButton = NULL; char* MiddleButton = NULL; char* RightButton = NULL; const char* mouseButtons[] = {"Widget", "Meter", "LeftButton", "MiddleButton", "RightButton", NULL}; if (!PyArg_ParseTupleAndKeywords(args, dict, (char*)"ll|sss:attachClickArea", (char**)mouseButtons, &widget, &meter, &LeftButton, &MiddleButton, &RightButton)) return NULL; if (!checkKaramba(widget)) return NULL; TQString lB, mB, rB; if (LeftButton != NULL) { lB.setAscii(LeftButton); } else { lB.setAscii(""); } if (MiddleButton != NULL) { mB.setAscii(MiddleButton); } else { mB.setAscii(""); } if (RightButton != NULL) { rB.setAscii(RightButton); } else { rB.setAscii(""); } return Py_BuildValue((char*)"l", attachClickArea(widget, meter, lB, mB, rB)); } /* now a method we need to expose to Python */ long toggleShowDesktop(long) { ShowDesktop *s = ShowDesktop::the(); s->toggle(); return 1; } PyObject* py_toggle_show_desktop(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:toggleShowDesktop", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", toggleShowDesktop(widget)); } /* now a method we need to expose to Python */ const char* getPrettyName(long widget) { karamba* currTheme = (karamba*)widget; return currTheme->prettyName.ascii(); } PyObject* py_get_pretty_name(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:getPrettyThemeName", &widget)) return NULL; return Py_BuildValue((char*)"s", getPrettyName(widget)); } /* now a method we need to expose to Python */ const char* getThemePath(long widget) { karamba* currTheme = (karamba*)widget; return currTheme->theme().path().ascii(); } PyObject* py_get_theme_path(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:getThemePath", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"s", getThemePath(widget)); } PyObject* py_language(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:language", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"s", ((karamba*)widget)->theme().locale()->language().ascii()); } PyObject* py_userLanguage(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:language", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"s", TDEGlobal::locale()->language().ascii()); } PyObject* py_userLanguages(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:language", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; unsigned int noOfLangs = TDEGlobal::locale()->languageList().count(); PyObject *list, *item; list = PyList_New(noOfLangs); for(unsigned int i = 0; i < noOfLangs; i++) { item = Py_BuildValue((char*)"s", TDEGlobal::locale()->languageList()[i].ascii()); PyList_SetItem(list, i, item); } return list; } PyObject* py_read_theme_file(PyObject *, PyObject *args) { long widget; char *file; if (!PyArg_ParseTuple(args, (char*)"ls:readThemeFile", &widget, &file)) return NULL; if (!checkKaramba(widget)) return NULL; karamba* k = (karamba*)widget; TQByteArray ba = k->theme().readThemeFile(file); return PyBytes_FromStringAndSize(ba.data(), ba.size()); } /* now a method we need to expose to Python */ long removeClickArea(long widget, long click) { karamba* currTheme = (karamba*)widget; ClickArea *tmp = (ClickArea*)click; currTheme -> clickList -> remove(tmp); delete tmp; return (long)tmp; } /* now a method we need to expose to Python */ long createServiceClickArea(long widget, long x, long y, long w, long h, char *name, char* exec, char *icon) { karamba* currTheme = (karamba*)widget; ClickArea *tmp = new ClickArea( currTheme, x, y, w, h ); TQString n; TQString e; TQString i; n.setAscii(name); e.setAscii(exec); i.setAscii(icon); tmp->setServiceOnClick(n, e, i); currTheme -> clickList -> append(tmp); return (long)tmp; } long createClickArea(long widget, long x, long y, long w, long h, char* text) { karamba* currTheme = (karamba*)widget; ClickArea *tmp = new ClickArea(currTheme, x, y, w, h ); TQString onclick; onclick.setAscii(text); tmp->setOnClick(onclick ); currTheme -> clickList -> append(tmp); return (long)tmp; } PyObject* py_remove_click_area(PyObject *, PyObject *args) { long widget, click; if (!PyArg_ParseTuple(args, (char*)"ll:removeClickArea", &widget, &click)) return NULL; return Py_BuildValue((char*)"l", removeClickArea(widget, click)); } PyObject* py_create_service_click_area(PyObject *, PyObject *args) { long widget, x, y, w, h; char *name; char *exec; char *icon; if (!PyArg_ParseTuple(args, (char*)"lllllsss:createServiceClickArea", &widget, &x, &y, &w, &h, &name, &exec, &icon)) return NULL; return Py_BuildValue((char*)"l", createServiceClickArea(widget, x, y, w, h, name, exec, icon)); } PyObject* py_create_click_area(PyObject *, PyObject *args) { long widget, x, y, w, h; char *text; if (!PyArg_ParseTuple(args, (char*)"llllls:createClickArea", &widget, &x, &y, &w, &h, &text)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", createClickArea(widget, x, y, w, h, text)); } static long callTheme(long widget, char* path, char *str) { karamba* currTheme = (karamba*) widget; if (currTheme) currTheme->callTheme(TQString(path), TQString(str)); return (long)currTheme; } static long setIncomingData(long widget, char* path, char *obj) { karamba* currTheme = (karamba*) widget; if (currTheme) currTheme->setIncomingData(TQString(path), TQString(obj)); return (long)currTheme; } static TQString getIncomingData(long widget) { karamba* currTheme = (karamba*) widget; if (currTheme) return currTheme->getIncomingData(); return TQString(""); } /* * openNamedTheme. this function checks to see whether the theme * being opened is unique or not (against all running karamba widgets). * this is important, as loading themes with the same name causes * grief. */ long openNamedTheme(char* path, char *name, bool is_sub_theme) { TQString filename; karamba* currTheme = 0; filename.setAscii(path); TQFileInfo file( filename ); if( file.exists() ) { TQCString prettyName(name); KarambaApplication* app = (KarambaApplication*)tqApp; if (!app->themeExists(prettyName)) { currTheme = new karamba( filename, prettyName, false , -1, is_sub_theme); currTheme->show(); } } return (long)currTheme; } /* now a method we need to expose to Python */ long openTheme(char* path) { TQString filename; karamba* currTheme = 0; filename.setAscii(path); TQFileInfo file( filename ); if( file.exists() ) { currTheme = new karamba( filename, TQString() ); currTheme->show(); } return (long)currTheme; } PyObject* py_get_incoming_data(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:getIncomingData", &widget)) return NULL; return Py_BuildValue((char*)"O", TQString2PyString(getIncomingData(widget))); } PyObject* py_set_incoming_data(PyObject *, PyObject *args) { char *themePath; long widget; char *obj; if (!PyArg_ParseTuple(args, (char*)"lss:setIncomingData", &widget, &themePath, &obj)) return NULL; return Py_BuildValue((char*)"l", setIncomingData(widget, themePath, obj)); } PyObject* py_call_theme(PyObject *, PyObject *args) { char *themePath; char *str; long widget; if (!PyArg_ParseTuple(args, (char*)"lss:callTheme", &widget, &themePath, &str)) return NULL; return Py_BuildValue((char*)"l", callTheme(widget, themePath, str)); } PyObject* py_open_named_theme(PyObject *, PyObject *args) { char *themePath; char *themeName; long is_sub_theme; if (!PyArg_ParseTuple(args, (char*)"ssl:openNamedTheme", &themePath, &themeName, &is_sub_theme)) return NULL; return Py_BuildValue((char*)"l", openNamedTheme(themePath, themeName, is_sub_theme ? true : false)); } PyObject* py_open_theme(PyObject *, PyObject *args) { char *themePath; if (!PyArg_ParseTuple(args, (char*)"s:openTheme", &themePath)) return NULL; return Py_BuildValue((char*)"l", openTheme(themePath)); } PyObject* py_reload_theme(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:reloadTheme", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; ((karamba*)widget)->reloadConfig(); return Py_BuildValue((char*)"l", 1); } /* now a method we need to expose to Python */ int getNumberOfDesktops(long widget) { karamba* currTheme = (karamba*)widget; return currTheme->kWinModule->numberOfDesktops(); } PyObject* py_get_number_of_desktops(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:getNumberOfDesktops", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", getNumberOfDesktops(widget)); } /* now a method we need to expose to Python */ int translateAll(long widget, int x, int y) { karamba* currTheme = (karamba*)widget; TQObjectListIt it2( *currTheme->meterList ); // iterate over meters while ( it2 != 0 ) { ((Meter*) *it2)->setSize(((Meter*) *it2)->getX()+x, ((Meter*) *it2)->getY()+y, ((Meter*) *it2)->getWidth(), ((Meter*) *it2)->getHeight()); ++it2; } if (currTheme->systray != 0) { currTheme->systray->move(currTheme->systray->x()+x, currTheme->systray->y()+y); } return 0; } PyObject* py_translate_all(PyObject *, PyObject *args) { long widget; int x, y; if (!PyArg_ParseTuple(args, (char*)"lii:translateAll", &widget, &x, &y)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"lii", translateAll(widget, x, y)); } /* now a method we need to expose to Python */ int show(long widget) { karamba* currTheme = (karamba*)widget; currTheme->show(); return 0; } PyObject* py_show(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:show", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", show(widget)); } /* now a method we need to expose to Python */ int hide(long widget) { karamba* currTheme = (karamba*)widget; currTheme->hide(); return 0; } PyObject* py_hide(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:hide", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"l", hide(widget)); } /*Putting includes here to show the dependency for the call(s) below (if we ever decide to move the networking callbacks into a separate file*/ #include #include #include #include #if defined(__FreeBSD__) || defined(__DragonFly__) #include #endif #if defined(Q_OS_SOLARIS) #include #endif /* now a method we need to expose to Python */ TQString getIp(char *device_name) { int i, sd, numdevs; struct ifconf ifc_conf; char ifc_conf_buf[sizeof ( struct ifreq ) * 32]; struct ifreq *devptr; int ifc_conf_buf_size; static struct in_addr host; TQString retval; retval = "Disconnected"; /* * Open a socket, any type will do so we choose UDP, and ask it with * an ioctl call what devices are behind it. */ if ((sd = socket(AF_INET,SOCK_DGRAM,0)) < 0) { tqWarning("Error: Unable to create socket (socket)"); return "Error"; } /* * Fill the buffer with our static buffer, probably big enough, and get * the interface configuration. */ ifc_conf_buf_size = sizeof ifc_conf_buf; ifc_conf.ifc_len = ifc_conf_buf_size; ifc_conf.ifc_buf = ifc_conf_buf; if (ioctl(sd,SIOCGIFCONF,&ifc_conf) < 0) { tqWarning("Error: Unable to get network interface conf (ioctl)"); close(sd); return "Error"; } /* * An array of devices were returned. Which ones are up right now and * have broadcast capability? */ numdevs = ifc_conf.ifc_len / sizeof (struct ifreq); //tqDebug("numdevs = %d", numdevs); for (i = 0; i < numdevs; i++) { //tqDebug("iterations: %d", i); /* devptr points into an array of ifreq structs. */ devptr = &ifc_conf.ifc_req[i]; if (ioctl(sd, SIOCGIFADDR, devptr) < 0 || devptr->ifr_addr.sa_family != AF_INET) continue; if (ioctl(sd,SIOCGIFFLAGS,devptr) < 0) { tqWarning("Error: Unable to get device interface flags (ioctl)."); close(sd); return "Error"; } //We generally don't want probing of the loopback devices if ((devptr->ifr_flags & IFF_LOOPBACK) != 0) continue; if ((devptr->ifr_flags & IFF_UP) == 0) continue; if ((devptr->ifr_flags & IFF_BROADCAST) == 0) continue; /* Get the broadcast address. */ if (ioctl(sd,SIOCGIFFLAGS,devptr) < 0) { tqWarning("Error: Unable to get device interface flags (ioctl)."); close(sd); return "Error"; } else { if (!strcmp((char*)devptr->ifr_name, device_name)) { host.s_addr = ((struct sockaddr_in*)&devptr->ifr_addr)->sin_addr.s_addr; retval = inet_ntoa(host); break; } } } close(sd); return retval; } PyObject* py_set_update_time(PyObject *, PyObject *args) { long widget; double time; if (!PyArg_ParseTuple(args, (char*)"ld:setUpdateTime", &widget, &time)) return NULL; karamba* currTheme = (karamba*)widget; currTheme->setUpdateTime(time); return Py_BuildValue((char*)"l", 1); } PyObject* py_get_update_time(PyObject *, PyObject *args) { long widget; double time; if (!PyArg_ParseTuple(args, (char*)"l:getUpdateTime", &widget, &time)) return NULL; karamba* currTheme = (karamba*)widget; return Py_BuildValue((char*)"d", currTheme->getUpdateTime()); } PyObject* py_get_ip(PyObject *, PyObject *args) { long widget; char *interface; if (!PyArg_ParseTuple(args, (char*)"ls:getIp", &widget, &interface)) return NULL; if (!checkKaramba(widget)) return NULL; return Py_BuildValue((char*)"O", TQString2PyString(getIp(interface))); } static void management_popup(long widget) { karamba* currTheme = (karamba*)widget; currTheme->management_popup(); } PyObject* py_management_popup(PyObject *, PyObject *args) { long widget; if (!PyArg_ParseTuple(args, (char*)"l:managementPopup", &widget)) return NULL; if (!checkKaramba(widget)) return NULL; management_popup(widget); return Py_BuildValue((char*)"l", 1); } static void set_want_right_button(long widget, long yesno) { karamba* currTheme = (karamba*)widget; currTheme->setWantRightButton(yesno); } PyObject* py_want_right_button(PyObject *, PyObject *args) { long widget, i; if (!PyArg_ParseTuple(args, (char*)"ll:setWantRightButton", &widget, &i)) return NULL; if (!checkKaramba(widget)) return NULL; set_want_right_button(widget, i); return Py_BuildValue((char*)"l", 1); } static void set_want_wheel_event(long widget, long yesno) { karamba* currTheme = (karamba*)widget; currTheme->setWantMeterWheelEvent(yesno); } PyObject* py_want_wheel_event(PyObject *, PyObject *args) { long widget, i; if (!PyArg_ParseTuple(args, (char*)"ll:setWantMeterWheelEvent", &widget, &i)) return NULL; if (!checkKaramba(widget)) return NULL; set_want_wheel_event(widget, i); return Py_BuildValue((char*)"l", 1); } static void changeInterval(long widget, long interval) { karamba* currTheme = (karamba*)widget; currTheme->changeInterval(interval); } PyObject* py_change_interval(PyObject *, PyObject *args) { long widget, i; if (!PyArg_ParseTuple(args, (char*)"ll:changeInterval", &widget, &i)) return NULL; if (!checkKaramba(widget)) return NULL; changeInterval(widget, i); return Py_BuildValue((char*)"l", 1); }