Регистрация | Войти
Lisp — программируемый язык программирования
RSS
Интерфейсы к GTK3 и DBF
Monk - 09.05.2012 11:19, Сообщений - 26
На правах рекламы:

GTK-CFFI: http://common-lisp.net/project/gtk-cffi/
Интерфейс к GTK3. Сделан с целью обеспечить на Лиспе не меньше возможностей, чем доступно на Си, но не заставлять вручную вызывать очистку памяти. Доступ к свойствам (properties) сделан автоматический, так как GObject позволяет запросить список свойств и их типы у класса. Добавлено несколько аксессоров к GtkWidget, которые зачем-то в GTK3 вынесли в GtkStyleContext: цвет, фоновое изображение, шрифт. Есть интеграция с cl-cairo2.

http://common-lisp.net/project/cffi-objects/
Набор типов для CFFI: структуры и объекты. Для структур есть возможность хранить как указатель на Си-структуру (с автоматическим вызовом free, если структура собрана сборщиком мусора), так и просто данные, содержащиеся в Си-Структуре (и не зависеть от того, что та может быть очищена). Поддерживается указание владения объектом (кто должен освобождать память: вызывающая или вызываемая функция).

http://common-lisp.net/project/cl-table/
Структура, позволяющая хранить иерархический упорядоченный набор строк. Используется в GTK-CFFI в качестве альтернативного хранилища для GtkTreeModel, если необходима иерархия. Обеспечивает O(1) поиск по итератору (GtkTreeIter) и O(уровень вложенности) поиск по пути (GtkTreePath).

