diff --git a/AUTHORS b/AUTHORS index ebb648f..7cb262d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,6 @@ Sam Hocevar Jean-Yves Lamoureux - cacaball - OpenGL driver - - Pypycaca Python wrapper - exporters - network driver - C# bindings @@ -29,4 +28,7 @@ Nicolas Vion Adrien Grand - Java bindings +Alex Foulon + - Python bindings + */ diff --git a/configure.ac b/configure.ac index 980bbfd..fea08db 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,8 @@ AC_ARG_ENABLE(java, [ --enable-java Java bindings (autodetected)]) AC_ARG_ENABLE(cxx, [ --enable-cxx C++ bindings (autodetected)]) +AC_ARG_ENABLE(python, + [ --enable-python Python bindings (autodetected)]) AC_ARG_ENABLE(ruby, [ --enable-ruby Ruby bindings (autodetected)]) @@ -464,6 +466,13 @@ if test "${enable_java}" != "no" -a "${ac_cv_my_have_kernel}" != "yes"; then fi AM_CONDITIONAL(USE_JAVA, test "${ac_cv_my_have_java}" = "yes") +# Build the Python bindings? +ac_cv_my_have_python="no" +if test "${enable_python}" != "no"; then + AM_PATH_PYTHON(2.2, ac_cv_my_have_python="yes", :) +fi +AM_CONDITIONAL(USE_PYTHON, test "${ac_cv_my_have_python}" = "yes") + # Build the Ruby bindings? ac_cv_my_have_ruby="no" if test "${enable_ruby}" != "no"; then diff --git a/python/Makefile.am b/python/Makefile.am index 3866a84..60a69a5 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -1,22 +1,17 @@ -EXTRA_DIST = caca.txt pypycaca.c pypycaca.h snake.py test1.py test2.py +if USE_PYTHON +python_PYTHON = \ + caca/__init__.py \ + caca/canvas.py \ + caca/common.py \ + caca/display.py \ + caca/dither.py \ + caca/font.py +endif + +EXTRA_DIST = \ + setup.py \ + examples/cacainfo.py \ + examples/drawing.py \ + examples/gol.py -CC = gcc -RM = rm -f -CACAFLAGS = `caca-config --cflags` -CACALIBS = `caca-config --libs` - -PYTHONFLAGS = -I/usr/include/python2.4 -PYTHONLIBS = -lpython2.4 - -NAME = caca.so - -all: - -python: - $(CC) pypycaca.c -c $(CACAFLAGS) $(PYTHONFLAGS) -Wall - $(LD) pypycaca.o -o $(NAME) $(CACALIBS) $(PYTHONLIBS) -shared - - -clean: - $(RM) *.o $(NAME) diff --git a/python/README b/python/README deleted file mode 100644 index e5e9fb6..0000000 --- a/python/README +++ /dev/null @@ -1,16 +0,0 @@ -Pypycaca - libcaca bindings for Python -(c) 2006 Jean-Yves Lamoureux - - -No warranty blaaah blaaah - - -These Python bindings will work with either Python 2.3 or 2.4, not tested previous versions. - -Don't forget to change Makefile options in case you are not using Python 2.4. - -No documentation yet, functions are all the same, with same arguments (using arrays or lists instead of C pointers, of course). - -It hasn't been tested on anything else than IA32 yet. - -I eat beef tonight, that was cool. Thanks. \ No newline at end of file diff --git a/python/caca.txt b/python/caca.txt deleted file mode 100644 index 1ea8648..0000000 --- a/python/caca.txt +++ /dev/null @@ -1,26 +0,0 @@ -12 6 6 3 - , - ` ,_ , -` _( )_ - _( ` )_ -( `-. ' ) - `-.____,-' - h - h gg h -h gggggg - gggggggggg -gggggggggggg - gggggggggg -12 6 6 3 - . , - ` ,_ - _( )_ ' - _( ` )_ -( `-. ' ) - `-.____,-' - h h - h gg - gggggg h - gggggggggg -gggggggggggg - gggggggggg diff --git a/python/caca/__init__.py b/python/caca/__init__.py new file mode 100644 index 0000000..7dbb299 --- /dev/null +++ b/python/caca/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes +from ctypes.util import find_library + +if find_library('caca') is not None: + _lib = ctypes.cdll.LoadLibrary(find_library('caca')) +else: + raise ImportError, \ + "Can't find shared library, you need to install libcaca in your path !" + +from common import * + diff --git a/python/caca/canvas.py b/python/caca/canvas.py new file mode 100644 index 0000000..d95336c --- /dev/null +++ b/python/caca/canvas.py @@ -0,0 +1,812 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes + +from caca import _lib + +class _Canvas(object): + """ Model for Canvas objects. + """ + + def __init__(self): + self._cv = 0 + + def from_param(self): + """ Required by ctypes module to call object as parameter of + a C function. + """ + return self._cv + + def __str__(self): + return "" % (self.get_width(), self.get_height()) + + def __del__(self): + if self._cv > 0: + self._free() + + def _free(self): + """ Free a libcaca canvas. + """ + _lib.caca_free_canvas.argtypes = [_Canvas] + _lib.caca_free_canvas.restype = ctypes.c_int + + return _lib.caca_free_canvas(self) + + def get_width(self): + raise CanvasError, "You can't use model canvas directly" + + def get_height(self): + raise CanvasError, "You can't use model canvas directly" + +class Canvas(_Canvas): + """ Canvas object, methods are libcaca functions with canvas_t as + first parameter. + """ + def __init__(self, width=0, height=0): + """ Canvas constructor. + + width -- the desired canvas width + height -- the desired canvas height + """ + _lib.caca_create_canvas.argtypes = [ctypes.c_int, ctypes.c_int] + + self._cv = _lib.caca_create_canvas(width, height) + if self._cv == 0: + raise CanvasError, "Failed to create canvas" + + def set_size(self, width, height): + """ Resize a canvas. + + width -- the desired canvas width + height -- the desired canvas height + """ + _lib.caca_set_canvas_size.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int + ] + _lib.caca_set_canvas_size.restype = ctypes.c_int + + return _lib.caca_set_canvas_size(self, width, height) + + def get_width(self): + """ Get the canvas width. + """ + _lib.caca_get_canvas_width.argtypes = [_Canvas] + _lib.caca_get_canvas_width.restype = ctypes.c_int + + return _lib.caca_get_canvas_width(self) + + def get_height(self): + """ Get the canvas height. + """ + _lib.caca_get_canvas_height.argtypes = [_Canvas] + _lib.caca_get_canvas_height.restype = ctypes.c_int + + return _lib.caca_get_canvas_height(self) + + def get_chars(self): + """ Get the canvas character array, return python list. + """ + chlist = [] + #get canvas size + w, h = self.get_width(), self.get_height() + + _lib.caca_get_canvas_chars.argtypes = [_Canvas] + _lib.caca_get_canvas_chars.restype = \ + ctypes.POINTER(ctypes.c_uint8 * (w * h)) + + plist = _lib.caca_get_canvas_chars(self) + + #build character list + for item in plist.contents: + if item != 0: + chlist.append(chr(item)) + + return chlist + + def gotoxy(self, x, y): + """ Set cursor position. + + x -- X cursor coordinate + y -- Y cursor coordinate + """ + _lib.caca_gotoxy.argtypes = [_Canvas, ctypes.c_int] + _lib.caca_gotoxy.restyoe = ctypes.c_int + + return _lib.caca_gotoxy(self, x, y) + + def wherex(self): + """ Get X cursor position. + """ + _lib.caca_wherex.argtypes = [_Canvas] + _lib.caca_wherex.restype = ctypes.c_int + + return _lib.caca_wherex(self) + + def wherey(self): + """ Get Y cursor position. + """ + _lib.caca_wherey.argtypes = [_Canvas] + _lib.caca_wherey.restype = ctypes.c_int + + return _lib.caca_wherey(self) + + def put_char(self, x, y, ch): + """ Print an ASCII or Unicode character. + + x -- X coordinate + y -- Y coordinate + ch -- the character to print + """ + _lib.caca_put_char.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_put_char.restype = ctypes.c_int + + return _lib.caca_put_char(self, x, y, ord(ch)) + + def get_char(self, x, y): + """ Get the Unicode character at the given coordinates. + + x -- X coordinate + y -- Y coordinate + """ + _lib.caca_get_char.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int + ] + _lib.caca_get_char.restype = ctypes.c_uint32 + + return _lib.caca_get_char(self, x, y) + + def put_str(self, x, y, s): + """ Print a string. + + x -- X coordinate + y -- Y coordinate + s -- the string to print + """ + _lib.caca_put_str.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_char_p + ] + _lib.caca_put_str.restype = ctypes.c_int + + return _lib.caca_put_str(self, x, y, s) + + def printf(self, x, y, fmt, *args): + """ Print a formated string. + + x -- X coordinate + y -- Y coordinate + fmt -- the format string to print + args -- Arguments to the format string + """ + _lib.caca_printf.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_char_p + ] + _lib.caca_printf.restype = ctypes.c_int + + return _lib.caca_printf(self, x, y, fmt, *args) + + def clear(self): + """ Clear the canvas. + """ + _lib.caca_clear_canvas.argtypes = [_Canvas] + _lib.caca_clear_canvas.restype = ctypes.c_int + + return _lib.caca_clear_canvas(self) + + def set_handle(self, x, y): + """ Set cursor handle. Blitting method will use the handle value to + put the canvas at the proper coordinates. + + x -- X handle coordinate + y -- Y handle coordinate + """ + _lib.caca_set_canvas_handle.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int + ] + _lib.caca_set_canvas_handle.restype = ctypes.c_int + + return _lib.caca_set_canvas_handle(self, x, y) + + def get_handle_x(self): + """ Get X handle position. + """ + _lib.caca_get_canvas_handle_x.argtypes = [_Canvas] + _lib.caca_get_canvas_handle_x.restype = ctypes.c_int + + return _lib.caca_get_canvas_handle_x(self) + + def get_handle_y(self): + """ Get Y handle position. + """ + _lib.caca_get_canvas_handle_y.argtypes = [_Canvas] + _lib.caca_get_canvas_handle_y.restype = ctypes.c_int + + return _lib.caca_get_canvas_handle_y(self) + + def blit(self, x, y, cv, mask): + """ Blit canvas onto another one. + + x -- X coordinate + y -- Y coordinate + cv -- the source canvas + mask -- the mask canvas + """ + _lib.caca_blit.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, _Canvas, _Canvas + ] + _lib.caca_blit.restype = ctypes.c_int + + return _lib.caca_blit(self, x, y, cv, mask) + + def set_boundaries(self, x, y, width, height): + """ Set a canvas' new boundaries. + + x -- X coordinate of the top-left corner + y -- Y coordinate of the top-left corner + width -- width of the box + height -- height of the box + """ + _lib.caca_set_canvas_boundaries.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_set_canvas_boundaries.restype = ctypes.c_int + + return _lib.caca_set_canvas_boundaries(self, x, y, width, height) + + def disable_dirty_rect(self): + """ Disable dirty rectangles. + """ + _lib.caca_disable_dirty_rect.argtypes = [_Canvas] + _lib.caca_disable_dirty_rect.restype = ctypes.c_int + + return _lib.caca_disable_dirty_rect(self) + + def enable_dirty_rect(self): + """ Enable dirty rectangles. + """ + _lib.caca_enable_dirty_rect.argtypes = [_Canvas] + _lib.caca_enable_dirty_rect.restype = ctypes.c_int + + return _lib.caca_enable_dirty_rect(self) + + def get_dirty_rect_count(self): + """ Get the number of dirty rectangles in the canvas. + """ + _lib.caca_get_dirty_rect_count.argtypes = [_Canvas] + _lib.caca_get_dirty_rect_count.restype = ctypes.c_int + + return _lib.caca_get_dirty_rect_count(self) + + def get_dirty_rect(self, idx): + """ Get a canvas's dirty rectangle. + + idx -- the requested rectangle index + """ + x = ctypes.POINTER(ctypes.c_int) + y = ctypes.POINTER(ctypes.c_int) + w = ctypes.POINTER(ctypes.c_int) + h = ctypes.POINTER(ctypes.c_int) + + _lib.caca_get_dirty_rect.argtypes = [ + _Canvas, ctypes.c_int, + ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), + ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int) + ] + _lib.caca_get_dirty_rect.restype = ctypes.c_int + + _lib.caca_get_dirty_rect(self, idx, x, y, w, h) + + return [x.contents.value, y.contents.value, + w.contents.value, h.contents.value] + + def add_dirty_rect(self, x, y, width, height): + """ Add an area to the canvas's dirty rectangle list. + + x -- the leftmost edge of the additional dirty rectangle + y -- the topmost edge of the additional dirty rectangle + width -- the width of the additional dirty rectangle + height -- the height of the additional dirty rectangle + """ + _lib.caca_add_dirty_rect.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int + ] + _lib.caca_add_dirty_rect.restype = ctypes.c_int + + return _lib.caca_add_dirty_rect(self, x, y, width, height) + + def remove_dirty_rect(self, x, y, width, height): + """ Remove an area from the dirty rectangle list. + + x -- the leftmost edge of the additional dirty rectangle + y -- the topmost edge of the additional dirty rectangle + width -- the width of the additional rectangle + height -- the height of the additional dirty rectangle + """ + _lib.caca_remove_dirty_rect.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int + ] + _lib.caca_remove_dirty_rect.restype = ctypes.c_int + + return _lib.caca_remove_dirty_rect(self, x, y, height, width) + + def clear_dirty_rect_list(self): + """ Clear a canvas's dirty rectangle list. + """ + _lib.caca_clear_dirty_rect_list.argtypes = [_Canvas] + _lib.caca_clear_dirty_rect_list.restype = ctypes.c_int + + return _lib.caca_clear_dirty_rect_list(self) + + def invert(self): + """ Invert a canvas' colours. + """ + _lib.caca_invert.argtypes = [_Canvas] + _lib.caca_invert.restype = ctypes.c_int + + return _lib.caca_invert(self) + + def flip(self): + """ Flip a canvas horizontally. + """ + _lib.caca_flip.argtypes = [_Canvas] + _lib.caca_flip.restype = ctypes.c_int + + return _lib.caca_flip(self) + + def flop(self): + """ Flip a canvas vertically. + """ + _lib.caca_flop.argtypes = [_Canvas] + _lib.caca_flop.restype = ctypes.c_int + + return _lib.caca_flop(self) + + def rotate_180(self): + """ Rotate a canvas. + """ + _lib.caca_rotate_180.argtypes = [_Canvas] + _lib.caca_rotate_180.restype = ctypes.c_int + + return _lib.caca_rotate_180(self) + + def rotate_left(self): + """ Rotate a canvas, 90 degrees counterclockwise. + """ + _lib.caca_rotate_left.argtypes = [_Canvas] + _lib.caca_rotate_left.restype = ctypes.c_int + + return _lib.caca_rotate_left(self) + + def rotate_right(self): + """ Rotate a canvas, 90 degrees clockwise. + """ + _lib.caca_rotate_right.argtypes = [_Canvas] + _lib.caca_rotate_right.restype = ctypes.c_int + + return _lib.caca_rotate_right(self) + + def stretch_left(self): + """ Rotate and stretch a canvas, 90 degrees counterclockwise. + """ + _lib.caca_stretch_left.argtypes = [_Canvas] + _lib.caca_stretch_left.restype = ctypes.c_int + + return _lib.caca_stretch_left(self) + + def stretch_right(self): + """ Rotate and stretch a canvas, 90 degrees clockwise. + """ + _lib.caca_stretch_right.argtypes = [_Canvas] + _lib.caca_stretch_right.restype = ctypes.c_int + + return _lib.caca_stretch_right(self) + + def get_attr(self, x, y): + """ Get the text attribute at the given coordinates. + + x -- X coordinate + y -- Y coordinate + """ + _lib.caca_get_attr.argtypes = [_Canvas, ctypes.c_int, ctypes.c_int] + _lib.caca_get_attr.restype = ctypes.c_uint32 + return _lib.caca_get_attr(self, x, y) + + def set_attr(self, attr): + """ Set the default character attribute. + + attr -- the requested attribute value + """ + _lib.caca_set_attr.argtypes = [_Canvas, ctypes.c_uint32] + _lib.caca_set_attr.restype = ctypes.c_int + + return _lib.caca_set_attr(self, attr) + + def put_attr(self, x, y, attr): + """ Set the character attribute at the given coordinates. + + x -- X coordinate + y -- Y coordinate + attr -- the requested attribute value + """ + _lib.caca_put_attr.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_put_attr.restype = ctypes.c_int + + return _lib.caca_put_attr(self, x, y, attr) + + def set_color_ansi(self, fg, bg): + """ Set the default colour pair for text (ANSI version). + + fg -- the requested ANSI foreground colour. + bg -- the requested ANSI background colour. + """ + _lib.caca_set_color_ansi.argtypes = [_Canvas, ctypes.c_uint8, ctypes.c_uint8] + _lib.caca_set_color_ansi.restype = ctypes.c_int + + return _lib.caca_set_color_ansi(self, fg, bg) + + def set_color_argb(self, fg, bg): + """ Set the default colour pair for text (truecolor version). + + fg -- the requested ARGB foreground colour. + bg -- the requested ARGB background colour. + """ + _lib.caca_set_color_argb.argtypes = [ + _Canvas, ctypes.c_uint16, ctypes.c_uint16 + ] + _lib.caca_set_color_argb.restype = ctypes.c_int + + return _lib.caca_set_color_argb(self, fg, bg) + + def draw_line(self, x1, y1, x2, y2, ch): + """ Draw a line on the canvas using the given character. + + x1 -- X coordinate of the first point + y1 -- Y coordinate of the first point + x2 -- X coordinate of the second point + y2 -- Y coordinate of the second point + ch -- character to be used to draw the line + """ + _lib.caca_draw_line.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_line.restype = ctypes.c_int + + return _lib.caca_draw_line(self, x1, y1, x2, y2, ord(ch)) + + def draw_polyline(self, array_x, array_y, n, ch): + """ Draw a polyline. + + array_x -- Array of X coordinates, must have n+1 elements + array-y -- Array of Y coordinates, must have n+1 elements + n -- Number of lines to draw + ch -- character to be used to draw the line + """ + _lib.caca_draw_polyline.argtypes = [ + _Canvas, ctypes.c_int * n, ctypes.c_int * n, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_polyline.restype = ctypes.c_int + + return _lib.caca_draw_polyline(self, array_x, array_y, n, ord(ch)) + + def draw_thin_line(self, x1, y1, x2, y2): + """ Draw a thin line on the canvas, using ASCII art. + + x1 -- X coordinate of the first point + y1 -- Y coordinate of the first point + x2 -- X coordinate of the second point + y2 -- Y coordinate of the second point + """ + _lib.caca_draw_thin_line.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_draw_thin_line.restype = ctypes.c_int + + return _lib.caca_draw_thin_line(self, x1, y1, x2, y2) + + def draw_thin_polyline(self, array_x, array_y, n): + """ Draw an ASCII art thin polyline. + + array_x -- Array of X coordinates, must have n+1 elements + array_y -- Array of Y coordinates, must have n+1 elements + n -- Number of lines to draw + """ + _lib.caca_draw_thin_polyline.argtypes = [ + Canvas, ctypes.c_int * n, ctypes.c_int * n, ctypes.c_int + ] + _lib.caca_draw_thin_polyline.restype = ctypes.c_int + + return _lib.caca_draw_thin_polyline(self, array_x, array_y, n) + + def draw_circle(self, x, y, r, ch): + """ Draw a circle on the canvas using the given character. + + x -- center X coordinate + y -- center Y coordinate + r -- circle radius + ch -- the UTF-32 character to be used to draw the circle outline + """ + _lib.caca_draw_circle.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_circle.restype = ctypes.c_int + + return _lib.caca_draw_circle(self, x, y, r, ord(ch)) + + def draw_ellipse(self, xo, yo, a, b, ch): + """ Draw an ellipse on the canvas using the given character. + + xo -- center X coordinate + yo -- center Y coordinate + a -- ellipse x radius + b -- ellipse y radius + ch -- UTF-32 character to be used to draw the ellipse outline + """ + _lib.caca_draw_ellipse.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_ellipse.restype = ctypes.c_int + + return _lib.caca_draw_ellipse(self, xo, yo, a, b, ord(ch)) + + def draw_thin_ellipse(self, xo, yo, a, b): + """ Draw a thin ellipse on the canvas. + + xo -- center X coordinate + yo -- center Y coordinate + a -- ellipse X radius + b -- ellipse Y radius + """ + _lib.caca_draw_thin_ellipse.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_draw_thin_ellipse.restype = ctypes.c_int + + return _lib.caca_draw_thin_ellipse(self, xo, yo, a, b) + + def fill_ellipse(self, xo, yo, a, b, ch): + """ Fill an ellipse on the canvas using the given character. + + xo -- center X coordinate + yo -- center Y coordinate + a -- ellipse X radius + b -- ellipse Y radius + ch -- UTF-32 character to be used to fill the ellipse + """ + _lib.caca_fill_ellipse.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_fill_ellipse.restype = ctypes.c_int + + return _lib.caca_fill_ellipse(self, xo, yo, a, b, ord(ch)) + + def draw_box(self, x, y, width, height, ch): + """ Draw a box on the canvas using the given character. + + x -- X coordinate of the upper-left corner of the box + y -- Y coordinate of the upper-left corner of the box + width -- width of the box + height -- height of the box + ch -- character to be used to draw the box + """ + _lib.caca_draw_box.argtypes = [ + Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_box.restype = ctypes.c_int + + return _lib.caca_draw_box(self, x, y, width, height, ord(ch)) + + def draw_thin_box(self, x, y, width, height): + """ Draw a thin box on the canvas. + + x -- X coordinate of the upper-left corner of the box + y -- Y coordinate of the upper-left corner of the box + width -- width of the box + height -- height of the box + """ + _lib.caca_draw_thin_box.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_draw_thin_box.restype = ctypes.c_int + + return _lib.caca_draw_thin_box(self, x, y, width, height) + + def draw_cp437_box(self, x, y, width, height): + """ Draw a box on the canvas using CP437 characters. + + x -- X coordinate of the upper-left corner box + y -- Y coordinate of the upper-left corner box + width -- width of the box + height -- height of the box + """ + _lib.caca_draw_cp437_box.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int + ] + _lib.caca_draw_cp437_box.restype = ctypes.c_int + + return _lib.caca_draw_cp437_box(self, x, y, width, height) + + def fill_box(self, x, y, width, height, ch): + """ Fill a box on the canvas using the given character. + + x -- X coordinate of the upper-left corner of the box + y -- Y coordinate of the upper-left corner of the box + width -- width of the box + height -- height of the box + ch -- UFT-32 character to be used to fill the box + """ + _lib.caca_fill_box.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_fill_box.restype = ctypes.c_int + + return _lib.caca_fill_box(self, x, y, width, height, ord(ch)) + + def draw_triangle(self, x1, y1, x2, y2, x3, y3, ch): + """ Draw a triangle on the canvas using the given character. + + x1 -- X coordinate of the first point + y1 -- Y coordinate of the first point + x2 -- X coordinate of the second point + y2 -- Y coordinate of the second point + x3 -- X coordinate of the third point + y3 -- Y coordinate of the third point + ch -- UTF-32 character to be used to draw the triangle outline + """ + _lib.caca_draw_triangle.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint32 + ] + _lib.caca_draw_triangle.restype = ctypes.c_int + + return _lib.caca_draw_triangle(self, x1, y1, x2, y2, x3, y3, ord(ch)) + + def draw_thin_triangle(self, x1, y1, x2, y2, x3, y3): + """ Draw a thin triangle on the canvas. + """ + _lib.caca_draw_thin_triangle.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_draw_thin_triangle.restype = ctypes.c_int + + return _lib.caca_draw_thin_triangle(self, x1, y1, x2, y2, x3, y3) + + def fill_triangle(self, x1, y1, x2, y2, x3, y3, ch): + """ Fill a triangle on the canvas using the given character. + + x1 -- X coordinate of the first point + y1 -- Y coordinate of the first point + x2 -- X coordinate of the second point + y2 -- Y coordinate of the second point + x3 -- X coordinate of the second point + y3 -- Y coordinate of the second point + ch -- UTF-32 character to be used to fill the triangle + """ + _lib.caca_fill_triangle.argtypes = [ + _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, + ctypes.c_int, ctypes.c_int, ctypes.c_int + ] + _lib.caca_fill_triangle.restype = ctypes.c_int + + return _lib.caca_fill_triangle(self, x1, y1, x2, y2, x3, y3, ord(ch)) + + def fill_triangle_textured(self, coords, tex, uv): + """ Fill a triangle on the canvas using an arbitrary-sized texture. + + coords -- coordinates of the triangle (3{x,y}) + tex -- the handle of the canvas texture + uv -- coordinates of the texture (3{u,v}) + """ + _lib.caca_fill_triangle_textured.argtypes = [ + _Canvas, ctypes.c_int * 6, _Canvas, ctypes.c_int * 6 + ] + _lib.caca_fill_triangle_textured.restype = ctypes.c_int + + return _lib.caca_fill_triangle_textured(self, coords, tex, uv) + + def get_frame_count(self): + """ Get the number of frames in a canvas. + """ + _lib.caca_get_frame_count.argtypes = [_Canvas] + _lib.caca_get_frame_count.restype = ctypes.c_int + + return _lib.caca_get_frame_count(self) + + def set_frame(self, idx): + """ Activate a given canvas frame. + + idx -- the canvas frame to activate + """ + _lib.caca_set_frame.argtypes = [_Canvas, ctypes.c_int] + _lib.caca_set_frame.restype = ctypes.c_int + + return _lib.caca_set_frame(self, idx) + + def get_frame_name(self): + """ Get the current frame's name. + """ + _lib.caca_get_frame_name.argtypes = [_Canvas] + _lib.caca_get_frame_name.restype = ctypes.c_char_p + + return _lib.caca_get_frame_name(self) + + def set_frame_name(self, name): + """ Set the current frame's name. + + name -- the name to give to the current frame + """ + _lib.caca_set_frame_name.argtypes = [_Canvas, ctypes.c_char_p] + _lib.caca_set_frame_name.restype = ctypes.c_int + + return _lib.caca_set_frame_name(self, name) + + def create_frame(self, idx): + """ Add a frame to a canvas. + + idx -- the index where to insert the new frame + """ + _lib.caca_create_frame.argtypes = [_Canvas, ctypes.c_int] + _lib.caca_create_frame.restype = ctypes.c_int + + return _lib.caca_create_frame(self, idx) + + def free_frame(self, idx): + """ Remove a frame from a canvas. + + idx -- the index of the frame to delete + """ + _lib.caca_free_frame.argtypes = [_Canvas, ctypes.c_int] + _lib.caca_free_frame.restype = ctypes.c_int + + return _lib.caca_free_frame(self, idx) + + def import_from_memory(self, data, length, fmt): + """ Import a memory buffer into the given libcaca canvas's current frame. + The current frame is resized accordingly and its contents are replaced + with the imported data. + + data -- a memory area containing the data to be loaded into the canvas + length -- the size in bytes of the memory area + fmt -- a string describing the input format + """ + + _lib.caca_import_canvas_from_memory.argtypes = [ + Canvas, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p + ] + _lib.caca_import_canvas_from_memory.restype = ctypes.c_int + + return _lib.caca_import_canvas_from_memory(self, data, length, fmt) + +class NullCanvas(_Canvas): + """ Represent a NULL canvas_t, eg to use as canvas mask for blit operations. + """ + def __str__(self): + return "" + +class CanvasError(Exception): + pass + diff --git a/python/caca/common.py b/python/caca/common.py new file mode 100644 index 0000000..d5d77f3 --- /dev/null +++ b/python/caca/common.py @@ -0,0 +1,335 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes + +from caca import _lib + +#color constants +COLOR_BLACK = 0x00 +COLOR_BLUE = 0x01 +COLOR_GREEN = 0x02 +COLOR_CYAN = 0x03 +COLOR_RED = 0x04 +COLOR_MAGENTA = 0x05 +COLOR_BROWN = 0x06 +COLOR_LIGHTGRAY = 0x07 +COLOR_DARKGRAY = 0x08 +COLOR_LIGHTBLUE = 0x09 +COLOR_LIGHTGREEN = 0x0a +COLOR_LIGHTCYAN = 0x0b +COLOR_LIGHTRED = 0x0c +COLOR_LIGHTMAGENTA = 0x0d +COLOR_YELLOW = 0x0e +COLOR_WHITE = 0x0f +COLOR_DEFAULT = 0x10 +COLOR_TRANSPARENT = 0x20 + +#styles constants +STYLE_BOLD = 0x01 +STYLE_ITALICS = 0x02 +STYLE_UNDERLINE = 0x04 +STYLE_BLINK = 0x08 + +#key constants +EVENT_NONE = 0x0000 +EVENT_KEY_PRESS = 0x0001 +EVENT_KEY_RELEASE = 0x0002 +EVENT_MOUSE_PRESS = 0x0004 +EVENT_MOUSE_RELEASE = 0x0008 +EVENT_MOUSE_MOTION = 0x0010 +EVENT_RESIZE = 0x0020 +EVENT_QUIT = 0x0040 +EVENT_ANY = 0xffff + +#event constants +KEY_UNKNOWN = 0x00 +KEY_CTRL_A = 0x01 +KEY_CTRL_B = 0x02 +KEY_CTRL_C = 0x03 +KEY_CTRL_D = 0x04 +KEY_CTRL_E = 0x05 +KEY_CTRL_F = 0x06 +KEY_CTRL_G = 0x07 +KEY_BACKSPACE = 0x08 +KEY_TAB = 0x09 +KEY_CTRL_J = 0x0a +KEY_CTRL_K = 0x0b +KEY_CTRL_L = 0x0c +KEY_RETURN = 0x0d +KEY_CTRL_N = 0x0e +KEY_CTRL_O = 0x0f +KEY_CTRL_P = 0x10 +KEY_CTRL_Q = 0x11 +KEY_CTRL_R = 0x12 +KEY_PAUSE = 0x13 +KEY_CTRL_T = 0x14 +KEY_CTRL_U = 0x15 +KEY_CTRL_V = 0x16 +KEY_CTRL_W = 0x17 +KEY_CTRL_X = 0x18 +KEY_CTRL_Y = 0x19 +KEY_CTRL_Z = 0x1a +KEY_ESCAPE = 0x1b +KEY_DELETE = 0x7f +KEY_UP = 0x111 +KEY_DOWN = 0x112 +KEY_LEFT = 0x113 +KEY_RIGHT = 0x114 +KEY_INSERT = 0x115 +KEY_HOME = 0x116 +KEY_END = 0x117 +KEY_PAGEUP = 0x118 +KEY_PAGEDOWN = 0x119 +KEY_F1 = 0x11a +KEY_F2 = 0x11b +KEY_F3 = 0x11c +KEY_F4 = 0x11d +KEY_F5 = 0x11e +KEY_F6 = 0x11f +KEY_F7 = 0x120 +KEY_F8 = 0x121 +KEY_F9 = 0x122 +KEY_F10 = 0x123 +KEY_F11 = 0x124 +KEY_F12 = 0x125 +KEY_F13 = 0x126 +KEY_F14 = 0x127 +KEY_F15 = 0x128 + + +def get_version(): + """ Return string with libcaca version information. + """ + _lib.caca_get_version.restype = ctypes.c_char_p + + return _lib.caca_get_version() + +def get_display_driver_list(): + """ Return a list of available drivers as tuple (name, description). + """ + tmplst = [] + retlst = [] + + _lib.caca_get_display_driver_list.restype = ctypes.POINTER(ctypes.c_char_p) + + for item in _lib.caca_get_display_driver_list(): + if item is not None and item != "": + tmplst.append(item) + else: + #memory error occured otherwise + break + + for i in xrange(0, len(tmplst)): + if i % 2 == 0: + retlst.append((tmplst[i], tmplst[i+1])) + + del tmplst + return retlst + +def get_export_list(): + """ Return list of available export formats as tuple (name, description). + """ + tmplst = [] + retlst = [] + + _lib.caca_get_export_list.restype = ctypes.POINTER(ctypes.c_char_p) + + for item in _lib.caca_get_export_list(): + if item is not None and item != "": + tmplst.append(item) + else: + #memory error occured otherwise + break + + for i in xrange(0, len(tmplst)): + if i % 2 == 0: + retlst.append((tmplst[i], tmplst[i+1])) + + del tmplst + return retlst + +def get_import_list(): + """ Return list of available import formats as tuple (name, description). + """ + tmplst = [] + retlst = [] + + _lib.caca_get_import_list.restype = ctypes.POINTER(ctypes.c_char_p) + + autodetect = False + for item in _lib.caca_get_import_list(): + if item is not None: + if item == "": + if not autodetect: + tmplst.append("\"\"") + autodetect = True + else: + #memory error occured otherwise + break + else: + tmplst.append(item) + else: + #memory error occured otherwise + break + + for i in xrange(0, len(tmplst)): + if i % 2 == 0: + retlst.append((tmplst[i], tmplst[i+1])) + + del tmplst + return retlst + +def get_font_list(): + """ Return a list of available fonts. + """ + fl = [] + + _lib.caca_get_font_list.restype = ctypes.POINTER(ctypes.c_char_p) + + for item in _lib.caca_get_font_list(): + if item is not None and item != "": + fl.append(item) + else: + #memory error occured otherwise + break + + return fl + +def rand(range_min, range_max): + """ Generate a random integer within a range. + + range_min -- the lower bound of the integer range + range_max __ the upper bound of the integer range + """ + _lib.caca_rand.argtypes = [ctypes.c_int, ctypes.c_int] + _lib.caca_rand.restype = ctypes.c_int + + return _lib.caca_rand(range_min, range_max) + +def attr_to_ansi(attr): + """ Get DOS ANSI information from attribute. + + attr -- the requested attribute value + """ + _lib.caca_attr_to_ansi.argtypes = [ctypes.c_uint32] + _lib.caca_attr_to_ansi.restype = ctypes.c_uint8 + + return _lib.caca_attr_to_ansi(attr) + +def attr_to_ansi_fg(attr): + """ Get ANSI foreground information from attribute. + + attr -- the requested attribute value + """ + _lib.caca_attr_to_ansi_fg.argtypes = [ctypes.c_uint32] + _lib.caca_attr_to_ansi_fg.restype = ctypes.c_uint8 + + return _lib.caca_attr_to_ansi_fg(attr) + +def attr_to_ansi_bg(attr): + """ Get ANSI background information from attribute. + + attr -- the requested attribute value + """ + _lib.caca_attr_to_ansi_bg.argtypes = [ctypes.c_uint32] + _lib.caca_attr_to_ansi_bg.restype = ctypes.c_uint8 + + return _lib.caca_attr_to_ansi_bg(attr) + +def attr_to_rgb12_fg(attr): + """ Get 12-bit RGB foreground information from attribute. + + attr -- the requested attribute value + """ + _lib.caca_attr_to_rgb12_fg.argtypes = [ctypes.c_uint32] + _lib.caca_attr_to_rgb12_fg.restype = ctypes.c_uint16 + + return _lib.caca_attr_to_rgb12_fg(attr) + +def attr_to_rgb12_bg(attr): + """ Get 12-bit RGB background information from attribute. + + attr -- the requested attribute value + """ + _lib.caca_attr_to_rgb12_bg.argtypes = [ctypes.c_uint32] + _lib.caca_attr_to_rgb12_bg.restype = ctypes.c_uint16 + + return _lib.caca_attr_to_rgb12_bg(attr) + +def utf8_to_utf32(ch): + """ Convert a UTF-8 character to UTF-32. + + ch -- the character to convert + """ + _lib.caca_utf8_to_utf32.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_size_t)] + _lib.caca_utf8_to_utf32.restype = ctypes.c_uint32 + + return _lib.caca_utf8_to_utf32(ch, ctypes.c_ulong(0)) + +def utf32_to_utf8(ch): + """ Convert a UTF-32 character to UTF-8. + + ch -- the character to convert + """ + _lib.caca_utf32_to_utf8.argtypes = [ctypes.c_char_p, ctypes.c_uint32] + _lib.caca_utf32_to_utf8.restype = ctypes.c_int + + buf = ctypes.c_buffer(2) + _lib.caca_utf32_to_utf8(buf, ch) + + return buf + +def utf32_to_cp437(ch): + """ Convert a UTF-32 character to CP437. + + ch -- the character to convert + """ + _lib.caca_utf32_to_cp437.argtypes = [ctypes.c_uint32] + _lib.caca_utf32_to_cp437.restype = ctypes.c_uint8 + + return _lib.caca_utf32_to_cp437(ch) + +def cp437_to_utf32(ch): + """ Convert a CP437 character to UTF-32. + + ch -- the character to convert + """ + _lib.caca_cp437_to_utf8.argtypes = [ctypes.c_uint8] + _lib.caca_cp437_to_utf8.restype = ctypes.c_uint32 + + return _lib.caca_cp437_to_utf8(ch) + +def utf32_to_ascii(ch): + """ Convert a UTF-32 character to ASCII. + + ch -- the character to convert + """ + _lib.caca_utf32_to_ascii.argtypes = [ctypes.c_uint32] + _lib.caca_utf32_to_ascii.restype = ctypes.c_uint8 + + return _lib.caca_utf32_to_ascii(ch) + +def utf32_is_fullwidth(ch): + """ Tell whether a UTF-32 character is fullwidth. + + ch -- the UTF-32 character + """ + _lib.caca_utf32_is_fullwidth.argtypes = [ctypes.c_uint32] + _lib.caca_utf32_is_fullwidth.restype = ctypes.c_int + + return _lib.caca_utf32_is_fullwidth(ch) + diff --git a/python/caca/display.py b/python/caca/display.py new file mode 100644 index 0000000..451b40a --- /dev/null +++ b/python/caca/display.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes + +from caca import _lib +from caca.canvas import _Canvas + +class _Display(object): + """ Model for Display objects. + """ + def from_param(self): + """ Required by ctypes module to call object as parameter of + a C function. + """ + return self._dp + + def __str__(self): + return "" + + def __del__(self): + if self._dp > 0: + self._free() + + def _free(self): + """ Free a libcaca display. + """ + _lib.caca_free_display.argtypes = [_Display] + _lib.caca_free_display.restype = ctypes.c_int + + return _lib.caca_free_display(self) + +class Display(_Display): + """ Display objects, methods are libcaca functions with display_t as first + parameter. + """ + def __init__(self, cv, driver=None): + """ Display constructor. + + cv -- canvas to attach. + driver -- caca driver to set with display + """ + + if driver is None: + _lib.caca_create_display.argtypes = [_Canvas] + self._dp = _lib.caca_create_display(cv) + else: + _lib.caca_create_display_with_driver.argtypes = [ + _Canvas, ctypes.c_char_p + ] + self._dp = _lib.caca_create_display_with_driver(cv, driver) + + def get_driver(self): + """ Return the caca graphical context's current output driver. + """ + _lib.caca_get_display_driver.argtypes = [_Display] + _lib.caca_get_display_driver.restype = ctypes.c_char_p + + return _lib.caca_get_display_driver(self) + + def set_driver(self, driver=None): + """ Set the output driver. + + driver -- A string describing the desired output driver or NULL + to choose the best driver automatically. + """ + _lib.caca_set_display_driver.argtypes = [_Display, ctypes.c_char_p] + _lib.caca_set_display_driver.restype = ctypes.c_int + + if not driver: + driver = ctypes.c_char_p(0) + + return _lib.caca_set_display_driver(self, driver) + + def get_canvas(self): + """ Get the canvas attached to a caca graphical context. + """ + _lib.caca_get_canvas.argtypes = [_Display] + + return _lib.caca_get_canvas(self) + + def refresh(self): + """ Flush pending changes and redraw the screen. + """ + _lib.caca_refresh_display.argtypes = [_Display] + _lib.caca_refresh_display.restype = ctypes.c_int + + return _lib.caca_refresh_display(self) + + def set_time(self, usec): + """ Set the refresh delay. + + usec -- the refresh delay in microseconds + """ + _lib.caca_set_display_time.argtypes = [_Display, ctypes.c_int] + _lib.caca_set_display_time.restype = ctypes.c_int + + return _lib.caca_set_display_time(self, usec) + + def get_time(self): + """ Get the display's average rendering time. + """ + _lib.caca_get_display_time.argtypes = [_Display] + _lib.caca_get_display_time.restype = ctypes.c_int + + return _lib.caca_get_display_time(self) + + def set_title(self, title): + """ Set the display title. + + title -- the desired display title + """ + _lib.caca_set_display_title.argtypes = [_Display, ctypes.c_char_p] + _lib.caca_set_display_title.restype = ctypes.c_int + + return _lib.caca_set_display_title(self, title) + + def set_mouse(self, flag): + """ Show or hide the mouse pointer. This function works with the ncurses, + S-Lang and X11 drivers. + + flag -- 0 hides the pointer, 1 shows the system's default pointer (usually an arrow). + """ + _lib.caca_set_mouse.argtypes = [_Display, ctypes.c_int] + _lib.caca_set_mouse.restype = ctypes.c_int + + return _lib.caca_set_mouse(self, flag) + + def set_cursor(self, flag): + """ Show or hide the cursor, for devices that support such a feature. + + flag -- 0 hides the cursor, 1 shows the system's default cursor (usually a white rectangle). + """ + + _lib.caca_set_cursor.argtypes = [Display, ctypes.c_int] + _lib.caca_set_cursor.restype = ctypes.c_int + + return _lib.caca_set_cursor(self, flag) + + def get_event(self, event_mask, event, timeout): + """ Poll the event queue for mouse or keyboard events matching the event mask + and return the first matching event. Non-matching events are discarded. + If event_mask is zero, the function returns immediately. + The timeout value tells how long this function needs to wait for an event. + A value of zero returns immediately and the function returns zero if no more events + are pending in the queue. A negative value causes the function to wait indefinitely + until a matching event is received. + If not null, ev will be filled with information about the event received. If null, + the function will return but no information about the event will be sent. + + event_mask -- bitmask of requested events + event -- a pointer to caca_event structure or NULL + tiemout -- a timeout value in microseconds + """ + + _lib.caca_get_event.argtypes = [Display, ctypes.c_int, ctypes.POINTER(Event), ctypes.c_int] + + return _lib.caca_get_event(self, event_mask, ctypes.byref(event), timeout) + + def get_mouse_x(self): + """ Return the X coordinate of the mouse position last time it was detected. + This function is not reliable if the ncurses or S-Lang drivers are being used, + because mouse position is only detected when the mouse is clicked. + Other drivers such as X11 work well. + """ + + _lib.caca_get_mouse_x.argtypes = [Display] + _lib.caca_get_mouse_x.restype = ctypes.c_int + + return _lib.caca_get_mouse_x(self) + + def get_mouse_y(self): + """ Return the Y coordinate of the mouse position last time it was detected. + This function is not reliable if the ncurses or S-Lang drivers are being used, + because mouse position is only detected when the mouse is clicked. + Other drivers such as X11 work well. + """ + + _lib.caca_get_mouse_y.argtypes = [Display] + _lib.caca_get_mouse_y.restype = ctypes.c_int + + return _lib.caca_get_mouse_y(self) + +class Event(ctypes.Structure): + """ Object to store libcaca event. + """ + _fields_ = ( + ('opaque_structure', ctypes.c_char_p * 32), + ) + + def from_param(self): + """ Required method to pass object as parameter of a C function. + """ + return ctypes.byref(self) + + def get_type(self): + """ Return the type of an event. This function may always be called + on an event after caca_get_event() was called, and its return value + indicates which other functions may be called. + """ + _lib.caca_get_event_type.argtypes = [Event] + _lib.caca_get_event_type.restype = ctypes.c_int + + return _lib.caca_get_event_type(self) + + def get_key_ch(self): + """ Return either the ASCII value for an event's key, or if the key is not + an ASCII character, an appropriate KEY_* value + """ + _lib.caca_get_event_key_ch.argtypes = [Event] + _lib.caca_get_event_key_ch.restype = ctypes.c_int + + return _lib.caca_get_event_key_ch(self) + + def get_key_utf32(self): + """ Return the UTF-32/UCS-4 value for an event's key if it resolves + to a printable character. + """ + _lib.caca_get_event_key_utf32.argtypes = [Event] + _lib.caca_get_event_key_utf32.restype = ctypes.c_uint32 + + return _lib.caca_get_event_key_utf32(self) + + def get_key_utf8(self): + """ Write the UTF-8 value for an event's key if it resolves to a + printable character. Up to 6 UTF-8 bytes and a null termination + are written. + """ + # set buffer for writing utf8 value + buf = ctypes.c_buffer(2) + + _lib.caca_get_event_key_utf8.argtypes = [Event, ctypes.c_char_p] + _lib.caca_get_event_key_utf8.restype = ctypes.c_int + + _lib.caca_get_event_key_utf8(self, buf) + + return buf + diff --git a/python/caca/dither.py b/python/caca/dither.py new file mode 100644 index 0000000..4c06df3 --- /dev/null +++ b/python/caca/dither.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes + +from caca import _lib + +class _Dither(object): + """ Model for Dither object. + """ + def __init__(self): + self._dither = 0 + + def from_param(self): + """ Required by ctypes module to call object as parameter of + a C function. + """ + return self._dither + + def __del__(self): + if self._dither > 0: + self._free() + + def __str__(self): + return "" + + def _free(self): + """ Free a libcaca dither. + """ + _lib.caca_free_font.argtypes = [_Dither] + _lib.caca_free_font.restype = ctypes.c_int + + return _lib.caca_free_font(self) + +class Dither(_Dither): + """ Dither object, methods are libcaca functions with caca_dither_t as first + argument. + """ + def __init__(self, bpp, width, height, pitch, rmask, gmask, bmask, amask): + """ Dither constructor + + bpp -- bitmap depth in bits per pixels + width -- bitmap width in pixels + height -- bitmap height in pixels + pitch -- bitmap pitch in bytes + rmask -- bitmask for red values + gmask -- bitmask for green values + bmask -- bitmask for blue values + amask -- bitmask for alpha values + """ + pass + diff --git a/python/caca/font.py b/python/caca/font.py new file mode 100644 index 0000000..bdeec49 --- /dev/null +++ b/python/caca/font.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes + +from caca import _lib + +class _Font(object): + """ Model for Font object. + """ + def __init__(self): + self._font = 0 + + def from_param(self): + """ Required by ctypes module to call object as parameter of + a C function. + """ + return self._font + + def __del__(self): + if self._font > 0: + self._free() + + def __str__(self): + return "" + + def _free(self): + """ Free a libcaca font. + """ + _lib.caca_free_font.argtypes = [_Font] + _lib.caca_free_font.restype = ctypes.c_int + + return _lib.caca_free_font(self) + +class Font(_Font): + """ Font object, methods are libcaca functions with caca_font_t as first + argument. + """ + def __init__(self, font, size=0): + """ Font constructor + + font -- the memory area containing the font or its name + size -- the size of the memory area, or 0 if the font name is given + """ + pass + diff --git a/python/examples/cacainfo.py b/python/examples/cacainfo.py new file mode 100755 index 0000000..3ecb69d --- /dev/null +++ b/python/examples/cacainfo.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import caca + +if __name__ == '__main__': + print("libcaca version %s" % caca.get_version()) + print("") + print("Available drivers:") + for drv, desc in caca.get_display_driver_list(): + print(" - %s: %s" % (drv, desc)) + print("") + print("Available fonts:") + for font in caca.get_font_list(): + print(" - %s" % font) + print("") + print("Export formats:") + for fmt, desc in caca.get_export_list(): + print(" - %s: %s" % (fmt, desc)) + print("") + print("Import formats:") + for fmt, desc in caca.get_import_list(): + print(" - %s: %s" % (fmt, desc)) diff --git a/python/examples/drawing.py b/python/examples/drawing.py new file mode 100755 index 0000000..829569a --- /dev/null +++ b/python/examples/drawing.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import ctypes +import sys +import time + +import caca +from caca.canvas import Canvas +from caca.display import Display, Event + +class Drawing(object): + def __init__(self, canvas): + self.cv = canvas + + def do_menu(self): + self.cv.put_str(0, 1, "Drawing Menu") + self.cv.put_str(0, 2, "------------") + self.cv.put_str(0, 4, "1) line") + self.cv.put_str(0, 5, "2) thin line") + self.cv.put_str(0, 6, "3) polyline") + self.cv.put_str(0, 7, "4) thin polyline") + self.cv.put_str(0, 8, "5) circle") + self.cv.put_str(0, 9, "6) ellipse") + self.cv.put_str(0, 10, "7) thin ellipse") + self.cv.put_str(0, 11, "8) box") + self.cv.put_str(0, 12, "9) thin box") + + def do_line(self, thin=False): + if thin: + self.cv.draw_thin_line(0, 0, self.cv.get_width(), 1) + else: + self.cv.draw_line(0, 0, self.cv.get_width(), 1, '#') + + def do_polyline(self, thin=False): + x = [0, self.cv.get_width() - 1, self.cv.get_width() - 1] + y = [0, self.cv.get_height(), 0] + array_x = ctypes.c_int * (len(x) + 1) + array_y = ctypes.c_int * (len(y) + 1) + ax = array_x(*x) + ay = array_y(*y) + if thin: + self.cv.draw_thin_polyline(ax, ay, len(x) + 1) + else: + self.cv.draw_polyline(ax, ay, len(x) + 1, '#') + + def do_circle(self): + x = self.cv.get_width() / 2 + y = self.cv.get_height() / 2 + radius = 5 + self.cv.draw_circle(x, y, radius, '@') + + def do_ellipse(self, thin=False): + x = self.cv.get_width() / 2 + y = self.cv.get_height() / 2 + a = 7 + b = 3 + if thin: + self.cv.draw_thin_ellipse(x, y, a, b) + else: + self.cv.draw_ellipse(x, y, a, b, '@') + + def do_box(self, thin=False): + if thin: + self.cv.draw_thin_box(0, 0, self.cv.get_width(), self.cv.get_height()) + else: + self.cv.draw_box(0, 0, self.cv.get_width(), self.cv.get_height(), '#') + +if __name__ == "__main__": + cv = Canvas() + dp = Display(cv) + ev = Event() + draw = Drawing(cv) + + while True: + cv.clear() + draw.do_menu() + dp.refresh() + if dp.get_event(caca.EVENT_KEY_PRESS, ev, 0): + ch = ev.get_key_ch() + cv.clear() + if ch == ord('q'): + sys.exit() + elif ch == ord('1'): + draw.do_line() + elif ch == ord('2'): + draw.do_line(thin=True) + elif ch == ord('3'): + draw.do_polyline() + elif ch == ord('4'): + draw.do_polyline(thin=True) + elif ch == ord('5'): + draw.do_circle() + elif ch == ord('6'): + draw.do_ellipse() + elif ch == ord('7'): + draw.do_ellipse(thin=True) + elif ch == ord('8'): + draw.do_box() + elif ch == ord('9'): + draw.do_box(thin=True) + dp.refresh() + time.sleep(2) + diff --git a/python/examples/gol.py b/python/examples/gol.py new file mode 100755 index 0000000..b07049c --- /dev/null +++ b/python/examples/gol.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# libcaca Colour ASCII-Art library +# Python language bindings +# Copyright (c) 2010 Alex Foulon +# All Rights Reserved +# +# This library is free software. It comes without any warranty, to +# the extent permitted by applicable law. You can redistribute it +# and/or modify it under the terms of the Do What The Fuck You Want +# To Public License, Version 2, as published by Sam Hocevar. See +# http://sam.zoy.org/wtfpl/COPYING for more details. +# + +""" Libcaca Python bindings """ + +import random +import sys +import time + +import caca + +from caca.canvas import Canvas +from caca.display import Display, Event + +class CellArray(object): + def __init__(self, width, height): + self.array = [] + self.width = width + self.height = height + + for i in xrange(0, self.height): + self.array.append([]) + for j in xrange(0, self.width): + self.array[i].append([]) + + def get(self, x, y): + return self.array[x][y] + + def set(self, x, y, value): + self.array[x][y] = value + + def neighbors(self, x, y): + n = 0 + h = self.height + w = self.width + + if self.get((x-1)%h, (y-1)%w): + n += 1 + if self.get((x-1)%h, y): + n += 1 + if self.get((x-1)%h, (y+1)%w): + n += 1 + if self.get(x, (y-1)%w): + n += 1 + if self.get(x, (y+1)%w): + n += 1 + if self.get((x+1)%h, (y-1)%w): + n += 1 + if self.get((x+1)%h, y): + n += 1 + if self.get((x+1)%h, (y+1)%w): + n += 1 + + return n + + def population(self): + n = 0 + + for i in xrange(0, self.height): + for j in xrange(0, self.width): + if self.get(i, j): + n += 1 + + return n + +class CellApp(object): + def __init__(self, width, height): + self.cycle = 0 + self.auto = False + self.width = width + self.height = height + + self.ca = CellArray(self.width, self.height) + self.cbuf = CellArray(self.width, self.height) + + def nextCycle(self): + self.cycle += 1 + for x in xrange(0, self.ca.height): + for y in xrange(0, self.ca.width): + if self.ca.get(x, y): + if self.ca.neighbors(x, y) >= 2 and self.ca.neighbors(x, y) <= 3: + self.cbuf.set(x, y, 1) + else: + self.cbuf.set(x, y, 0) + elif not self.ca.get(x, y): + if self.ca.neighbors(x, y) == 3: + self.cbuf.set(x, y, 1) + else: + self.cbuf.set(x, y, 0) + else: + self.cbuf.set(x, y, 0) + for x in xrange(0, self.ca.height): + for y in xrange(0, self.ca.width): + self.ca.set(x, y, self.cbuf.get(x, y)) + + def resetCycle(self): + self.cycle = 0 + + def randomCells(self): + for x in xrange(0, self.ca.height): + for y in xrange(0, self.ca.width): + self.ca.set(x, y, random.randint(0, 1)) + + def renderCells(self, cv): + cv.clear() + cv.set_color_ansi(caca.COLOR_WHITE, caca.COLOR_BLUE) + cv.put_str(0, 0, " "*cv.get_width()) + cv.put_str(0, 0, "s: start, p: pause, n: next, r: random cells, z: reset all") + cv.put_str(0, cv.get_height()-1, " "*cv.get_width()) + cv.put_str(0, cv.get_height()-1, "generation: %d, population: %d" % (self.cycle, self.ca.population())) + cv.set_color_ansi(caca.COLOR_DEFAULT, caca.COLOR_BLACK) + posx = (cv.get_height() - self.height) / 2 + posy = (cv.get_width() - self.width) / 2 + for x in xrange(0, self.ca.height): + for y in xrange(0, self.ca.width): + if self.ca.get(x, y): + cv.put_str(posy+y, posx+x, '@') + + def zeroCells(self): + for x in xrange(0, self.ca.height): + for y in xrange(0, self.ca.width): + self.ca.set(x, y, 0) + +if __name__ == "__main__": + cv = Canvas() + dp = Display(cv) + ev = Event() + + app = CellApp(80, 20) + app.zeroCells() + + while True: + if dp.get_event(caca.EVENT_KEY_PRESS, ev, 2): + ch = ev.get_key_ch() + if ch == ord('q'): + break + elif ch == ord('s'): + app.auto = True + elif ch == ord('n'): + app.nextCycle() + elif ch == ord('r'): + app.randomCells() + elif ch == ord('p'): + if app.auto: + app.auto = False + else: + app.auto = True + elif ch == ord('z'): + app.resetCycle() + app.zeroCells() + app.auto = False + + if app.auto: + app.nextCycle() + + app.renderCells(cv) + dp.refresh() + time.sleep(0.2) + diff --git a/python/pypycaca.c b/python/pypycaca.c deleted file mode 100644 index d213464..0000000 --- a/python/pypycaca.c +++ /dev/null @@ -1,860 +0,0 @@ -/* - * PypyCaca libcaca Python bindings - * Copyright (c) 2006 Jean-Yves Lamoureux - * All Rights Reserved - * - * This library is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -#include "pypycaca.h" - -static PyMethodDef CacaMethods[] = { - {"init", pycaca_init, METH_VARARGS, "Init libcaca"}, - {"set_display_time", pycaca_set_display_time, METH_VARARGS, "Set display time"}, - {"get_display_time", pycaca_get_display_time, METH_NOARGS, "Get render time"}, - {"get_width", pycaca_get_width, METH_NOARGS, "Get width"}, - {"get_height", pycaca_get_height, METH_NOARGS, "Get Height"}, - {"set_size", pycaca_set_size, METH_VARARGS, "Set size"}, - {"set_width", pycaca_set_width, METH_VARARGS, "Set width"}, - {"set_height", pycaca_set_height, METH_VARARGS, "Set height"}, - {"set_display_title", pycaca_set_display_title, METH_VARARGS, "Set window titl"}, - {"get_display_width", pycaca_get_display_width, METH_NOARGS, "Get window width"}, - {"get_display_height", pycaca_get_display_height, METH_NOARGS, "Get Window height"}, - {"refresh", pycaca_refresh, METH_NOARGS, "Refresh window"}, - {"end", pycaca_end, METH_NOARGS, "End libcaca"}, - {"get_feature", pycaca_get_feature, METH_VARARGS, "Get feature"}, - {"set_feature", pycaca_set_feature, METH_VARARGS, "Set feature"}, - {"get_feature_name", pycaca_get_feature_name, METH_VARARGS, "Get feature name"}, - - {"get_event", pycaca_get_event, METH_VARARGS, "Get event"}, - {"wait_event", pycaca_wait_event, METH_VARARGS, "Wait event"}, - {"get_mouse_x", pycaca_get_mouse_x, METH_NOARGS, "Get Mouse X"}, - {"get_mouse_y", pycaca_get_mouse_y, METH_NOARGS, "Get mouse Y"}, - {"draw_line", pycaca_draw_line, METH_VARARGS, "Init libcaca"}, - {"draw_thin_line", pycaca_draw_thin_line, METH_VARARGS, "Init libcaca"}, - {"draw_circle", pycaca_draw_circle, METH_VARARGS, "Init libcaca"}, - {"draw_ellipse", pycaca_draw_ellipse, METH_VARARGS, "Init libcaca"}, - {"draw_thin_ellipse", pycaca_draw_thin_ellipse, METH_VARARGS, "Init libcaca"}, - {"fill_ellipse", pycaca_fill_ellipse, METH_VARARGS, "Init libcaca"}, - {"draw_box", pycaca_draw_box, METH_VARARGS, "Init libcaca"}, - {"fill_box", pycaca_fill_box, METH_VARARGS, "Init libcaca"}, - {"draw_thin_box", pycaca_draw_thin_box, METH_VARARGS, "Init libcaca"}, - {"draw_triangle", pycaca_draw_triangle, METH_VARARGS, "Init libcaca"}, - {"draw_thin_triangle", pycaca_draw_thin_triangle, METH_VARARGS, "Init libcaca"}, - {"fill_triangle", pycaca_fill_triangle, METH_VARARGS, "Init libcaca"}, - {"draw_polyline", pycaca_draw_polyline, METH_VARARGS, ""}, - {"draw_thin_polyline", pycaca_draw_thin_polyline, METH_VARARGS, ""}, - - {"set_color", pycaca_set_color, METH_VARARGS, "Init libcaca"}, - {"get_fg_color", pycaca_get_fg_color, METH_VARARGS, ""}, - {"get_bg_color", pycaca_get_bg_color, METH_VARARGS, ""}, - {"get_color_name", pycaca_get_color_name, METH_VARARGS, ""}, - {"putchar", pycaca_putchar, METH_VARARGS, ""}, - {"putstr", pycaca_putstr, METH_VARARGS, ""}, - {"printf", pycaca_printf, METH_VARARGS, ""}, - {"clear", pycaca_clear, METH_VARARGS, ""}, - - {"load_sprite", pycaca_load_sprite, METH_VARARGS, ""}, - {"draw_sprite", pycaca_draw_sprite, METH_VARARGS, ""}, - {"get_sprite_frames", pycaca_get_sprite_frames, METH_VARARGS, ""}, - {"get_sprite_width", pycaca_get_sprite_width, METH_VARARGS, ""}, - {"get_sprite_height", pycaca_get_sprite_height, METH_VARARGS, ""}, - {"get_sprite_dx", pycaca_get_sprite_dx, METH_VARARGS, ""}, - {"get_sprite_dy", pycaca_get_sprite_dy, METH_VARARGS, ""}, - {"free_sprite", pycaca_free_sprite, METH_VARARGS, ""}, - - {"get_html", pycaca_get_html, METH_VARARGS, ""}, - {"get_html3", pycaca_get_html3, METH_VARARGS, ""}, - {"get_irc", pycaca_get_irc, METH_VARARGS, ""}, - {"get_ansi", pycaca_get_ansi, METH_VARARGS, ""}, - - {"create_bitmap", pycaca_create_bitmap, METH_VARARGS, ""}, - {"set_bitmap_palette", pycaca_set_bitmap_palette, METH_VARARGS, ""}, - {"set_bitmap_gamma", pycaca_set_bitmap_gamma, METH_VARARGS, ""}, - {"draw_bitmap", pycaca_draw_bitmap, METH_VARARGS, ""}, - {"free_bitmap", pycaca_free_bitmap, METH_VARARGS, ""}, - - - - - // {"", , METH_VARARGS, ""}, - - - - - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC -initcaca(void) -{ - PyObject *obj, *dict; - - obj = Py_InitModule("caca", CacaMethods); - dict = PyModule_GetDict(obj); - - SET_INTCONSTANT(dict,CACA_EVENT_NONE ); - SET_INTCONSTANT(dict,CACA_EVENT_KEY_PRESS ); - SET_INTCONSTANT(dict,CACA_EVENT_KEY_RELEASE ); - SET_INTCONSTANT(dict,CACA_EVENT_MOUSE_PRESS ); - SET_INTCONSTANT(dict,CACA_EVENT_MOUSE_RELEASE ); - SET_INTCONSTANT(dict,CACA_EVENT_MOUSE_MOTION ); - SET_INTCONSTANT(dict,CACA_EVENT_RESIZE ); - SET_INTCONSTANT(dict,CACA_EVENT_ANY ); - - SET_INTCONSTANT(dict, CACA_COLOR_BLACK ); - SET_INTCONSTANT(dict, CACA_COLOR_BLUE ); - SET_INTCONSTANT(dict, CACA_COLOR_GREEN ); - SET_INTCONSTANT(dict, CACA_COLOR_CYAN ); - SET_INTCONSTANT(dict, CACA_COLOR_RED ); - SET_INTCONSTANT(dict, CACA_COLOR_MAGENTA ); - SET_INTCONSTANT(dict, CACA_COLOR_BROWN ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTGRAY ); - SET_INTCONSTANT(dict, CACA_COLOR_DARKGRAY ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTBLUE ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTGREEN ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTCYAN ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTRED ); - SET_INTCONSTANT(dict, CACA_COLOR_LIGHTMAGENTA ); - SET_INTCONSTANT(dict, CACA_COLOR_YELLOW ); - SET_INTCONSTANT(dict, CACA_COLOR_WHITE ); - - SET_INTCONSTANT(dict, CACA_BACKGROUND ); - SET_INTCONSTANT(dict, CACA_BACKGROUND_BLACK ); - SET_INTCONSTANT(dict, CACA_BACKGROUND_SOLID ); - SET_INTCONSTANT(dict, CACA_BACKGROUND_MIN ); - SET_INTCONSTANT(dict, CACA_BACKGROUND_MAX ); - SET_INTCONSTANT(dict, CACA_ANTIALIASING ); - SET_INTCONSTANT(dict, CACA_ANTIALIASING_NONE ); - SET_INTCONSTANT(dict, CACA_ANTIALIASING_PREFILTER ); - SET_INTCONSTANT(dict, CACA_ANTIALIASING_MIN ); - SET_INTCONSTANT(dict, CACA_ANTIALIASING_MAX ); - SET_INTCONSTANT(dict, CACA_DITHERING ); - SET_INTCONSTANT(dict, CACA_DITHERING_NONE ); - SET_INTCONSTANT(dict, CACA_DITHERING_ORDERED2 ); - SET_INTCONSTANT(dict, CACA_DITHERING_ORDERED4 ); - SET_INTCONSTANT(dict, CACA_DITHERING_ORDERED8 ); - SET_INTCONSTANT(dict, CACA_DITHERING_RANDOM ); - SET_INTCONSTANT(dict, CACA_DITHERING_FSTEIN ); - SET_INTCONSTANT(dict, CACA_DITHERING_MIN ); - SET_INTCONSTANT(dict, CACA_DITHERING_MAX ); - SET_INTCONSTANT(dict, CACA_FEATURE_UNKNOWN ); - - SET_INTCONSTANT(dict, CACA_KEY_UNKNOWN ); - SET_INTCONSTANT(dict, CACA_KEY_BACKSPACE ); - SET_INTCONSTANT(dict, CACA_KEY_TAB ); - SET_INTCONSTANT(dict, CACA_KEY_RETURN ); - SET_INTCONSTANT(dict, CACA_KEY_PAUSE ); - SET_INTCONSTANT(dict, CACA_KEY_ESCAPE ); - SET_INTCONSTANT(dict, CACA_KEY_DELETE ); - SET_INTCONSTANT(dict, CACA_KEY_UP ); - SET_INTCONSTANT(dict, CACA_KEY_DOWN ); - SET_INTCONSTANT(dict, CACA_KEY_LEFT ); - SET_INTCONSTANT(dict, CACA_KEY_RIGHT ); - SET_INTCONSTANT(dict, CACA_KEY_INSERT ); - SET_INTCONSTANT(dict, CACA_KEY_HOME ); - SET_INTCONSTANT(dict, CACA_KEY_END ); - SET_INTCONSTANT(dict, CACA_KEY_PAGEUP ); - SET_INTCONSTANT(dict, CACA_KEY_PAGEDOWN ); - SET_INTCONSTANT(dict, CACA_KEY_F1 ); - SET_INTCONSTANT(dict, CACA_KEY_F2 ); - SET_INTCONSTANT(dict, CACA_KEY_F3 ); - SET_INTCONSTANT(dict, CACA_KEY_F4 ); - SET_INTCONSTANT(dict, CACA_KEY_F5 ); - SET_INTCONSTANT(dict, CACA_KEY_F6 ); - SET_INTCONSTANT(dict, CACA_KEY_F7 ); - SET_INTCONSTANT(dict, CACA_KEY_F8 ); - SET_INTCONSTANT(dict, CACA_KEY_F9 ); - SET_INTCONSTANT(dict, CACA_KEY_F10 ); - SET_INTCONSTANT(dict, CACA_KEY_F11 ); - SET_INTCONSTANT(dict, CACA_KEY_F12 ); - SET_INTCONSTANT(dict, CACA_KEY_F13 ); - SET_INTCONSTANT(dict, CACA_KEY_F14 ); - SET_INTCONSTANT(dict, CACA_KEY_F15 ); - - - - -} - - -/*******************/ -/* Basic functions */ -/*******************/ -static PyObject * -pycaca_init(PyObject *self, PyObject *args) -{ - int ret; - - ret = caca_init(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_set_display_time(PyObject *self, PyObject *args) -{ - int value=0; - if (!PyArg_ParseTuple(args, "i", &value)) - caca_set_display_time(value); - return Py_BuildValue("i", 1); /*FIXME*/ -} - -static PyObject * -pycaca_get_display_time(PyObject *self, PyObject *args) -{ - int ret = caca_get_display_time(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_get_width(PyObject *self, PyObject *args) -{ - int ret = caca_get_width(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_get_height(PyObject *self, PyObject *args) -{ - int ret = caca_get_height(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_set_size(PyObject *self, PyObject *args) -{ - int width, height; - if (!PyArg_ParseTuple(args, "ii", &width, &height)) - caca_set_size(width, height); - return Py_BuildValue("i", 1); /* FIXME */ -} - -static PyObject * -pycaca_set_width(PyObject *self, PyObject *args) -{ - int width; - - if (!PyArg_ParseTuple(args, "i", &width)); - caca_set_width(width); - - return Py_BuildValue("i", 1); /* FIXME */ -} - -static PyObject * -pycaca_set_height(PyObject *self, PyObject *args) -{ - int height; - if (!PyArg_ParseTuple(args, "i", &height)); - caca_set_height(height); - return Py_BuildValue("i", 1); /* FIXME */ -} - -static PyObject * -pycaca_set_display_title(PyObject *self, PyObject *args) -{ - int ret; - const char *str; - if (!PyArg_ParseTuple(args, "s", &str)); - ret = caca_set_display_title(str); - return Py_BuildValue("i", ret); /* FIXME */ -} - -static PyObject * -pycaca_get_display_width(PyObject *self, PyObject *args) -{ - int ret = caca_get_display_width(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_get_display_height(PyObject *self, PyObject *args) -{ - int ret = caca_get_display_height(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_refresh(PyObject *self, PyObject *args) -{ - caca_refresh(); - return Py_BuildValue("i", 1); /*FIXME*/ -} - -static PyObject * -pycaca_end(PyObject *self, PyObject *args) -{ - caca_end(); - return Py_BuildValue("i", 1); /*FIXME*/ -} - - -static PyObject * -pycaca_get_feature(PyObject *self, PyObject *args) -{ - int value, ret; - if (!PyArg_ParseTuple(args, "i", &value)); - ret = caca_get_feature(value); - - return Py_BuildValue("i", ret); - -} - -static PyObject * -pycaca_set_feature(PyObject *self, PyObject *args) -{ - int value; - if (!PyArg_ParseTuple(args, "i", &value)); - caca_set_feature(value); - - return Py_BuildValue("i", 1); /* FIXME */ - -} -static PyObject * -pycaca_get_feature_name(PyObject *self, PyObject *args) -{ - int value; - char* ret; - if (!PyArg_ParseTuple(args, "i", &value)); - - ret = (char* const)caca_get_feature_name(value); - - return Py_BuildValue("s", ret); -} - -/******************/ -/* Event handling */ -/******************/ -static PyObject * -pycaca_get_event(PyObject *self, PyObject *args) -{ - int value, ret; - if (!PyArg_ParseTuple(args, "i", &value)); - - ret = caca_get_event(value); - - return Py_BuildValue("i", ret); -} -static PyObject * -pycaca_wait_event(PyObject *self, PyObject *args) -{ - int value, ret; - if (!PyArg_ParseTuple(args, "i", &value)); - - ret = caca_get_event(value); - - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_get_mouse_x(PyObject *self, PyObject *args) -{ - int ret = caca_get_mouse_x(); - return Py_BuildValue("i", ret); -} - -static PyObject * -pycaca_get_mouse_y(PyObject *self, PyObject *args) -{ - int ret = caca_get_mouse_y(); - return Py_BuildValue("i", ret); -} - -/**********************/ -/* Primitives drawing */ -/**********************/ -static PyObject * -pycaca_draw_line(PyObject *self, PyObject *args) -{ - int x1, y1, x2, y2; - char c; - - if (!PyArg_ParseTuple(args, "iiiic", &x1,&y1,&x2,&y2,&c)); - caca_draw_line(x1,y1,x2,y2,c); - return Py_BuildValue("i", 1); /* FIXME */ -} -static PyObject * -pycaca_draw_polyline(PyObject *self, PyObject *args) -{ - PyObject *list_x, *list_y, *item; - int *x, *y, n, lenx, leny, i; - char c; - - if (!PyArg_ParseTuple(args, "OOic", &list_x, &list_y, &n, &c)); - - lenx = PySequence_Length(list_x); - leny = PySequence_Length(list_y); - - x = (int*) malloc(lenx*sizeof(int)); - y = (int*) malloc(leny*sizeof(int)); - - if((x == NULL) || (y==NULL)) - return NULL; /* FIXME */ - - for(i=0;i - * All Rights Reserved - * - * This library is free software. It comes without any warranty, to - * the extent permitted by applicable law. You can redistribute it - * and/or modify it under the terms of the Do What The Fuck You Want - * To Public License, Version 2, as published by Sam Hocevar. See - * http://sam.zoy.org/wtfpl/COPYING for more details. - */ - -#include -#include -#define SET_INTCONSTANT(dict, value) \ - PyDict_SetItemString(dict, #value, PyInt_FromLong((long) value)) - - -PyMODINIT_FUNC initcaca(void); - -/* Basic functions */ - -static PyObject * -pycaca_init(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_display_time(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_display_time(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_width(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_height(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_size(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_width(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_height(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_display_title(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_display_width(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_display_height(PyObject *self, PyObject *args); -static PyObject * -pycaca_refresh(PyObject *self, PyObject *args); -static PyObject * -pycaca_end(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_feature(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_feature(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_feature_name(PyObject *self, PyObject *args); - -/* Event handling */ -static PyObject * -pycaca_get_event(PyObject *self, PyObject *args); -static PyObject * -pycaca_wait_event(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_mouse_x(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_mouse_y(PyObject *self, PyObject *args); - - -/* Primitives drawing */ -static PyObject * -pycaca_draw_line(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_polyline(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_thin_polyline(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_thin_line(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_circle(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_ellipse(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_thin_ellipse(PyObject *self, PyObject *args); -static PyObject * -pycaca_fill_ellipse(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_box(PyObject *self, PyObject *args); -static PyObject * -pycaca_fill_box(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_thin_box(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_triangle(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_thin_triangle(PyObject *self, PyObject *args); -static PyObject * -pycaca_fill_triangle(PyObject *self, PyObject *args); - -/* Charactere drawing */ -static PyObject * -pycaca_set_color(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_fg_color(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_bg_color(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_color_name(PyObject *self, PyObject *args); -static PyObject * -pycaca_putchar(PyObject *self, PyObject *args); -static PyObject * -pycaca_putstr(PyObject *self, PyObject *args); -static PyObject * -pycaca_printf(PyObject *self, PyObject *args); -/*static PyObject * -pycaca_get_screen(PyObject *self, PyObject *args);*/ - static PyObject * -pycaca_clear(PyObject *self, PyObject *args); - - -/* Sprites functions */ -static PyObject * -pycaca_load_sprite(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_sprite(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_sprite_frames(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_sprite_width(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_sprite_height(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_sprite_dx(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_sprite_dy(PyObject *self, PyObject *args); -static PyObject * -pycaca_free_sprite(PyObject *self, PyObject *args); - - - -/* Exporters */ -static PyObject * -pycaca_get_html(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_html3(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_irc(PyObject *self, PyObject *args); -static PyObject * -pycaca_get_ansi(PyObject *self, PyObject *args); - - -/* Bitmap functions */ -static PyObject * -pycaca_create_bitmap(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_bitmap_palette(PyObject *self, PyObject *args); -static PyObject * -pycaca_set_bitmap_gamma(PyObject *self, PyObject *args); -static PyObject * -pycaca_draw_bitmap(PyObject *self, PyObject *args); -static PyObject * -pycaca_free_bitmap(PyObject *self, PyObject *args); diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..9a83072 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +from setuptools import setup + +setup( + name='caca', + version='0.0', + packages=['caca'], + package_dir={ + 'caca': 'caca', + }, +) diff --git a/python/snake.py b/python/snake.py deleted file mode 100755 index 15bb390..0000000 --- a/python/snake.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python -# -# snake.py -# Playing with ctypes and libcaca -# http://mornie.org/blog/2007/03/25/Playng-with-ctypes-and-libcaca/ -# -# Copyright (C) 2007 Daniele Tricoli aka Eriol -# -# This program 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. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# -- Changelog -# * 23/03/07 -# Initial release -# * 20/10/07 -# Applied patch by Sam Hocevar: check for caca_get_event's return value -# and added caca_event's missing first member -# * 25/10/07 -# Updated for newer libcaca API (Sam Hocevar) - -import ctypes as C -import random -import sys -import time - -CANVAS_WIDTH = 80 -CANVAS_HEIGHT = 40 - -CENTER_X = CANVAS_WIDTH / 2 -CENTER_Y = CANVAS_HEIGHT / 2 - -UP = 273 -DOWN = 274 -LEFT = 275 -RIGHT = 276 - -class ev(C.Structure): - _fields_ = [('opaque_structure', C.c_char_p * 32)] - -class Snake(object): - - def __init__(self, center_point, length): - - self.head = center_point - self.body = [] - - for y in xrange(self.head[1] + 1, self.head[1] + length + 1): - self.body.append((self.head[0], y)) - - def move(self, direction): - - phead = tuple(self.head) - - if direction == 'UP': - self.head[1] -=1 - elif direction == 'DOWN': - self.head[1] +=1 - elif direction == 'LEFT': - self.head[0] -=1 - elif direction == 'RIGHT': - self.head[0] +=1 - - self.body = [phead] + self.body[:-1] - - def grow(self): - self.body += [tuple(self.head)] * 2 - - def draw(self): - global cv - lcaca.caca_set_color_ansi(cv, 0x05, 0x00) - - for p in self.body: - lcaca.caca_put_char(cv, p[0], p[1], ord('o')) - lcaca.caca_set_color_ansi(cv, 0x02, 0x00) - lcaca.caca_put_char(cv, self.head[0], self.head[1], ord('@')) - lcaca.caca_refresh_display(dp) - -class Target(object): - - def __init__(self): - self.total = 0 - - def random(self, width, height): - self.x = int(random.uniform(1, width)) - self.y = int(random.uniform(1, height)) - self.value = random.choice(range(1,10)) - - def sum(self): - self.total += self.value - - def draw(self): - global cv - lcaca.caca_set_color_ansi(cv, 0x03, 0x00) - lcaca.caca_put_char(cv, self.x, self.y, ord(str(self.value))) - lcaca.caca_refresh_display(dp) - -def draw_border(): - lcaca.caca_set_color_ansi(cv, 0x04, 0x00) - lcaca.caca_draw_box(cv, - 0, - 0, - CANVAS_WIDTH - 1, - CANVAS_HEIGHT - 1, - ord('#')) - -event = ev() -lcaca = C.cdll.LoadLibrary('libcaca.so.0') -cv = lcaca.caca_create_canvas(CANVAS_WIDTH, CANVAS_HEIGHT) -dp = lcaca.caca_create_display(cv) -lcaca.caca_set_display_title(dp, "snake.py - playing with ctypes and libcaca") - -s = Snake([CENTER_X, CENTER_Y], 5) -t = Target() -t.random(CANVAS_WIDTH - 2, CANVAS_HEIGHT - 2) - -draw_border() -s.draw() -t.draw() - -lcaca.caca_get_event(dp, 0x0001, C.byref(event), -1) - -while True: - while lcaca.caca_get_event(dp, 0x0001, C.byref(event), 0): - ch = lcaca.caca_get_event_key_ch(C.byref(event)) - if ch == 113: # 'q' pressed - sys.exit() - elif ch == UP: - d = 'UP' - elif ch == DOWN: - d = 'DOWN' - elif ch == LEFT: - d = 'LEFT' - elif ch == RIGHT: - d = 'RIGHT' - - try: - s.move(d) - except NameError: - pass - - if (tuple(s.head) in s.body[1:] or - not 0 < s.head[0] < CANVAS_WIDTH - 1 or - not 0 < s.head[1] < CANVAS_HEIGHT - 1): - print 'Game Over!' - print 'Total score:', t.total - sys.exit() - elif tuple(s.head) == (t.x, t.y): - t.sum() - t.random(CANVAS_WIDTH - 2, CANVAS_HEIGHT - 2) - s.grow() - - lcaca.caca_clear_canvas(cv) - draw_border() - s.draw() - t.draw() - time.sleep(0.1) diff --git a/python/test1.py b/python/test1.py deleted file mode 100755 index e348334..0000000 --- a/python/test1.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/python2.4 - -import caca -import math -from random import Random -from math import * - - -ret = caca.init() -print "caca.init() returned ", ret -print "Window size is ",caca.get_window_width(),"x",caca.get_window_height() -print "Buffer size is ",caca.get_width(),"x",caca.get_height() - -caca.set_size(80,25) -print "Buffer size is now",caca.get_width(),"x",caca.get_height() - - -print "Feature name for CACA_DITHERING_FSTEIN is "+caca.get_feature_name(caca.CACA_DITHERING_FSTEIN) - - -sprite = int(caca.load_sprite("./caca.txt")) - - -rand = Random() - -i = 0 -while caca.get_event(caca.CACA_EVENT_KEY_PRESS) != caca.CACA_EVENT_KEY_PRESS|caca.CACA_KEY_ESCAPE: - - - i=i+1; - - caca.clear(); - - caca.set_color(caca.CACA_COLOR_YELLOW, caca.CACA_COLOR_BLACK); - xo = caca.get_width() / 4; - yo = caca.get_height() / 4 + 5 * sin(0.03*i); - - for j in range(0,16): - xa = xo - (30 + sin(0.03*i) * 8) * sin(0.03*i + 3.1415*j/8); - ya = yo + (15 + sin(0.03*i) * 4) * cos(0.03*i + 3.1415*j/8); - caca.draw_thin_line(int(xo), int(yo), int(xa), int(ya)); - - j = 15 + sin(0.03*i) * 8; - caca.set_color(caca.CACA_COLOR_WHITE, caca.CACA_COLOR_BLACK); - caca.fill_ellipse(int(xo), int(yo), int(j), int(j / 2), '#'); - caca.set_color(caca.CACA_COLOR_YELLOW, caca.CACA_COLOR_BLACK); - caca.draw_ellipse(xo, yo, j, j / 2, '0'); - - xo = caca.get_width() * 5 / 8; - yo = 2; - - xa = caca.get_width() / 8 + sin(0.03*i) * 5; - ya = caca.get_height() / 2 + cos(0.03*i) * 5; - - xb = caca.get_width() - 10 - cos(0.02*i) * 10; - yb = caca.get_height() * 3 / 4 - 5 + sin(0.02*i) * 5; - - xc = caca.get_width() / 4 - sin(0.02*i) * 5; - yc = caca.get_height() * 3 / 4 + cos(0.02*i) * 5; - - caca.set_color(caca.CACA_COLOR_GREEN, caca.CACA_COLOR_BLACK); - caca.fill_triangle(xo, yo, xb, yb, xa, ya, '%'); - caca.set_color(caca.CACA_COLOR_YELLOW, caca.CACA_COLOR_BLACK); - caca.draw_thin_triangle(xo, yo, xb, yb, xa, ya); - - caca.set_color(caca.CACA_COLOR_RED, caca.CACA_COLOR_BLACK); - caca.fill_triangle(xa, ya, xb, yb, xc, yc, ' '); - caca.set_color(caca.CACA_COLOR_YELLOW, caca.CACA_COLOR_BLACK); - caca.draw_thin_triangle(xa, ya, xb, yb, xc, yc); - - caca.set_color(caca.CACA_COLOR_BLUE, caca.CACA_COLOR_BLACK); - caca.fill_triangle(xo, yo, xb, yb, xc, yc, '%'); - caca.set_color(caca.CACA_COLOR_YELLOW, caca.CACA_COLOR_BLACK); - caca.draw_thin_triangle(xo, yo, xb, yb, xc, yc); - - xa = 2; - ya = 2; - - xb = caca.get_width() - 3; - yb = caca.get_height() / 2; - - xc = caca.get_width() / 3; - yc = caca.get_height() - 3; - - caca.set_color(caca.CACA_COLOR_CYAN, caca.CACA_COLOR_BLACK); - caca.draw_thin_triangle(xa, ya, xb, yb, xc, yc); - - xo = caca.get_width() / 2 + cos(0.027*i) * caca.get_width() / 3; - yo = caca.get_height() / 2 - sin(0.027*i) * caca.get_height() / 2; - - caca.draw_thin_line(xa, ya, xo, yo); - caca.draw_thin_line(xb, yb, xo, yo); - caca.draw_thin_line(xc, yc, xo, yo); - - caca.draw_sprite(xo, yo, sprite, 0); - - for j in range(i - 60, i): - delta = (rand.random()*10)-5; - caca.set_color(rand.random()*15, rand.random()*15); - caca.putchar(caca.get_width() / 2 - + cos(0.02*j) * (delta + caca.get_width() / 4), - caca.get_height() / 2 - + sin(0.02*j) * (delta + caca.get_height() / 3), - ' '); - caca.draw_sprite(caca.get_width() / 2 + cos(0.02*i) * caca.get_width() / 4, - caca.get_height() / 2 + sin(0.02*i) * caca.get_height() / 3, - int(sprite), int(0)); - - - - caca.refresh(); - - -caca.end() diff --git a/python/test2.py b/python/test2.py deleted file mode 100755 index 1bcbafe..0000000 --- a/python/test2.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python2.3 - -import caca -import math -from random import Random -from math import * -import Numeric as N - -ret = caca.init() - -r = N.zeros(256) -g = N.zeros(256) -b = N.zeros(256) -a = N.zeros(256) - -rand = Random() - -# Our pixel array -pixels = N.zeros(32*32*4) -#pixels = pixelst.tolist() - -for i in range(0,256): - r[i] = i - g[i] = i - b[i] = i - a[i] = 128 - - -bitmap = caca.create_bitmap(32,32,32,32*4,0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000) -#caca.set_bitmap_palette(bitmap, r, g, b, a) - - -color = 0 - -while caca.get_event(caca.CACA_EVENT_KEY_PRESS) != caca.CACA_EVENT_KEY_PRESS|caca.CACA_KEY_ESCAPE: - - for y in range(0,32): - for x in range(0,(32*4), 4): - offset = x + y * (32*4) - pixels[offset] = rand.random()*256 - pixels[offset+1] = rand.random()*256 - pixels[offset+2] = rand.random()*256 - pixels[offset+3] = 128 - - - - color = color + 1 - - caca.draw_bitmap(0,0,caca.get_width() - 1, caca.get_height() - 1, - bitmap, pixels) - - caca.refresh(); - - - -caca.end();