DBus @Targion

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

DBus @Targion

Beitrag von theo »

Targion hat geschrieben:Leider findet sich keiner, der diesen "Bug" in FPC bearbeitet und das DBus interface aktualisiert.
@Targion: Das ist vllt gar nicht soo schwierig, wenn man das unbedingt haben will.

Die Variante in /fpcsrc/packages/dbus/src basiert auf der Version 0.92. Die neueste Version ist 1.3.0.

Wenn du die relevanten *.h Dateien im dbus Verzeichnis beider Versionen gegeinander diffst und die Änderungen in /fpcsrc/packages/dbus/src nachvollziehst, ist das vielleicht machbar. Etwas Arbeit ist es schon, aber ich denke dass ein grosser Teil gleich geblieben ist.
Die beiden DBus Versionen gibt's hier:
http://dbus.freedesktop.org/releases/dbus/" onclick="window.open(this.href);return false;

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: DBus @Targion

Beitrag von Targion »

Ich habe leider kaum Erfahrung mit dem Umwandeln von C-Headern in Pascal-Code. Ich habe halt festgestellt, dass es aufgrund der alten Implementierung nicht mehr läuft. Sowieso wird empfohlen, die DBus-Implementierung von GObject zu benutzen. Dazu müsste ich aber die DBus-GObject-Header auf Pascal umschreiben und das GObject der GLib nutzen lassen.
Das ist mir im Moment viel zu aufwändig, aber vielleicht setze ich mich später mal daran. Eine DBus-Verbindung wäre für einige meiner Projekte wirklich ein Segen.

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

Targion hat geschrieben:Ich habe halt festgestellt, dass es aufgrund der alten Implementierung nicht mehr läuft.
Also das fpcsrc/packages/dbus/examples/busexample.pp läuft bei mir. Bei dir nicht?

P.S: Das example hat zwei kleine Macken:
Ersetze
conn := dbus_bus_get(DBUS_BUS_SESSION, @err);
durch
conn := dbus_bus_get_private(DBUS_BUS_SESSION, @err);

Plus der Hilfetext ist falsch: Statt query wird call erwartet. Sonst ist aber alles i.O.
Ich glaube, das geht grundsätzlich schon.

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

Hab mal eben ein bisschen rumgespielt. Bei mir funzt das prima.
Beispiel: Kernel-Version von libhal abfragen und devices auflisten (Benötigt evtl. noch Symlink in /usr/lib: libhal.so oder das Devel Paket).

Code: Alles auswählen

unit Unit1;
 
