Inline::C to XS

This commit is contained in:
Sergiotarxz 2024-11-10 18:04:52 +01:00
parent a078795c0c
commit 546545b195
12 changed files with 195 additions and 148 deletions

45
Build.PL Executable file
View File

@ -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 <contact@owlcode.tech>',
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;

View File

@ -1,16 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cd HiperthermiaSource cd HiperthermiaSource
perl lib/Exd/Fontconfig.pm perl Build.PL
perl lib/Exd/FileFormat/Fontconfig.pm perl Build build
perl -Ilib lib/Exd/Gui.pm
chmod 755 -R _Inline/
cd - cd -
cp HiperthermiaSource/app_config.prod.json HiperthermiaSource/app_config.json cp HiperthermiaSource/app_config.prod.json HiperthermiaSource/app_config.json
cp -vr HiperthermiaSource ${FLATPAK_DEST}/Hiperthermia cp -vr HiperthermiaSource ${FLATPAK_DEST}/Hiperthermia
glib-compile-resources --sourcedir=${FLATPAK_DEST}/Hiperthermia ${FLATPAK_DEST}/Hiperthermia/resources.xml 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.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 -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 install -Dm644 HiperthermiaSource/exd-logo.png /app/share/icons/hicolor/256x256/apps/me.sergiotarxz.Exd.png
update-mime-database /app/share/mime update-mime-database /app/share/mime
install -Dm644 HiperthermiaSource/me.sergiotarxz.Exd.metainfo.xml -t /app/share/metainfo/ install -Dm644 HiperthermiaSource/me.sergiotarxz.Exd.metainfo.xml -t /app/share/metainfo/

2
deps
View File

@ -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

View File

