terminal, more rebust dynamic binding, allowing to detect invalid funcs

This commit is contained in:
Basile Burg 2020-03-07 15:34:23 +01:00
parent a60bca7c96
commit 3b358c9a48
2 changed files with 88 additions and 78 deletions

View File

@ -49,8 +49,6 @@ const
type
TGSpawnChildSetupFunc = procedure(user_data: Pointer); cdecl;
PVteTerminal = ^TVteTerminal;
TVteTerminal = record
widget: PGtkWidget;
@ -80,9 +78,6 @@ var
vte_terminal_set_color_highlight: procedure(terminal: PVteTerminal;
const background: PGdkColor); cdecl;
vte_terminal_set_color_highlight_foreground: procedure(terminal: PVteTerminal;
const background: PGdkColor); cdecl;
vte_terminal_set_font: procedure(terminal: PVteTerminal;
const font_desc: PPangoFontDescription); cdecl;
@ -110,72 +105,94 @@ var
vte_terminal_get_adjustment: function(terminal: PVteTerminal): PGtkAdjustment; cdecl;
function Gtk2TermLoad: Boolean;
implementation
var
Initialized: Boolean;
Loaded: Boolean;
vteInitialized: Boolean;
vteLoaded: Boolean;
function bindFunction(var funcPtr: Pointer; const identifier: string; handle: TLibHandle): boolean;
begin
funcPtr := GetProcAddress(handle, identifier);
result := funcPtr <> nil;
end;
function Gtk2TermLoad: Boolean;
const
vten1 = 'libvte.so';
vten2 = 'libvte.so.9';
vteSoNames: array[0..1] of string = ('libvte.so', 'libvte.so.9');
var
Lib: TLibHandle;
h: TLibHandle;
n: string;
begin
if Initialized then
Exit(Loaded);
Initialized := True;
Lib := LoadLibrary(vten2);
if Lib = 0 then
Lib := LoadLibrary(vten1);
if Lib = 0 then
Exit(Loaded);
if vteInitialized then
Exit(vteLoaded);
vteInitialized := True;
@vte_terminal_new := GetProcAddress(Lib,
'vte_terminal_new');
@vte_terminal_fork_command_full := GetProcAddress(Lib,
'vte_terminal_fork_command_full');
@vte_terminal_set_color_background := GetProcAddress(Lib,
'vte_terminal_set_color_background');
@vte_terminal_set_color_foreground := GetProcAddress(Lib,
'vte_terminal_set_color_foreground');
@vte_terminal_set_color_bold := GetProcAddress(Lib,
'vte_terminal_set_color_bold');
@vte_terminal_set_color_highlight := GetProcAddress(Lib,
'vte_terminal_set_color_highlight');
@vte_terminal_set_color_highlight_foreground := GetProcAddress(Lib,
'vte_terminal_set_color_highlight_foreground');
@vte_terminal_set_font := GetProcAddress(Lib,
'vte_terminal_set_font');
@vte_terminal_feed := GetProcAddress(Lib,
'vte_terminal_feed');
@vte_terminal_feed_child := GetProcAddress(Lib,
'vte_terminal_feed_child');
@vte_terminal_copy_clipboard := GetProcAddress(Lib,
'vte_terminal_copy_clipboard');
@vte_terminal_paste_clipboard := GetProcAddress(Lib,
'vte_terminal_paste_clipboard');
@vte_get_user_shell := GetProcAddress(Lib,
'vte_get_user_shell');
@vte_terminal_get_row_count := GetProcAddress(Lib,
'vte_terminal_get_row_count');
@vte_terminal_get_column_count:= GetProcAddress(Lib,
'vte_terminal_get_column_count');
@vte_terminal_get_cursor_position:= GetProcAddress(Lib,
'vte_terminal_get_cursor_position');
@vte_terminal_get_text_range:= GetProcAddress(Lib,
'vte_terminal_get_text_range');
@vte_terminal_get_adjustment:= GetProcAddress(Lib,
'vte_terminal_get_adjustment');
for n in vteSoNames do
begin
h := LoadLibrary(n);
if h <> 0 then
break;
end;
if h = 0 then
exit(false);
// assume all or none
Loaded := @vte_terminal_new <> nil;
if not bindFunction(@vte_terminal_new,
'vte_terminal_new', h) then
exit(false);
if not bindFunction(@vte_terminal_fork_command_full,
'vte_terminal_fork_command_full', h) then
exit(false);
if not bindFunction(@vte_terminal_set_color_background,
'vte_terminal_set_color_background', h) then
exit(false);
if not bindFunction(@vte_terminal_set_color_foreground,
'vte_terminal_set_color_foreground', h) then
exit(false);
if not bindFunction(@vte_terminal_set_color_bold,
'vte_terminal_set_color_bold', h) then
exit(false);
if not bindFunction(@vte_terminal_set_color_highlight,
'vte_terminal_set_color_highlight', h) then
exit(false);
if not bindFunction(@vte_terminal_set_font,
'vte_terminal_set_font', h) then
exit(false);
if not bindFunction(@vte_terminal_feed,
'vte_terminal_feed', h) then
exit(false);
if not bindFunction(@vte_terminal_feed_child,
'vte_terminal_feed_child', h) then
exit(false);
if not bindFunction(@vte_terminal_copy_clipboard,
'vte_terminal_copy_clipboard', h) then
exit(false);
if not bindFunction(@vte_terminal_paste_clipboard,
'vte_terminal_paste_clipboard', h) then
exit(false);
if not bindFunction(@vte_get_user_shell,
'vte_get_user_shell', h) then
exit(false);
if not bindFunction(@vte_terminal_get_row_count,
'vte_terminal_get_row_count', h) then
exit(false);
if not bindFunction(@vte_terminal_get_column_count,
'vte_terminal_get_column_count', h) then
exit(false);
if not bindFunction(@vte_terminal_get_cursor_position,
'vte_terminal_get_cursor_position', h) then
exit(false);
if not bindFunction(@vte_terminal_get_text_range,
'vte_terminal_get_text_range', h) then
exit(false);
if not bindFunction(@vte_terminal_get_adjustment,
'vte_terminal_get_adjustment', h) then
exit(false);
Result := Loaded;
vteLoaded := true;
result := vteLoaded;
end;
{$else}
implementation

