source: neercs/trunk/src/python/interpreter.c @ 4046

Last change on this file since 4046 was 4046, checked in by Jean-Yves Lamoureux, 11 years ago
  • mini-command now recognizes commands like window_manager="full" or borders=0 or eyecandy=False
File size: 8.2 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
4 *                All Rights Reserved
5 *
6 *  $Id: interpreter.c 3996 2009-11-22 12:41:45Z jylam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#ifdef USE_PYTHON
18
19#include <Python.h>
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include <fcntl.h>
27#include <signal.h>
28#include <sys/ioctl.h>
29#include <sys/socket.h>
30#include <sys/time.h>
31#include <time.h>
32#include <sys/wait.h>
33#include <sys/types.h>
34
35#include <caca.h>
36
37#include "neercs.h"
38#include "py_module.h"
39
40static void add_char(struct screen_list *sl, unsigned int c);
41static void del_char(struct screen_list *sl);
42static int python_execute(struct screen_list *sl);
43 char *getStringFromPyObject(PyObject * p);
44static char *getPythonError(void);
45
46static void add_char(struct screen_list *sl, unsigned int c)
47{
48    /* FIXME handle return values */
49    if (!sl->interpreter_props.command)
50    {
51        sl->interpreter_props.size = 1;
52        sl->interpreter_props.x = 0;
53        sl->interpreter_props.command = (char *)malloc(2);
54        sl->interpreter_props.command[0] = 0;
55    }
56    else
57    {
58        sl->interpreter_props.command =
59            (char *)realloc(sl->interpreter_props.command,
60                            sl->interpreter_props.size + 1);
61    }
62    memmove(&sl->interpreter_props.command[sl->interpreter_props.x + 1],
63            &sl->interpreter_props.command[sl->interpreter_props.x],
64            (sl->interpreter_props.size - sl->interpreter_props.x));
65
66    sl->interpreter_props.command[sl->interpreter_props.x] = c;
67    sl->interpreter_props.x++;
68    sl->interpreter_props.size++;
69}
70
71static void del_char(struct screen_list *sl)
72{
73    if (sl->interpreter_props.x < 1)
74        return;
75    if (sl->interpreter_props.size > 1)
76        sl->interpreter_props.size--;
77    else
78        return;
79
80    memcpy(&sl->interpreter_props.command[sl->interpreter_props.x - 1],
81           &sl->interpreter_props.command[sl->interpreter_props.x],
82           sl->interpreter_props.size - sl->interpreter_props.x);
83
84    sl->interpreter_props.command =
85        (char *)realloc(sl->interpreter_props.command,
86                        sl->interpreter_props.size);
87
88    if (sl->interpreter_props.x)
89        sl->interpreter_props.x--;
90    sl->interpreter_props.command[sl->interpreter_props.size - 1] = 0;
91}
92
93
94int python_command_handle_key(struct screen_list *screen_list, unsigned int c)
95{
96    if (c == CACA_KEY_ESCAPE)
97    {
98        if (screen_list->interpreter_props.command)
99        {
100            free(screen_list->interpreter_props.command);
101            screen_list->interpreter_props.command = NULL;
102        }
103        screen_list->python_command = 0;
104        screen_list->changed = 1;
105        return 1;
106    }
107    else if (c == CACA_KEY_LEFT)
108    {
109        if (screen_list->interpreter_props.x)
110            screen_list->interpreter_props.x--;
111    }
112    else if (c == CACA_KEY_RIGHT)
113    {
114        if (screen_list->interpreter_props.x <
115            screen_list->interpreter_props.size - 1)
116            screen_list->interpreter_props.x++;
117    }
118    else if (c == CACA_KEY_RETURN)
119    {
120        python_execute(screen_list);
121    }
122    else
123    {
124        if (c >= ' ' && c < 127)
125            add_char(screen_list, c);
126        else if (c == 8)
127        {
128            del_char(screen_list);
129        }
130        screen_list->changed = 1;
131        return 0;
132    }
133    return 0;
134}
135
136void draw_python_command(struct screen_list *screen_list)
137{
138    int w = 65, h = 6;
139    int x = (caca_get_canvas_width(screen_list->cv) - w) / 2;
140    int y = (caca_get_canvas_height(screen_list->cv) - h) / 2;
141
142    caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
143    caca_fill_box(screen_list->cv, x, y, w, h, '#');
144    caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
145    caca_draw_cp437_box(screen_list->cv, x, y, w, h);
146    caca_printf(screen_list->cv, x, y, "Execute command");
147
148    caca_printf(screen_list->cv, x + 2, y + 2,
149                "[___________________________________________________________]");
150
151    if (screen_list->interpreter_props.command)
152    {
153        caca_printf(screen_list->cv, x + 3, y + 2,
154                    "%s", screen_list->interpreter_props.command);
155        caca_gotoxy(screen_list->cv,
156                    x + 3 + screen_list->interpreter_props.x, y + 2);
157    }
158    else
159    {
160        caca_gotoxy(screen_list->cv, x + 3, y + 2);
161    }
162
163    if (screen_list->interpreter_props.output_err)
164    {
165        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLUE);
166        caca_printf(screen_list->cv, x + 2, y + 4,
167                    screen_list->interpreter_props.output_err);
168    }
169    if (screen_list->interpreter_props.output_res)
170    {
171        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLUE);
172        caca_printf(screen_list->cv, x + 2, y + 4,
173                    screen_list->interpreter_props.output_res);
174    }
175}
176
177/* Actual Python interpreter stuff */
178int python_init(struct screen_list *sl)
179{
180    sl->interpreter_props.output_err = NULL;
181    sl->interpreter_props.output_res = NULL;
182    Py_Initialize();
183   
184    initNeercsModule(sl);
185   
186    return 0;
187}
188
189int python_close(struct screen_list *sl)
190{
191    if (sl->interpreter_props.output_err)
192        free(sl->interpreter_props.output_err);
193    if (sl->interpreter_props.output_res)
194        free(sl->interpreter_props.output_res);
195    sl->interpreter_props.output_err = NULL;
196    sl->interpreter_props.output_res = NULL;
197    Py_Finalize();
198    return 0;
199}
200
201
202static int python_execute(struct screen_list *sl)
203{
204    if (!sl->interpreter_props.command || sl->interpreter_props.size < 1)
205        return -1;
206    int err = 0;
207
208    debug("py Executing '%s'\n", sl->interpreter_props.command);
209
210    if (sl->interpreter_props.output_err)
211    {
212        free(sl->interpreter_props.output_err);
213        sl->interpreter_props.output_err = NULL;
214    }
215    if (sl->interpreter_props.output_res)
216    {
217        free(sl->interpreter_props.output_res);
218        sl->interpreter_props.output_res = NULL;
219    }
220   
221    PyObject *pModule, *pName, *pFunc;
222
223    /* Module from which to call the function */
224    pName = PyUnicode_FromString("neercs");
225    if (!pName)
226    {
227        sl->interpreter_props.output_err = getPythonError();
228        err = 1;
229        debug("py Error 1\n");
230        goto end;
231    }
232   
233    pModule = PyImport_Import(pName);
234    Py_DECREF(pName);
235
236    if (pModule != NULL)
237    {
238        PyObject * dictionary = PyModule_GetDict(pModule);
239       
240        getExportedValues(dictionary);
241       
242                PyObject *o = PyRun_String(sl->interpreter_props.command, Py_single_input, dictionary, NULL);
243        if(!o)
244        {
245                sl->interpreter_props.output_err = getPythonError();   
246            err = 1;
247        }
248        else
249        {
250            setExportedValues(dictionary);
251           
252            sl->interpreter_props.output_res = getStringFromPyObject(o);
253            err = 1;
254        }
255                goto end;
256           
257    }
258    else
259    {
260        sl->interpreter_props.output_err = getPythonError();
261        err = 1;
262        debug("py: %s\n", sl->interpreter_props.output_err);
263        goto end;
264    }
265
266  end:
267   
268    Py_XDECREF(pFunc);
269    Py_DECREF(pModule);
270   
271    if (!err)
272    {
273        free(sl->interpreter_props.command);
274        sl->interpreter_props.command = NULL;
275        sl->interpreter_props.size = 0;
276        sl->interpreter_props.x = 0;
277        sl->python_command = 0;
278    }
279    sl->changed = 1;
280
281    return 0;
282}
283
284
285
286static char *getPythonError(void)
287{
288    char *err;
289    PyObject *type, *value, *traceback;
290    PyErr_Fetch(&type, &value, &traceback);
291
292    char *evalue = getStringFromPyObject(value);
293
294    int r = asprintf(&err, "%s", evalue);
295        (void)r;
296    return err;
297}
298
299 char *getStringFromPyObject(PyObject * p)
300{
301    PyObject *str = PyObject_Repr(p);
302    char *err = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8",
303                                                            "Error ~"));
304   
305    char *ret = strdup(err);
306    return ret;
307}
308
309
310#endif
Note: See TracBrowser for help on using the repository browser.