I think I can provide a bit more useful information about versions. The first thing to note is that all the versions I'm looking at have a function returning a char* (i.e. a PChar in Pascal terms) to a brief version number e.g. '1.2', this is set in configure.ac in the project's root directory e.g.
AC_INIT([libgpiod], 1.6.3) <=====
AC_SUBST(EXTRA_VERSION, [])
AC_DEFINE_UNQUOTED([GPIOD_VERSION_STR],
["$PACKAGE_VERSION$EXTRA_VERSION"],
[Full library version string.])
AC_SUBST(VERSION_STR, [$PACKAGE_VERSION$EXTRA_VERSION])
The one I've been using since about February, which comes with Debian "Buster" (which was stable at the time) is v1.2. The one being shipped with "Bullseye" (now Debian stable) is 1.6.2, there's also a 1.6.3 at kernel.org which appears to still have the "old" API.
The master branch at kernel.org is at 2.0, but all of the application developer discussion etc. ends up there... there's a possibility that the only people using that API are "insiders" working on the bundled tools with everybody else still using the sysfs API or (worse) direct access.
Being charitable, kernel.org's git suggests that the branch was "only" made in about March this year (in which case how did I mistakenly pick up the v2 header in February?), so we can hope that either they fix the entry point naming or that the various distreaux have the decency to call it libgpio2 even if the developers don't.
So I think that what I need to do is fairly clear: rename the interface I've been using for the last few months gpiod2 and call the one I'm currently working on gpiod (i.e. an implicit v1).
In any event, straightforward medium-performance bit-twiddling looks- so far at least- as though it is unchanged between the two APIs.
One of the nasties in the v1 API is that in an effort to avoid giving anything away about the internal representation they don't document how large a bulk object should be, space has to be reserved at the application level for the result of gpiod_line_event_wait_bulk(), and when an event is received this has to treated as an indexable array of pointers to lines. Something like this:
procedure TmonitorThread.Execute;
const
milliSec= 1000 * 1000;
(* The size of the bulk object isn't documented, a guess would suggest that it *)
(* should be GPIOD_LINE_BULK_MAX_LINES but inspection indicates that some extra *)
(* space is needed to store the count. *)
var
lineHandles: array[0..255] of Pgpiod_line;
eventedLines: array[1..(GPIOD_LINE_BULK_MAX_LINES + 1)] of Pgpiod_line;
event: gpiod_line_event;
timeout: timespec;
i: integer;
begin
FillByte(lineHandles, SizeOf(lineHandles), 0);
// Assume chipHandle is stored at thread creation.
if Gpiod.gpiod_chip_get_all_lines(chipHandle, @lineHandles) <> 0 then
exit;
try
if Gpiod.gpiod_line_request_bulk_both_edges_events(@lineHandles, 'gui_test') = 0 then
while not stopMonitorThread do begin
timeout.tv_sec := 0;
timeout.tv_nsec := 100 * milliSec;
FillByte(eventedLines, SizeOf(eventedLines), 0);
i := Gpiod.gpiod_line_event_wait_bulk(@lineHandles, @timeout, @eventedLines);
if i < 0 then (* 0 represents timeout, <0 error *)
break;
while i > 0 do begin
if Gpiod.gpiod_line_event_read(eventedLines[i], @event) = 0 then
seenEvent := true;
i -= 1
end
end
finally
Gpiod.gpiod_line_release_bulk(@lineHandles)
end
end { TmonitorThread.Execute } ;
I can confirm that gpiod is applicable to Android, although I don't know whether it is used by internal devices or purely by people using an Android-based phone/tablet/board to control e.g. laboratory equipment. As I've already said, it works fairly well with an external board on a PC.
Later: I don't like the position of the try in that example, but I'm not changing it since it's working code.
MarkMLl