From The Compiler, 5 Years ago, written in Python.
Embed
  1. ########## cherbstclient.pxd ##########
  2.  
  3. cdef extern from "glib.h":
  4.     ctypedef char gchar
  5.     ctypedef unsigned long gsize
  6.     ctypedef struct GString:
  7.         gchar *str
  8.         gsize len
  9.         gsize allocated_len
  10.  
  11. cdef extern from "X11/Xlib.h":
  12.     ctypedef struct Display:
  13.         pass
  14.  
  15. cdef extern from "herbstclient.h":
  16.     ctypedef struct HCConnection:
  17.         pass
  18.  
  19.     HCConnection* hc_connect()
  20.     HCConnection* hc_connect_to_display(Display* display)
  21.     void hc_disconnect(HCConnection* con)
  22.     bint hc_create_client_window(HCConnection* con)
  23.  
  24.     bint hc_send_command(HCConnection* con, int argc, char* argv[],
  25.                          GString** ret_out, int* ret_status)
  26.     bint hc_send_command_once(int argc, char* argv[],
  27.                               GString** ret_out, int* ret_status)
  28.  
  29.     bint hc_hook_window_connect(HCConnection* con)
  30.     bint hc_next_hook(HCConnection* con, int* argc, char** argv[])
  31.  
  32.  
  33.  
  34. ########## herbstclient.pyx ##########
  35.  
  36. cimport cherbstclient as chc
  37. from libc.stdlib cimport malloc, free
  38.  
  39. class HerbstClientError(Exception):
  40.     pass
  41.  
  42. cdef class Client:
  43.     cdef chc.HCConnection* _c_con
  44.  
  45.     def __cinit__(self, display=None):
  46.         if display is None:
  47.             self._c_con = chc.hc_connect()
  48.         else:
  49.             #self._c_con = chc.hc_connect_to_display(display)
  50.             raise NotImplementedError("Only hc_connect() is implemented at the moment")
  51.         if self._c_con is NULL:
  52.             raise HerbstClientError("Could not open connection")
  53.  
  54.     cdef create_client_window(self):
  55.         if not chc.hc_create_client_window(self._c_con):
  56.             raise HerbstClientError("Could not create client window")
  57.  
  58.     cdef hook_window_connect(self):
  59.         if not chc.hc_hook_window_connect(self._c_con):
  60.             raise HerbstClientError("Could not connect to hook window")
  61.  
  62.     def send_command(self, *args):
  63.         cdef chc.GString* c_output
  64.         cdef int c_status
  65.         cdef char** c_argv = <char**>malloc(len(args) * sizeof(char*))
  66.  
  67.         if c_argv is NULL:
  68.             raise MemoryError
  69.  
  70.         try:
  71.             args = [arg.encode('UTF-8') for arg in args]
  72.             for (i, arg) in enumerate(args):
  73.                c_argv[i] = arg
  74.             if not chc.hc_send_command(self._c_con, len(args), c_argv,
  75.                                        &c_output, &c_status):
  76.                 raise HerbstClientError("Could not send command")
  77.         finally:
  78.             free(c_argv)
  79.  
  80.         return (c_status, c_output.str.decode('UTF-8'))
  81.  
  82.     def __dealloc__(self):
  83.         if self._c_con is not NULL:
  84.             chc.hc_disconnect(self._c_con)