{$MODE objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, dbus;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;     
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
type
  PLibHalContext = ^LibHalContext;
  LibHalContext = THandle;
 
const External_library = 'hal';
 
 
function libhal_ctx_new: PLibHalContext; cdecl; external External_library name 'libhal_ctx_new';
function libhal_device_get_property_string(ctx: pLibHalContext; udi: pchar; key: pchar; error: pDBusError): Pchar; cdecl; external External_library name 'libhal_device_get_property_string';
function libhal_ctx_set_dbus_connection(ctx: pLibHalContext; conn: pDBusConnection): dbus_bool_t; cdecl; external External_library name 'libhal_ctx_set_dbus_connection';
function libhal_ctx_init(ctx: pLibHalContext; error: pDBusError): dbus_bool_t; cdecl; external External_library name 'libhal_ctx_init';
procedure libhal_free_string(str: pchar); cdecl; external External_library name 'libhal_free_string';
function libhal_ctx_free(ctx: pLibHalContext): dbus_bool_t; cdecl; external External_library name 'libhal_ctx_free';
function libhal_get_all_devices(ctx: pLibHalContext; num_devices: PInteger;error: pDBusError): PPChar; cdecl; external External_library name 'libhal_get_all_devices';
function libhal_ctx_shutdown(ctx: pLibHalContext; error: pDBusError): dbus_bool_t; cdecl; external External_library name 'libhal_ctx_shutdown';
 
 
var
  Form1: TForm1;
 
implementation
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var connection: PDBusConnection;
  error: DBusError;
  ctx: PLibHalContext;
  KernelVersion: PChar;
  devices:PPChar;
  i_devices,i:integer;    
const udi = '/org/freedesktop/Hal/devices/computer';
begin
  dbus_error_init(@error);
  connection := dbus_bus_get(DBUS_BUS_SYSTEM, @error);
 
  if dbus_error_is_set(@error) <> 0 then
  begin
    writeln('Unable to connect to DBus: ', error.message);
    dbus_error_free(@error);
    exit;
  end;
 
  ctx := libhal_ctx_new();
 
  if not libhal_ctx_set_dbus_connection(ctx, connection) = 0 then
  begin
    writeln('Error ', error.message);
    dbus_error_free(@error);
    exit;
  end;
 
  if not libhal_ctx_init(ctx, @error) = 0 then
  begin
    writeln('Hal context initializing failure ', error.message);
    exit;
  end;
 
  KernelVersion := libhal_device_get_property_string(ctx, udi, 'system.kernel.version', @error);
  Edit1.Text:=KernelVersion;
  libhal_free_string(KernelVersion);
 
  devices := libhal_get_all_devices (ctx, @i_devices, @error);
   if devices=nil then
   begin
     writeln ('HAL not running: ', error.message);
     dbus_error_free (@error);
     libhal_ctx_shutdown (ctx, nil);
     libhal_ctx_free (ctx);
     exit;
   end;
 
   for i:=0 to i_devices-1 do
   begin
    Memo1.lines.add(devices^);
    inc(devices);
   end;                
 
  dbus_error_free (@error);
  libhal_ctx_free(ctx);   
end;
 
initialization
{$I unit1.lrs}
 
end.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: DBus @Targion

Beitrag von Targion »

Ich probiere das jetzt auch nochmal. Ich brauche insbesondere Zugriff auf PackageKit um das Dependency-Handling des Listallers zu beschleunigen. Die aktuelle PackageKit-Verbindung über einen Wrapper ist sehr ineffizient und lagsam.
Was ist an dieser art des Anhängens mehrerer Parameter falsch?

Code: Alles auswählen

// append arguments
  a:='ein-string';
  dbus_message_iter_init_append(msg, @args);
  if (dbus_message_iter_append_basic(@args, DBUS_TYPE_STRING, @a) = 0) then
  begin
    WriteLn('Out Of Memory!');
    Exit;
  end;
 
 b:=false;
 if (dbus_message_iter_append_basic(@args, DBUS_TYPE_BOOLEAN, @b) = 0) then
  begin
    WriteLn('Out Of Memory!');
    Exit;
  end;
Ich bekomme folgende Nachricht:

Code: Alles auswählen

Request Sent
Argument is not boolean!
Message has too few arguments!
Got Reply: TRUE, 3787858768

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

Du musst halt unterscheiden zwischen libdbus und libdbus-glib.
Für das erstere gibt es header Übersetzungen, für das zweite afaik noch nicht.
Wenn du Beispiele umsetzen willst, die auf dbus-glib gemünzt sind, geht das nat. nicht mit dbus.pp.
Das heisst aber nicht, dass dbus.pp nicht funzt. Es ist halt auf einem tieferen Level als das glib-Teil.
Deshalb stimmt dein Bugreport so wahrscheinlich (mal wieder ;-) ) nicht.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: DBus @Targion

Beitrag von Targion »

Eigentlich sollte es da keinen Unterschied geben.
Auf dieser Seite wird auch empfohlen, nicht die Low-Level bindings zu nutzen.

Code: Alles auswählen

WARNING: you should NOT use this API unless you absolutely have to. This is NOT designed for application developers. Application developers should use one of the bindings if at all possible. If you are writing in C then the GLib bindings are recommended.
In Sachen Bindings gibt es keinen Unterschied zwischen low-level DBus und GLib-Dbus, alles funktioniert mit allem. (Wie sonst sollten die DBus-Bindings kompatibel bleiben?)

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

Wenn es so wäre, dann hättest du ja kein Problem, oder? ;-)

Ich kann mich irren, aber ich meine das glib Ding kapselt dbus mit praktischeren Funktionen, die so in dbus nicht enthalten sind, aber auf dbus zurückgreifen.
Mit dem Glib Teil machst du dich aber davon abhängig, deshalb gibt es auch noch die qt-dbus library.

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: DBus @Targion

Beitrag von Targion »

Echt? Kommt mir zwar sinnlos vor, aber wenn du das sagst... Entwickelst du nebenbei auch in C unter Linux? Denn du kennst dich mit den ganzen Sachen echt gut aus.
(Wenn das stimmt, dann habe ich keine Chance, mit dem Pascal-DBus weiter zu kommen. Ich werde DBus für alle anderen Aufgaben nehmen, aber bei PackageKit werde ich wohl die C-Header übersetzen müssen... Versuche ich später ^^ )

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

Ich hab mal versucht, nur die Anforderungen des Beispiels hier http://www.packagekit.org/pk-faq.html#session-methods" onclick="window.open(this.href);return false; auf Pascal zu übersetzen.
Ich habe nicht die geringste Ahnung, ob das geht. Hab's nicht getestet und verstehe auch nichts von PackageKit.
Aber eine geringe Chance besteht. Falls es nicht geht, kannste selber noch feilen.
Kompilieren und Linken sollte es schon mal.

Code: Alles auswählen

unit dbusglib;
 
