diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b57ed59..da646f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -181,7 +181,7 @@ fedora:37@container-prep: - .policy stage: build script: - - .gitlab-ci/meson-build.sh + - .gitlab-ci/meson-build.sh --run-test artifacts: name: "meson-logs-$CI_JOB_NAME" when: always diff --git a/.gitlab-ci/ci.template b/.gitlab-ci/ci.template index 115998d..0e23398 100644 --- a/.gitlab-ci/ci.template +++ b/.gitlab-ci/ci.template @@ -195,7 +195,7 @@ python-ruff: - .policy stage: build script: - - .gitlab-ci/meson-build.sh + - .gitlab-ci/meson-build.sh --run-test artifacts: name: "meson-logs-$CI_JOB_NAME" when: always diff --git a/doc/meson.build b/doc/meson.build index a27648e..c41c2df 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -1,3 +1,7 @@ +if not get_option('documentation') + subdir_done() +endif + doxygen = find_program('doxygen', required : false) if not doxygen.found() error('Program "doxygen" not found or not executable. Try building with -Ddocumentation=false') diff --git a/meson.build b/meson.build index 90ee48b..72cfbe5 100644 --- a/meson.build +++ b/meson.build @@ -5,6 +5,7 @@ project('libei', 'c', meson_version: '>= 0.57.0') pkgconfig = import('pkgconfig') +fs = import('fs') cc = meson.get_compiler('c') cflags =[ @@ -51,200 +52,19 @@ config_h.set('_GNU_SOURCE', '1') config_h.set_quoted('EI_VERSION', meson.project_version()) config_h.set_quoted('EIS_VERSION', meson.project_version()) -subdir('proto') - -src_libutil = files( - 'src/util-bits.c', - 'src/util-io.c', - 'src/util-list.c', - 'src/util-logger.c', - 'src/util-memfile.c', - 'src/util-sources.c', - 'src/util-strings.c', -) - -lib_util = static_library('util', src_libutil) - -dep_libutil = declare_dependency(link_with: lib_util) - - -proto_c_template = files('src/ei-proto.c.tmpl') -proto_h_template = files('src/ei-proto.h.tmpl') -brei_proto_h_template = files('src/brei-proto.h.tmpl') - -brei_proto_headers = custom_target('brei-proto-headers', - input: protocol_xml, - output: ['brei-proto.h'], - command: [scanner, '--component=brei', '--output=@OUTPUT@', '@INPUT@', brei_proto_h_template]) - -ei_proto_headers = custom_target('ei-proto-headers', - input: protocol_xml, - output: ['ei-proto.h'], - command: [scanner, '--component=ei', '--output=@OUTPUT@', '@INPUT@', proto_h_template]) -ei_proto_sources = custom_target('ei-proto-sources', - input: protocol_xml, - output: ['ei-proto.c'], - command: [scanner, '--component=ei', '--output=@OUTPUT@', '@INPUT@', - '--jinja-extra-data={"headerfile": "ei-proto.h"}', proto_c_template]) -src_libei = files( - 'src/brei-shared.c', - 'src/libei.c', - 'src/libei-callback.c', - 'src/libei-handshake.c', - 'src/libei-connection.c', - 'src/libei-device.c', - 'src/libei-event.c', - 'src/libei-fd.c', - 'src/libei-keyboard.c', - 'src/libei-log.c', - 'src/libei-pingpong.c', - 'src/libei-pointer.c', - 'src/libei-region.c', - 'src/libei-region.c', - 'src/libei-seat.c', - 'src/libei-socket.c', - 'src/libei-touchscreen.c', -) + [brei_proto_headers, ei_proto_headers, ei_proto_sources] - -deps_libei = [ - dep_libutil, -] - -lib_libei = shared_library('ei', - src_libei, - dependencies: deps_libei, - gnu_symbol_visibility: 'hidden', - include_directories: ['src'], - install: true -) -install_headers('src/libei.h') - -dep_libei = declare_dependency(link_with: lib_libei, - include_directories: [inc_src]) -meson.override_dependency('libei', dep_libei) - -pkgconfig.generate(lib_libei, - filebase: 'libei', - name: 'libEI', - description: 'Emulated Input client library', - version: meson.project_version(), - libraries: lib_libei, -) - -eis_proto_headers = custom_target('eis-proto-headers', - input: protocol_xml, - output: ['eis-proto.h'], - command: [scanner, '--component=eis', '--output=@OUTPUT@', '@INPUT@', proto_h_template]) -eis_proto_sources = custom_target('eis-proto-sources', - input: protocol_xml, - output: ['eis-proto.c'], - command: [scanner, '--component=eis', '--output=@OUTPUT@', '@INPUT@', - '--jinja-extra-data={"headerfile": "eis-proto.h"}', proto_c_template]) - -src_libeis = files( - 'src/brei-shared.c', - 'src/libeis.c', - 'src/libeis-callback.c', - 'src/libeis-client.c', - 'src/libeis-handshake.c', - 'src/libeis-connection.c', - 'src/libeis-device.c', - 'src/libeis-event.c', - 'src/libeis-fd.c', - 'src/libeis-keyboard.c', - 'src/libeis-log.c', - 'src/libeis-pingpong.c', - 'src/libeis-pointer.c', - 'src/libeis-region.c', - 'src/libeis-seat.c', - 'src/libeis-socket.c', - 'src/libeis-touchscreen.c', -) + [brei_proto_headers, eis_proto_headers, eis_proto_sources] - -lib_libeis = shared_library('eis', - src_libeis, - dependencies: [dep_libutil], - include_directories: [inc_src], - gnu_symbol_visibility: 'hidden', - install: true -) -install_headers('src/libeis.h') - -dep_libeis = declare_dependency(link_with: lib_libeis, - include_directories: [inc_src]) -meson.override_dependency('libeis', dep_libeis) - -pkgconfig.generate(lib_libeis, - filebase: 'libeis', - name: 'libEIS', - description: 'Emulated Input server library', - version: meson.project_version(), - libraries: lib_libeis, -) - dep_libxkbcommon = dependency('xkbcommon', required: false) config_h.set10('HAVE_LIBXKBCOMMON', dep_libxkbcommon.found()) dep_libevdev = dependency('libevdev', required: false) config_h.set10('HAVE_LIBEVDEV', dep_libevdev.found()) - -src_eis_demo_server = files( - 'tools/eis-demo-server.c', -) -if dep_libevdev.found() - src_eis_demo_server += files( - 'tools/eis-demo-server-uinput.c', - ) -endif - - -eis_demo_server = executable('eis-demo-server', - src_eis_demo_server, - dependencies: [ - dep_libutil, - dep_libeis, - dep_libxkbcommon, - dep_libevdev - ]) - -executable('ei-demo-client', - 'tools/ei-demo-client.c', - dependencies: [dep_libutil, dep_libei, dep_libxkbcommon]) - -executable('ei-debug-events', - 'tools/ei-debug-events.c', - dependencies: [dep_libutil, dep_libei, dep_libevdev], - install: true) - dep_systemd = dependency('libsystemd', required: get_option('liboeffis')) -build_oeffis = dep_systemd.found() -if build_oeffis - src_liboeffis = files('src/liboeffis.c') - deps_liboeffis = [dep_libutil, dep_systemd] - lib_liboeffis = shared_library('oeffis', - src_liboeffis, - dependencies: deps_liboeffis, - gnu_symbol_visibility: 'hidden', - install: true - ) - install_headers('src/liboeffis.h') +configure_file(output: 'config.h', configuration: config_h) - dep_liboeffis = declare_dependency(link_with: lib_liboeffis, - include_directories: [inc_src]) - meson.override_dependency('liboeffis', dep_liboeffis) - - pkgconfig.generate(lib_liboeffis, - filebase: 'liboeffis', - name: 'libOeffis', - description: 'RemoteDesktop portal DBus helper library', - version: meson.project_version(), - libraries: lib_liboeffis, - ) - - executable('oeffis-demo-tool', - 'tools/oeffis-demo-tool.c', - dependencies: [dep_libutil, dep_liboeffis]) -endif +subdir('proto') +subdir('src') +subdir('tools') +subdir('test') +subdir('doc') black = find_program('black', required: false) if black.found() @@ -262,13 +82,3 @@ if ruff.found() ) endif -# tests -if get_option('tests') - subdir('test') -endif - -configure_file(output: 'config.h', configuration: config_h) - -if get_option('documentation') - subdir('doc') -endif diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..7d45086 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,158 @@ +src_libutil = files( + 'util-bits.c', + 'util-io.c', + 'util-list.c', + 'util-logger.c', + 'util-memfile.c', + 'util-sources.c', + 'util-strings.c', +) + +lib_util = static_library('util', + src_libutil, + include_directories: [inc_builddir], +) + +dep_libutil = declare_dependency(link_with: lib_util) + +proto_c_template = files('ei-proto.c.tmpl') +proto_h_template = files('ei-proto.h.tmpl') +brei_proto_h_template = files('brei-proto.h.tmpl') + +brei_proto_headers = custom_target('brei-proto-headers', + input: protocol_xml, + output: ['brei-proto.h'], + command: [scanner, '--component=brei', '--output=@OUTPUT@', '@INPUT@', brei_proto_h_template]) + +ei_proto_headers = custom_target('ei-proto-headers', + input: protocol_xml, + output: ['ei-proto.h'], + command: [scanner, '--component=ei', '--output=@OUTPUT@', '@INPUT@', proto_h_template]) +ei_proto_sources = custom_target('ei-proto-sources', + input: protocol_xml, + output: ['ei-proto.c'], + command: [scanner, '--component=ei', '--output=@OUTPUT@', '@INPUT@', + '--jinja-extra-data={"headerfile": "ei-proto.h"}', proto_c_template]) +src_libei = files( + 'brei-shared.c', + 'libei.c', + 'libei-callback.c', + 'libei-handshake.c', + 'libei-connection.c', + 'libei-device.c', + 'libei-event.c', + 'libei-fd.c', + 'libei-keyboard.c', + 'libei-log.c', + 'libei-pingpong.c', + 'libei-pointer.c', + 'libei-region.c', + 'libei-region.c', + 'libei-seat.c', + 'libei-socket.c', + 'libei-touchscreen.c', +) + [brei_proto_headers, ei_proto_headers, ei_proto_sources] + +deps_libei = [ + dep_libutil, +] + +lib_libei = shared_library('ei', + src_libei, + dependencies: deps_libei, + include_directories: [inc_builddir], + gnu_symbol_visibility: 'hidden', + install: true +) +install_headers('libei.h') + +dep_libei = declare_dependency(link_with: lib_libei, + include_directories: [inc_src]) +meson.override_dependency('libei', dep_libei) + +pkgconfig.generate(lib_libei, + filebase: 'libei', + name: 'libEI', + description: 'Emulated Input client library', + version: meson.project_version(), + libraries: lib_libei, +) + +eis_proto_headers = custom_target('eis-proto-headers', + input: protocol_xml, + output: ['eis-proto.h'], + command: [scanner, '--component=eis', '--output=@OUTPUT@', '@INPUT@', proto_h_template]) +eis_proto_sources = custom_target('eis-proto-sources', + input: protocol_xml, + output: ['eis-proto.c'], + command: [scanner, '--component=eis', '--output=@OUTPUT@', '@INPUT@', + '--jinja-extra-data={"headerfile": "eis-proto.h"}', proto_c_template]) + +src_libeis = files( + 'brei-shared.c', + 'libeis.c', + 'libeis-callback.c', + 'libeis-client.c', + 'libeis-handshake.c', + 'libeis-connection.c', + 'libeis-device.c', + 'libeis-event.c', + 'libeis-fd.c', + 'libeis-keyboard.c', + 'libeis-log.c', + 'libeis-pingpong.c', + 'libeis-pointer.c', + 'libeis-region.c', + 'libeis-seat.c', + 'libeis-socket.c', + 'libeis-touchscreen.c', +) + [brei_proto_headers, eis_proto_headers, eis_proto_sources] + +lib_libeis = shared_library('eis', + src_libeis, + dependencies: [dep_libutil], + include_directories: [inc_builddir], + gnu_symbol_visibility: 'hidden', + install: true +) +install_headers('libeis.h') + +dep_libeis = declare_dependency(link_with: lib_libeis, + include_directories: [inc_src]) +meson.override_dependency('libeis', dep_libeis) + +pkgconfig.generate(lib_libeis, + filebase: 'libeis', + name: 'libEIS', + description: 'Emulated Input server library', + version: meson.project_version(), + libraries: lib_libeis, +) + +build_oeffis = dep_systemd.found() +if build_oeffis + src_liboeffis = files('liboeffis.c') + deps_liboeffis = [dep_libutil, dep_systemd] + + lib_liboeffis = shared_library('oeffis', + src_liboeffis, + include_directories: [inc_builddir], + dependencies: deps_liboeffis, + gnu_symbol_visibility: 'hidden', + install: true + ) + install_headers('liboeffis.h') + + dep_liboeffis = declare_dependency(link_with: lib_liboeffis, + include_directories: [inc_src]) + meson.override_dependency('liboeffis', dep_liboeffis) + + pkgconfig.generate(lib_liboeffis, + filebase: 'liboeffis', + name: 'libOeffis', + description: 'RemoteDesktop portal DBus helper library', + version: meson.project_version(), + libraries: lib_liboeffis, + ) + +endif diff --git a/test/meson.build b/test/meson.build index f1a9285..474aad8 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,3 +1,7 @@ +if not get_option('tests') + subdir_done() +endif + subproject('munit', default_options: 'werror=false') munit = dependency('munit', fallback: ['munit', 'munit_dep']) @@ -62,7 +66,7 @@ if build_oeffis dependencies: deps_liboeffis + [dep_unittest])) env = environment() - env.set('LD_LIBRARY_PATH', meson.project_build_root()) + env.set('LD_LIBRARY_PATH', fs.parent(lib_liboeffis.full_path())) test('oeffis-pytest', pytest, args: pytest_args, suite: 'python', diff --git a/tools/ei-demo-client.c b/tools/ei-demo-client.c index d7b8738..61c1540 100644 --- a/tools/ei-demo-client.c +++ b/tools/ei-demo-client.c @@ -280,11 +280,13 @@ int main(int argc, char **argv) _unref_(ei_device) *ptr = NULL; _unref_(ei_device) *kbd = NULL; _unref_(ei_device) *abs = NULL; + _unref_(ei_device) *touch = NULL; bool stop = false; bool have_ptr = false; bool have_kbd = false; bool have_abs = false; + bool have_touch = false; struct ei_seat *default_seat = NULL; uint32_t sequence = 0; @@ -345,6 +347,11 @@ int main(int argc, char **argv) abs = ei_device_ref(device); handle_regions(device); } + if (ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH)) { + colorprint("New touch device: %s\n", ei_device_get_name(device)); + touch = ei_device_ref(device); + handle_regions(device); + } } break; case EI_EVENT_DEVICE_RESUMED: @@ -366,20 +373,30 @@ int main(int argc, char **argv) colorprint("Abs pointer device was resumed\n"); have_abs = true; } + if (ei_event_get_device(e) == touch) { + if (!receiver) + ei_device_start_emulating(touch, ++sequence); + colorprint("Touch device was resumed\n"); + have_touch = true; + } break; case EI_EVENT_DEVICE_PAUSED: if (ei_event_get_device(e) == ptr) { - colorprint("Pointer device was resumed\n"); + colorprint("Pointer device was paused\n"); have_ptr = false; } if (ei_event_get_device(e) == kbd) { - colorprint("Keyboard device was resumed\n"); + colorprint("Keyboard device was paused\n"); have_kbd = false; } if (ei_event_get_device(e) == abs) { - colorprint("Abs pointer device was resumed\n"); + colorprint("Abs pointer device was paused\n"); have_abs = false; } + if (ei_event_get_device(e) == touch) { + colorprint("Touch device was paused\n"); + have_touch = false; + } break; case EI_EVENT_DEVICE_REMOVED: { @@ -442,6 +459,21 @@ int main(int argc, char **argv) ei_event_keyboard_get_key_is_press(e) ? "press" : "release"); } break; + case EI_EVENT_TOUCH_DOWN: + case EI_EVENT_TOUCH_MOTION: + { + colorprint("touch %s %u %.2f/%.2f\n", + ei_event_get_type(e) == EI_EVENT_TOUCH_DOWN ? "down" : "motion", + ei_event_touch_get_id(e), + ei_event_touch_get_x(e), + ei_event_touch_get_y(e)); + } + break; + case EI_EVENT_TOUCH_UP: + { + colorprint("touch up %u\n", ei_event_touch_get_id(e)); + } + break; default: abort(); } @@ -494,6 +526,32 @@ int main(int argc, char **argv) ei_device_frame(abs, now); now += interval; } + + if (have_touch) { + static int x, y; + static int counter = 0; + static struct ei_touch *t; + + switch (counter++ % 5) { + case 0: + colorprint("sending touch down event\n"); + t = ei_device_touch_new(touch); + ei_touch_down(t, 100 + ++x, 200 - ++y); + ei_device_frame(touch, now); + break; + case 4: + colorprint("sending touch down event\n"); + ei_touch_up(t); + ei_device_frame(touch, now); + t = ei_touch_unref(t); + break; + default: + ei_touch_motion(t, 100 + ++x, 200 - ++y); + ei_device_frame(touch, now); + break; + } + + } } } diff --git a/tools/eis-demo-server.c b/tools/eis-demo-server.c index 7e6af41..14195d6 100644 --- a/tools/eis-demo-server.c +++ b/tools/eis-demo-server.c @@ -123,6 +123,7 @@ eis_demo_client_destroy(struct eis_demo_client *democlient) eis_device_unref(democlient->ptr); eis_device_unref(democlient->abs); eis_device_unref(democlient->kbd); + eis_device_unref(democlient->touchscreen); } static @@ -304,8 +305,19 @@ add_device(struct eis_demo_server *server, struct eis_client *client, break; } case EIS_DEVICE_CAP_TOUCH: - assert(!"Not implemented"); + { + struct eis_device *touchscreen = eis_seat_new_device(seat); + eis_device_configure_name(touchscreen, "test touchscreen"); + eis_device_configure_capability(touchscreen, EIS_DEVICE_CAP_TOUCH); + colorprint("Creating touchscreen device %s for %s\n", eis_device_get_name(touchscreen), + eis_client_get_name(client)); + eis_device_add(touchscreen); + eis_device_resume(touchscreen); + if (!eis_client_is_sender(client)) + eis_device_start_emulating(touchscreen, ++sequence); + device = steal(&touchscreen); break; + } } return device; @@ -392,6 +404,16 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server, } } + if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_TOUCH)) { + if (!democlient->touchscreen) + democlient->touchscreen = add_device(server, client, seat, EIS_DEVICE_CAP_TOUCH); + } else { + if (democlient->touchscreen) { + eis_device_remove(democlient->touchscreen); + democlient->touchscreen = eis_device_unref(democlient->touchscreen); + } + } + /* Special "Feature", if all caps are unbound remove the seat. * This is a demo server after all, so let's demo this. */ if (!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER) && @@ -419,6 +441,9 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server, if (democlient->kbd == device) democlient->kbd = NULL; + if (democlient->touchscreen == device) + democlient->touchscreen = NULL; + eis_device_unref(device); } break; @@ -476,6 +501,21 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server, eis_event_keyboard_get_key_is_press(e)); } break; + case EIS_EVENT_TOUCH_DOWN: + case EIS_EVENT_TOUCH_MOTION: + { + colorprint("touch %s %u %.2f/%.2f\n", + eis_event_get_type(e) == EIS_EVENT_TOUCH_DOWN ? "down" : "motion", + eis_event_touch_get_id(e), + eis_event_touch_get_x(e), + eis_event_touch_get_y(e)); + } + break; + case EIS_EVENT_TOUCH_UP: + { + colorprint("touch up %u\n", eis_event_touch_get_id(e)); + } + break; case EIS_EVENT_FRAME: { colorprint("frame timestamp: %" PRIu64 "\n", @@ -634,6 +674,7 @@ int main(int argc, char **argv) struct eis_device *ptr = democlient->ptr; struct eis_device *kbd = democlient->kbd; struct eis_device *abs = democlient->abs; + struct eis_device *touchscreen = democlient->touchscreen; if (ptr) { colorprint("sending motion event\n"); eis_device_pointer_motion(ptr, -1, 1); @@ -673,6 +714,33 @@ int main(int argc, char **argv) eis_device_frame(abs, now); now += interval; } + + if (touchscreen) { + static int x, y; + static int counter = 0; + struct eis_touch *touch = democlient->touch; + + switch (counter++ % 5) { + case 0: + colorprint("sending touch down event\n"); + touch = eis_device_touch_new(touchscreen); + eis_touch_down(touch, 100 + ++x, 200 - ++y); + eis_device_frame(touchscreen, now); + democlient->touch = touch; + break; + case 4: + colorprint("sending touch down event\n"); + eis_touch_up(touch); + eis_device_frame(touchscreen, now); + democlient->touch = eis_touch_unref(touch); + break; + default: + eis_touch_motion(touch, 100 + ++x, 200 - ++y); + eis_device_frame(touchscreen, now); + break; + } + + } } } diff --git a/tools/eis-demo-server.h b/tools/eis-demo-server.h index 5f57ed0..00adefd 100644 --- a/tools/eis-demo-server.h +++ b/tools/eis-demo-server.h @@ -38,6 +38,8 @@ struct eis_demo_client { struct eis_device *ptr; struct eis_device *kbd; struct eis_device *abs; + struct eis_device *touchscreen; + struct eis_touch *touch; }; struct eis_demo_server { diff --git a/tools/meson.build b/tools/meson.build new file mode 100644 index 0000000..af68c6e --- /dev/null +++ b/tools/meson.build @@ -0,0 +1,40 @@ +src_eis_demo_server = files( + 'eis-demo-server.c', +) +if dep_libevdev.found() + src_eis_demo_server += files( + 'eis-demo-server-uinput.c', + ) +endif + +eis_demo_server = executable('eis-demo-server', + src_eis_demo_server, + dependencies: [ + dep_libutil, + dep_libeis, + dep_libxkbcommon, + dep_libevdev + ], + include_directories: [inc_builddir], +) + +executable('ei-demo-client', + 'ei-demo-client.c', + dependencies: [dep_libutil, dep_libei, dep_libxkbcommon], + include_directories: [inc_builddir], +) + +executable('ei-debug-events', + 'ei-debug-events.c', + dependencies: [dep_libutil, dep_libei, dep_libevdev], + include_directories: [inc_builddir], + install: true +) + +if build_oeffis + executable('oeffis-demo-tool', + 'oeffis-demo-tool.c', + include_directories: [inc_builddir], + dependencies: [dep_libutil, dep_liboeffis], + ) +endif