http://common-lisp.net/project/cl-dbf/
Библиотека доступа к файлам DBF. Имеется графический интерфейс, построенный на этой библиотеке: http://common-lisp.net/viewvc/cl-dbf/cl-dbf/dbfview/
[#]
gtk-cffi в quicklisp'е есть?
michael.filonenko - 09.05.2012 12:54
[#] Ответ на комментарий от michael.filonenko 09.05.2012 12:54
Да. На https://github.com/quicklisp/quicklisp-projects -- двухмесячной давности.
Monk - 09.05.2012 13:10
[#]
g-lib-cffi -- это оно?
andy128k - 09.05.2012 13:32
[#] Ответ на комментарий от Monk 09.05.2012 13:10
Отбагрепортил тот факт, что не все asdf системы представлены в quicklispe.
michael.filonenko - 09.05.2012 13:57
[#] Ответ на комментарий от michael.filonenko 09.05.2012 13:57
http://www.quicklisp.org/beta/releases.html -- если это весь список библиотек в quicklisp, то туда надо ещё как-то cl-table, от него gtk-cffi-ext зависит.
Monk - 09.05.2012 14:32
[#] Ответ на комментарий от andy128k 09.05.2012 13:32
g-lib-cffi -- оно, только там ещё должны быть, как минимум, ещё g-object-cffi,gdk-cffi,gtk-cffi
gtk-cffi-20120407-cvs на http://www.quicklisp.org/beta/releases.html
Monk - 09.05.2012 14:34
[#] Ответ на комментарий от Monk 09.05.2012 14:34
Пинайте Зака, чтоб нужные изменения попали в ближайший апдейт (уже на носу http://blog.quicklisp.org/2012/05/updates-coming-soon.html).

Также хотелось бы минимальный туториал.
andy128k - 10.05.2012 21:59
[#] Ответ на комментарий от andy128k 10.05.2012 21:59
Зак сказал у него нету libgdk.3.so.0 Это мол специфичная библиотека. Может в некоторых дистрах у нее путь не стандартный.
michael.filonenko - 10.05.2012 22:04
[#] Ответ на комментарий от michael.filonenko 10.05.2012 22:04
У меня (Debian Sid) она называется иначе (/usr/lib/x86_64-linux-gnu/libgdk-3.so.0). Может стоит добавить альтернативных имён в /gtk-cffi/gdk/loadlib.lisp?
andy128k - 10.05.2012 22:28
[#] Ответ на комментарий от michael.filonenko 10.05.2012 22:04
В gtk-cffi/gdk/loadlib

(define-foreign-library :gdk
  (:unix "libgdk-3.so.0")
  (:windows "libgdk-win32-3xs-0.dll"))

Никакого libgdk.3.so.0 там нет. Впрочем, если у кого-то она называется по-другому, могу добавить синонимы.
Monk - 11.05.2012 06:44
[#] Ответ на комментарий от andy128k 10.05.2012 21:59
В качестве туториала там есть gtk-cffi/examples/*. Фактически, там лежат примеры с php-gtk2 cookbook, переведённые на Lisp близко к тексту.
В качестве продвинутого (относительно) примера можно смотреть http://common-lisp.net/viewvc/cl-dbf/cl-dbf/dbfview/
Monk - 11.05.2012 06:48
[#] Ответ на комментарий от Monk 11.05.2012 06:44
Прошу прощения. Я и имел ввиду эту библиотеку.
michael.filonenko - 11.05.2012 08:30
[#] Ответ на комментарий от michael.filonenko 11.05.2012 08:30
Пусть у себя запустит
$ ldd `which gnome-session` | grep gdk

и скажет, какая тогда у него библиотека (или весь GTK3 считаем "специфичной библиотекой"?)

У меня
libgdk-3.so.0 => /usr/lib/i386-linux-gnu/libgdk-3.so.0
Monk - 11.05.2012 11:10
[#] Ответ на комментарий от Monk 11.05.2012 06:48
Так добавь ссылки сюда http://common-lisp.net/project/gtk-cffi/. Чтоб не искать.
andy128k - 11.05.2012 11:12
[#] Ответ на комментарий от andy128k 11.05.2012 11:12
Добавил
Monk - 11.05.2012 12:26
[#] Ответ на комментарий от Monk 11.05.2012 12:26
Мерси.

Давайте всё-таки разбираться, что мешает попаданию в quicklisp. Отмазка про нестандартный путь не канает, путь всё равно в /etc/ld.conf прописан.
andy128k - 11.05.2012 15:04
[#] Ответ на комментарий от andy128k 11.05.2012 15:04
У Зака debian 6. Сказал, что попытается найти gtk3.
michael.filonenko - 11.05.2012 19:10
[#]
Добавил ещё один пример на сайт (текстовый редактор а-ля Emacs + Lisp REPL)
Monk - 13.05.2012 20:30
[#] Ответ на комментарий от Monk 13.05.2012 20:30
Такой вопрос:
А можно ли с помощью gtk-cffi сделать классическое:

(defclass my-widget (widget))

(defmethod draw ((widget my-widget) ....)
;; А здесь как-нибудь порисовать
)


(defmethod mouse-move ((widget my-widget) ....)
;;; etc
)

Ну то есть отображается ли gtk'шная модель событий в clos?
michael.filonenko - 15.05.2012 00:50
[#] Ответ на комментарий от michael.filonenko 15.05.2012 00:50
Нет не отображается. Для отображения приходится писать что-то вроде gtk-cffi//ext/lisp-model.lisp : пример реализации GtkTreeModel
Monk - 17.05.2012 12:25
[#]
>http://common-lisp.net/project/cl-dbf/
>Библиотека доступа к файлам DBF.
Пример напрямую не заработал.
В Lispworks 6 в итоге заработало вот так:

(in-package :cl-dbf)

(defun driver-list-field-names (driver)
              (loop :for field :in (slot-value driver 'fields)
                    :collect (slot-value field 'name)
)
)


(defun dbf-to-conses-of-strings (filename)
   "filename is a name of dbf file to open.
Returns a list (field-names . record-values),
where values are strings"

   (with-open-file (stream filename
                           :direction :io
                           :element-type '(unsigned-byte 8)
                           :if-exists :overwrite
)

     (let ((driver (dbopen stream)))
       (cons
        (driver-list-field-names driver)
        (loop
         :for rec = (read-record driver)
         :while rec
         :collect rec
)
)
)
)
)


#+example
(dbf-to-conses-of-string "path/dbf.dbf")


den73 - 17.10.2012 18:29
[#]
В cl-dbf.asd написана другая лицензия, чем на странице проекта.
den73 - 17.10.2012 18:33
[#] Ответ на комментарий от den73 17.10.2012 18:33
Лицензию исправил (верно BSD).
А какой пример не заработал? dbfview?
Monk - 13.12.2012 17:05
[#] Ответ на комментарий от Monk 13.12.2012 17:05
> А какой пример не заработал? dbfview?
Сейчас уже не помню. Пытался отправить письмо в список рассылки, ничего не вышло, пишу теперь сюда.
Мне попался файл без символа 26 в конце (наверное, он создан с помощью
компоненты tdbf для Дельфи
)


Разные утилиты просмотра dbf его открывают, а cl-dbf - падает при чтении последней записи.
Предлагается следующее:

(defmethod read-record ((driver dbase3-header))
  "Return record value as list and move to the next record"
  (with-slots (stream) driver
    (case (read-byte stream nil #\SUB)
      (32 (loop
             :for field :in (fields driver)
             :collect
             (let ((s (make-array (size field)
                                  :element-type '(unsigned-byte 8)
)
)
)

               (read-sequence s stream)
               (flexi-streams:octets-to-string
                s
                :external-format (external-format driver)
)
)
)
)

      (t (file-position stream
                        (+ (file-position stream)
                           (1- (record-size driver))
)
)

         nil
)
)
)
)


правда, я не совсем понимаю последнюю установку file-position за пределы файла,
может быть, она сломается.

Также попался файл с неверной кодовой страницей. На этот случай предлагается функция
(defun code-page-id-to-dbf-code-page-value (code-page-id)
  (case code-page-id
    (850 2)
    (1252 3)
    (852 #x64)
    (865 #x65)
    (866 #x66)
    (1250 #xC8)
    (1251 #xC9)
    (t nil)
    
)
)


к-рая позволит потом сделать
(setf (code-page driver)
   (code-page-id-to-dbf-code-page-value 866)
)


для насильственной установки кодовой страницы.

соответственно,
(defun dbf-to-conses-of-strings (filename &key code-page)
   "filename is a name of dbf file to open.
Returns a list (field-names . record-values),
where values are strings. code-page можно использовать для насильственного указания кодовой страницы"

   (with-open-file (stream filename
                           :direction :io
                           :element-type '(unsigned-byte 8)
                           :if-exists :overwrite
)

     (let ((driver (dbopen stream))
           force-code-page
)

       (when code-page
         (setf force-code-page (code-page-id-to-dbf-code-page-value code-page))
         (assert (typep force-code-page 'integer))
         (setf (code-page driver) force-code-page)
)

       (cons
        (driver-list-field-names driver)
        (loop
         :for rec = (read-record driver)
         :while rec
         :collect rec
)
)
)
)
)
den73 - 26.12.2012 21:33
[#] Ответ на комментарий от den73 26.12.2012 21:33
отличие ф-ии read-record в том, что в ней для read-byte добавлены аргументы.
den73 - 26.12.2012 21:34
[#] Ответ на комментарий от den73 26.12.2012 21:34
Обновил в cvs.
Если что, пиши в почту. В asd я её везде указываю.

Monk - 01.01.2013 02:19
@2009-2013 lisper.ru