From f6b02ed08bb39257436921154dc617f4a07ca990 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 29 Dec 2018 14:52:26 +0100
Subject: Updated code to scroll loaded panels from Python.

---
 plugins/pychrysalide/glibext/Makefile.am   |   1 +
 plugins/pychrysalide/glibext/linecursor.c  | 239 +++++++++++++++++++++++++++++
 plugins/pychrysalide/glibext/linecursor.h  |  45 ++++++
 plugins/pychrysalide/glibext/loadedpanel.c |  83 ++--------
 plugins/pychrysalide/glibext/module.c      |   2 +
 src/glibext/gloadedpanel.h                 |   2 +
 6 files changed, 302 insertions(+), 70 deletions(-)
 create mode 100644 plugins/pychrysalide/glibext/linecursor.c
 create mode 100644 plugins/pychrysalide/glibext/linecursor.h

diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index 4e1e579..c09f4fa 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -5,6 +5,7 @@ libpychrysaglibext_la_SOURCES =			\
 	buffercache.h buffercache.c			\
 	bufferline.h bufferline.c			\
 	configuration.h configuration.c		\
+	linecursor.h linecursor.c			\
 	linegen.h linegen.c					\
 	loadedpanel.h loadedpanel.c			\
 	module.h module.c
diff --git a/plugins/pychrysalide/glibext/linecursor.c b/plugins/pychrysalide/glibext/linecursor.c
new file mode 100644
index 0000000..bb3b8ba
--- /dev/null
+++ b/plugins/pychrysalide/glibext/linecursor.c
@@ -0,0 +1,239 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linecursor.c - équivalent Python du fichier "glibext/glinecursor.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "linecursor.h"
+
+
+#include <malloc.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <glibext/glinecursor.h>
+
+
+#include "../access.h"
+#include "../helpers.h"
+
+
+
+/* Détermine si la position de suivi est pertinente ou non. */
+static PyObject *py_line_cursor_is_valid(PyObject *, void *);
+
+/* Construit une étiquette de représentation d'un suivi. */
+static PyObject *py_line_cursor_get_label(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Détermine si la position de suivi est pertinente ou non.     *
+*                                                                             *
+*  Retour      : Bilan de validité.                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_line_cursor_is_valid(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GLineCursor *cursor;                    /* Curseur à consulter         */
+    bool status;                            /* Bilan de validité           */
+
+    cursor = G_LINE_CURSOR(pygobject_get(self));
+    status = g_line_cursor_is_valid(cursor);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Construit une étiquette de représentation d'un suivi.        *
+*                                                                             *
+*  Retour      : Etiquette à libérer de la mémoire après usage.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_line_cursor_get_label(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GLineCursor *cursor;                    /* Curseur à consulter         */
+    char *label;                            /* Etiquette mise en place     */
+
+    cursor = G_LINE_CURSOR(pygobject_get(self));
+    label = g_line_cursor_build_label(cursor);
+
+    result = PyUnicode_FromString(label);
+
+    free(label);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_line_cursor_type(void)
+{
+    static PyMethodDef py_line_cursor_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_line_cursor_getseters[] = {
+        {
+            "valid", py_line_cursor_is_valid, NULL,
+            "Validity status of the line cursor.", NULL
+        },
+        {
+            "label", py_line_cursor_get_label, NULL,
+            "Label for the current state of a line cursor.", NULL
+        },
+        { NULL }
+    };
+
+    static PyTypeObject py_line_cursor_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.glibext.LineCursor",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide line cursor",
+
+        .tp_methods     = py_line_cursor_methods,
+        .tp_getset      = py_line_cursor_getseters,
+
+    };
+
+    return &py_line_cursor_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.glibext.Linecursor'.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_line_cursor_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'LineCursor'    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_line_cursor_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.glibext");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_LINE_CURSOR, type, &PyGObject_Type))
+            return false;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en curseur pour ligne.                    *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_line_cursor(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_line_cursor_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, _("unable to convert the provided argument to line cursor"));
+            break;
+
+        case 1:
+            *((GLineCursor **)dst) = G_LINE_CURSOR(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/linecursor.h b/plugins/pychrysalide/glibext/linecursor.h
new file mode 100644
index 0000000..896e6bb
--- /dev/null
+++ b/plugins/pychrysalide/glibext/linecursor.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * linecursor.h - prototypes pour l'équivalent Python du fichier "glibext/linecursor.h"
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINECURSOR_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINECURSOR_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_line_cursor_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.Linecursor'. */
+bool ensure_python_line_cursor_is_registered(void);
+
+/* Tente de convertir en curseur pour ligne. */
+int convert_to_line_cursor(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINECURSOR_H */
diff --git a/plugins/pychrysalide/glibext/loadedpanel.c b/plugins/pychrysalide/glibext/loadedpanel.c
index ce94b27..949ed1c 100644
--- a/plugins/pychrysalide/glibext/loadedpanel.c
+++ b/plugins/pychrysalide/glibext/loadedpanel.c
@@ -28,19 +28,16 @@
 #include <pygobject.h>
 
 
+#include <i18n.h>
 #include <glibext/gloadedpanel.h>
 
 
+#include "linecursor.h"
 #include "../access.h"
 #include "../helpers.h"
 
 
 
-/* Retrouve l'emplacement correspondant à une position donnée. */
-//static PyObject *py_loaded_panel_compute_addr(PyObject *, PyObject *);
-
-
-
 /* S'assure qu'un emplacement donné est visible à l'écran. */
 static PyObject *py_loaded_panel_scroll_to_cursor(PyObject *, PyObject *);
 
@@ -49,52 +46,6 @@ static bool py_loaded_panel_define_constants(PyTypeObject *);
 
 
 
-
-#if 0
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant un générateur à manipuler.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Retrouve l'emplacement correspondant à une position donnée.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_loaded_panel_compute_addr(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Localisation à retourner    */
-    GLineGenerator *generator;              /* Version native              */
-    gint x;                                 /* Position géographique       */
-    size_t index;                           /* Indice dans le tampon       */
-    size_t repeat;                          /* Utilisations successives    */
-    int ret;                                /* Bilan de lecture des args.  */
-    vmpa2t addr;                            /* Adresse visée par l'opérat° */
-
-    generator = G_LOADED_PANEL(pygobject_get(self));
-
-    ret = PyArg_ParseTuple(args, "ikk", &x, &index, &repeat);
-    if (!ret) return NULL;
-
-    g_loaded_panel_compute_addr(generator, x, &addr, index, repeat);
-
-    result = build_from_internal_vmpa(&addr);
-
-    return result;
-
-}
-
-#endif
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : self = classe représentant un tampon de code.                *
@@ -110,38 +61,30 @@ static PyObject *py_loaded_panel_compute_addr(PyObject *self, PyObject *args)
 
 static PyObject *py_loaded_panel_scroll_to_cursor(PyObject *self, PyObject *args)
 {
-#if 0
-
-    GLoadedPanel *panel;                    /* Panneau à manipuler         */
-    PyObject *py_vmpa;                      /* Localisation version Python */
+    GLineCursor *cursor;                    /* Emplacement à cibler        */
+    unsigned long tweak;                    /* Adapation à effectuer       */
+    int move;                               /* Déplacement à l'écran ?     */
     int ret;                                /* Bilan de lecture des args.  */
-    vmpa2t *addr;                           /* Adresse visée par l'opérat° */
-
-    ret = PyArg_ParseTuple(args, "O", &py_vmpa);
-    if (!ret) return NULL;
+    GLoadedPanel *panel;                    /* Panneau à manipuler         */
 
-    ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type());
+    ret = PyArg_ParseTuple(args, "O&kp", convert_to_line_cursor, &cursor, &tweak, &move);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(py_vmpa);
-    if (addr == NULL) return NULL;
+    if (!IS_VALID_STP(tweak))
+    {
+        PyErr_SetString(PyExc_ValueError, _("invalid position tweak"));
+        return NULL;
+    }
 
     panel = G_LOADED_PANEL(pygobject_get(self));
 
-    // FIXME
-    //gtk_loaded_panel_scroll_to_address(panel, addr, SPT_RAW, true);
-#endif
+    g_loaded_panel_scroll_to_cursor(panel, cursor, tweak, move);
 
     Py_RETURN_NONE;
 
 }
 
 
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index 45c92e8..2429dbd 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -31,6 +31,7 @@
 #include "buffercache.h"
 #include "bufferline.h"
 #include "configuration.h"
+#include "linecursor.h"
 #include "linegen.h"
 #include "loadedpanel.h"
 #include "../helpers.h"
@@ -97,6 +98,7 @@ bool populate_glibext_module(void)
     if (result) result = ensure_python_config_param_is_registered();
     if (result) result = ensure_python_config_param_iterator_is_registered();
     if (result) result = ensure_python_generic_config_is_registered();
+    if (result) result = ensure_python_line_cursor_is_registered();
     if (result) result = ensure_python_line_generator_is_registered();
     if (result) result = ensure_python_loaded_panel_is_registered();
 
diff --git a/src/glibext/gloadedpanel.h b/src/glibext/gloadedpanel.h
index 9d460c7..e1e1e27 100644
--- a/src/glibext/gloadedpanel.h
+++ b/src/glibext/gloadedpanel.h
@@ -75,6 +75,8 @@ typedef enum _ScrollPositionTweak
 
 } ScrollPositionTweak;
 
+#define IS_VALID_STP(t) (SPT_RAW <= (t) && (t) <= SPT_BOTTOM)
+
 /* S'assure qu'un emplacement donné est visible à l'écran. */
 void g_loaded_panel_scroll_to_cursor(GLoadedPanel *, const GLineCursor *, ScrollPositionTweak, bool);
 
-- 
cgit v0.11.2-87-g4458