[ghex: 2/5] Massive cleanup in preparation for 4.alpha.1
- From: Logan Rathbone <larathbone src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ghex: 2/5] Massive cleanup in preparation for 4.alpha.1
- Date: Thu, 16 Dec 2021 23:05:34 +0000 (UTC)
commit 9511b9f730353b5e5ad901c02459d7cbd5779010
Author: Logan Rathbone <poprocks gmail com>
Date: Thu Dec 16 17:30:33 2021 -0500
Massive cleanup in preparation for 4.alpha.1
ALPHA-INFO.txt | 63 +++++++---
README.md | 6 +-
src/findreplace.c | 3 -
src/ghex-application-window.c | 278 +++++++++++++++++++++++-------------------
src/ghex-notebook-tab.c | 37 +++---
src/ghex-notebook-tab.h | 3 +-
src/gtkhex-layout-manager.c | 42 ++++++-
src/gtkhex-layout-manager.h | 3 +
src/gtkhex.c | 20 ++-
src/hex-buffer-malloc.h | 2 +-
src/hex-buffer-mmap.c | 2 +-
src/hex-buffer-mmap.h | 4 +-
src/hex-document.c | 58 +++------
src/hex-document.h | 3 +-
src/main.c | 8 +-
src/meson.build | 4 +-
16 files changed, 300 insertions(+), 236 deletions(-)
---
diff --git a/ALPHA-INFO.txt b/ALPHA-INFO.txt
index ff006dd..17209a7 100644
--- a/ALPHA-INFO.txt
+++ b/ALPHA-INFO.txt
@@ -1,7 +1,7 @@
-GHex 4 pre-alpha information
-============================
+GHex 4 alpha information
+========================
-GHex 4 is currently in pre-alpha state. As it has been substantially reworked
+GHex 4 is currently in alpha state. As it has been substantially reworked
from GHex 3.x and, as of the time of writing, has only been recently merged to
the `master` branch (December 2021), it will require some substantial testing
and translation updates.
@@ -12,32 +12,37 @@ Visibly to the end user, some new features include:
- Tabbed interface.
- - Dark Mode (by default, the GTK system default is used, but can be
- overridden with a checkbox and a switch in the Preferences dialog).
+ - Dark Mode (by default, the GTK system-wide "prefer-dark-theme" setting is
+ used, but can be overridden with a checkbox and a switch in the Preferences
+ dialog).
- libadwaita colour compatibility; if you use the Adwaita theme and GNOME
- apps that utilize libadwaita, GHex will match the colour scheme. libadwaita
- is not a planned dependency for GHex at this time as many of its users are
- GTK users who do not run GNOME, and I want to keep GHex's dependency
- requirements to a minimum.
+ apps that utilize libadwaita, GHex will (read: should) match the colour
+ scheme. libadwaita is not a planned dependency for GHex at this time as many
+ of its users are GTK users who do not run GNOME, and I want to keep GHex's
+ dependency requirements to a minimum.
- Custom clipboard data, for less error-prone copying and pasting of binary
data; this will fall back to plaintext when unavailable.
- Copy and Paste Special dialogs, which allow you to, for instance, copy and
- paste hex pairs from GHex into other applications, and from other
- applications into GHex.
+ paste hex pairs from GHex into other applications, and to paste hex pairs
+ from other applications into GHex.
I'll break up the known issues into two categories: items I would consider to
be blockers for a beta, blockers for stable release, and other known issues,
which will be earmarked for priority after the first stable release of GHex 4.
-I have no more blockers for alpha. The first alpha will be released shortly
-after a minor cleanup.
-
Blockers for beta:
- - HexBufferIface: Implement asynchronous API for read/save operations.
+ - HexBufferIface (and to a lesser extent, GtkHex and HexDocument): things
+ need to cook a bit more to ensure the API will be stable before moving to
+ beta. This GObject Interface is quite new, and I want to ensure the API is not
+ missing anything glaring before locking it into place. Specifically missing
+ is...
+
+ - ... HexBufferIface/HexDocument: Implement asynchronous API for read/save
+ operations.
Blockers for stable release:
@@ -46,15 +51,35 @@ Blockers for stable release:
- Improvement of some redraw issues, at least on X11 (if you experience this,
try just slightly resizing the window).
+ - Auto-highlights (ie, from searches) are sometimes not redrawn properly
+ after a window resize.
+
- The offsets column shows some spurious lines when a file is first loaded.
This can be cleared by clicking anywhere on the hex widget to clear it.
+ - Paste Special can sometimes crash when a certain combination of available
+ MIME types is advertised to GHex from other applications.
+
Other known issues to be addressed in a future version:
- - Memory-mapping: I have started work on a memory-mapping backend for the
- HexBuffer interface. This will at least be available as an experimental
- compile-time feature by beta, but I cannot guarantee it will be enabled by
- default or swappable on the fly for the first stable release of GHex 4.
+ - Assertion errors upon exit - you may see assertion errors like the
+ following:
+
+(ghex:28200): GLib-GObject-WARNING **: 14:36:13.411: instance of invalid non-instantiatable type
'-g-type-private--GTypeFlags'
+
+(ghex:28200): GLib-GObject-CRITICAL **: 14:36:13.412: g_signal_handler_disconnect: assertion
'G_TYPE_CHECK_INSTANCE (instance)' failed
+
+(ghex:28200): GLib-GObject-CRITICAL **: 14:36:13.412: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
+
+ I am told this may be a bug in GTK relating to the context menu.
+
+ - Memory-mapping of files instead of reading directly into memory.
+ See: https://gitlab.gnome.org/GNOME/ghex/-/issues/15
+ I have started work on a memory-mapping backend for the HexBuffer
+ interface. If you want to try hacking it, you can enable it at compile-time
+ with `-Dexperimental-mmap=true`. Note that it is HIGHLY experimental and
+ unstable at this time. Do NOT trust your data with it in any way, shape or
+ form! You have been warned.
- Users have requested other features as well. Some will be implemented, some
will not, and some will be taken under advisement.
diff --git a/README.md b/README.md
index c151154..2ce87a4 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,13 @@ a traditional hex editor view. The display is split in two columns, with
hexadecimal values in one column and the ASCII representation in the
other. GHex is a useful tool for working with raw data.
-## Note re: Pre-Alpha State of GHex 4
+## Note re: Alpha State of GHex 4
-The `master` branch now contains GHex 4, which is presently in pre-alpha state.
+The `master` branch now contains GHex 4, which is presently in alpha state.
However, testing is welcome. It may be most easily installed for most users via
Flatpak, using the `gnome-nightly` repository.
-For more information, please see [this document](/PRE-ALPHA-INFO.txt).
+For more information, please see [this document](/ALPHA-INFO.txt).
## System Requirements
diff --git a/src/findreplace.c b/src/findreplace.c
index 44007ad..c75e793 100644
--- a/src/findreplace.c
+++ b/src/findreplace.c
@@ -660,9 +660,6 @@ pane_dialog_set_hex (PaneDialog *self, GtkHex *gh)
priv = pane_dialog_get_instance_private (PANE_DIALOG(self));
- g_debug("%s: setting GtkHex of PaneDialog %p to: %p",
- __func__, (void *)self, (void *)gh);
-
/* Clear auto-highlight if any.
*/
if (priv->auto_highlight)
diff --git a/src/ghex-application-window.c b/src/ghex-application-window.c
index 851007d..b767e21 100644
--- a/src/ghex-application-window.c
+++ b/src/ghex-application-window.c
@@ -33,6 +33,12 @@
/* DEFINES */
#define offset_fmt "0x%X"
+#define ACTIVE_GH \
+ (ghex_application_window_get_hex (self))
+
+#ifndef EXPERIMENTAL_MMAP
+static GFile *tmp_global_gfile_for_nag_screen;
+#endif
/* ----------------------- */
/* MAIN GOBJECT DEFINITION */
@@ -48,7 +54,6 @@ struct _GHexApplicationWindow
GtkCssProvider *conversions_box_provider;
guint statusbar_id;
GtkAdjustment *adj;
- GList *gh_list;
gboolean can_save;
gboolean insert_mode;
@@ -257,25 +262,32 @@ settings_group_type_changed_cb (GSettings *settings,
static void
refresh_dialogs (GHexApplicationWindow *self)
{
- pane_dialog_set_hex (PANE_DIALOG(self->find_dialog), self->gh);
- pane_dialog_set_hex (PANE_DIALOG(self->replace_dialog), self->gh);
- pane_dialog_set_hex (PANE_DIALOG(self->jump_dialog), self->gh);
+ if (ACTIVE_GH)
+ {
+ pane_dialog_set_hex (PANE_DIALOG(self->find_dialog), ACTIVE_GH);
+ pane_dialog_set_hex (PANE_DIALOG(self->replace_dialog), ACTIVE_GH);
+ pane_dialog_set_hex (PANE_DIALOG(self->jump_dialog), ACTIVE_GH);
+ }
}
static GHexNotebookTab *
ghex_application_window_get_current_tab (GHexApplicationWindow *self)
{
GtkNotebook *notebook;
+ GtkHex *gh;
GHexNotebookTab *tab;
g_return_val_if_fail (GTK_IS_NOTEBOOK (self->hex_notebook), NULL);
- g_return_val_if_fail (GTK_IS_HEX (self->gh), NULL);
notebook = GTK_NOTEBOOK(self->hex_notebook);
+ gh = GTK_HEX(gtk_notebook_get_nth_page (notebook,
+ gtk_notebook_get_current_page (notebook)));
- tab = GHEX_NOTEBOOK_TAB(gtk_notebook_get_tab_label (notebook,
- GTK_WIDGET(self->gh)));
- g_return_val_if_fail (GHEX_IS_NOTEBOOK_TAB (tab), NULL);
+ if (gh)
+ tab = GHEX_NOTEBOOK_TAB(gtk_notebook_get_tab_label (notebook,
+ GTK_WIDGET(gh)));
+ else
+ tab = NULL;
return tab;
}
@@ -291,17 +303,9 @@ ghex_application_window_remove_tab (GHexApplicationWindow *self,
tab_gh = ghex_notebook_tab_get_hex (tab);
g_return_if_fail (GTK_IS_HEX(tab_gh));
- /* unref our additional ref we made to gh in _add_hex */
- g_object_unref (tab_gh);
-
page_num = gtk_notebook_page_num (notebook, GTK_WIDGET(tab_gh));
gtk_notebook_remove_page (notebook, page_num);
- /* FIXME - remove as a possible optimization - but let's keep it in
- * for now for debugging purposes. */
- g_return_if_fail (g_list_find (self->gh_list, tab_gh));
- self->gh_list = g_list_remove (self->gh_list, tab_gh);
-
update_gui_data (self);
}
@@ -310,9 +314,9 @@ file_save (GHexApplicationWindow *self)
{
HexDocument *doc;
- g_return_if_fail (GTK_IS_HEX (self->gh));
+ g_return_if_fail (GTK_IS_HEX (ACTIVE_GH));
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
g_return_if_fail (HEX_IS_DOCUMENT (doc));
if (hex_document_write (doc)) {
@@ -471,11 +475,12 @@ close_doc_response_cb (GtkDialog *dialog,
/* GtkNotebook likes to grab the focus. Possible TODO would be to subclass
* GtkNotebook so we can maintain the grab on the gh widget more easily.
*/
- gtk_widget_grab_focus (GTK_WIDGET (self->gh));
+ gtk_widget_grab_focus (GTK_WIDGET (ACTIVE_GH));
}
static void
-close_doc_confirmation_dialog (GHexApplicationWindow *self)
+close_doc_confirmation_dialog (GHexApplicationWindow *self,
+ GHexNotebookTab *tab)
{
GtkWidget *dialog;
HexDocument *doc;
@@ -483,9 +488,8 @@ close_doc_confirmation_dialog (GHexApplicationWindow *self)
char *message;
char *basename = NULL;
- g_return_if_fail (GTK_IS_HEX (self->gh));
-
- doc = gtk_hex_get_document (self->gh);
+ GtkHex *gh = ghex_notebook_tab_get_hex (tab);
+ doc = gtk_hex_get_document (gh);
g_return_if_fail (HEX_IS_DOCUMENT (doc));
if (G_IS_FILE (file = hex_document_get_file (doc)))
@@ -600,9 +604,9 @@ copy_special (GtkWidget *widget,
GdkClipboard *clipboard;
(void)action_name; (void)parameter;
- g_return_if_fail (GTK_IS_HEX (self->gh));
+ g_return_if_fail (GTK_IS_HEX (ACTIVE_GH));
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET(self->gh));
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET(ACTIVE_GH));
if (! self->copy_special_dialog)
{
@@ -624,9 +628,9 @@ paste_special (GtkWidget *widget,
GdkClipboard *clipboard;
(void)action_name; (void)parameter;
- g_return_if_fail (GTK_IS_HEX (self->gh));
+ g_return_if_fail (GTK_IS_HEX (ACTIVE_GH));
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET(self->gh));
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET(ACTIVE_GH));
if (! self->paste_special_dialog)
{
@@ -676,24 +680,26 @@ ghex_application_window_document_changed_cb (HexDocument *doc,
/* The appwindow as a whole not interested in any document changes that
* don't pertain to the one that is actually in view.
*/
- if (doc != gtk_hex_get_document (self->gh))
+ if (doc != gtk_hex_get_document (ACTIVE_GH))
return;
ghex_application_window_set_can_save (self, assess_can_save (doc));
}
static void
-tab_close_cb (GHexNotebookTab *tab,
+tab_close_request_cb (GHexNotebookTab *tab,
gpointer user_data)
{
GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
HexDocument *doc;
+ GtkHex *gh;
- doc = gtk_hex_get_document (self->gh);
+ gh = ghex_notebook_tab_get_hex (tab);
+ doc = gtk_hex_get_document (gh);
g_return_if_fail (HEX_IS_DOCUMENT (doc));
if (hex_document_has_changed (doc)) {
- close_doc_confirmation_dialog (self);
+ close_doc_confirmation_dialog (self, tab);
} else {
ghex_application_window_remove_tab (self, tab);
}
@@ -706,22 +712,14 @@ notebook_switch_page_cb (GtkNotebook *notebook,
gpointer user_data)
{
GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(user_data);
- GHexNotebookTab *tab;
- GtkHex *tab_gh;
HexDocument *doc;
- tab = GHEX_NOTEBOOK_TAB(gtk_notebook_get_tab_label (notebook, page));
- g_return_if_fail (GHEX_IS_NOTEBOOK_TAB (tab));
- tab_gh = ghex_notebook_tab_get_hex (tab);
- g_return_if_fail (GTK_IS_HEX (tab_gh));
+ if (! ACTIVE_GH) return;
- if (tab_gh != self->gh) {
- ghex_application_window_set_hex (self, tab_gh);
- ghex_application_window_activate_tab (self, self->gh);
- }
+ refresh_dialogs (self);
/* Assess saveability based on new tab we've switched to */
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
ghex_application_window_set_can_save (self, assess_can_save (doc));
/* Update dialogs, offset status bar, etc. */
@@ -775,7 +773,8 @@ pane_close_cb (PaneDialog *pane, gpointer user_data)
g_return_if_fail (PANE_IS_DIALOG (pane));
- gtk_widget_grab_focus (GTK_WIDGET(self->gh));
+ if (ACTIVE_GH)
+ gtk_widget_grab_focus (GTK_WIDGET(ACTIVE_GH));
if (FIND_IS_DIALOG (pane)) {
g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_FIND_OPEN]);
@@ -809,9 +808,9 @@ converter_close_cb (GtkWindow *window,
static void
setup_chartable (GHexApplicationWindow *self)
{
- g_return_if_fail (GTK_IS_HEX(self->gh));
+ g_return_if_fail (GTK_IS_HEX(ACTIVE_GH));
- self->chartable = create_char_table (GTK_WINDOW(self), self->gh);
+ self->chartable = create_char_table (GTK_WINDOW(self), ACTIVE_GH);
g_signal_connect(self->chartable, "close-request",
G_CALLBACK(chartable_close_cb), self);
@@ -820,9 +819,9 @@ setup_chartable (GHexApplicationWindow *self)
static void
setup_converter (GHexApplicationWindow *self)
{
- g_return_if_fail (GTK_IS_HEX(self->gh));
+ g_return_if_fail (GTK_IS_HEX(ACTIVE_GH));
- self->converter = create_converter (GTK_WINDOW(self), self->gh);
+ self->converter = create_converter (GTK_WINDOW(self), ACTIVE_GH);
g_signal_connect(self->converter, "close-request",
G_CALLBACK(converter_close_cb), self);
@@ -831,10 +830,9 @@ setup_converter (GHexApplicationWindow *self)
static void
update_titlebar (GHexApplicationWindow *self)
{
- HexDocument *doc = gtk_hex_get_document (self->gh);
GFile *file;
- if (GTK_IS_HEX (self->gh) &&
+ if (ACTIVE_GH &&
/* This is kind of cheap, but checking at this exact time whether
* we hold any further references to gh doesn't seem to work
* reliably.
@@ -843,6 +841,7 @@ update_titlebar (GHexApplicationWindow *self)
{
char *basename;
char *title;
+ HexDocument *doc = gtk_hex_get_document (ACTIVE_GH);
if (G_IS_FILE (file = hex_document_get_file (doc)))
basename = g_file_get_basename (file);
@@ -876,17 +875,17 @@ update_gui_data (GHexApplicationWindow *self)
update_status_message (self);
update_titlebar (self);
- if (GTK_IS_HEX (self->gh))
+ if (ACTIVE_GH)
{
- current_pos = gtk_hex_get_cursor (self->gh);
- }
+ current_pos = gtk_hex_get_cursor (ACTIVE_GH);
- for (int i = 0; i < 8; i++)
- {
- /* returns 0 on buffer overflow, which is what we want */
- val.v[i] = gtk_hex_get_byte (self->gh, current_pos+i);
+ for (int i = 0; i < 8; i++)
+ {
+ /* returns 0 on buffer overflow, which is what we want */
+ val.v[i] = gtk_hex_get_byte (ACTIVE_GH, current_pos+i);
+ }
+ hex_dialog_updateview (self->dialog, &val);
}
- hex_dialog_updateview (self->dialog, &val);
}
static void
@@ -898,7 +897,7 @@ cursor_moved_cb (GtkHex *gh, gpointer user_data)
/* If the cursor has been moved by a function call for a GtkHex that is
* *not* in view, we're not interested. */
- if (self->gh != gh) {
+ if (ACTIVE_GH != gh) {
return;
}
else {
@@ -925,7 +924,7 @@ ghex_application_window_set_show_ ##WIDGET (GHexApplicationWindow *self, \
if (GTK_IS_WIDGET (self->WIDGET) &&
\
gtk_widget_is_visible (self->WIDGET)) {
\
gtk_widget_hide (self->WIDGET);
\
- gtk_widget_grab_focus (GTK_WIDGET(self->gh)); \
+ gtk_widget_grab_focus (GTK_WIDGET(ACTIVE_GH)); \
}
\
}
\
g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_ARR_ENTRY]); \
@@ -1021,7 +1020,7 @@ save_as_response_cb (GtkNativeDialog *dialog,
goto end;
/* Fetch doc. No need for sanity checks as this is just a helper. */
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
gfile = gtk_file_chooser_get_file (chooser);
@@ -1057,9 +1056,9 @@ save_as (GtkWidget *widget,
GtkResponseType resp;
HexDocument *doc;
- g_return_if_fail (GTK_IS_HEX (self->gh));
+ g_return_if_fail (GTK_IS_HEX (ACTIVE_GH));
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
g_return_if_fail (HEX_IS_DOCUMENT (doc));
file_sel =
@@ -1092,7 +1091,7 @@ revert_response_cb (GtkDialog *dialog,
if (response_id != GTK_RESPONSE_ACCEPT)
goto end;
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
hex_document_read (doc);
@@ -1111,9 +1110,9 @@ revert (GtkWidget *widget,
gint reply;
char *basename = NULL;
- g_return_if_fail (GTK_IS_HEX (self->gh));
+ g_return_if_fail (GTK_IS_HEX (ACTIVE_GH));
- doc = gtk_hex_get_document (self->gh);
+ doc = gtk_hex_get_document (ACTIVE_GH);
g_return_if_fail (HEX_IS_DOCUMENT (doc));
/* Yes, this *is* a programmer error. The Revert menu should not be shown
@@ -1153,10 +1152,10 @@ print_preview (GtkWidget *widget,
{
GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(widget);
- g_return_if_fail (GTK_IS_HEX(self->gh));
+ g_return_if_fail (GTK_IS_HEX(ACTIVE_GH));
(void)widget, (void)action_name, (void)parameter; /* unused */
- common_print (GTK_WINDOW(self), self->gh, /* preview: */ TRUE);
+ common_print (GTK_WINDOW(self), ACTIVE_GH, /* preview: */ TRUE);
}
static void
@@ -1166,10 +1165,10 @@ do_print (GtkWidget *widget,
{
GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW(widget);
- g_return_if_fail (GTK_IS_HEX(self->gh));
+ g_return_if_fail (GTK_IS_HEX(ACTIVE_GH));
(void)widget, (void)action_name, (void)parameter; /* unused */
- common_print (GTK_WINDOW(self), self->gh, /* preview: */ FALSE);
+ common_print (GTK_WINDOW(self), ACTIVE_GH, /* preview: */ FALSE);
}
static void
@@ -1185,14 +1184,11 @@ new_file (GtkWidget *widget,
gh = GTK_HEX(gtk_hex_new (doc));
ghex_application_window_add_hex (self, gh);
- ghex_application_window_set_hex (self, gh);
+ refresh_dialogs (self);
ghex_application_window_activate_tab (self, gh);
ghex_application_window_set_insert_mode (self, TRUE);
}
-/* convenience helper function to build a GtkHex widget pre-loaded with
- * a hex document, from a GFile *.
- */
static GtkHex *
new_gh_from_gfile (GFile *file)
{
@@ -1204,7 +1200,6 @@ new_gh_from_gfile (GFile *file)
g_return_val_if_fail (HEX_IS_DOCUMENT (doc), NULL);
gh = GTK_HEX(gtk_hex_new (doc));
- g_return_val_if_fail (GTK_IS_HEX (gh), NULL);
return gh;
}
@@ -1233,7 +1228,7 @@ open_response_cb (GtkNativeDialog *dialog,
}
static void
-open_file (GtkWidget *widget,
+open_file_action (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
@@ -1332,11 +1327,12 @@ clear_statusbar (GHexApplicationWindow *self)
static void
update_status_message (GHexApplicationWindow *self)
{
- gchar fmt[FMT_LEN], status[STATUS_LEN];
- gint current_pos;
- gint ss, se, len;
+ char fmt[FMT_LEN], status[STATUS_LEN];
+ int current_pos;
+ int ss, se, len;
- if (! GTK_IS_HEX(self->gh)) {
+ if (! ACTIVE_GH)
+ {
clear_statusbar (self);
return;
}
@@ -1345,10 +1341,10 @@ update_status_message (GHexApplicationWindow *self)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
- current_pos = gtk_hex_get_cursor(self->gh);
+ current_pos = gtk_hex_get_cursor(ACTIVE_GH);
if (g_snprintf(fmt, FMT_LEN, _("Offset: %s"), offset_fmt) < FMT_LEN) {
g_snprintf(status, STATUS_LEN, fmt, current_pos);
- if (gtk_hex_get_selection(self->gh, &ss, &se)) {
+ if (gtk_hex_get_selection(ACTIVE_GH, &ss, &se)) {
if (g_snprintf(fmt, FMT_LEN, _("; %s bytes from %s to %s selected"),
offset_fmt, offset_fmt, offset_fmt) < FMT_LEN) {
len = strlen(status);
@@ -1609,9 +1605,6 @@ ghex_application_window_dispose(GObject *object)
g_clear_pointer (&self->chartable, gtk_widget_unparent);
g_clear_pointer (&self->converter, gtk_widget_unparent);
- /* Unref GtkHex */
- g_list_free_full (g_steal_pointer (&self->gh_list), g_object_unref);
-
/* Clear conversions box CSS provider */
g_clear_object (&self->conversions_box_provider);
@@ -1708,7 +1701,7 @@ ghex_application_window_class_init(GHexApplicationWindowClass *klass)
gtk_widget_class_install_action (widget_class, "ghex.open",
NULL, /* GVariant string param_type */
- open_file);
+ open_file_action);
gtk_widget_class_install_action (widget_class, "ghex.save",
NULL, /* GVariant string param_type */
@@ -1916,25 +1909,6 @@ ghex_application_window_activate_tab (GHexApplicationWindow *self,
gtk_widget_grab_focus (GTK_WIDGET(gh));
}
-void
-ghex_application_window_set_hex (GHexApplicationWindow *self,
- GtkHex *gh)
-{
- HexDocument *doc = gtk_hex_get_document (gh);
-
- g_return_if_fail (GTK_IS_HEX(gh));
- g_return_if_fail (HEX_IS_DOCUMENT(doc));
-
- g_debug ("%s: Setting active gh to: %p",
- __func__, (void *)gh);
-
- self->gh = gh;
-
- /* Update dialogs: */
-
- refresh_dialogs (self);
-}
-
void
ghex_application_window_add_hex (GHexApplicationWindow *self,
GtkHex *gh)
@@ -1957,22 +1931,11 @@ ghex_application_window_add_hex (GHexApplicationWindow *self,
/* GtkHex: Set insert mode based on our global appwindow prop */
gtk_hex_set_insert_mode (gh, self->insert_mode);
- /* Add this GtkHex to our internal list
- */
- self->gh_list = g_list_append (self->gh_list, gh);
- g_object_ref (gh);
-
- /* Set this GtkHex as the current viewed gh if there is no currently
- * open document
- */
- if (! self->gh)
- ghex_application_window_set_hex (self, gh);
-
/* Generate a tab */
- tab = ghex_notebook_tab_new ();
- ghex_notebook_tab_add_hex (GHEX_NOTEBOOK_TAB(tab), gh);
- g_signal_connect (tab, "closed",
- G_CALLBACK(tab_close_cb), self);
+ tab = ghex_notebook_tab_new (gh);
+
+ g_signal_connect (tab, "close-request",
+ G_CALLBACK(tab_close_request_cb), self);
gtk_notebook_append_page (GTK_NOTEBOOK(self->hex_notebook),
GTK_WIDGET(gh),
@@ -2003,21 +1966,77 @@ ghex_application_window_add_hex (GHexApplicationWindow *self,
G_CALLBACK(ghex_application_window_file_saved_cb), self);
}
-GList *
-ghex_application_window_get_list (GHexApplicationWindow *self)
+#ifndef EXPERIMENTAL_MMAP
+/* Helper */
+static void
+nag_screen_response_cb (GtkDialog *nag_screen,
+ int response,
+ gpointer user_data)
{
- g_return_val_if_fail (GHEX_IS_APPLICATION_WINDOW (self), NULL);
+ GHexApplicationWindow *self = GHEX_APPLICATION_WINDOW (user_data);
+
+ switch (response)
+ {
+ case GTK_RESPONSE_YES:
+ ghex_application_window_open_file (self,
+ tmp_global_gfile_for_nag_screen);
+ break;
+
+ default:
+ break;
+ }
+ gtk_window_destroy (GTK_WINDOW(nag_screen));
+}
+
+/* Helper */
+static void
+do_nag_screen (GHexApplicationWindow *self)
+{
+ GtkWidget *nag_screen;
+ char *msg = _("You are attempting to open a file 1GB or larger.\n\n"
+ "This can make GHex and your machine unstable as the file "
+ "will be loaded into memory.\n\n"
+ "Are you sure you want to proceed?\n\n"
+ "This message will not be shown again for the remainder of "
+ "this GHex session.\n\n"
+ "This limitation will be removed in a future version of GHex.");
+
+ g_printerr (msg); g_printerr ("\n");
- return self->gh_list;
+ nag_screen = gtk_message_dialog_new (GTK_WINDOW(self),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_YES_NO,
+ msg);
+ g_signal_connect (nag_screen, "response",
+ G_CALLBACK(nag_screen_response_cb), self);
+ gtk_widget_show (nag_screen);
}
+#endif
void
ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
{
GtkHex *gh;
+#ifndef EXPERIMENTAL_MMAP
+ static gboolean nag_screen_shown = FALSE;
+#endif
g_return_if_fail (GHEX_IS_APPLICATION_WINDOW(self));
+#ifndef EXPERIMENTAL_MMAP
+ if (! nag_screen_shown)
+ /* FIXME: Temporary nag-screen until we get the underlying issues
+ * sorted. */
+ if (hex_buffer_util_get_file_size (file) >= 1073741824)
+ {
+ nag_screen_shown = TRUE;
+ tmp_global_gfile_for_nag_screen = file;
+ do_nag_screen (self);
+ return;
+ }
+#endif
+
/* If we get it from the GApp :open signal, it's tfr:none - once
* HexDocument gets hold of it, though, it _refs it itself so we don't need
* to hold onto it.
@@ -2027,16 +2046,23 @@ ghex_application_window_open_file (GHexApplicationWindow *self, GFile *file)
gh = new_gh_from_gfile (file);
ghex_application_window_add_hex (self, gh);
- ghex_application_window_set_hex (self, gh);
+ refresh_dialogs (self);
ghex_application_window_activate_tab (self, gh);
g_object_unref (file);
}
-
+
GtkHex *
ghex_application_window_get_hex (GHexApplicationWindow *self)
{
+ GHexNotebookTab *tab;
+ GtkHex *gh = NULL;
+
g_return_val_if_fail (GHEX_IS_APPLICATION_WINDOW (self), NULL);
- return self->gh;
+ tab = ghex_application_window_get_current_tab (self);
+ if (tab)
+ gh = ghex_notebook_tab_get_hex (tab);
+
+ return gh;
}
diff --git a/src/ghex-notebook-tab.c b/src/ghex-notebook-tab.c
index 0d5e596..f1462ad 100644
--- a/src/ghex-notebook-tab.c
+++ b/src/ghex-notebook-tab.c
@@ -25,7 +25,7 @@
#include "ghex-notebook-tab.h"
enum signal_types {
- CLOSED,
+ CLOSE_REQUEST,
LAST_SIGNAL
};
@@ -87,7 +87,7 @@ ghex_notebook_tab_close_click_cb (GtkButton *button,
GHexNotebookTab *self = GHEX_NOTEBOOK_TAB(user_data);
g_signal_emit(self,
- signals[CLOSED],
+ signals[CLOSE_REQUEST],
0); /* GQuark detail (just set to 0 if unknown) */
}
@@ -134,8 +134,7 @@ ghex_notebook_tab_dispose (GObject *object)
/* Unparent children */
g_clear_pointer (&self->label, gtk_widget_unparent);
g_clear_pointer (&self->close_btn, gtk_widget_unparent);
- g_object_unref (self->gh);
-
+
/* Boilerplate: chain up */
G_OBJECT_CLASS(ghex_notebook_tab_parent_class)->dispose(object);
}
@@ -164,7 +163,7 @@ ghex_notebook_tab_class_init (GHexNotebookTabClass *klass)
/* SIGNALS */
- signals[CLOSED] = g_signal_new_class_handler("closed",
+ signals[CLOSE_REQUEST] = g_signal_new_class_handler("close-request",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
/* GCallback class_handler: */
@@ -202,17 +201,7 @@ refresh_file_name (GHexNotebookTab *self)
g_free (basename);
}
-/* Public Methods */
-
-GtkWidget *
-ghex_notebook_tab_new (void)
-{
- return g_object_new (GHEX_TYPE_NOTEBOOK_TAB,
- /* no properties to set */
- NULL);
-}
-
-void
+static void
ghex_notebook_tab_add_hex (GHexNotebookTab *self, GtkHex *gh)
{
HexDocument *doc;
@@ -228,9 +217,10 @@ ghex_notebook_tab_add_hex (GHexNotebookTab *self, GtkHex *gh)
g_return_if_fail (HEX_IS_DOCUMENT (doc));
/* Associate this notebook tab with a GtkHex widget. */
- g_object_ref (gh);
self->gh = gh;
+ g_object_add_weak_pointer (G_OBJECT(self->gh), (gpointer *)&self->gh);
+
/* Set name of tab. */
refresh_file_name (self);
@@ -245,6 +235,17 @@ ghex_notebook_tab_add_hex (GHexNotebookTab *self, GtkHex *gh)
G_CALLBACK(refresh_file_name), self);
}
+/* Public Methods */
+
+GtkWidget *
+ghex_notebook_tab_new (GtkHex *gh)
+{
+ GHexNotebookTab *self = g_object_new (GHEX_TYPE_NOTEBOOK_TAB, NULL);
+ ghex_notebook_tab_add_hex (self, gh);
+
+ return GTK_WIDGET(self);
+}
+
const char *
ghex_notebook_tab_get_filename (GHexNotebookTab *self)
{
@@ -257,7 +258,7 @@ ghex_notebook_tab_get_filename (GHexNotebookTab *self)
GtkHex *
ghex_notebook_tab_get_hex (GHexNotebookTab *self)
{
- g_return_val_if_fail (GTK_IS_HEX (self->gh), NULL);
+ g_return_val_if_fail (GHEX_IS_NOTEBOOK_TAB (self), NULL);
return self->gh;
}
diff --git a/src/ghex-notebook-tab.h b/src/ghex-notebook-tab.h
index e4c8647..eaea4d3 100644
--- a/src/ghex-notebook-tab.h
+++ b/src/ghex-notebook-tab.h
@@ -38,8 +38,7 @@ G_DECLARE_FINAL_TYPE (GHexNotebookTab, ghex_notebook_tab, GHEX, NOTEBOOK_TAB,
/* Method Declarations */
-GtkWidget * ghex_notebook_tab_new (void);
-void ghex_notebook_tab_add_hex (GHexNotebookTab *self, GtkHex *gh);
+GtkWidget * ghex_notebook_tab_new (GtkHex *gh);
const char * ghex_notebook_tab_get_filename (GHexNotebookTab *self);
GtkHex * ghex_notebook_tab_get_hex (GHexNotebookTab *self);
diff --git a/src/gtkhex-layout-manager.c b/src/gtkhex-layout-manager.c
index 697afa5..666b95a 100644
--- a/src/gtkhex-layout-manager.c
+++ b/src/gtkhex-layout-manager.c
@@ -37,6 +37,8 @@ struct _GtkHexLayout {
int cpl;
int hex_cpl;
+
+ int cursor_x, cursor_y;
};
G_DEFINE_TYPE (GtkHexLayout, gtk_hex_layout, GTK_TYPE_LAYOUT_MANAGER)
@@ -62,6 +64,7 @@ gtk_hex_layout_column_get_type (void)
{
static GType hex_layout_column_type = 0;
static const GEnumValue format_types[] = {
+ {NO_COLUMN, "No column", "no-column"},
{OFFSETS_COLUMN, "Offsets", "offsets"},
{HEX_COLUMN, "Hex", "hex"},
{ASCII_COLUMN, "ASCII", "ascii"},
@@ -150,7 +153,7 @@ gtk_hex_layout_child_class_init (GtkHexLayoutChildClass *klass)
"Column type",
"The column type of a child of a hex layout",
GTK_HEX_LAYOUT_COLUMN,
- HEX_COLUMN,
+ NO_COLUMN,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
@@ -230,6 +233,12 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
{
GtkHexLayoutChild *child_info;
+ if (GTK_IS_POPOVER (child))
+ {
+ gtk_popover_set_pointing_to (GTK_POPOVER(child),
+ &(const GdkRectangle){ self->cursor_x, self->cursor_y, 1, 1 });
+ }
+
/* If it's invisible, etc., this should fail. */
if (! gtk_widget_should_layout (child))
continue;
@@ -250,6 +259,30 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
break;
case SCROLLBAR_COLUMN: scrollbar = child;
break;
+
+ case NO_COLUMN:
+ {
+#if 0
+ GtkRequisition child_req;
+ GtkAllocation alloc = {0};
+
+ gtk_widget_get_preferred_size (child, &child_req, NULL);
+
+ alloc.height = child_req.height;
+ alloc.width = child_req.width;
+
+ if (GTK_IS_POPOVER (child))
+ {
+ alloc.x = self->cursor_x;
+ alloc.y = self->cursor_y;
+ }
+
+ gtk_widget_size_allocate (child, &alloc, -1);
+ return;
+#endif
+ }
+ break;
+
/* We won't test for this each loop. */
default:
g_error ("%s: Programmer error. Requested column invalid.",
@@ -475,6 +508,13 @@ gtk_hex_layout_get_hex_cpl (GtkHexLayout *layout)
return layout->hex_cpl;
}
+void
+gtk_hex_layout_set_cursor_pos (GtkHexLayout *layout, int x, int y)
+{
+ layout->cursor_x = x;
+ layout->cursor_y = y;
+}
+
/* GtkHexLayoutChild - Public Methods */
void
diff --git a/src/gtkhex-layout-manager.h b/src/gtkhex-layout-manager.h
index 48f44b8..e4512ad 100644
--- a/src/gtkhex-layout-manager.h
+++ b/src/gtkhex-layout-manager.h
@@ -37,6 +37,7 @@ G_DECLARE_FINAL_TYPE (GtkHexLayout, gtk_hex_layout, GTK, HEX_LAYOUT,
GtkLayoutManager)
typedef enum {
+ NO_COLUMN,
OFFSETS_COLUMN,
HEX_COLUMN,
ASCII_COLUMN,
@@ -57,6 +58,8 @@ int gtk_hex_layout_get_cpl (GtkHexLayout *layout);
int gtk_hex_layout_get_hex_cpl (GtkHexLayout *layout);
void gtk_hex_layout_set_group_type (GtkHexLayout *layout,
guint group_type);
+void gtk_hex_layout_set_cursor_pos (GtkHexLayout *layout,
+ int x, int y);
G_END_DECLS
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 0d48884..08d045b 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -207,15 +207,6 @@ static void show_cursor (GtkHex *gh, gboolean show);
/* GtkHex - Method Definitions */
-static void
-popup_context_menu (GtkHex *gh, int x, int y)
-{
- GdkRectangle rect = { .x = x, .y = y, .width = 1, .height = 1 };
-
- gtk_popover_set_pointing_to (GTK_POPOVER(gh->context_menu), &rect);
- gtk_popover_popup (GTK_POPOVER(gh->context_menu));
-}
-
/* ACTIONS */
static void
@@ -1382,7 +1373,8 @@ gh_pressed_cb (GtkGestureClick *gesture,
{
GtkHex *gh = GTK_HEX (user_data);
- popup_context_menu (gh, x, y);
+ gtk_hex_layout_set_cursor_pos (GTK_HEX_LAYOUT(gh->layout_manager), x, y);
+ gtk_popover_popup (GTK_POPOVER(gh->context_menu));
}
static void
@@ -2261,9 +2253,11 @@ gtk_hex_dispose (GObject *object)
g_clear_pointer (&gh->offsets, gtk_widget_unparent);
g_clear_pointer (&gh->scrollbar, gtk_widget_unparent);
- /* Clear layout manager
+ /* FIXME - This results in assertion errors upon exit. I have been told
+ * by ebassi on IRC (16-Dec-2021) that this may be a bug in gtk. See:
+ * https://gitlab.gnome.org/GNOME/gtk/-/issues/4548
*/
- g_clear_object (&gh->layout_manager);
+ g_clear_pointer (&gh->context_menu, gtk_widget_unparent);
/* Clear pango layouts
*/
@@ -2271,7 +2265,7 @@ gtk_hex_dispose (GObject *object)
g_clear_object (&gh->alayout);
g_clear_object (&gh->olayout);
- g_object_unref (&gh->document);
+ g_clear_object (&gh->document);
/* Chain up */
G_OBJECT_CLASS(gtk_hex_parent_class)->dispose(object);
diff --git a/src/hex-buffer-malloc.h b/src/hex-buffer-malloc.h
index ed63626..f44c81b 100644
--- a/src/hex-buffer-malloc.h
+++ b/src/hex-buffer-malloc.h
@@ -16,7 +16,7 @@
#ifndef HEX_DOCUMENT_MALLOC_H
#define HEX_DOCUMENT_MALLOC_H
-#include "hex-buffer-iface.h"
+#include <hex-buffer-iface.h>
#define _GNU_SOURCE
diff --git a/src/hex-buffer-mmap.c b/src/hex-buffer-mmap.c
index 9c6944b..31193e7 100644
--- a/src/hex-buffer-mmap.c
+++ b/src/hex-buffer-mmap.c
@@ -112,6 +112,7 @@ hex_buffer_mmap_finalize (GObject *gobject)
HexBufferMmap *self = HEX_BUFFER_MMAP (gobject);
munmap (self->data, self->mapped);
+ munmap (self->clean, self->clean_bytes);
if (self->fd >= 0)
{
@@ -636,4 +637,3 @@ hex_buffer_mmap_iface_init (HexBufferInterface *iface)
iface->write_to_file = hex_buffer_mmap_write_to_file;
iface->get_payload_size = hex_buffer_mmap_get_payload_size;
}
-
diff --git a/src/hex-buffer-mmap.h b/src/hex-buffer-mmap.h
index 535fd31..9b63309 100644
--- a/src/hex-buffer-mmap.h
+++ b/src/hex-buffer-mmap.h
@@ -13,12 +13,10 @@
* Copyright © 2021 Logan Rathbone
*/
-// WIP - NOT WORKING CODE!
-
#ifndef HEX_DOCUMENT_MMAP_H
#define HEX_DOCUMENT_MMAP_H
-#include "hex-buffer-iface.h"
+#include <hex-buffer-iface.h>
#define _GNU_SOURCE
diff --git a/src/hex-document.c b/src/hex-document.c
index b824494..e5a5e1f 100644
--- a/src/hex-document.c
+++ b/src/hex-document.c
@@ -30,24 +30,26 @@
Author: Jaka Mocnik <jaka gnu org>
*/
-#include <glib-object.h>
-#include <glib/gi18n.h>
-
-#include <gtkhex.h>
-
-/* FIXME / TODO - Allow for swappability. Hardcoding for now for testing
- * purposes.
- */
-//#include "hex-buffer-malloc.h"
-#include "hex-buffer-mmap.h"
+#include "hex-document.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
+#include <glib/gi18n.h>
+
#include <config.h>
+/* FIXME / TODO - Allow for swappability. Hardcoding for now for testing
+ * purposes. Keep this include below config.h, as it is (un)def'd there.
+ */
+#ifdef EXPERIMENTAL_MMAP
+# include "hex-buffer-mmap.h"
+#else
+# include "hex-buffer-malloc.h"
+#endif
+
static void hex_document_real_changed (HexDocument *doc,
gpointer change_data,
gboolean undoable);
@@ -115,10 +117,6 @@ undo_stack_push(HexDocument *doc, HexChangeData *change_data)
HexChangeData *cd;
GList *stack_rest;
-#ifdef ENABLE_DEBUG
- g_message("undo_stack_push");
-#endif
-
if(doc->undo_stack != doc->undo_top) {
stack_rest = doc->undo_stack;
doc->undo_stack = doc->undo_top;
@@ -138,17 +136,9 @@ undo_stack_push(HexDocument *doc, HexChangeData *change_data)
doc->undo_depth++;
-#ifdef ENABLE_DEBUG
- g_message("depth at: %d", doc->undo_depth);
-#endif
-
if(doc->undo_depth > doc->undo_max) {
GList *last;
-#ifdef ENABLE_DEBUG
- g_message("forget last undo");
-#endif
-
last = g_list_last(doc->undo_stack);
doc->undo_stack = g_list_remove_link(doc->undo_stack, last);
doc->undo_depth--;
@@ -167,28 +157,16 @@ undo_stack_push(HexDocument *doc, HexChangeData *change_data)
static void
undo_stack_descend(HexDocument *doc)
{
-#ifdef ENABLE_DEBUG
- g_message("undo_stack_descend");
-#endif
-
if(doc->undo_top == NULL)
return;
doc->undo_top = doc->undo_top->next;
doc->undo_depth--;
-
-#ifdef ENABLE_DEBUG
- g_message("undo depth at: %d", doc->undo_depth);
-#endif
}
static void
undo_stack_ascend(HexDocument *doc)
{
-#ifdef ENABLE_DEBUG
- g_message("undo_stack_ascend");
-#endif
-
if(doc->undo_stack == NULL || doc->undo_top == doc->undo_stack)
return;
@@ -202,10 +180,6 @@ undo_stack_ascend(HexDocument *doc)
static void
undo_stack_free(HexDocument *doc)
{
-#ifdef ENABLE_DEBUG
- g_message("undo_stack_free");
-#endif
-
if(doc->undo_stack == NULL)
return;
@@ -225,6 +199,8 @@ hex_document_dispose (GObject *obj)
if (doc->file)
g_object_unref (doc->file);
+ g_clear_object (&doc->buffer);
+
G_OBJECT_CLASS(hex_document_parent_class)->dispose (obj);
}
@@ -312,9 +288,11 @@ hex_document_class_init (HexDocumentClass *klass)
static void
hex_document_init (HexDocument *doc)
{
-// doc->buffer = HEX_BUFFER(hex_buffer_malloc_new (NULL));
- // TEST
+#ifdef EXPERIMENTAL_MMAP
doc->buffer = HEX_BUFFER(hex_buffer_mmap_new (NULL));
+#else
+ doc->buffer = HEX_BUFFER(hex_buffer_malloc_new (NULL));
+#endif
doc->undo_max = DEFAULT_UNDO_DEPTH;
}
diff --git a/src/hex-document.h b/src/hex-document.h
index 2bdd5f4..bedccc0 100644
--- a/src/hex-document.h
+++ b/src/hex-document.h
@@ -36,9 +36,8 @@
#include <stdio.h>
#include <glib-object.h>
-#include <gtk/gtk.h>
-#include "hex-buffer-iface.h"
+#include <hex-buffer-iface.h>
G_BEGIN_DECLS
diff --git a/src/main.c b/src/main.c
index 7757908..2f8772f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -119,6 +119,11 @@ activate (GtkApplication *app,
gtk_window_set_application (window, app);
gtk_window_present (window);
+
+#ifdef EXPERIMENTAL_MMAP
+ g_warning ("Your build has the HIGHLY EXPERIMENTAL `mmap` backend enabled. "
+ "Use with care! Do NOT trust this with any important data!");
+#endif
}
static void
@@ -130,9 +135,6 @@ open (GApplication *application,
{
GHexApplicationWindow *app_win;
-// if (n_files > 1)
-// g_warning ("Can only open a single file");
-
activate (GTK_APPLICATION(application), NULL);
app_win = GHEX_APPLICATION_WINDOW(window);
diff --git a/src/meson.build b/src/meson.build
index 5132fa1..1d4b737 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,8 +1,8 @@
libghex_sources = [
'gtkhex.c',
'hex-buffer-iface.c', # TEST
- 'hex-buffer-malloc.c', # TEST
'hex-buffer-mmap.c', # TEST
+ 'hex-buffer-malloc.c', # TEST
'gtkhex-layout-manager.c',
'gtkhex-paste-data.c',
'hex-document.c'
@@ -11,6 +11,8 @@ libghex_sources = [
libghex_headers = [
'hex-document.h',
'hex-buffer-iface.h',
+ 'hex-buffer-malloc.h',
+ 'hex-buffer-mmap.h',
'gtkhex.h',
'gtkhex-paste-data.h'
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]