From c5631dd09fa9981e914ec9082c6270b69a719ca4 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 18 Aug 2020 22:08:39 +0200 Subject: Refreshed the rendering for newly added bookmarks. --- configure.ac | 17 +++++ plugins/pychrysalide/glibext/buffercache.c | 108 +++++++++++++++++++++++++++++ plugins/pychrysalide/glibext/bufferline.c | 92 +----------------------- src/analysis/db/collection.c | 2 +- src/analysis/db/items/bookmark.c | 13 ++-- src/glibext/buffercache-int.h | 2 + src/glibext/buffercache.c | 88 +++++++++++++++++++++++ src/glibext/buffercache.h | 8 ++- src/glibext/bufferline.c | 2 +- src/glibext/bufferview.c | 25 +++++++ 10 files changed, 255 insertions(+), 102 deletions(-) diff --git a/configure.ac b/configure.ac index f467f66..855091f 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,23 @@ AC_CHECK_HEADERS([unistd.h]) AC_TYPE_SIZE_T +AC_MSG_CHECKING([for suitable size_t]) +AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include ]], + [[char dummy[sizeof(size_t) == sizeof(unsigned long) ? 1 : -1];]])], + [ + AC_MSG_RESULT([yes]) + suitable_size_t=yes + ], + [ + AC_MSG_RESULT([no]) + suitable_size_t=no + ] + ) + +if test "x$suitable_size_t" = "xno"; then + AC_MSG_FAILURE([Current size of size_t is not supported]) +fi + #--- Checks for structures diff --git a/plugins/pychrysalide/glibext/buffercache.c b/plugins/pychrysalide/glibext/buffercache.c index 019d981..d3bee45 100644 --- a/plugins/pychrysalide/glibext/buffercache.c +++ b/plugins/pychrysalide/glibext/buffercache.c @@ -73,9 +73,15 @@ static PyObject *py_buffer_cache_extend_with(PyObject *, PyObject *); /* Réduit le tampon à une quantité de lignes précise. */ static PyObject *py_buffer_cache_truncate(PyObject *, PyObject *); +/* Ajoute une propriété particulière à une ligne. */ +static PyObject *py_buffer_cache_add_line_flag(PyObject *, PyObject *); + /* Détermine l'ensemble des propriétés attachées à une ligne. */ static PyObject *py_buffer_cache_get_line_flags(PyObject *, PyObject *); +/* Retire une propriété particulière attachée à une ligne. */ +static PyObject *py_buffer_cache_remove_line_flag(PyObject *, PyObject *); + /* Retrouve une ligne au sein d'un tampon avec un indice. */ static PyObject *py_buffer_cache_find_line_by_index(PyObject *, PyObject *); @@ -568,6 +574,56 @@ static PyObject *py_buffer_cache_truncate(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = tampon de lignes à venir consulter. * +* args = arguments fournis à l'appel. * +* * +* Description : Ajoute une propriété particulière à une ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_add_line_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de la ligne visée */ + BufferLineFlags flag; /* Drapeau à considérer */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_ADD_LINE_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + add_line_flag, "$self, index, flag, /", \ + METH_VARARGS, py_buffer_cache, \ + "Add one optional flag to those assigned to a given buffer" \ + " line. The line is located using the *index* argument.\n" \ + "\n" \ + "The *index* has to be a simple integer, and the *flag* a" \ + " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "nO&", &index, convert_to_buffer_line_flags, &flag); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_add_line_flag(cache, index, flag); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = classe représentant un tampon de code. * * args = arguments fournis à l'appel. * * * @@ -617,6 +673,56 @@ static PyObject *py_buffer_cache_get_line_flags(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = tampon de lignes à venir consulter. * +* args = arguments fournis à l'appel. * +* * +* Description : Retire une propriété particulière attachée à une ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_remove_line_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de la ligne visée */ + BufferLineFlags flag; /* Drapeau à considérer */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_REMOVE_LINE_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + remove_line_flag, "$self, index, flag, /", \ + METH_VARARGS, py_buffer_cache, \ + "Remove one optional flag from those assigned to a given buffer" \ + " line. The line is located using the *index* argument.\n" \ + "\n" \ + "The *index* has to be a simple integer, and the *flag* a" \ + " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "nO&", &index, convert_to_buffer_line_flags, &flag); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_remove_line_flag(cache, index, flag); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = classe représentant un tampon de code. * * args = arguments fournis à l'appel. * * * @@ -942,7 +1048,9 @@ PyTypeObject *get_python_buffer_cache_type(void) BUFFER_CACHE_APPEND_METHOD, BUFFER_CACHE_EXTEND_WITH_METHOD, BUFFER_CACHE_TRUNCATE_METHOD, + BUFFER_CACHE_ADD_LINE_FLAG_METHOD, BUFFER_CACHE_GET_LINE_FLAGS_METHOD, + BUFFER_CACHE_REMOVE_LINE_FLAG_METHOD, BUFFER_CACHE_FIND_LINE_BY_INDEX_METHOD, BUFFER_CACHE_LOOK_FOR_FLAG_METHOD, { NULL } diff --git a/plugins/pychrysalide/glibext/bufferline.c b/plugins/pychrysalide/glibext/bufferline.c index ea84567..c88fe7f 100644 --- a/plugins/pychrysalide/glibext/bufferline.c +++ b/plugins/pychrysalide/glibext/bufferline.c @@ -51,12 +51,6 @@ static PyObject *py_buffer_line_append_text(PyObject *, PyObject *); /* Reconstruit et fournit le texte présent sur une ligne tampon. */ static PyObject *py_buffer_line_get_text(PyObject *, PyObject *); -/* Ajoute une propriété particulière à une ligne donnée. */ -static PyObject *py_buffer_line_add_flag(PyObject *, PyObject *); - -/* Retire une propriété particulière à une ligne donnée. */ -static PyObject *py_buffer_line_remove_flag(PyObject *, PyObject *); - /* Renseigne sur les propriétés particulières liées à une ligne. */ static PyObject *py_buffer_line_get_flags(PyObject *, void *); @@ -93,7 +87,9 @@ static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject " BufferLine()" \ "\n" \ "Such objets aim to be created from the Chrysalide core only, and" \ - " then get populated by plugins on demand." + " then get populated on demand. Thus, these lines can be viewed as" \ + " cached lines and their properties have to be set through the" \ + " pychrysalide.glibext.BufferCache instance which contains them." /* Validations diverses */ @@ -235,78 +231,6 @@ static PyObject *py_buffer_line_get_text(PyObject *self, PyObject *args) /****************************************************************************** * * -* Paramètres : self = classe représentant une ligne de tampon. * -* args = arguments fournis à l'appel. * -* * -* Description : Ajoute une propriété particulière à une ligne donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_buffer_line_add_flag(PyObject *self, PyObject *args) -{ - BufferLineFlags flag; /* Drapeau à considérer */ - int ret; /* Bilan de lecture des args. */ - GBufferLine *line; /* Version native */ - - ret = PyArg_ParseTuple(args, "I", &flag); - if (!ret) return NULL; - - if ((flag & ~BLF_ALL) != 0) - { - PyErr_SetString(PyExc_ValueError, _("Invalid flag")); - return NULL; - } - - line = G_BUFFER_LINE(pygobject_get(self)); - g_buffer_line_add_flag(line, flag); - - Py_RETURN_NONE; - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe représentant une ligne de tampon. * -* args = arguments fournis à l'appel. * -* * -* Description : Retire une propriété particulière à une ligne donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_buffer_line_remove_flag(PyObject *self, PyObject *args) -{ - BufferLineFlags flag; /* Drapeau à considérer */ - int ret; /* Bilan de lecture des args. */ - GBufferLine *line; /* Version native */ - - ret = PyArg_ParseTuple(args, "I", &flag); - if (!ret) return NULL; - - if ((flag & ~BLF_ALL) != 0) - { - PyErr_SetString(PyExc_ValueError, _("Invalid flag")); - return NULL; - } - - line = G_BUFFER_LINE(pygobject_get(self)); - g_buffer_line_remove_flag(line, flag); - - Py_RETURN_NONE; - -} - - -/****************************************************************************** -* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -355,16 +279,6 @@ PyTypeObject *get_python_buffer_line_type(void) METH_VARARGS, "get_text($self, first_col, last_col, markup, /)\n--\n\nProvide the text of a buffer line." }, - { - "add_flag", py_buffer_line_add_flag, - METH_VARARGS, - "add_flag($self, flag, /)\n--\n\nAdd a flag to the buffer line." - }, - { - "remove_flag", py_buffer_line_remove_flag, - METH_VARARGS, - "remove_flag($self, flag, /)\n--\n\nRemove a flag from the buffer line." - }, { NULL } }; diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 57e675b..4c7a496 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -652,7 +652,7 @@ static void g_db_collection_set_last_item(GDbCollection *collec, GDbItem *item, else { - if (g_db_item_get_flags(item) & DIF_ERASER) + if ((g_db_item_get_flags(item) & DIF_ERASER) == 0) { g_object_ref(G_OBJECT(item)); g_object_ref(G_OBJECT(item)); diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index f493559..2afbbc0 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -526,7 +526,6 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool GBufferCache *cache; /* Tampon d'impression colorée */ GLineCursor *cursor; /* Emplacement dans un tampon */ size_t index; /* Indice de ligne à traiter */ - GBufferLine *line; /* Ligne de tampon à marquer */ result = false; @@ -544,22 +543,18 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool g_object_unref(G_OBJECT(cursor)); - line = g_buffer_cache_find_line_by_index(cache, index); + index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE); /* Application du changement */ - result = (line != NULL); + result = (index < g_buffer_cache_count_lines(cache)); if (result) { if (set) - g_buffer_line_add_flag(line, BLF_BOOKMARK); + g_buffer_cache_add_line_flag(cache, index, BLF_BOOKMARK); else - g_buffer_line_remove_flag(line, BLF_BOOKMARK); - - g_object_unref(G_OBJECT(line)); - - g_buffer_cache_throw_update_at_index(cache, index); + g_buffer_cache_remove_line_flag(cache, index, BLF_BOOKMARK); } diff --git a/src/glibext/buffercache-int.h b/src/glibext/buffercache-int.h index 3dfd5e2..2ffa8ec 100644 --- a/src/glibext/buffercache-int.h +++ b/src/glibext/buffercache-int.h @@ -89,6 +89,8 @@ struct _GBufferCacheClass void (* size_changed) (GBufferCache *, bool, size_t, size_t); + void (* line_updated) (GBufferCache *, size_t); + }; diff --git a/src/glibext/buffercache.c b/src/glibext/buffercache.c index 6f52956..169c75e 100644 --- a/src/glibext/buffercache.c +++ b/src/glibext/buffercache.c @@ -397,6 +397,8 @@ static GBufferLine *get_cache_info_line(cache_info *info, const GWidthTracker *t { result = g_buffer_line_new(g_width_tracker_count_columns(tracker)); + g_buffer_line_add_flag(result, info->extra_flags); + g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info); if (info->count == 1) @@ -515,6 +517,14 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class) g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG, G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG); + g_signal_new("line-updated", + G_TYPE_BUFFER_CACHE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GBufferCacheClass, line_updated), + NULL, NULL, + g_cclosure_marshal_VOID__ULONG, + G_TYPE_NONE, 1, G_TYPE_ULONG); + } @@ -761,6 +771,8 @@ gint g_buffer_cache_get_text_position(const GBufferCache *cache) size_t g_buffer_cache_count_lines(const GBufferCache *cache) { + // TODO check lock + return cache->used; } @@ -1337,6 +1349,44 @@ void g_buffer_cache_get_line_cursor(const GBufferCache *cache, size_t index, gin * * * Paramètres : cache = tampon de lignes à venir consulter. * * index = indice de la ligne visée par la consultation. * +* flag = propriété à intégrer. * +* * +* Description : Ajoute une propriété particulière à une ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_cache_add_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag) +{ + cache_info *info; /* Accès direct à une ligne */ + + // TODO : check lock + + assert(index < cache->used); + + info = &cache->lines[index]; + + if ((info->extra_flags & flag) == 0) + { + info->extra_flags |= flag; + + if (info->line != NULL) + g_buffer_line_add_flag(info->line, flag); + + g_signal_emit_by_name(cache, "line-updated", index); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes à venir consulter. * +* index = indice de la ligne visée par la consultation. * * * * Description : Détermine l'ensemble des propriétés attachées à une ligne. * * * @@ -1381,6 +1431,44 @@ BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *cache, size_t /****************************************************************************** * * +* Paramètres : cache = tampon de lignes à venir consulter. * +* index = indice de la ligne visée par la consultation. * +* flag = propriété à supprimer. * +* * +* Description : Retire une propriété particulière attachée à une ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_cache_remove_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag) +{ + cache_info *info; /* Accès direct à une ligne */ + + // TODO : check lock + + assert(index < cache->used); + + info = &cache->lines[index]; + + if ((info->extra_flags & flag) != 0) + { + info->extra_flags &= ~flag; + + if (info->line != NULL) + g_buffer_line_remove_flag(info->line, flag); + + g_signal_emit_by_name(cache, "line-updated", index); + + } + +} + + +/****************************************************************************** +* * * Paramètres : cache = tampon de lignes à consulter. * * index = indice de la ligne recherchée. * * * diff --git a/src/glibext/buffercache.h b/src/glibext/buffercache.h index 61114b0..7422c76 100644 --- a/src/glibext/buffercache.h +++ b/src/glibext/buffercache.h @@ -99,14 +99,18 @@ void g_buffer_cache_truncate(GBufferCache *, size_t); /* Retrouve l'emplacement correspondant à une position de ligne. */ void g_buffer_cache_get_line_cursor(const GBufferCache *, size_t, gint, GLineCursor **); +/* Ajoute une propriété particulière à une ligne. */ +void g_buffer_cache_add_line_flag(GBufferCache *, size_t, BufferLineFlags); + /* Détermine l'ensemble des propriétés attachées à une ligne. */ BufferLineFlags g_buffer_cache_get_line_flags(const GBufferCache *, size_t); +/* Retire une propriété particulière attachée à une ligne. */ +void g_buffer_cache_remove_line_flag(GBufferCache *, size_t, BufferLineFlags); + #define g_buffer_cache_lock(c) #define g_buffer_cache_unlock(c) -#define g_buffer_cache_throw_update_at_index(c, i) // check locked - /* Retrouve une ligne au sein d'un tampon avec un indice. */ GBufferLine *g_buffer_cache_find_line_by_index(const GBufferCache *, size_t); diff --git a/src/glibext/bufferline.c b/src/glibext/bufferline.c index dd6bc19..85fe027 100644 --- a/src/glibext/bufferline.c +++ b/src/glibext/bufferline.c @@ -1430,7 +1430,7 @@ void g_buffer_line_draw(GBufferLine *line, size_t index, cairo_t *cairo, gint x_ size_t i; /* Boucle de parcours */ gint max_width; /* Largeur maximale de colonne */ - if (line->flags != BLF_NONE && line->flags != BLF_HAS_CODE) + if (line->flags != BLF_NONE) { class = G_BUFFER_LINE_GET_CLASS(line); diff --git a/src/glibext/bufferview.c b/src/glibext/bufferview.c index 769cd8b..7ac6718 100644 --- a/src/glibext/bufferview.c +++ b/src/glibext/bufferview.c @@ -75,6 +75,9 @@ static void g_buffer_view_finalize(GBufferView *); /* Accompagne une variation de la quantité de lignes du tampon. */ static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *); +/* Réagit à la modification d'une ligne du tampon. */ +static void on_buffer_cache_line_updated(const GBufferCache *, size_t, GBufferView *); + /* Calcule la position idéale de curseur pour un point donné. */ static bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const GDisplayOptions *, cairo_rectangle_int_t *, GLineCursor **); @@ -236,6 +239,7 @@ GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted) g_buffer_view_restrict(result, NULL, NULL); g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result); + g_signal_connect(cache, "line-updated", G_CALLBACK(on_buffer_cache_line_updated), result); if (highlighted != NULL) { @@ -253,6 +257,27 @@ GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted) /****************************************************************************** * * * Paramètres : cache = tampon de lignes cohérentes à manipuler. * +* index = indice de la première ligne actualisée. * +* * +* Description : Réagit à la modification d'une ligne du tampon. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_buffer_cache_line_updated(const GBufferCache *cache, size_t index, GBufferView *view) +{ + if (view->first <= index && index <= view->last) + g_signal_emit_by_name(view, "need-redraw"); + +} + + +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes cohérentes à manipuler. * * added = indication sur la variation de la taille du tampon. * * index = indice de la première ligne à traiter. * * count = nombre de lignes à traiter. * -- cgit v0.11.2-87-g4458