diff options
| author | Mattias Andrée <m@maandree.se> | 2026-06-06 20:39:36 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-06-06 20:39:36 +0200 |
| commit | e61c74dba5dd3cd2a3e48aa1fc7ff2658e5cb6e1 (patch) | |
| tree | ed75883a7c2527e2adc395b5e20c06d00632a5b7 | |
| parent | Second commit (diff) | |
| download | gcmap-e61c74dba5dd3cd2a3e48aa1fc7ff2658e5cb6e1.tar.gz gcmap-e61c74dba5dd3cd2a3e48aa1fc7ff2658e5cb6e1.tar.bz2 gcmap-e61c74dba5dd3cd2a3e48aa1fc7ff2658e5cb6e1.tar.xz | |
misc
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | LICENSE | 2 | ||||
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | README | 2 | ||||
| -rw-r--r-- | char-table.c | 44 | ||||
| -rw-r--r-- | char-table.h | 23 | ||||
| -rw-r--r-- | common.h | 27 | ||||
| -rw-r--r-- | config.mk | 4 | ||||
| -rw-r--r-- | gcmap.1 | 2 | ||||
| -rw-r--r-- | gcmap.c | 75 |
9 files changed, 134 insertions, 52 deletions
@@ -1,6 +1,6 @@ ISC License -© 2025 Mattias Andrée <m@maandree.se> +© 2025, 2026 Mattias Andrée <m@maandree.se> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -4,9 +4,12 @@ CONFIGFILE = config.mk include $(CONFIGFILE) OBJ =\ - gcmap.o + gcmap.o\ + char-table.o -HDR = +HDR =\ + common.h\ + char-table.h all: gcmap $(OBJ): $(HDR) @@ -42,4 +42,4 @@ OPERANDS No operands are supported. SEE ALSO - None. + cmap(1) diff --git a/char-table.c b/char-table.c new file mode 100644 index 0000000..da82544 --- /dev/null +++ b/char-table.c @@ -0,0 +1,44 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +G_DEFINE_TYPE(CharTable, gcmap_char_table, GTK_TYPE_DRAWING_AREA) + + +static gboolean +gcmap_char_table_expose(GtkWidget *widget, GdkEventExpose *event) +{ + cairo_t *cr = gdk_cairo_create(widget->window); + + (void) event; + + cairo_set_source_rgb(cr, 0.2f, 0.2f, 0.2f); + cairo_paint(cr); + + cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f); + cairo_move_to(cr, 10, 20); + cairo_show_text(cr, "Hello GTK+ 2"); + + cairo_destroy(cr); + return FALSE; +} + +static void +gcmap_char_table_init(CharTable *self) +{ + gtk_widget_set_size_request(GTK_WIDGET(self), 200, 100); +} + + +static void +gcmap_char_table_class_init(CharTableClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + widget_class->expose_event = gcmap_char_table_expose; +} + + +GtkWidget * +gcmap_char_table_new(void) +{ + return g_object_new(GCMAP_TYPE_CHAR_TABLE, NULL); +} diff --git a/char-table.h b/char-table.h new file mode 100644 index 0000000..0097e05 --- /dev/null +++ b/char-table.h @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define GCMAP_TYPE_CHAR_TABLE (gcmap_char_table_get_type()) +#define GCMAP_TYPE_CHAR(OBJ) (G_TYPE_CHECK_INSTANCE_CAST((OBJ), GCMAP_TYPE_CHAR_TABLE, CharTable)) +#define GCMAP_CHAR_TABLE_CLASS(CLASS) (G_TYPE_CHECK_CLASS_CAST((CLASS), GCMAP_TYPE_CHAR_TABLE, CharTableClass)) +#define IS_GCMAP_CHAR_TABLE(OBJ) (G_TYPE_CHECK_INSTANCE_TYPE((OBJ), GCMAP_TYPE_CHAR_TABLE)) +#define IS_GCMAP_CHAR_TABLE_CLASS(CLASS) (G_TYPE_CHECK_CLASS_TYPE((CLASS), GCMAP_TYPE_CHAR_TABLE)) +#define GCMAP_CHAR_TABLE_GET_CLASS(OBJ) (G_TYPE_INSTANCE_GET_CLASS((OBJ), GCMAP_TYPE_CHAR_TABLE, CharTableClass)) + + +typedef struct _CharTable { + GtkDrawingArea parent_instance; +} CharTable; + +typedef struct _CharTableClass { + GtkDrawingAreaClass parent_class; +} CharTableClass; + + +GType gcmap_char_table_get_type(void); +GtkWidget *gcmap_char_table_new(void); diff --git a/common.h b/common.h new file mode 100644 index 0000000..a7cd690 --- /dev/null +++ b/common.h @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef COMMON_H_ +#define COMMON_H_ + +#include <libsimple.h> +#include <libsimple-arg.h> +#include <libcmap.h> +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + +#if GTK_CHECK_VERSION(2, 12, 0) +# define HAVE_ITEM_TOOLTIPS +#endif + +#define COMMA , + +#include "char-table.h" + +#endif @@ -4,8 +4,8 @@ MANPREFIX = $(PREFIX)/share/man CC = c99 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -CFLAGS = -LDFLAGS = -lsimple -lcmap +CFLAGS = $$(pkg-config --cflags pango) +LDFLAGS = -lsimple -lcmap $$(pkg-config --libs pango) CFLAGS_GTK2 = $$(pkg-config --cflags gtk+-2.0) LDFLAGS_GTK2 = $$(pkg-config --libs gtk+-2.0) @@ -64,4 +64,4 @@ is affected by environment variables that affects its tooltik. .SH SEE ALSO -None. +.BR cmap (1) @@ -1,28 +1,9 @@ /* See LICENSE file for copyright and license details. */ -#include <libsimple.h> -#include <libsimple-arg.h> -#include <libcmap.h> -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# pragma GCC diagnostic ignored "-Wstrict-prototypes" -#endif -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif +#include "common.h" USAGE("[-f font-family] [-s [font-size][/[[min]-[max]]]] [-B | -S] [-bi]"); -#if GTK_CHECK_VERSION(2, 12, 0) -# define HAVE_ITEM_TOOLTIPS -#endif - - -#define COMMA , - #define DEFAULT_LISTING_TYPE "script" #define LIST_LISTINGS(X, D)\ X(BY_SCRIPT, "By _script", DEFAULT_LISTING_TYPE, by_script_selected, populate_scripts, GDK_s) D\ @@ -37,6 +18,9 @@ enum listing { #define NLISTINGS_X(...) (size_t)1 #define NLISTINGS (LIST_LISTINGS(NLISTINGS_X, +)) + +static const struct libcmap_block all_block = {.name = "All", .range = LIBCMAP_UNIVERSE_RANGE}; + static unsigned int min_font_size = 4; static unsigned int default_font_size = 22; static unsigned int max_font_size = 500; @@ -139,7 +123,6 @@ grouplist_query_tooltip(GtkWidget *widget, int x, int y, int keyboard_mode, static char * script_tooltip(const struct libcmap_script *script) { - unsigned long int low, high; size_t i, len, off = 0; int r; char *ret; @@ -149,9 +132,7 @@ script_tooltip(const struct libcmap_script *script) len = strlen(script->name) + 1U; for (i = 0; i < script->nranges; i++) { - low = (unsigned long int)script->ranges[i].first; - high = (unsigned long int)script->ranges[i].last; - r = snprintf(NULL, 0, "U+%04lX–U+%04lX", low, high); + r = libcmap_sprint_range(NULL, &script->ranges[i], NULL); if (r < 0) return NULL; len += (size_t)r + 2U; @@ -161,14 +142,15 @@ script_tooltip(const struct libcmap_script *script) if (!ret) return NULL; - stpcpy(ret, script->name); - off = strlen(script->name); + off = (size_t)(stpcpy(ret, script->name) - ret); ret[off++] = ' '; ret[off++] = '('; for (i = 0; i < script->nranges; i++) { - low = (unsigned long int)script->ranges[i].first; - high = (unsigned long int)script->ranges[i].last; - r = sprintf(&ret[off], "%sU+%04lX–U+%04lX", i ? ", " : "", low, high); + if (i) { + ret[off++] = ','; + ret[off++] = ' '; + } + r = libcmap_sprint_range(&ret[off], &script->ranges[i], NULL); if (r < 0) return NULL; off += (size_t)r; @@ -185,22 +167,25 @@ script_tooltip(const struct libcmap_script *script) static char * block_tooltip(const struct libcmap_block *block) { - unsigned long int low = (unsigned long int)block->range.first; - unsigned long int high = (unsigned long int)block->range.last; int len, r; - char *ret; + char *ret, *p; + size_t size; - len = snprintf(NULL, 0, "%s (U+%04lX–U+%04lX)", block->name, low, high); + size = strlen(block->name) + sizeof(" ()"); + len = libcmap_sprint_range(NULL, &block->range, NULL); if (len < 0) return NULL; + size += (size_t)len; - ret = malloc((size_t)len + 1U); + ret = malloc(size); if (!ret) return NULL; - r = sprintf(ret, "%s (U+%04lX–U+%04lX)", block->name, low, high); + p = stpcpy(stpcpy(ret, block->name), " ("); + r = libcmap_sprint_range(p, &block->range, NULL); if (r < 0 || r > len) abort(); + stpcpy(&p[r], ")"); return ret; } @@ -227,7 +212,7 @@ populate_scripts(GtkListStore *store) if (!group_tooltips[BY_SCRIPT]) { ngroup_tooltips[BY_SCRIPT] = n + 1U; group_tooltips[BY_SCRIPT] = calloc(ngroup_tooltips[BY_SCRIPT], sizeof(**group_tooltips)); - group_tooltips[BY_SCRIPT][0] = "All (U+0000–U+10FFFF)"; + group_tooltips[BY_SCRIPT][0] = block_tooltip(&all_block); for (i = 0; i < n; i++) { if (!strcmp(list[i].name, "Unknown")) group_tooltips[BY_SCRIPT][i + 1U] = "Unknown (Codepoints not assigned any script)"; @@ -261,7 +246,7 @@ populate_blocks(GtkListStore *store) if (!group_tooltips[BY_BLOCK]) { ngroup_tooltips[BY_BLOCK] = n + 2U; group_tooltips[BY_BLOCK] = calloc(ngroup_tooltips[BY_BLOCK], sizeof(**group_tooltips)); - group_tooltips[BY_BLOCK][0] = "All (U+0000–U+10FFFF)"; + group_tooltips[BY_BLOCK][0] = block_tooltip(&all_block); group_tooltips[BY_BLOCK][n + 1U] = "No Block (Codepoints not assigned any block)"; for (i = 0; i < n; i++) group_tooltips[BY_BLOCK][i + 1U] = block_tooltip(&list[i]); @@ -299,7 +284,7 @@ fontcombo_changed(GtkComboBox *combo, void *user_data) /* TODO */ (void) user_data; if (!gtk_combo_box_get_active_iter(combo, &iter)) return; - gtk_tree_model_get(GTK_TREE_MODEL(fontcombo_store), &iter,0, &family, -1); + gtk_tree_model_get(GTK_TREE_MODEL(fontcombo_store), &iter, 0, &family, -1); if (!family) return; } @@ -764,7 +749,7 @@ create_window(void) gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(fontcombo), FALSE); gtk_box_pack_start(GTK_BOX(hbox), fontcombo, FALSE, FALSE, 0); gtk_combo_box_set_active(GTK_COMBO_BOX(fontcombo), -1); - g_signal_connect(fontcombo, "changed", G_CALLBACK(fontcombo_changed), NULL); + g_signal_connect(fontcombo, "changed", G_CALLBACK(&fontcombo_changed), NULL); accessible = gtk_widget_get_accessible(fontcombo); atk_object_set_name(accessible, "Font family"); @@ -822,7 +807,7 @@ create_window(void) scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_NONE); - gtk_container_add(GTK_CONTAINER(scrolled), gtk_label_new("TODO")); + gtk_container_add(GTK_CONTAINER(scrolled), gcmap_char_table_new()); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled, gtk_label_new_with_mnemonic("Character _table")); #ifdef TODO @@ -1017,20 +1002,20 @@ main(int argc, char *argv[]) gtk_init(&xargc, &xargv); theme = gtk_icon_theme_get_default(); - if (!gtk_icon_theme_has_icon(theme, icon = "apps/gcmap") || - !gtk_icon_theme_has_icon(theme, icon = "gcmap") || - !gtk_icon_theme_has_icon(theme, icon = "apps/accessories-character-map") || + if (!gtk_icon_theme_has_icon(theme, icon = "apps/gcmap") && + !gtk_icon_theme_has_icon(theme, icon = "gcmap") && + !gtk_icon_theme_has_icon(theme, icon = "apps/accessories-character-map") && !gtk_icon_theme_has_icon(theme, icon = "accessories-character-map")) icon = "gcmap"; gtk_window_set_default_icon_name(icon); create_window(); gtk_window_set_icon_name(GTK_WINDOW(window), icon); + gtk_window_set_wmclass(GTK_WINDOW(window), "gcmap", "gcmap"); + gtk_window_set_role(GTK_WINDOW(window), "gcmap"); if (gtk_combo_box_get_active(GTK_COMBO_BOX(listcombo)) != (int)listing) gtk_combo_box_set_active(GTK_COMBO_BOX(listcombo), (int)listing); - if (gtk_combo_box_get_active(GTK_COMBO_BOX(listcombo)) != (int)listing) - gtk_combo_box_set_active(GTK_COMBO_BOX(listcombo), (int)listing); if (use_bold) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bold), TRUE); if (use_italic) |