@ -11,6 +11,9 @@ use JSON;
use Path::Tiny; use Path::Tiny;
use UUID::URandom qw/create_uuid_string/; use UUID::URandom qw/create_uuid_string/;
require XSLoader;
XSLoader::load();
has config => ( is => 'lazy' ); has config => ( is => 'lazy' );
sub _build_config($self) { sub _build_config($self) {
@ -18,7 +21,11 @@ sub _build_config($self) {
} }
sub _config_file_name($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) { sub licenser_server($self) {

123
lib/Exd.xs Normal file
View File

@ -0,0 +1,123 @@
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <stdio.h>
#include <fontconfig/fontconfig.h>
#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_

View File

@ -11,7 +11,7 @@ use Path::Tiny;
use Data::Dumper; use Data::Dumper;
use Inline C => DATA => LIBS => '-lfontconfig -lfreetype'; require Exd;
has exd => ( is => 'ro', required => 1, weak_ref => 1 ); has exd => ( is => 'ro', required => 1, weak_ref => 1 );
@ -53,7 +53,7 @@ sub import_font($self, $file) {
sub migration1($self) { sub migration1($self) {
my $exd = $self->exd; my $exd = $self->exd;
my $app_font_dir = 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'); my $exd_font_dir = $self->_font_dir->child('dir');
$exd_font_dir->mkpath; $exd_font_dir->mkpath;
$app_font_dir->visit( $app_font_dir->visit(
@ -96,56 +96,3 @@ sub _add_font_to_database($self, $font_name, $hash) {
$hash, $font_name); $hash, $font_name);
} }
1; 1;
__DATA__
__C__
#include <stdio.h>
#include <fontconfig/fontconfig.h>
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;
}

View File

@ -8,41 +8,8 @@ use utf8;
use Moo; use Moo;
use Inline C => DATA => LIBS => '-lfontconfig -lfreetype';
sub list_fonts($self) { sub list_fonts($self) {
my $fonts = $self->_list_fonts_c; my $fonts = $self->_list_fonts_c;
return $fonts; return $fonts;
} }
1; 1;
__DATA__
__C__
#include <stdio.h>
#include <fontconfig/fontconfig.h>
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;
}

View File

@ -31,32 +31,6 @@ use Exd;
use JSON; use JSON;
use Net::DBus; 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( Glib::Object::Introspection->setup(
basename => 'Gtk', basename => 'Gtk',
version => '4.0', version => '4.0',
@ -112,7 +86,7 @@ has _gresources_path => ( is => 'lazy', );
has _exd => ( is => 'lazy' ); has _exd => ( is => 'lazy' );
sub _build__gresources_path($self) { sub _build__gresources_path($self) {
my $root = path(__FILE__)->parent->parent->parent; my $root = Exd->root;
my $gresources = $root->child('resources.gresource'); my $gresources = $root->child('resources.gresource');
0 == system( 'which', 'glib-compile-resources' ) 0 == system( 'which', 'glib-compile-resources' )
&& system( 'glib-compile-resources', $root->child('resources.xml') ); && system( 'glib-compile-resources', $root->child('resources.xml') );
@ -145,7 +119,7 @@ sub start($self) {
$app->signal_connect( $app->signal_connect(
open => sub( $app, $files, $n_files, $hint ) { open => sub( $app, $files, $n_files, $hint ) {
if ( $n_files > 0 ) { if ( $n_files > 0 ) {
$self->__get_first_file($files); $self->_get_first_file($files);
} }
} }
); );

View File

@ -14,6 +14,8 @@ use Glib::Object::Introspection;
use Path::Tiny; use Path::Tiny;
use Mojo::UserAgent; use Mojo::UserAgent;
require Exd;
has app => ( is => 'rw', required => 1, weak_ref => 1 ); has app => ( is => 'rw', required => 1, weak_ref => 1 );
has instance_id => ( is => 'rw', required => 1 ); has instance_id => ( is => 'rw', required => 1 );
has window => ( is => 'rw' ); has window => ( is => 'rw' );
@ -171,7 +173,7 @@ sub start( $self, $exd_file ) {
$execute_log->set_cursor_visible(0); $execute_log->set_cursor_visible(0);
$win->set_title( 'Hiperthermia (Thermal Printer) ' $win->set_title( 'Hiperthermia (Thermal Printer) '
. ( $self->_exd->debug ? 'DEBUG' : '' ) ); . ( $self->_exd->debug ? 'DEBUG ' : '' ) );
$win->set_default_size( 1200, 900 ); $win->set_default_size( 1200, 900 );
$execute_log->set_hexpand(1); $execute_log->set_hexpand(1);
@ -228,7 +230,7 @@ sub _show_about_dialog($self) {
$picture->set_property( 'width-request', 256 ); $picture->set_property( 'width-request', 256 );
$picture->set_property( 'height-request', 256 ); $picture->set_property( 'height-request', 256 );
$picture->set_filename( $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); my $label = Gtk4::Label->new(undef);
$label->set_markup(<<"EOF"); $label->set_markup(<<"EOF");
@ -312,7 +314,7 @@ sub _show_paywall( $self, $overlay ) {
} }
); );
my $picture = Gtk4::Image->new_from_file( 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); $picture->set_pixel_size(256);
$inner_paywall_box->append($picture); $inner_paywall_box->append($picture);
@ -516,8 +518,7 @@ sub _show_recommended_printers($self) {
for my $product (@products) { for my $product (@products) {
my $product_box = Gtk4::Box->new( 'horizontal', 10 ); my $product_box = Gtk4::Box->new( 'horizontal', 10 );
my $image_file = path(__FILE__) my $image_file = Exd->root->child( $product->{image} );
->parent->parent->parent->parent->child( $product->{image} );
my $image = Gtk4::Image->new_from_file($image_file); my $image = Gtk4::Image->new_from_file($image_file);
$image->set_pixel_size(256); $image->set_pixel_size(256);
$product_box->append($image); $product_box->append($image);
@ -950,7 +951,7 @@ sub _open_file( $self, $file ) {
$self->_save_path($file); $self->_save_path($file);
my $window = $self->window; my $window = $self->window;
$window->set_title( "Hiperthermia (Thermal Printer) " $window->set_title( "Hiperthermia (Thermal Printer) "
. ( $self->_exd->debug ? 'DEBUG' : '' ) . ( $self->_exd->debug ? 'DEBUG ' : '' )
. path( $self->_save_path )->basename ); . path( $self->_save_path )->basename );
$self->file_format( Exd::FileFormat->from_zip_file($file) ); $self->file_format( Exd::FileFormat->from_zip_file($file) );
$self->_update_editor_buffer; $self->_update_editor_buffer;

18
run.pl
View File

@ -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();

3
run.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
cd /app/Hiperthermia/
perl scripts/main.pl

View File

@ -5,7 +5,7 @@ use strict;
use warnings; use warnings;
use File::Basename qw/dirname/; use File::Basename qw/dirname/;
use lib dirname(dirname(__FILE__)).'/lib'; use blib;
use Exd::Gui; use Exd::Gui;