{$MODE objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, glib2, dbus;
 
type
  PDBusGConnection = Pointer;
  PDBusGMessage = Pointer;
  PDBusGMethodInvocation = Pointer;
  PDBusGObjectInfo = Pointer;
  PDBusGProxy = Pointer;
  PDBusGProxyCall = Pointer;
 
const External_library = 'dbus-glib-1';
const G_TYPE_STRV: GType = 0;
 
function dbus_g_proxy_new_for_name(connection: pDBusGConnection; name: pchar; path: pchar; dinterface: pchar): PDBusGProxy; cdecl; external External_library name 'dbus_g_proxy_new_for_name';
function dbus_g_bus_get(_type: DBusBusType; error: PpGError): PDBusGConnection; cdecl; external External_library name 'dbus_g_bus_get';
function dbus_g_proxy_call(proxy: pDBusGProxy; method: pchar; error: PpGError; first_arg_type: GType; args: array of const): gboolean; cdecl; external External_library name 'dbus_g_proxy_call';
function g_strv_get_type: gulong; cdecl; external gobjectlib name 'g_strv_get_type';
 
procedure InstallPackage;
 
implementation
 
procedure InstallPackage;
var connection: PDBusGConnection;
  proxy: PDBusGProxy;
  error: PGError = nil;
  ret: gboolean;
  arg: PPchar;
  ast: string;
begin
  connection := dbus_g_bus_get(DBUS_BUS_SESSION, nil);
 
  proxy := dbus_g_proxy_new_for_name(connection,
    'org.freedesktop.PackageKit',
    '/org/freedesktop/PackageKit',
    'org.freedesktop.PackageKit.Modify');
 
  ast := 'openoffice-clipart '; //Achtung, Space am Schluss evtl wichtig.
  arg := StringToPPchar(ast, 0);
 
  ret := dbus_g_proxy_call(proxy, 'InstallPackageNames', @error,
    G_TYPE_STRV, [arg,
    G_TYPE_STRING, '',
      G_TYPE_INVALID, G_TYPE_INVALID]);
 
  if not ret then
  begin
    g_warning('failed: %s', [error^.message]);
    g_error_free(error);
  end;
 
end;
 
initialization
  g_type_init;
  G_TYPE_STRV := g_strv_get_type;
 
end.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1641
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: DBus @Targion

Beitrag von corpsman »

sorry das ich mich hier so einmische ..

Aber ich versuche ja gerade ein Programm zu schreiben, das meinen Rechner ( Kubuntu 9.04 ) runterfahren kann, und angeblich ist Dbus da auch die Lösung.

Nun habe ich mal versucht das oben gezeigte Programm zu kompilieren, und mein Rechner sagt mir dann :
/usr/bin/ld: cannot find -lhal
project1.lpr(20,1) Error: Error while linking
project1.lpr(20,1) Fatal: There were 1 errors compiling module, stopping
laut Aptitude habe ich HAL aber installiert, mus man da noch wo anders was einstellen ?
--
Just try it

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

corpsman hat geschrieben: laut Aptitude habe ich HAL aber installiert, mus man da noch wo anders was einstellen ?
Hab ich doch oben geschrieben:
Benötigt evtl. noch Symlink in /usr/lib: libhal.so oder das Devel Paket

Targion
Beiträge: 688
Registriert: Mi 3. Okt 2007, 21:00
OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
CPU-Target: x86_64

Re: DBus @Targion

Beitrag von Targion »

Und hir noch ein paar Infos, wenn du das System "nur" herunterfahren willst:
Interface: org.freedesktop.Hal
Objekt: /org/freedesktop/Hal/devices/computer
Kommando: org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown
Sollte auch ohne Einbindung von HAL funktionieren. Übrigens: HAL ist unter Linux verhaltet, es wird durch DeviceKit ersetzt. Du solltest bei neueren Linux-Distributionen auf die DevoceKit-DBus-Spezifikationen zurückgreifen.

Benutzeravatar
theo
Beiträge: 10999
Registriert: Mo 11. Sep 2006, 19:01

Re: DBus @Targion

Beitrag von theo »

HAL ist unter Linux verhaltet, es wird durch DeviceKit ersetzt.
Hab die Hal Libs trotzdem mal übersetzt. DeviceKit ist noch sehr neu und Hal wird uns noch eine Weile erhalten bleiben.
Vielleicht kann's ja mal jemand brauchen.

Edit: Habe eine Demo nachgeschoben, damit man sieht, dass es auch funzt.
Es ist eine Übersetzung von lshal.c.

Optionen mit -h
z.B. ./lshalpas -m zeigt an ob devices dazukommen oder weggenommen werden. Einfach mal einen USB-Stick oder sowas einhängen.

http://www.theo.ch/lazarus/dbus/hal.tar.gz" onclick="window.open(this.href);return false;

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: DBus @Targion

Beitrag von pluto »

Nicht schlecht ! Das währe praktisch für ein "Datei Manager" oder für ein "Media Player".
Gibt es eine Übersicht was alles mit DBus zusammen arbeitet ?
MFG
Michael Springwald

Antworten