View File

@ -364,7 +364,7 @@ end;
procedure TTerminal.Command(const data: string);
begin
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_feed_child) then
if assigned(fTerminalHanlde) then
vte_terminal_feed_child(fTerminalHanlde, PChar(data + #10), data.Length + 1);
{$endif}
end;
@ -375,7 +375,7 @@ var
begin
{$ifdef hasgtk2term}
c := Char(cc);
if assigned(fTerminalHanlde) and assigned(vte_terminal_feed_child) then
if assigned(fTerminalHanlde) then
vte_terminal_feed_child(fTerminalHanlde, @c, 1);
{$endif}
end;
@ -383,7 +383,7 @@ end;
procedure TTerminal.copyToClipboard();
begin
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_copy_clipboard) then
if assigned(fTerminalHanlde) then
vte_terminal_copy_clipboard(fTerminalHanlde);
{$endif}
end;
@ -391,7 +391,7 @@ end;
procedure TTerminal.pasteFromClipboard();
begin
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_paste_clipboard) then
if assigned(fTerminalHanlde) then
vte_terminal_paste_clipboard(fTerminalHanlde);
{$endif}
end;
@ -412,7 +412,7 @@ var
begin
result := '';
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_get_text_range) then
if assigned(fTerminalHanlde) then
begin
c := vte_terminal_get_column_count(fTerminalHanlde);
result := vte_terminal_get_text_range(fTerminalHanlde, line, 0, line, c, @clbckTrueSel, nil, a);
@ -431,7 +431,7 @@ var
begin
result := '';
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_get_text_range) then
if assigned(fTerminalHanlde) then
begin
c := vte_terminal_get_column_count(fTerminalHanlde);
for i:= 0 to high(integer) do
@ -510,7 +510,7 @@ begin
{$ifdef hasgtk2term}
result.x:=0;
result.y:=0;
if assigned(fTerminalHanlde) and assigned(vte_terminal_get_cursor_position) then
if assigned(fTerminalHanlde) then
begin
vte_terminal_get_cursor_position(fTerminalHanlde, @col, @row);
result.x:= col;
@ -575,7 +575,7 @@ var
begin
fBackgroundColor:=value;
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_set_color_background) then
if assigned(fTerminalHanlde) then
begin
c := TColortoTGDKColor(fBackgroundColor);
vte_terminal_set_color_background(fTerminalHanlde, @c);
@ -591,8 +591,7 @@ var
begin
fForegroundColor:=value;
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_set_color_foreground) and
assigned(vte_terminal_set_color_bold) then
if assigned(fTerminalHanlde) then
begin
c := TColortoTGDKColor(fForegroundColor);
vte_terminal_set_color_foreground(fTerminalHanlde, @c);
@ -609,13 +608,10 @@ var
begin
fSelectedColor:=value;
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_set_color_highlight)
and assigned(vte_terminal_set_color_highlight_foreground) then
if assigned(fTerminalHanlde) then
begin
c := TColortoTGDKColor(fSelectedColor);
vte_terminal_set_color_highlight(fTerminalHanlde, @c);
c := TColortoTGDKColor(InvertColor(fSelectedColor));
vte_terminal_set_color_highlight_foreground(fTerminalHanlde, @c);
end;
{$endif}
end;
@ -625,11 +621,8 @@ begin
inherited;
{$ifdef hasgtk2term}
{$push}{$Hints off}
if assigned(fTerminalHanlde) and assigned(vte_terminal_set_font) and
(Handle <> INVALID_HANDLE_VALUE) then
begin
if assigned(fTerminalHanlde) and (Handle <> INVALID_HANDLE_VALUE) then
vte_terminal_set_font(fTerminalHanlde, PGtkWidget(Handle).style.font_desc);
end;
{$pop}
{$endif}
end;
@ -641,7 +634,7 @@ var
{$endif}
begin
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_get_adjustment) then
if assigned(fTerminalHanlde) then
begin
a := vte_terminal_get_adjustment(fTerminalHanlde);
result.max := round(a^.upper);
@ -658,7 +651,7 @@ var
{$endif}
begin
{$ifdef hasgtk2term}
if assigned(fTerminalHanlde) and assigned(vte_terminal_get_adjustment) then
if assigned(fTerminalHanlde) then
begin
a := vte_terminal_get_adjustment(fTerminalHanlde);
gtk_adjustment_set_value(a, i);