From 546545b195150679092b2aeae85c268bd94c7000 Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Sun, 10 Nov 2024 18:04:52 +0100 Subject: [PATCH] Inline::C to XS --- Build.PL | 45 +++++++++++ build-for-flatpak.sh | 8 +- deps | 2 +- lib/Exd.pm | 9 ++- lib/Exd.xs | 123 +++++++++++++++++++++++++++++++ lib/Exd/FileFormat/Fontconfig.pm | 57 +------------- lib/Exd/Fontconfig.pm | 33 --------- lib/Exd/Gui.pm | 30 +------- lib/Exd/Gui/Instance.pm | 13 ++-- run.pl | 18 ----- run.sh | 3 + scripts/main.pl | 2 +- 12 files changed, 195 insertions(+), 148 deletions(-) create mode 100755 Build.PL create mode 100644 lib/Exd.xs delete mode 100755 run.pl create mode 100755 run.sh diff --git a/Build.PL b/Build.PL new file mode 100755 index 0000000..238faa4 --- /dev/null +++ b/Build.PL @@ -0,0 +1,45 @@ +#!/usr/bin/env perl +use Module::Build; + +my $home = $ENV{HOME}; + +my $build = Module::Build->new( + module_name => 'Exd', + license => 'AGPLv3', + dist_author => 'Sergio Iglesias ', + dist_abstract => 'Program your thermal printer.', + requires => { + 'Moo' => 0, + 'IO::File' => 0, + 'Glib' => 0, + 'Glib::IO' => 0, + 'Glib::Object::Introspection' => 0, + 'JSON' => 0, + 'DBI' => 0, + 'DBD::SQLite' => 0, + 'Path::Tiny' => 0, + 'Net::Bluetooth' => 0, + 'Mojolicious' => 0, + 'Pango' => 0, + 'Device::SerialPort' => 0, + 'Archive::Zip' => 0, + 'GD::Image' => 0, + 'Net::DBus' => 0, + 'UUID::URandom' => 0, + 'Capture::Tiny' => 0, + 'Class::Load' => 0, + 'aliased' => 0, + 'Carp::Always' => 0, + 'IO::Socket::SSL' => 0, + 'Scalar::Util::Numeric' => 0, + 'GD::Barcode::QRcode' => 0, + }, + extra_linker_flags => [ '-lfontconfig', '-lfreetype' ], + extra_compiler_flags => [ split /\s/, (`pkg-config --cflags gio-2.0 glib-2.0`) ], + test_requires => { + 'Test::MockModule' => 0, + 'Test::Most' => 0, + 'Test::MockObject' => 0, + } +); +$build->create_build_script; diff --git a/build-for-flatpak.sh b/build-for-flatpak.sh index 39d93fb..31c54df 100644 --- a/build-for-flatpak.sh +++ b/build-for-flatpak.sh @@ -1,16 +1,14 @@ #!/usr/bin/env bash cd HiperthermiaSource - perl lib/Exd/Fontconfig.pm - perl lib/Exd/FileFormat/Fontconfig.pm - perl -Ilib lib/Exd/Gui.pm - chmod 755 -R _Inline/ + perl Build.PL + perl Build build cd - cp HiperthermiaSource/app_config.prod.json HiperthermiaSource/app_config.json cp -vr HiperthermiaSource ${FLATPAK_DEST}/Hiperthermia glib-compile-resources --sourcedir=${FLATPAK_DEST}/Hiperthermia ${FLATPAK_DEST}/Hiperthermia/resources.xml install -Dm644 HiperthermiaSource/me.sergiotarxz.Exd.desktop /app/share/applications/me.sergiotarxz.Exd.desktop install -Dm644 HiperthermiaSource/me.sergiotarxz.Exd.mime.xml /app/share/mime/packages/me.sergiotarxz.Exd.mime.xml -install -Dm755 HiperthermiaSource/run.pl /app/bin/hiperthermia +install -Dm755 HiperthermiaSource/run.sh /app/bin/hiperthermia install -Dm644 HiperthermiaSource/exd-logo.png /app/share/icons/hicolor/256x256/apps/me.sergiotarxz.Exd.png update-mime-database /app/share/mime install -Dm644 HiperthermiaSource/me.sergiotarxz.Exd.metainfo.xml -t /app/share/metainfo/ diff --git a/deps b/deps index 234f44a..01f40a6 100644 --- a/deps +++ b/deps @@ -1 +1 @@ -Moo IO::File Glib Glib::IO Glib::Object::Introspection JSON DBI DBD::SQLite Path::Tiny Net::Bluetooth Inline Inline::C Mojolicious Pango Device::SerialPort Archive::Zip GD::Image Net::DBus UUID::URandom Capture::Tiny Class::Load aliased Carp::Always IO::Socket::SSL Scalar::Util::Numeric GD::Barcode::QRcode +Moo IO::File Glib Glib::IO Glib::Object::Introspection JSON DBI DBD::SQLite Path::Tiny Net::Bluetooth Mojolicious Pango Device::SerialPort Archive::Zip GD::Image Net::DBus UUID::URandom Capture::Tiny Class::Load aliased Carp::Always IO::Socket::SSL Scalar::Util::Numeric GD::Barcode::QRcode diff --git a/lib/Exd.pm b/lib/Exd.pm index 1e66197..bd4f76c 100644 --- a/lib/Exd.pm +++ b/lib/Exd.pm @@ -11,6 +11,9 @@ use JSON; use Path::Tiny; use UUID::URandom qw/create_uuid_string/; +require XSLoader; +XSLoader::load(); + has config => ( is => 'lazy' ); sub _build_config($self) { @@ -18,7 +21,11 @@ sub _build_config($self) { } sub _config_file_name($self) { - return path(__FILE__)->parent->parent->child('app_config.json'); + $self->root->child('app_config.json'); +} + +sub root($class) { + return path(__FILE__)->parent->parent->parent; } sub licenser_server($self) { diff --git a/lib/Exd.xs b/lib/Exd.xs new file mode 100644 index 0000000..4767666 --- /dev/null +++ b/lib/Exd.xs @@ -0,0 +1,123 @@ +#define PERL_NO_GET_CONTEXT +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include +#include +#include "glib-2.0/gio/gio.h" + +FcConfig *old_system_config = NULL; + +void +exd_fileformat_fontconfig__restore_system_config_c(SV *self) { + if (old_system_config != NULL) { + FcConfigSetCurrent(old_system_config); + } +} + +void +exd_fileformat_fontconfig__set_current_c(SV *self, char *font_dir) { + if (old_system_config == NULL) { + old_system_config = FcConfigGetCurrent(); + } + FcConfig *new_config = FcConfigCreate(); + FcConfigAppFontAddDir(new_config, font_dir); + FcConfigBuildFonts(new_config); + FcConfigSetCurrent(new_config); +} + +AV * +exd_fileformat_fontconfig__list_fonts_c(SV *self, char *font_dir) { + AV *return_array = newAV(); + FcConfig *config = FcConfigCreate(); + FcConfigAppFontAddDir(config, font_dir); + FcConfigBuildFonts(config); + FcFontSet *fonts = FcConfigGetFonts(config, FcSetApplication); + if (fonts == NULL) { + return return_array; + } + for (int i = 0; i < fonts->nfont; i++) { + FcPattern *pattern = fonts->fonts[i]; + FcChar8 *family; + FcChar8 *style; + FcChar8 *file; + FcPatternGetString(pattern, FC_FAMILY, 0, &family); + FcPatternGetString(pattern, FC_STYLE, 0, &style); + FcPatternGetString(pattern, FC_FILE, 0, &file); + char *familyKey; + HV *hash = newHV(); + SV *hash_ref = newRV_noinc((SV *) hash); + hv_stores(hash, "family", newSVpv(family, 0)); + hv_stores(hash, "style", newSVpv(style, 0)); + hv_stores(hash, "file", newSVpv(file, 0)); + av_push(return_array, hash_ref); + } + return return_array; +} + +AV * +exd_fontconfig__list_fonts_c(SV *self) { + AV *return_array = newAV(); + FcConfig *config = FcConfigGetCurrent(); + FcFontSet *fonts = FcConfigGetFonts(config, FcSetSystem); + if (fonts == NULL) { + return return_array; + } + for (int i = 0; i < fonts->nfont; i++) { + FcPattern *pattern = fonts->fonts[i]; + FcChar8 *family; + FcChar8 *style; + FcChar8 *file; + FcPatternGetString(pattern, FC_FAMILY, 0, &family); + FcPatternGetString(pattern, FC_STYLE, 0, &style); + FcPatternGetString(pattern, FC_FILE, 0, &file); + char *familyKey; + HV *hash = newHV(); + SV *hash_ref = newRV_noinc((SV *) hash); + hv_stores(hash, "family", newSVpv(family, 0)); + hv_stores(hash, "style", newSVpv(style, 0)); + hv_stores(hash, "file", newSVpv(file, 0)); + av_push(return_array, hash_ref); + } + return return_array; +} + +void +exd_gui__get_first_file(SV *class, size_t int_files) { + dSP; + ENTER; + SAVETMPS; + + GFile *file = (((GFile **)int_files)[0]); + char *path = g_file_get_path(file); + + PUSHMARK(SP); + EXTEND(SP, 2); + PUSHs(class); + PUSHs(sv_2mortal(newSVpv(path, 0))); + PUTBACK; + + call_pv("_activate", G_DISCARD); + + FREETMPS; + LEAVE; +} + +MODULE = Exd PACKAGE = Exd::FileFormat::Fontconfig PREFIX = exd_fileformat_fontconfig_ + +AV * exd_fileformat_fontconfig__list_fonts_c(SV *self, char *font_dir) + +void exd_fileformat_fontconfig__set_current_c(SV *self, char *font_dir) + +void exd_fileformat_fontconfig__restore_system_config_c(SV *self) + +MODULE = Exd PACKAGE = Exd::Fontconfig PREFIX = exd_fontconfig_ + +AV * exd_fontconfig__list_fonts_c(SV *self) + +MODULE = Exd PACKAGE = Exd::Gui PREFIX = exd_gui_ + +void exd_gui__get_first_file(SV *class, size_t int_files) + +MODULE = Exd PACKAGE = Exd PREFIX = exd_ diff --git a/lib/Exd/FileFormat/Fontconfig.pm b/lib/Exd/FileFormat/Fontconfig.pm index 8c487d3..25496b6 100644 --- a/lib/Exd/FileFormat/Fontconfig.pm +++ b/lib/Exd/FileFormat/Fontconfig.pm @@ -11,7 +11,7 @@ use Path::Tiny; use Data::Dumper; -use Inline C => DATA => LIBS => '-lfontconfig -lfreetype'; +require Exd; has exd => ( is => 'ro', required => 1, weak_ref => 1 ); @@ -53,7 +53,7 @@ sub import_font($self, $file) { sub migration1($self) { my $exd = $self->exd; my $app_font_dir = - path(__FILE__)->parent->parent->parent->parent->child('fonts/dir'); + Exd->root->child('fonts/dir'); my $exd_font_dir = $self->_font_dir->child('dir'); $exd_font_dir->mkpath; $app_font_dir->visit( @@ -96,56 +96,3 @@ sub _add_font_to_database($self, $font_name, $hash) { $hash, $font_name); } 1; -__DATA__ -__C__ -#include -#include - -FcConfig *old_system_config = NULL; - -void -_restore_system_config_c(SV *self) { - if (old_system_config != NULL) { - FcConfigSetCurrent(old_system_config); - } -} - -void -_set_current_c(SV *self, char *font_dir) { - if (old_system_config == NULL) { - old_system_config = FcConfigGetCurrent(); - } - FcConfig *new_config = FcConfigCreate(); - FcConfigAppFontAddDir(new_config, font_dir); - FcConfigBuildFonts(new_config); - FcConfigSetCurrent(new_config); -} - -AV * -_list_fonts_c(SV *self, char *font_dir) { - AV *return_array = newAV(); - FcConfig *config = FcConfigCreate(); - FcConfigAppFontAddDir(config, font_dir); - FcConfigBuildFonts(config); - FcFontSet *fonts = FcConfigGetFonts(config, FcSetApplication); - if (fonts == NULL) { - return return_array; - } - for (int i = 0; i < fonts->nfont; i++) { - FcPattern *pattern = fonts->fonts[i]; - FcChar8 *family; - FcChar8 *style; - FcChar8 *file; - FcPatternGetString(pattern, FC_FAMILY, 0, &family); - FcPatternGetString(pattern, FC_STYLE, 0, &style); - FcPatternGetString(pattern, FC_FILE, 0, &file); - char *familyKey; - HV *hash = newHV(); - SV *hash_ref = newRV_noinc((SV *) hash); - hv_stores(hash, "family", newSVpv(family, 0)); - hv_stores(hash, "style", newSVpv(style, 0)); - hv_stores(hash, "file", newSVpv(file, 0)); - av_push(return_array, hash_ref); - } - return return_array; -} diff --git a/lib/Exd/Fontconfig.pm b/lib/Exd/Fontconfig.pm index ed97187..68435d0 100644 --- a/lib/Exd/Fontconfig.pm +++ b/lib/Exd/Fontconfig.pm @@ -8,41 +8,8 @@ use utf8; use Moo; -use Inline C => DATA => LIBS => '-lfontconfig -lfreetype'; - sub list_fonts($self) { my $fonts = $self->_list_fonts_c; return $fonts; } 1; -__DATA__ -__C__ -#include -#include - -AV * -_list_fonts_c(SV *self) { - AV *return_array = newAV(); - FcConfig *config = FcConfigGetCurrent(); - FcFontSet *fonts = FcConfigGetFonts(config, FcSetSystem); - if (fonts == NULL) { - return return_array; - } - for (int i = 0; i < fonts->nfont; i++) { - FcPattern *pattern = fonts->fonts[i]; - FcChar8 *family; - FcChar8 *style; - FcChar8 *file; - FcPatternGetString(pattern, FC_FAMILY, 0, &family); - FcPatternGetString(pattern, FC_STYLE, 0, &style); - FcPatternGetString(pattern, FC_FILE, 0, &file); - char *familyKey; - HV *hash = newHV(); - SV *hash_ref = newRV_noinc((SV *) hash); - hv_stores(hash, "family", newSVpv(family, 0)); - hv_stores(hash, "style", newSVpv(style, 0)); - hv_stores(hash, "file", newSVpv(file, 0)); - av_push(return_array, hash_ref); - } - return return_array; -} diff --git a/lib/Exd/Gui.pm b/lib/Exd/Gui.pm index b66f06e..0ada770 100644 --- a/lib/Exd/Gui.pm +++ b/lib/Exd/Gui.pm @@ -31,32 +31,6 @@ use Exd; use JSON; use Net::DBus; -use Inline C => - <<'EOF' => LIBS => '', ccflags => (`pkg-config --cflags gio-2.0` || '-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -pthread'); -#include "glib-2.0/gio/gio.h" - -void -__get_first_file(SV *class, size_t int_files) { - dSP; - ENTER; - SAVETMPS; - - GFile *file = (((GFile **)int_files)[0]); - char *path = g_file_get_path(file); - - PUSHMARK(SP); - EXTEND(SP, 2); - PUSHs(class); - PUSHs(sv_2mortal(newSVpv(path, 0))); - PUTBACK; - - call_pv("_activate", G_DISCARD); - - FREETMPS; - LEAVE; -} -EOF - Glib::Object::Introspection->setup( basename => 'Gtk', version => '4.0', @@ -112,7 +86,7 @@ has _gresources_path => ( is => 'lazy', ); has _exd => ( is => 'lazy' ); sub _build__gresources_path($self) { - my $root = path(__FILE__)->parent->parent->parent; + my $root = Exd->root; my $gresources = $root->child('resources.gresource'); 0 == system( 'which', 'glib-compile-resources' ) && system( 'glib-compile-resources', $root->child('resources.xml') ); @@ -145,7 +119,7 @@ sub start($self) { $app->signal_connect( open => sub( $app, $files, $n_files, $hint ) { if ( $n_files > 0 ) { - $self->__get_first_file($files); + $self->_get_first_file($files); } } ); diff --git a/lib/Exd/Gui/Instance.pm b/lib/Exd/Gui/Instance.pm index 2286a2b..7aaa0ee 100644 --- a/lib/Exd/Gui/Instance.pm +++ b/lib/Exd/Gui/Instance.pm @@ -14,6 +14,8 @@ use Glib::Object::Introspection; use Path::Tiny; use Mojo::UserAgent; +require Exd; + has app => ( is => 'rw', required => 1, weak_ref => 1 ); has instance_id => ( is => 'rw', required => 1 ); has window => ( is => 'rw' ); @@ -171,7 +173,7 @@ sub start( $self, $exd_file ) { $execute_log->set_cursor_visible(0); $win->set_title( 'Hiperthermia (Thermal Printer) ' - . ( $self->_exd->debug ? 'DEBUG' : '' ) ); + . ( $self->_exd->debug ? 'DEBUG ' : '' ) ); $win->set_default_size( 1200, 900 ); $execute_log->set_hexpand(1); @@ -228,7 +230,7 @@ sub _show_about_dialog($self) { $picture->set_property( 'width-request', 256 ); $picture->set_property( 'height-request', 256 ); $picture->set_filename( - path(__FILE__)->parent->parent->parent->parent->child('exd-logo.png') + Exd->root->child('exd-logo.png') . '' ); my $label = Gtk4::Label->new(undef); $label->set_markup(<<"EOF"); @@ -312,7 +314,7 @@ sub _show_paywall( $self, $overlay ) { } ); my $picture = Gtk4::Image->new_from_file( - path(__FILE__)->parent->parent->parent->parent->child('exd-logo.png') + Exd->root->child('exd-logo.png') . '' ); $picture->set_pixel_size(256); $inner_paywall_box->append($picture); @@ -516,8 +518,7 @@ sub _show_recommended_printers($self) { for my $product (@products) { my $product_box = Gtk4::Box->new( 'horizontal', 10 ); - my $image_file = path(__FILE__) - ->parent->parent->parent->parent->child( $product->{image} ); + my $image_file = Exd->root->child( $product->{image} ); my $image = Gtk4::Image->new_from_file($image_file); $image->set_pixel_size(256); $product_box->append($image); @@ -950,7 +951,7 @@ sub _open_file( $self, $file ) { $self->_save_path($file); my $window = $self->window; $window->set_title( "Hiperthermia (Thermal Printer) " - . ( $self->_exd->debug ? 'DEBUG' : '' ) + . ( $self->_exd->debug ? 'DEBUG ' : '' ) . path( $self->_save_path )->basename ); $self->file_format( Exd::FileFormat->from_zip_file($file) ); $self->_update_editor_buffer; diff --git a/run.pl b/run.pl deleted file mode 100755 index 346e6de..0000000 --- a/run.pl +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env perl - -use v5.40.0; -use strict; -use warnings; -use Carp::Always; - -use File::Basename qw/dirname/; - -BEGIN { - chdir '/app/Hiperthermia'; -}; - -use lib '/app/Hiperthermia/lib'; - -use Exd::Gui; - -Exd::Gui->new->start(); diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..3eda328 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd /app/Hiperthermia/ +perl scripts/main.pl diff --git a/scripts/main.pl b/scripts/main.pl index a3e09f8..b41b6f8 100644 --- a/scripts/main.pl +++ b/scripts/main.pl @@ -5,7 +5,7 @@ use strict; use warnings; use File::Basename qw/dirname/; -use lib dirname(dirname(__FILE__)).'/lib'; +use blib; use Exd::Gui;