You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

308 rivejä
9.3 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # libcaca Colour ASCII-Art library
  4. # Python language bindings
  5. # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com>
  6. # All Rights Reserved
  7. #
  8. # This library 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://www.wtfpl.net/ for more details.
  13. #
  14. """ Libcaca Python bindings """
  15. import ctypes
  16. from caca import _lib, _PYTHON3, _str_to_bytes
  17. from caca.canvas import _Canvas, Canvas
  18. class _DisplayStruct(ctypes.Structure):
  19. pass
  20. class _Display(object):
  21. """ Model for Display objects.
  22. """
  23. def from_param(self):
  24. """ Required by ctypes module to call object as parameter of
  25. a C function.
  26. """
  27. return self._dp
  28. def __str__(self):
  29. return "<CacaDisplay>"
  30. def __del__(self):
  31. if self._dp and _lib is not None:
  32. self._free()
  33. def _free(self):
  34. """ Free a libcaca display.
  35. """
  36. _lib.caca_free_display.argtypes = [_Display]
  37. _lib.caca_free_display.restype = ctypes.c_int
  38. return _lib.caca_free_display(self)
  39. class Display(_Display):
  40. """ Display objects, methods are libcaca functions with display_t as first
  41. parameter.
  42. """
  43. def __init__(self, cv, driver=None):
  44. """ Display constructor.
  45. cv -- canvas to attach.
  46. driver -- caca driver to set with display
  47. """
  48. if driver is None:
  49. _lib.caca_create_display.argtypes = [_Canvas]
  50. _lib.caca_create_display.restype = ctypes.POINTER(_DisplayStruct)
  51. self._dp = _lib.caca_create_display(cv)
  52. else:
  53. _lib.caca_create_display_with_driver.argtypes = [
  54. _Canvas, ctypes.c_char_p
  55. ]
  56. _lib.caca_create_display_with_driver.restype = ctypes.POINTER(
  57. _DisplayStruct
  58. )
  59. if _PYTHON3 and isinstance(driver, str):
  60. driver = _str_to_bytes(driver)
  61. self._dp = _lib.caca_create_display_with_driver(cv, driver)
  62. if self._dp == 0:
  63. raise DisplayError("Failed to create display")
  64. def get_driver(self):
  65. """ Return the caca graphical context's current output driver.
  66. """
  67. _lib.caca_get_display_driver.argtypes = [_Display]
  68. _lib.caca_get_display_driver.restype = ctypes.c_char_p
  69. return _lib.caca_get_display_driver(self)
  70. def set_driver(self, driver=None):
  71. """ Set the output driver.
  72. driver -- A string describing the desired output driver or NULL
  73. to choose the best driver automatically.
  74. """
  75. _lib.caca_set_display_driver.argtypes = [_Display, ctypes.c_char_p]
  76. _lib.caca_set_display_driver.restype = ctypes.c_int
  77. if not driver:
  78. driver = ctypes.c_char_p(0)
  79. else:
  80. if _PYTHON3 and isinstance(driver, str):
  81. driver = _str_to_bytes(driver)
  82. return _lib.caca_set_display_driver(self, driver)
  83. def get_canvas(self):
  84. """ Get the canvas attached to a caca graphical context.
  85. """
  86. _lib.caca_get_canvas.argtypes = [_Display]
  87. _lib.caca_get_canvas.restype = ctypes.POINTER(ctypes.c_char_p)
  88. return Canvas(pointer=_lib.caca_get_canvas(self))
  89. def refresh(self):
  90. """ Flush pending changes and redraw the screen.
  91. """
  92. _lib.caca_refresh_display.argtypes = [_Display]
  93. _lib.caca_refresh_display.restype = ctypes.c_int
  94. return _lib.caca_refresh_display(self)
  95. def set_time(self, usec):
  96. """ Set the refresh delay.
  97. usec -- the refresh delay in microseconds
  98. """
  99. _lib.caca_set_display_time.argtypes = [_Display, ctypes.c_int]
  100. _lib.caca_set_display_time.restype = ctypes.c_int
  101. return _lib.caca_set_display_time(self, usec)
  102. def get_time(self):
  103. """ Get the display's average rendering time.
  104. """
  105. _lib.caca_get_display_time.argtypes = [_Display]
  106. _lib.caca_get_display_time.restype = ctypes.c_int
  107. return _lib.caca_get_display_time(self)
  108. def set_title(self, title):
  109. """ Set the display title.
  110. title -- the desired display title
  111. """
  112. _lib.caca_set_display_title.argtypes = [_Display, ctypes.c_char_p]
  113. _lib.caca_set_display_title.restype = ctypes.c_int
  114. if _PYTHON3 and isinstance(title, str):
  115. title = _str_to_bytes(title)
  116. return _lib.caca_set_display_title(self, title)
  117. def set_mouse(self, flag):
  118. """ Show or hide the mouse pointer. This function works with the
  119. ncurses, S-Lang and X11 drivers.
  120. flag -- 0 hides the pointer, 1 shows the system's default pointer
  121. (usually an arrow)
  122. """
  123. _lib.caca_set_mouse.argtypes = [_Display, ctypes.c_int]
  124. _lib.caca_set_mouse.restype = ctypes.c_int
  125. return _lib.caca_set_mouse(self, flag)
  126. def set_cursor(self, flag):
  127. """ Show or hide the cursor, for devices that support such a feature.
  128. flag -- 0 hides the cursor, 1 shows the system's default cursor
  129. (usually a white rectangle).
  130. """
  131. _lib.caca_set_cursor.argtypes = [Display, ctypes.c_int]
  132. _lib.caca_set_cursor.restype = ctypes.c_int
  133. return _lib.caca_set_cursor(self, flag)
  134. def get_event(self, event_mask, event, timeout):
  135. """ Get the next mouse or keyboard input event.
  136. event_mask -- bitmask of requested events
  137. event -- a pointer to caca_event structure or NULL
  138. tiemout -- a timeout value in microseconds
  139. """
  140. _lib.caca_get_event.argtypes = [
  141. Display, ctypes.c_int, ctypes.POINTER(Event), ctypes.c_int
  142. ]
  143. return _lib.caca_get_event(self, event_mask, ctypes.byref(event),
  144. timeout)
  145. def get_mouse_x(self):
  146. """ Return the X mouse coordinate.
  147. """
  148. _lib.caca_get_mouse_x.argtypes = [Display]
  149. _lib.caca_get_mouse_x.restype = ctypes.c_int
  150. return _lib.caca_get_mouse_x(self)
  151. def get_mouse_y(self):
  152. """ Return the Y mouse coordinate.
  153. """
  154. _lib.caca_get_mouse_y.argtypes = [Display]
  155. _lib.caca_get_mouse_y.restype = ctypes.c_int
  156. return _lib.caca_get_mouse_y(self)
  157. class DisplayError(Exception):
  158. pass
  159. class Event(ctypes.Structure):
  160. """ Object to store libcaca event.
  161. """
  162. _fields_ = (
  163. ('opaque_structure', ctypes.c_char_p * 32),
  164. )
  165. def from_param(self):
  166. """ Required method to pass object as parameter of a C function.
  167. """
  168. return ctypes.byref(self)
  169. def get_type(self):
  170. """ Return an event's type.
  171. """
  172. _lib.caca_get_event_type.argtypes = [Event]
  173. _lib.caca_get_event_type.restype = ctypes.c_int
  174. return _lib.caca_get_event_type(self)
  175. def get_key_ch(self):
  176. """ Return a key press or key release event's value.
  177. """
  178. _lib.caca_get_event_key_ch.argtypes = [Event]
  179. _lib.caca_get_event_key_ch.restype = ctypes.c_int
  180. return _lib.caca_get_event_key_ch(self)
  181. def get_key_utf32(self):
  182. """ Not implemented.
  183. """
  184. raise DisplayError("Not implemented")
  185. def get_key_utf8(self):
  186. """ Return a key press or key release event's UTF-8 value
  187. as python string.
  188. """
  189. # set buffer for writing utf8 value
  190. buf = ctypes.c_buffer(7)
  191. _lib.caca_get_event_key_utf8.argtypes = [Event, ctypes.c_char_p]
  192. _lib.caca_get_event_key_utf8.restype = ctypes.c_int
  193. _lib.caca_get_event_key_utf8(self, buf)
  194. raw = []
  195. for item in list(buf.raw):
  196. if item == '\x00':
  197. break
  198. else:
  199. raw.append(item)
  200. return "".join(raw)
  201. def get_mouse_button(self):
  202. """ Return a mouse press or mouse release event's button.
  203. """
  204. _lib.caca_get_event_mouse_button.argtypes = [Event]
  205. _lib.caca_get_event_mouse_button.restype = ctypes.c_int
  206. return _lib.caca_get_event_mouse_button(self)
  207. def get_mouse_x(self):
  208. """ Return a mouse motion event's X coordinate.
  209. """
  210. _lib.caca_get_event_mouse_x.argtypes = [Event]
  211. _lib.caca_get_event_mouse_x.restype = ctypes.c_int
  212. return _lib.caca_get_event_mouse_x(self)
  213. def get_mouse_y(self):
  214. """ Return a mouse motion event's Y coordinate.
  215. """
  216. _lib.caca_get_event_mouse_y.argtypes = [Event]
  217. _lib.caca_get_event_mouse_y.restype = ctypes.c_int
  218. return _lib.caca_get_event_mouse_y(self)
  219. def get_resize_width(self):
  220. """ Return a resize event's display width value.
  221. """
  222. _lib.caca_get_event_resize_width.argtypes = [Event]
  223. _lib.caca_get_event_resize_width.restype = ctypes.c_int
  224. return _lib.caca_get_event_resize_width(self)
  225. def get_resize_height(self):
  226. """ Return a resize event's display height value.
  227. """
  228. _lib.caca_get_event_resize_height.argtypes = [Event]
  229. _lib.caca_get_event_resize_height.restype = ctypes.c_int
  230. return _lib.caca_get_event_resize_height(self)