diff --git a/.gitignore b/.gitignore index 6496a2e..75e73b0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,12 @@ debian/libmce-glib debian/libmce-glib-dev debian/*.debhelper.log debian/*.debhelper +debian/*.install debian/*.substvars debian/tmp documentation.list installroot build RPMS +examples/example +examples/example.o diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b5b9b8c --- /dev/null +++ b/LICENSE @@ -0,0 +1,33 @@ +Copyright (C) 2016-2022 Jolla Ltd. +Copyright (C) 2016-2022 Slava Monich + +You may use this file under the terms of BSD license as follows: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the names of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation +are those of the authors and should not be interpreted as representing +any official policies, either expressed or implied. diff --git a/Makefile b/Makefile index fc72999..34dd6c3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # -*- Mode: makefile-gmake -*- -.PHONY: clean all debug release pkgconfig +.PHONY: clean all debug release pkgconfig install install-dev # # Required packages @@ -19,8 +19,8 @@ all: debug release pkgconfig # VERSION_MAJOR = 1 -VERSION_MINOR = 0 -VERSION_RELEASE = 5 +VERSION_MINOR = 1 +VERSION_RELEASE = 0 # Version for pkg-config PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE) @@ -38,7 +38,10 @@ LIB = $(LIB_SONAME).$(VERSION_MINOR).$(VERSION_RELEASE) # SRC = \ + mce_battery.c \ + mce_charger.c \ mce_display.c \ + mce_inactivity.c \ mce_proxy.c GEN_SRC = \ com.canonical.Unity.Screen.c @@ -59,30 +62,29 @@ RELEASE_BUILD_DIR = $(BUILD_DIR)/release # Tools and flags # -CC = $(CROSS_COMPILE)gcc +CC ?= $(CROSS_COMPILE)gcc LD = $(CC) +DEFINES += -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 \ + -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_MAX_ALLOWED WARNINGS = -Wall -Wno-unused-parameter -Wno-multichar INCLUDES = -I$(INCLUDE_DIR) -I$(GEN_DIR) BASE_FLAGS = -fPIC $(CFLAGS) FULL_CFLAGS = $(BASE_FLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \ $(shell pkg-config --cflags $(PKGS)) -LDFLAGS = $(BASE_FLAGS) -shared -Wl,-soname -Wl,$(LIB_SONAME) \ - $(shell pkg-config --libs $(PKGS)) +FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS) -shared -Wl,-soname -Wl,$(LIB_SONAME) \ + -Wl,--version-script=$(LIB_NAME).map DEBUG_FLAGS = -g RELEASE_FLAGS = -ifndef KEEP_SYMBOLS -KEEP_SYMBOLS = 0 -endif - +KEEP_SYMBOLS ?= 0 ifneq ($(KEEP_SYMBOLS),0) RELEASE_FLAGS += -g endif DEBUG_CFLAGS = $(FULL_CFLAGS) $(DEBUG_FLAGS) -DDEBUG RELEASE_CFLAGS = $(FULL_CFLAGS) $(RELEASE_FLAGS) -O2 -DEBUG_LDFLAGS = $(LDFLAGS) $(DEBUG_FLAGS) -RELEASE_LDFLAGS = $(LDFLAGS) $(RELEASE_FLAGS) +DEBUG_LDFLAGS = $(FULL_LDFLAGS) $(DEBUG_FLAGS) +RELEASE_LDFLAGS = $(FULL_LDFLAGS) $(RELEASE_FLAGS) # # Files @@ -97,6 +99,7 @@ RELEASE_OBJS = \ $(GEN_SRC:%.c=$(RELEASE_BUILD_DIR)/%.o) \ $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o) GEN_FILES = $(GEN_SRC:%=$(GEN_DIR)/%) +LIBS = $(shell pkg-config --libs $(PKGS)) .PRECIOUS: $(GEN_FILES) # @@ -110,31 +113,33 @@ ifneq ($(strip $(DEPS)),) endif endif -$(GEN_FILES): | $(GEN_DIR) -$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR) -$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR) - -# -# Rules -# - DEBUG_LIB = $(DEBUG_BUILD_DIR)/$(LIB) RELEASE_LIB = $(RELEASE_BUILD_DIR)/$(LIB) DEBUG_LINK = $(DEBUG_BUILD_DIR)/$(LIB_SONAME) RELEASE_LINK = $(RELEASE_BUILD_DIR)/$(LIB_SONAME) +$(GEN_FILES): | $(GEN_DIR) +$(DEBUG_OBJS): | $(DEBUG_BUILD_DIR) $(GEN_FILES) +$(RELEASE_OBJS): | $(RELEASE_BUILD_DIR) $(GEN_FILES) +$(PKGCONFIG): | $(BUILD_DIR) +$(DEBUG_LINK): | $(DEBUG_LIB) +$(RELEASE_LINK): | $(RELEASE_LIB) + +# +# Rules +# + debug: $(DEBUG_LIB) $(DEBUG_LINK) release: $(RELEASE_LIB) $(RELEASE_LINK) -pkgconfig: $(PKGCONFIG) - clean: rm -f *~ $(SRC_DIR)/*~ $(INCLUDE_DIR)/*~ rpm/*~ rm -fr $(BUILD_DIR) RPMS installroot rm -fr debian/tmp debian/lib$(NAME) debian/lib$(NAME)-dev rm -f documentation.list debian/files debian/*.substvars rm -f debian/*.debhelper.log debian/*.debhelper debian/*~ + rm -f debian/*.install $(GEN_DIR): mkdir -p $@ @@ -160,11 +165,11 @@ $(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c $(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@ -$(DEBUG_LIB): $(DEBUG_BUILD_DIR) $(DEBUG_OBJS) - $(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) -o $@ +$(DEBUG_LIB): $(DEBUG_OBJS) + $(LD) $(DEBUG_LDFLAGS) -o $@ $^ $(LIBS) -$(RELEASE_LIB): $(RELEASE_BUILD_DIR) $(RELEASE_OBJS) - $(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) -o $@ +$(RELEASE_LIB): $(RELEASE_OBJS) + $(LD) $(RELEASE_LDFLAGS) -o $@ $^ $(LIBS) ifeq ($(KEEP_SYMBOLS),0) strip $@ endif @@ -175,29 +180,32 @@ $(DEBUG_LINK): $(RELEASE_LINK): ln -sf $(LIB) $@ -$(PKGCONFIG): $(LIB_NAME).pc.in - sed -e 's/\[version\]/'$(PCVERSION)/g $< > $@ +# This one could be substituted with arch specific dir +LIBDIR ?= /usr/lib +ABS_LIBDIR := $(shell echo /$(LIBDIR) | sed -r 's|/+|/|g') + +pkgconfig: $(PKGCONFIG) + +$(PKGCONFIG): $(LIB_NAME).pc.in Makefile + sed -e 's|@version@|$(PCVERSION)|g' -e 's|@libdir@|$(ABS_LIBDIR)|g' $< > $@ + +debian/%.install: debian/%.install.in + sed 's|@LIBDIR@|$(LIBDIR)|g' $< > $@ # # Install # -INSTALL_PERM = 644 -INSTALL_OWNER = $(shell id -u) -INSTALL_GROUP = $(shell id -g) - INSTALL = install INSTALL_DIRS = $(INSTALL) -d -INSTALL_FILES = $(INSTALL) -m $(INSTALL_PERM) +INSTALL_FILES = $(INSTALL) -m 644 -INSTALL_LIB_DIR = $(DESTDIR)/usr/lib +INSTALL_LIB_DIR = $(DESTDIR)$(ABS_LIBDIR) INSTALL_INCLUDE_DIR = $(DESTDIR)/usr/include/$(LIB_NAME) -INSTALL_PKGCONFIG_DIR = $(DESTDIR)/usr/lib/pkgconfig - -INSTALL_ALIAS = $(INSTALL_LIB_DIR)/$(LIB_SHORTCUT) +INSTALL_PKGCONFIG_DIR = $(DESTDIR)$(ABS_LIBDIR)/pkgconfig install: $(INSTALL_LIB_DIR) - $(INSTALL_FILES) $(RELEASE_LIB) $(INSTALL_LIB_DIR) + $(INSTALL) -m 755 $(RELEASE_LIB) $(INSTALL_LIB_DIR) ln -sf $(LIB) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK2) ln -sf $(LIB_SYMLINK2) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK1) diff --git a/debian/changelog b/debian/changelog index d3367b4..2382fe1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,54 @@ -libmce-glib (1.0.5+gemian) buster; urgency=low +libmce-glib (1.1.0) unstable; urgency=low - * Branched for Gemian + * Add an example application + * Add MceInactivity object - -- Adam Boardman Thu, 7 Jun 2018 16:25:48 +0100 + -- Simo Piiroinen Mon, 08 May 2023 10:46:08 +0300 + +libmce-glib (1.0.13) unstable; urgency=low + + * Shuffled includes a bit + * Unified and freshened up licenses + + -- Slava Monich Wed, 19 Jan 2022 14:21:38 +0200 + +libmce-glib (1.0.12) unstable; urgency=low + + * Housekeeping release + + -- Slava Monich Mon, 08 Nov 2021 02:44:15 +0200 + +libmce-glib (1.0.10) unstable; urgency=low + + * Hide internal symbols + * Respect arch specific lib dir + + -- Slava Monich Mon, 25 May 2020 15:11:04 +0300 + +libmce-glib (1.0.9) unstable; urgency=low + + * Ignore GLib deprecation warnings + + -- Slava Monich Sun, 08 Mar 2020 16:30:35 +0200 + +libmce-glib (1.0.8) unstable; urgency=low + + * Avoid overlinking + + -- Slava Monich Tue, 05 Nov 2019 14:21:43 +0300 + +libmce-glib (1.0.7) unstable; urgency=low + + * Allow use of CC & LDFLAGS defined by build system + + -- Slava Monich Fri, 30 Aug 2019 18:14:21 +0300 + +libmce-glib (1.0.6) unstable; urgency=low + + * Added MceBattery object + * Added MceCharger object + + -- Slava Monich Thu, 22 Aug 2019 12:14:38 +0300 libmce-glib (1.0.5) unstable; urgency=low diff --git a/debian/control b/debian/control index c557862..29e67be 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Standards-Version: 3.8.4 Package: libmce-glib Section: libs Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: libglibutil (>= 1.0.5), ${shlibs:Depends}, ${misc:Depends} Description: Client library for mce Package: libmce-glib-dev diff --git a/debian/copyright b/debian/copyright index 19b3195..b5b9b8c 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,4 +1,5 @@ -Copyright (C) 2016 Jolla Ltd. +Copyright (C) 2016-2022 Jolla Ltd. +Copyright (C) 2016-2022 Slava Monich You may use this file under the terms of BSD license as follows: @@ -11,9 +12,9 @@ are met: 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - 3. Neither the name of Jolla Ltd nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. + 3. Neither the names of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/debian/libmce-glib-dev.install b/debian/libmce-glib-dev.install deleted file mode 100644 index cce5a7d..0000000 --- a/debian/libmce-glib-dev.install +++ /dev/null @@ -1,3 +0,0 @@ -debian/tmp/usr/lib/libmce-glib.so usr/lib -include/*.h usr/include/libmce-glib -build/libmce-glib.pc usr/lib/pkgconfig diff --git a/debian/libmce-glib-dev.install.in b/debian/libmce-glib-dev.install.in new file mode 100644 index 0000000..c07d428 --- /dev/null +++ b/debian/libmce-glib-dev.install.in @@ -0,0 +1,3 @@ +debian/tmp/@LIBDIR@/libmce-glib.so @LIBDIR@ +debian/tmp/@LIBDIR@/pkgconfig/libmce-glib.pc @LIBDIR@/pkgconfig +debian/tmp/usr/include/* usr/include diff --git a/debian/libmce-glib.install b/debian/libmce-glib.install deleted file mode 100644 index 6a4fd9f..0000000 --- a/debian/libmce-glib.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libmce-glib.so.* usr/lib diff --git a/debian/libmce-glib.install.in b/debian/libmce-glib.install.in new file mode 100644 index 0000000..661666a --- /dev/null +++ b/debian/libmce-glib.install.in @@ -0,0 +1 @@ +debian/tmp/@LIBDIR@/libmce-glib.so.* @LIBDIR@ diff --git a/debian/rules b/debian/rules index 3a92007..fd7b2a3 100755 --- a/debian/rules +++ b/debian/rules @@ -4,8 +4,13 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 +LIBDIR=usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +override_dh_auto_build: + dh_auto_build -- LIBDIR=$(LIBDIR) release pkgconfig debian/libmce-glib.install debian/libmce-glib-dev.install + override_dh_auto_install: - dh_auto_install -- install-dev + dh_auto_install -- LIBDIR=$(LIBDIR) install-dev %: dh $@ diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..70e9e55 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,15 @@ +.PHONY: build clean mostlyclean +build:: +clean:: mostlyclean +mostlyclean:: ; $(RM) *.o *~ *.bak +PKG_NAMES += glib-2.0 +PKG_NAMES += libmce-glib +CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +CFLAGS += -Wall -Wextra -Os -g -std=c99 +LDFLAGS += -g +LDLIBS += -Wl,--as-needed +CFLAGS += $(shell pkg-config --cflags $(PKG_NAMES)) +LDLIBS += $(shell pkg-config --libs $(PKG_NAMES)) +example : example.o +build:: example +clean:: ; $(RM) example diff --git a/examples/example.c b/examples/example.c new file mode 100644 index 0000000..ea872dd --- /dev/null +++ b/examples/example.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2023 Jolla Ltd. + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +/* ========================================================================= * + * MAINLOOP + * ========================================================================= */ + +static int mainloop_result = EXIT_SUCCESS; +static GMainLoop *mainloop_handle = NULL; + +static void mainloop_exit(int exitcode) +{ + if( mainloop_result < exitcode ) + mainloop_result = exitcode; + if( !mainloop_handle ) + exit(mainloop_result); + g_main_loop_quit(mainloop_handle); +} + +static void mainloop_quit(void) +{ + mainloop_exit(EXIT_SUCCESS); +} + +static int mainloop_run(void) +{ + mainloop_handle = g_main_loop_new(NULL, false); + g_main_loop_run(mainloop_handle); + g_main_loop_unref(mainloop_handle), + mainloop_handle = NULL; + return mainloop_result; +} + +/* ========================================================================= * + * STATUS + * ========================================================================= */ + +static const char *bool_repr(bool value) +{ + return value ? "true" : "false"; +} + +static const char *battery_status_repr(MCE_BATTERY_STATUS status) +{ + static const char * const lut[] = { + [MCE_BATTERY_UNKNOWN] = "unknown", + [MCE_BATTERY_EMPTY] = "empty", + [MCE_BATTERY_LOW] = "low", + [MCE_BATTERY_OK] = "ok", + [MCE_BATTERY_FULL] = "full", + }; + return lut[status]; +} + +static const char *charger_state_repr(MCE_CHARGER_STATE state) +{ + static const char * const lut[] = { + [MCE_CHARGER_UNKNOWN] = "unknown", + [MCE_CHARGER_ON] = "on", + [MCE_CHARGER_OFF] = "off", + }; + return lut[state]; +} + +static const char *display_state_repr(MCE_DISPLAY_STATE state) +{ + static const char * const lut[] = { + [MCE_DISPLAY_STATE_OFF] = "off", + [MCE_DISPLAY_STATE_DIM] = "dim", + [MCE_DISPLAY_STATE_ON] = "on", + }; + return lut[state]; +} + +static const char *tklock_mode_repr(MCE_TKLOCK_MODE mode) +{ + static const char * const lut[] = { + [MCE_TKLOCK_MODE_LOCKED] = "locked", + [MCE_TKLOCK_MODE_SILENT_LOCKED] = "silent_locked", + [MCE_TKLOCK_MODE_LOCKED_DIM] = "locked_dim", + [MCE_TKLOCK_MODE_LOCKED_DELAY] = "locked_delay", + [MCE_TKLOCK_MODE_SILENT_LOCKED_DIM] = "silent_locked_dim", + [MCE_TKLOCK_MODE_UNLOCKED] = "unlocked", + [MCE_TKLOCK_MODE_SILENT_UNLOCKED] = "silent_unlocked", + }; + return lut[mode]; +} + +static void battery_cb(MceBattery *battery, void *arg) +{ + const char *what_changed = arg; + printf("battery: valid=%s level=%d status=%s (%s changed)\n", + bool_repr(battery->valid), + battery->level, + battery_status_repr(battery->status), + what_changed); +} + +static void charger_cb(MceCharger *charger, void *arg) +{ + const char *what_changed = arg; + printf("charger: valid=%s state=%s (%s changed)\n", + bool_repr(charger->valid), + charger_state_repr(charger->state), + what_changed); +} + +static void display_cb(MceDisplay *display, void *arg) +{ + const char *what_changed = arg; + printf("display: valid=%s state=%s (%s changed)\n", + bool_repr(display->valid), + display_state_repr(display->state), + what_changed); +} + +static void tklock_cb(MceTklock *tklock, void *arg) +{ + const char *what_changed = arg; + printf("tklock: valid=%s mode=%s locked=%s (%s changed)\n", + bool_repr(tklock->valid), + tklock_mode_repr(tklock->mode), + bool_repr(tklock->locked), + what_changed); +} + +static void inactivity_cb(MceInactivity *inactivity, void *arg) +{ + const char *what_changed = arg; + printf("inactivity: valid=%s status=%s (%s changed)\n", + bool_repr(inactivity->valid), + bool_repr(inactivity->status), + what_changed); +} + +/* ========================================================================= * + * MAIN_ENTRY + * ========================================================================= */ + +static gboolean quit_cb(gpointer aptr) +{ + printf("quit\n"); + mainloop_quit(); + guint *id_ptr = aptr; + *id_ptr = 0; + return G_SOURCE_REMOVE; +} + +int +main(int argc, char **argv) +{ + printf("startup\n"); + + int exitcode = EXIT_FAILURE; + + MceBattery *battery = mce_battery_new(); + gulong battery_valid_id = + mce_battery_add_valid_changed_handler(battery, battery_cb, "valid"); + gulong battery_level_id = + mce_battery_add_level_changed_handler(battery, battery_cb, "level"); + gulong battery_status_id = + mce_battery_add_status_changed_handler(battery, battery_cb, "status"); + + MceCharger *charger = mce_charger_new(); + gulong charger_valid_id = + mce_charger_add_valid_changed_handler(charger, charger_cb, "valid"); + gulong charger_state_id = + mce_charger_add_state_changed_handler(charger, charger_cb, "state"); + + MceDisplay *display = mce_display_new(); + gulong display_valid_id = + mce_display_add_valid_changed_handler(display, display_cb, "valid"); + gulong display_state_id = + mce_display_add_state_changed_handler(display, display_cb, "state"); + + MceTklock *tklock = mce_tklock_new(); + gulong tklock_valid_id = + mce_tklock_add_valid_changed_handler(tklock, tklock_cb, "valid"); + gulong tklock_mode_id = + mce_tklock_add_mode_changed_handler(tklock, tklock_cb, "mode"); + gulong tklock_locked_id = + mce_tklock_add_locked_changed_handler(tklock, tklock_cb, "locked"); + + MceInactivity *inactivity = mce_inactivity_new(); + gulong inactivity_valid_id = + mce_inactivity_add_valid_changed_handler(inactivity, inactivity_cb, "valid"); + gulong inactivity_status_id = + mce_inactivity_add_status_changed_handler(inactivity, inactivity_cb, "status"); + + guint timeout_id = 0; + gint timeout_s = (argc > 1) ? strtol(argv[1], NULL, 0) : 0; + if( timeout_s > 0) + timeout_id = g_timeout_add(timeout_s * 1000, quit_cb, &timeout_id); + + guint sigterm_id = g_unix_signal_add(SIGTERM, quit_cb, &sigterm_id); + guint sigint_id = g_unix_signal_add(SIGINT, quit_cb, &sigint_id); + + printf("mainloop\n"); + exitcode = mainloop_run(); + printf("cleanup\n"); + + if( sigterm_id ) + g_source_remove(sigterm_id); + if( sigint_id ) + g_source_remove(sigint_id); + if( timeout_id ) + g_source_remove(timeout_id); + + mce_battery_remove_handler(battery, battery_valid_id); + mce_battery_remove_handler(battery, battery_level_id); + mce_battery_remove_handler(battery, battery_status_id); + mce_battery_unref(battery); + + mce_charger_remove_handler(charger, charger_valid_id); + mce_charger_remove_handler(charger, charger_state_id); + mce_charger_unref(charger); + + mce_display_remove_handler(display, display_valid_id); + mce_display_remove_handler(display, display_state_id); + mce_display_unref(display); + + mce_tklock_remove_handler(tklock, tklock_valid_id); + mce_tklock_remove_handler(tklock, tklock_mode_id); + mce_tklock_remove_handler(tklock, tklock_locked_id); + mce_tklock_unref(tklock); + + mce_inactivity_remove_handler(inactivity, inactivity_valid_id); + mce_inactivity_remove_handler(inactivity, inactivity_status_id); + mce_inactivity_unref(inactivity); + + printf("exit\n"); + return exitcode; +} diff --git a/include/mce_battery.h b/include/mce_battery.h new file mode 100644 index 0000000..f3deeed --- /dev/null +++ b/include/mce_battery.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2019-2022 Jolla Ltd. + * Copyright (C) 2019-2022 Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#ifndef MCE_BATTERY_H +#define MCE_BATTERY_H + +/* Since 1.0.6 */ + +#include "mce_types.h" + +#include + +G_BEGIN_DECLS + +typedef enum mce_battery_status { + MCE_BATTERY_UNKNOWN, + MCE_BATTERY_EMPTY, + MCE_BATTERY_LOW, + MCE_BATTERY_OK, + MCE_BATTERY_FULL +} MCE_BATTERY_STATUS; + +typedef struct mce_battery_priv MceBatteryPriv; + +struct mce_battery { + GObject object; + MceBatteryPriv* priv; + gboolean valid; + guint level; + MCE_BATTERY_STATUS status; +}; /* MceBattery */ + +typedef void +(*MceBatteryFunc)( + MceBattery* battery, + void* arg); + +MceBattery* +mce_battery_new( + void); + +MceBattery* +mce_battery_ref( + MceBattery* battery); + +void +mce_battery_unref( + MceBattery* battery); + +gulong +mce_battery_add_valid_changed_handler( + MceBattery* battery, + MceBatteryFunc fn, + void* arg); + +gulong +mce_battery_add_level_changed_handler( + MceBattery* battery, + MceBatteryFunc fn, + void* arg); + +gulong +mce_battery_add_status_changed_handler( + MceBattery* battery, + MceBatteryFunc fn, + void* arg); + +void +mce_battery_remove_handler( + MceBattery* battery, + gulong id); + +void +mce_battery_remove_handlers( + MceBattery* battery, + gulong* ids, + guint count); + +#define mce_battery_remove_all_handlers(d, ids) \ + mce_battery_remove_handlers(d, ids, G_N_ELEMENTS(ids)) + +G_END_DECLS + +#endif /* MCE_BATTERY_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/mce_charger.h b/include/mce_charger.h new file mode 100644 index 0000000..776c884 --- /dev/null +++ b/include/mce_charger.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2019-2022 Jolla Ltd. + * Copyright (C) 2019-2022 Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#ifndef MCE_CHARGER_H +#define MCE_CHARGER_H + +/* Since 1.0.6 */ + +#include "mce_types.h" + +#include + +G_BEGIN_DECLS + +typedef enum mce_charger_state { + MCE_CHARGER_UNKNOWN, + MCE_CHARGER_ON, + MCE_CHARGER_OFF +} MCE_CHARGER_STATE; + +typedef struct mce_charger_priv MceChargerPriv; + +struct mce_charger { + GObject object; + MceChargerPriv* priv; + gboolean valid; + MCE_CHARGER_STATE state; +}; /* MceCharger */ + +typedef void +(*MceChargerFunc)( + MceCharger* charger, + void* arg); + +MceCharger* +mce_charger_new( + void); + +MceCharger* +mce_charger_ref( + MceCharger* charger); + +void +mce_charger_unref( + MceCharger* charger); + +gulong +mce_charger_add_valid_changed_handler( + MceCharger* charger, + MceChargerFunc fn, + void* arg); + +gulong +mce_charger_add_state_changed_handler( + MceCharger* charger, + MceChargerFunc fn, + void* arg); + +void +mce_charger_remove_handler( + MceCharger* charger, + gulong id); + +void +mce_charger_remove_handlers( + MceCharger* charger, + gulong* ids, + guint count); + +#define mce_charger_remove_all_handlers(d, ids) \ + mce_charger_remove_handlers(d, ids, G_N_ELEMENTS(ids)) + +G_END_DECLS + +#endif /* MCE_CHARGER_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/mce_display.h b/include/mce_display.h index 4828fdf..1084d04 100644 --- a/include/mce_display.h +++ b/include/mce_display.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016-2017 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -39,6 +39,8 @@ #include "mce_types.h" +#include + G_BEGIN_DECLS typedef enum mce_display_state { @@ -48,12 +50,12 @@ typedef enum mce_display_state { typedef struct mce_display_priv MceDisplayPriv; -typedef struct mce_display { +struct mce_display { GObject object; MceDisplayPriv* priv; gboolean valid; MCE_DISPLAY_STATE state; -} MceDisplay; +}; /* MceDisplay */ typedef void (*MceDisplayFunc)( @@ -92,7 +94,7 @@ mce_display_remove_handler( void mce_display_remove_handlers( MceDisplay* display, - gulong *ids, + gulong* ids, guint count); #define mce_display_remove_all_handlers(d, ids) \ diff --git a/include/mce_inactivity.h b/include/mce_inactivity.h new file mode 100644 index 0000000..7fbb9ad --- /dev/null +++ b/include/mce_inactivity.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016 - 2023 Jolla Ltd. + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#ifndef MCE_INACTIVITY_H +#define MCE_INACTIVITY_H + +#include "mce_types.h" + +#include + +G_BEGIN_DECLS + +typedef struct mce_inactivity_priv MceInactivityPriv; + +struct mce_inactivity { + GObject object; + MceInactivityPriv* priv; + gboolean valid; + gboolean status; +}; /* MceInactivity */ + +typedef void +(*MceInactivityFunc)( + MceInactivity* inactivity, + void* arg); + +MceInactivity* +mce_inactivity_new( + void); + +MceInactivity* +mce_inactivity_ref( + MceInactivity* inactivity); + +void +mce_inactivity_unref( + MceInactivity* inactivity); + +gulong +mce_inactivity_add_valid_changed_handler( + MceInactivity* inactivity, + MceInactivityFunc fn, + void* arg); + +gulong +mce_inactivity_add_status_changed_handler( + MceInactivity* inactivity, + MceInactivityFunc fn, + void* arg); + +void +mce_inactivity_remove_handler( + MceInactivity* inactivity, + gulong id); + +void +mce_inactivity_remove_handlers( + MceInactivity* inactivity, + gulong* ids, + guint count); + +#define mce_inactivity_remove_all_handlers(t, ids) \ + mce_inactivity_remove_handlers(t, ids, G_N_ELEMENTS(ids)) + +G_END_DECLS + +#endif /* MCE_INACTIVITY_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/mce_log.h b/include/mce_log.h index d4351c9..2cab08b 100644 --- a/include/mce_log.h +++ b/include/mce_log.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -38,6 +38,7 @@ #define MCE_LOG_H #include "mce_types.h" + #include G_BEGIN_DECLS diff --git a/include/mce_tklock.h b/include/mce_tklock.h index c5aad6e..8aee093 100644 --- a/include/mce_tklock.h +++ b/include/mce_tklock.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016-2017 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -39,6 +39,8 @@ #include "mce_types.h" +#include + G_BEGIN_DECLS typedef enum mce_tklock_mode { @@ -53,13 +55,13 @@ typedef enum mce_tklock_mode { typedef struct mce_tklock_priv MceTklockPriv; -typedef struct mce_tklock { +struct mce_tklock { GObject object; MceTklockPriv* priv; gboolean valid; MCE_TKLOCK_MODE mode; gboolean locked; -} MceTklock; +}; /* MceTklock */ typedef void (*MceTklockFunc)( @@ -104,7 +106,7 @@ mce_tklock_remove_handler( void mce_tklock_remove_handlers( MceTklock* tklock, - gulong *ids, + gulong* ids, guint count); #define mce_tklock_remove_all_handlers(t, ids) \ diff --git a/include/mce_types.h b/include/mce_types.h index 5515a4f..663d367 100644 --- a/include/mce_types.h +++ b/include/mce_types.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (c) 2016 - 2023 Jolla Ltd. + * Copyright (c) 2016 - 2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -38,7 +38,16 @@ #define MCE_TYPES_H #include -#include + +G_BEGIN_DECLS + +typedef struct mce_battery MceBattery; +typedef struct mce_charger MceCharger; +typedef struct mce_display MceDisplay; +typedef struct mce_inactivity MceInactivity; +typedef struct mce_tklock MceTklock; + +G_END_DECLS #endif /* MCE_TYPES_H */ diff --git a/libmce-glib.map b/libmce-glib.map new file mode 100644 index 0000000..e0d8ab8 --- /dev/null +++ b/libmce-glib.map @@ -0,0 +1,6 @@ +{ + global: + mce_*; + local: + *; +}; diff --git a/libmce-glib.pc.in b/libmce-glib.pc.in index 4889656..c89a268 100644 --- a/libmce-glib.pc.in +++ b/libmce-glib.pc.in @@ -1,9 +1,9 @@ -libdir=/usr/lib +libdir=@libdir@ includedir=/usr/include Name: libmce-glib Description: MCE client library -Version: [version] -Requires: libglibutil glib-2.0 gio-2.0 +Version: @version@ +Requires.private: libglibutil glib-2.0 gio-2.0 Libs: -lmce-glib Cflags: -I${includedir}/libmce-glib diff --git a/rpm/libmce-glib.spec b/rpm/libmce-glib.spec index 1d4db40..0673af8 100644 --- a/rpm/libmce-glib.spec +++ b/rpm/libmce-glib.spec @@ -1,15 +1,24 @@ Name: libmce-glib -Version: 1.0.4 + +Version: 1.1.0 Release: 0 Summary: MCE client library -Group: Development/Libraries License: BSD -URL: https://git.merproject.org/mer-core/libmce-glib +URL: https://github.com/sailfishos/libmce-glib Source: %{name}-%{version}.tar.bz2 + +%define libglibutil_version 1.0.5 + +BuildRequires: pkgconfig BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(libglibutil) -BuildRequires: pkgconfig(mce) -Requires: libglibutil >= 1.0.5 +BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version} +BuildRequires: pkgconfig(mce) >= 1.24.0 + +# license macro requires rpm >= 4.11 +BuildRequires: pkgconfig(rpm) +%define license_support %(pkg-config --exists 'rpm >= 4.11'; echo $?) + +Requires: libglibutil >= %{libglibutil_version} Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -19,7 +28,6 @@ Provides glib-based MCE client API %package devel Summary: Development library for %{name} Requires: %{name} = %{version} -Requires: pkgconfig %description devel This package contains the development library for %{name}. @@ -28,11 +36,11 @@ This package contains the development library for %{name}. %setup -q %build -make KEEP_SYMBOLS=1 release pkgconfig +make %{_smp_mflags} LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig %install rm -rf %{buildroot} -make install-dev DESTDIR=%{buildroot} +make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev %post -p /sbin/ldconfig @@ -41,6 +49,9 @@ make install-dev DESTDIR=%{buildroot} %files %defattr(-,root,root,-) %{_libdir}/%{name}.so.* +%if %{license_support} == 0 +%license LICENSE +%endif %files devel %defattr(-,root,root,-) diff --git a/src/mce_battery.c b/src/mce_battery.c new file mode 100644 index 0000000..1ce4acc --- /dev/null +++ b/src/mce_battery.c @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2019-2022 Jolla Ltd. + * Copyright (C) 2019-2022 Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#include "mce_battery.h" +#include "mce_proxy.h" +#include "mce_log_p.h" + +#include +#include + +#include + +/* Generated headers */ +#include "com.nokia.mce.request.h" +#include "com.nokia.mce.signal.h" + +enum mce_battery_ind { + BATTERY_IND_LEVEL, + BATTERY_IND_STATUS, + BATTERY_IND_COUNT +}; + +typedef enum mce_battery_flags { + BATTERY_HAVE_NONE = 0x00, + BATTERY_HAVE_LEVEL = 0x01, + BATTERY_HAVE_STATUS = 0x02 +} BATTERY_FLAGS; + +#define BATTERY_HAVE_ALL (BATTERY_HAVE_LEVEL | BATTERY_HAVE_STATUS) + +struct mce_battery_priv { + MceProxy* proxy; + BATTERY_FLAGS flags; + gulong proxy_valid_id; + gulong battery_ind_id[BATTERY_IND_COUNT]; +}; + +enum mce_battery_signal { + SIGNAL_VALID_CHANGED, + SIGNAL_LEVEL_CHANGED, + SIGNAL_STATUS_CHANGED, + SIGNAL_COUNT +}; + +#define SIGNAL_VALID_CHANGED_NAME "mce-battery-valid-changed" +#define SIGNAL_LEVEL_CHANGED_NAME "mce-battery-level-changed" +#define SIGNAL_STATUS_CHANGED_NAME "mce-battery-status-changed" + +static guint mce_battery_signals[SIGNAL_COUNT] = { 0 }; + +typedef GObjectClass MceBatteryClass; +G_DEFINE_TYPE(MceBattery, mce_battery, G_TYPE_OBJECT) +#define PARENT_CLASS mce_battery_parent_class +#define MCE_BATTERY_TYPE (mce_battery_get_type()) +#define MCE_BATTERY(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj,\ + MCE_BATTERY_TYPE,MceBattery)) + +/*==========================================================================* + * Implementation + *==========================================================================*/ + +static +void +mce_battery_check_valid( + MceBattery* self) +{ + MceBatteryPriv* priv = self->priv; + const gboolean valid = priv->proxy->valid && + (priv->flags & BATTERY_HAVE_ALL) == BATTERY_HAVE_ALL; + + if (valid != self->valid) { + self->valid = valid; + g_signal_emit(self, mce_battery_signals[SIGNAL_VALID_CHANGED], 0); + } +} + +static +void +mce_battery_level_update( + MceBattery* self, + gint level) +{ + MceBatteryPriv* priv = self->priv; + const guint new_level = (level < 0) ? 0 : (level > 100) ? 100 : level; + + if (self->level != new_level) { + self->level = new_level; + g_signal_emit(self, mce_battery_signals[SIGNAL_LEVEL_CHANGED], 0); + } + priv->flags |= BATTERY_HAVE_LEVEL; + mce_battery_check_valid(self); +} + +static +void +mce_battery_status_update( + MceBattery* self, + const char* status) +{ + MceBatteryPriv* priv = self->priv; + MCE_BATTERY_STATUS new_status; + + if (!g_strcmp0(status, MCE_BATTERY_STATUS_FULL)) { + new_status = MCE_BATTERY_FULL; + } else if (!g_strcmp0(status, MCE_BATTERY_STATUS_OK)) { + new_status = MCE_BATTERY_OK; + } else if (!g_strcmp0(status, MCE_BATTERY_STATUS_LOW)) { + new_status = MCE_BATTERY_LOW; + } else if (!g_strcmp0(status, MCE_BATTERY_STATUS_EMPTY)) { + new_status = MCE_BATTERY_EMPTY; + } else { + GASSERT(!g_strcmp0(status, MCE_BATTERY_STATUS_UNKNOWN)); + new_status = MCE_BATTERY_UNKNOWN; + } + if (self->status != new_status) { + self->status = new_status; + g_signal_emit(self, mce_battery_signals[SIGNAL_STATUS_CHANGED], 0); + } + priv->flags |= BATTERY_HAVE_STATUS; + mce_battery_check_valid(self); +} + +static +void +mce_battery_level_query_done( + GObject* proxy, + GAsyncResult* result, + gpointer arg) +{ + MceBattery* self = MCE_BATTERY(arg); + GError* error = NULL; + gint level; + + if (com_nokia_mce_request_call_get_battery_level_finish( + COM_NOKIA_MCE_REQUEST(proxy), &level, result, &error)) { + GDEBUG("Battery level is currently %d", level); + mce_battery_level_update(self, level); + } else { + /* Should retry? */ + GWARN("Failed to query battery level %s", GERRMSG(error)); + g_error_free(error); + } + mce_battery_unref(self); +} + +static +void +mce_battery_status_query_done( + GObject* proxy, + GAsyncResult* result, + gpointer arg) +{ + MceBattery* self = MCE_BATTERY(arg); + GError* error = NULL; + char* status = NULL; + + if (com_nokia_mce_request_call_get_battery_status_finish( + COM_NOKIA_MCE_REQUEST(proxy), &status, result, &error)) { + GDEBUG("Battery is currently %s", status); + mce_battery_status_update(self, status); + g_free(status); + } else { + /* Should retry? */ + GWARN("Failed to query battery status %s", GERRMSG(error)); + g_error_free(error); + } + mce_battery_unref(self); +} + +static +void +mce_battery_level_ind( + ComNokiaMceSignal* proxy, + gint level, + gpointer arg) +{ + GDEBUG("Battery level is %d", level); + mce_battery_level_update(MCE_BATTERY(arg), level); +} + +static +void +mce_battery_status_ind( + ComNokiaMceSignal* proxy, + const char* status, + gpointer arg) +{ + GDEBUG("Battery is %s", status); + mce_battery_status_update(MCE_BATTERY(arg), status); +} + +static +void +mce_battery_query( + MceBattery* self) +{ + MceBatteryPriv* priv = self->priv; + MceProxy* proxy = priv->proxy; + + /* + * proxy->signal and proxy->request may not be available at the + * time when MceBattery is created. In that case we have to wait + * for the valid signal before we can connect the battery state + * signal and submit the initial query. + */ + if (proxy->signal) { + if (!priv->battery_ind_id[BATTERY_IND_LEVEL]) { + priv->battery_ind_id[BATTERY_IND_LEVEL] = + g_signal_connect(proxy->signal, "battery-level-ind", + G_CALLBACK(mce_battery_level_ind), self); + } + + if (!priv->battery_ind_id[BATTERY_IND_STATUS]) { + priv->battery_ind_id[BATTERY_IND_STATUS] = + g_signal_connect(proxy->signal, "battery-status-ind", + G_CALLBACK(mce_battery_status_ind), self); + } + } + if (proxy->request && proxy->valid) { + com_nokia_mce_request_call_get_battery_level(proxy->request, NULL, + mce_battery_level_query_done, mce_battery_ref(self)); + com_nokia_mce_request_call_get_battery_status(proxy->request, NULL, + mce_battery_status_query_done, mce_battery_ref(self)); + } +} + +static +void +mce_battery_valid_changed( + MceProxy* proxy, + void* arg) +{ + MceBattery* self = MCE_BATTERY(arg); + MceBatteryPriv* priv = self->priv; + + if (proxy->valid) { + mce_battery_query(self); + } else { + priv->flags = BATTERY_HAVE_NONE; + } + mce_battery_check_valid(self); +} + +/*==========================================================================* + * API + *==========================================================================*/ + +MceBattery* +mce_battery_new() +{ + /* MCE assumes one battery */ + static MceBattery* mce_battery_instance = NULL; + + if (mce_battery_instance) { + mce_battery_ref(mce_battery_instance); + } else { + mce_battery_instance = g_object_new(MCE_BATTERY_TYPE, NULL); + mce_battery_query(mce_battery_instance); + g_object_add_weak_pointer(G_OBJECT(mce_battery_instance), + (gpointer*)(&mce_battery_instance)); + } + return mce_battery_instance; +} + +MceBattery* +mce_battery_ref( + MceBattery* self) +{ + if (G_LIKELY(self)) { + g_object_ref(MCE_BATTERY(self)); + } + return self; +} + +void +mce_battery_unref( + MceBattery* self) +{ + if (G_LIKELY(self)) { + g_object_unref(MCE_BATTERY(self)); + } +} + +gulong +mce_battery_add_valid_changed_handler( + MceBattery* self, + MceBatteryFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_VALID_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +gulong +mce_battery_add_level_changed_handler( + MceBattery* self, + MceBatteryFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_LEVEL_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +gulong +mce_battery_add_status_changed_handler( + MceBattery* self, + MceBatteryFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_STATUS_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +void +mce_battery_remove_handler( + MceBattery* self, + gulong id) +{ + if (G_LIKELY(self) && G_LIKELY(id)) { + g_signal_handler_disconnect(self, id); + } +} + +void +mce_battery_remove_handlers( + MceBattery* self, + gulong* ids, + guint count) +{ + gutil_disconnect_handlers(self, ids, count); +} + +/*==========================================================================* + * Internals + *==========================================================================*/ + +static +void +mce_battery_init( + MceBattery* self) +{ + MceBatteryPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MCE_BATTERY_TYPE, + MceBatteryPriv); + + self->priv = priv; + priv->proxy = mce_proxy_new(); + priv->proxy_valid_id = mce_proxy_add_valid_changed_handler(priv->proxy, + mce_battery_valid_changed, self); +} + +static +void +mce_battery_finalize( + GObject* object) +{ + MceBattery* self = MCE_BATTERY(object); + MceBatteryPriv* priv = self->priv; + + gutil_disconnect_handlers(priv->proxy->signal, priv->battery_ind_id, + G_N_ELEMENTS(priv->battery_ind_id)); + mce_proxy_remove_handler(priv->proxy, priv->proxy_valid_id); + mce_proxy_unref(priv->proxy); + G_OBJECT_CLASS(PARENT_CLASS)->finalize(object); +} + +static +void +mce_battery_class_init( + MceBatteryClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = mce_battery_finalize; + g_type_class_add_private(klass, sizeof(MceBatteryPriv)); + mce_battery_signals[SIGNAL_VALID_CHANGED] = + g_signal_new(SIGNAL_VALID_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + mce_battery_signals[SIGNAL_LEVEL_CHANGED] = + g_signal_new(SIGNAL_LEVEL_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + mce_battery_signals[SIGNAL_STATUS_CHANGED] = + g_signal_new(SIGNAL_STATUS_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/mce_charger.c b/src/mce_charger.c new file mode 100644 index 0000000..e40aa31 --- /dev/null +++ b/src/mce_charger.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2019-2022 Jolla Ltd. + * Copyright (C) 2019-2022 Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#include "mce_charger.h" +#include "mce_proxy.h" +#include "mce_log_p.h" + +#include +#include + +#include + +/* Generated headers */ +#include "com.nokia.mce.request.h" +#include "com.nokia.mce.signal.h" + +struct mce_charger_priv { + MceProxy* proxy; + gulong proxy_valid_id; + gulong charger_state_ind_id; +}; + +enum mce_charger_signal { + SIGNAL_VALID_CHANGED, + SIGNAL_STATE_CHANGED, + SIGNAL_COUNT +}; + +#define SIGNAL_VALID_CHANGED_NAME "mce-charger-valid-changed" +#define SIGNAL_STATE_CHANGED_NAME "mce-charger-state-changed" + +static guint mce_charger_signals[SIGNAL_COUNT] = { 0 }; + +typedef GObjectClass MceChargerClass; +G_DEFINE_TYPE(MceCharger, mce_charger, G_TYPE_OBJECT) +#define PARENT_CLASS mce_charger_parent_class +#define MCE_CHARGER_TYPE (mce_charger_get_type()) +#define MCE_CHARGER(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj,\ + MCE_CHARGER_TYPE,MceCharger)) + +/*==========================================================================* + * Implementation + *==========================================================================*/ + +static +void +mce_charger_state_update( + MceCharger* self, + const char* value) +{ + MCE_CHARGER_STATE state; + MceChargerPriv* priv = self->priv; + + if (!g_strcmp0(value, MCE_CHARGER_STATE_ON)) { + state = MCE_CHARGER_ON; + } else if (!g_strcmp0(value, MCE_CHARGER_STATE_OFF)) { + state = MCE_CHARGER_OFF; + } else { + GASSERT(!g_strcmp0(value, MCE_CHARGER_STATE_UNKNOWN)); + state = MCE_CHARGER_UNKNOWN; + } + if (self->state != state) { + self->state = state; + g_signal_emit(self, mce_charger_signals[SIGNAL_STATE_CHANGED], 0); + } + if (priv->proxy->valid && !self->valid) { + self->valid = TRUE; + g_signal_emit(self, mce_charger_signals[SIGNAL_VALID_CHANGED], 0); + } +} + +static +void +mce_charger_state_query_done( + GObject* proxy, + GAsyncResult* result, + gpointer arg) +{ + GError* error = NULL; + char* state = NULL; + MceCharger* self = MCE_CHARGER(arg); + + if (com_nokia_mce_request_call_get_charger_state_finish( + COM_NOKIA_MCE_REQUEST(proxy), &state, result, &error)) { + GDEBUG("Charger is currently %s", state); + mce_charger_state_update(self, state); + g_free(state); + } else { + /* + * We could retry but it's probably not worth the trouble + * because the next time charger state changes we receive + * charger_state_ind signal and sync our state with mce. + * Until then, this object stays invalid. + */ + GWARN("Failed to query charger state %s", GERRMSG(error)); + g_error_free(error); + } + mce_charger_unref(self); +} + +static +void +mce_charger_state_ind( + ComNokiaMceSignal* proxy, + const char* state, + gpointer arg) +{ + GDEBUG("Charger is %s", state); + mce_charger_state_update(MCE_CHARGER(arg), state); +} + +static +void +mce_charger_state_query( + MceCharger* self) +{ + MceChargerPriv* priv = self->priv; + MceProxy* proxy = priv->proxy; + + /* + * proxy->signal and proxy->request may not be available at the + * time when MceCharger is created. In that case we have to wait + * for the valid signal before we can connect the charger state + * signal and submit the initial query. + */ + if (proxy->signal && !priv->charger_state_ind_id) { + priv->charger_state_ind_id = g_signal_connect(proxy->signal, + MCE_CHARGER_STATE_SIG, G_CALLBACK(mce_charger_state_ind), self); + } + if (proxy->request && proxy->valid) { + com_nokia_mce_request_call_get_charger_state(proxy->request, NULL, + mce_charger_state_query_done, mce_charger_ref(self)); + } +} + +static +void +mce_charger_valid_changed( + MceProxy* proxy, + void* arg) +{ + MceCharger* self = MCE_CHARGER(arg); + + if (proxy->valid) { + mce_charger_state_query(self); + } else { + if (self->valid) { + self->valid = FALSE; + g_signal_emit(self, mce_charger_signals[SIGNAL_VALID_CHANGED], 0); + } + } +} + +/*==========================================================================* + * API + *==========================================================================*/ + +MceCharger* +mce_charger_new() +{ + /* MCE assumes one charger */ + static MceCharger* mce_charger_instance = NULL; + + if (mce_charger_instance) { + mce_charger_ref(mce_charger_instance); + } else { + mce_charger_instance = g_object_new(MCE_CHARGER_TYPE, NULL); + mce_charger_state_query(mce_charger_instance); + g_object_add_weak_pointer(G_OBJECT(mce_charger_instance), + (gpointer*)(&mce_charger_instance)); + } + return mce_charger_instance; +} + +MceCharger* +mce_charger_ref( + MceCharger* self) +{ + if (G_LIKELY(self)) { + g_object_ref(MCE_CHARGER(self)); + } + return self; +} + +void +mce_charger_unref( + MceCharger* self) +{ + if (G_LIKELY(self)) { + g_object_unref(MCE_CHARGER(self)); + } +} + +gulong +mce_charger_add_valid_changed_handler( + MceCharger* self, + MceChargerFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_VALID_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +gulong +mce_charger_add_state_changed_handler( + MceCharger* self, + MceChargerFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_STATE_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +void +mce_charger_remove_handler( + MceCharger* self, + gulong id) +{ + if (G_LIKELY(self) && G_LIKELY(id)) { + g_signal_handler_disconnect(self, id); + } +} + +void +mce_charger_remove_handlers( + MceCharger* self, + gulong* ids, + guint count) +{ + gutil_disconnect_handlers(self, ids, count); +} + +/*==========================================================================* + * Internals + *==========================================================================*/ + +static +void +mce_charger_init( + MceCharger* self) +{ + MceChargerPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MCE_CHARGER_TYPE, + MceChargerPriv); + + self->priv = priv; + priv->proxy = mce_proxy_new(); + priv->proxy_valid_id = mce_proxy_add_valid_changed_handler(priv->proxy, + mce_charger_valid_changed, self); +} + +static +void +mce_charger_finalize( + GObject* object) +{ + MceCharger* self = MCE_CHARGER(object); + MceChargerPriv* priv = self->priv; + + if (priv->charger_state_ind_id) { + g_signal_handler_disconnect(priv->proxy->signal, + priv->charger_state_ind_id); + } + mce_proxy_remove_handler(priv->proxy, priv->proxy_valid_id); + mce_proxy_unref(priv->proxy); + G_OBJECT_CLASS(PARENT_CLASS)->finalize(object); +} + +static +void +mce_charger_class_init( + MceChargerClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = mce_charger_finalize; + g_type_class_add_private(klass, sizeof(MceChargerPriv)); + mce_charger_signals[SIGNAL_VALID_CHANGED] = + g_signal_new(SIGNAL_VALID_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + mce_charger_signals[SIGNAL_STATE_CHANGED] = + g_signal_new(SIGNAL_STATE_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/src/mce_display.c b/src/mce_display.c index 9dd513a..3dd9477 100644 --- a/src/mce_display.c +++ b/src/mce_display.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -249,7 +249,7 @@ mce_display_remove_handler( void mce_display_remove_handlers( MceDisplay* self, - gulong *ids, + gulong* ids, guint count) { gutil_disconnect_handlers(self, ids, count); diff --git a/src/mce_inactivity.c b/src/mce_inactivity.c new file mode 100644 index 0000000..7e0c3b3 --- /dev/null +++ b/src/mce_inactivity.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2016 - 2023 Jolla Ltd. + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#include "mce_inactivity.h" +#include "mce_proxy.h" +#include "mce_log_p.h" + +#include +#include + +#include + +/* Generated headers */ +#include "com.nokia.mce.request.h" +#include "com.nokia.mce.signal.h" + +struct mce_inactivity_priv { + MceProxy* proxy; + gulong proxy_valid_id; + gulong inactivity_status_ind_id; +}; + +enum mce_inactivity_signal { + SIGNAL_VALID_CHANGED, + SIGNAL_STATUS_CHANGED, + SIGNAL_COUNT +}; + +#define SIGNAL_VALID_CHANGED_NAME "mce-inactivity-valid-changed" +#define SIGNAL_STATUS_CHANGED_NAME "mce-inactivity-mode-changed" + +static guint mce_inactivity_signals[SIGNAL_COUNT] = { 0 }; + +typedef GObjectClass MceInactivityClass; +G_DEFINE_TYPE(MceInactivity, mce_inactivity, G_TYPE_OBJECT) +#define PARENT_CLASS mce_inactivity_parent_class +#define MCE_INACTIVITY_TYPE (mce_inactivity_get_type()) +#define MCE_INACTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj,\ + MCE_INACTIVITY_TYPE,MceInactivity)) + +/*==========================================================================* + * Implementation + *==========================================================================*/ + +static +void +mce_inactivity_status_update( + MceInactivity* self, + gboolean status) +{ + MceInactivityPriv* priv = self->priv; + const gboolean prev_status = self->status; + self->status = status; + if (self->status != prev_status) { + g_signal_emit(self, mce_inactivity_signals[SIGNAL_STATUS_CHANGED], 0); + } + if (priv->proxy->valid && !self->valid) { + self->valid = TRUE; + g_signal_emit(self, mce_inactivity_signals[SIGNAL_VALID_CHANGED], 0); + } +} + +static +void +mce_inactivity_status_query_done( + GObject* proxy, + GAsyncResult* result, + gpointer arg) +{ + GError* error = NULL; + gboolean status = FALSE; + MceInactivity* self = MCE_INACTIVITY(arg); + + if (com_nokia_mce_request_call_get_inactivity_status_finish( + COM_NOKIA_MCE_REQUEST(proxy), &status, result, &error)) { + GDEBUG("inactivlty is currently %s", status ? "true" : "false"); + mce_inactivity_status_update(self, status); + } else { + /* + * We could retry but it's probably not worth the trouble. + * There is signal broadcast on mce startup / when inactivity + * state changes. + * Until then, this object stays invalid. + */ + GWARN("Failed to query inactivity status %s", GERRMSG(error)); + g_error_free(error); + } + mce_inactivity_unref(self); +} + +static +void +mce_inactivity_status_ind( + ComNokiaMceSignal* proxy, + gboolean status, + gpointer arg) +{ + GDEBUG("status is %s", status ? "true" : "false"); + mce_inactivity_status_update(MCE_INACTIVITY(arg), status); +} + +static +void +mce_inactivity_status_query( + MceInactivity* self) +{ + MceInactivityPriv* priv = self->priv; + MceProxy* proxy = priv->proxy; + + /* + * proxy->signal and proxy->request may not be available at the + * time when MceInactivity is created. In that case we have to wait + * for the valid signal before we can connect the inactivity status + * signal and submit the initial query. + */ + if (proxy->signal && !priv->inactivity_status_ind_id) { + priv->inactivity_status_ind_id = g_signal_connect(proxy->signal, + MCE_INACTIVITY_SIG, G_CALLBACK(mce_inactivity_status_ind), self); + } + if (proxy->request && proxy->valid) { + com_nokia_mce_request_call_get_inactivity_status(proxy->request, NULL, + mce_inactivity_status_query_done, mce_inactivity_ref(self)); + } +} + +static +void +mce_inactivity_valid_changed( + MceProxy* proxy, + void* arg) +{ + MceInactivity* self = MCE_INACTIVITY(arg); + + if (proxy->valid) { + mce_inactivity_status_query(self); + } else { + if (self->valid) { + self->valid = FALSE; + g_signal_emit(self, mce_inactivity_signals[SIGNAL_VALID_CHANGED], 0); + } + } +} + +/*==========================================================================* + * API + *==========================================================================*/ + +MceInactivity* +mce_inactivity_new() +{ + static MceInactivity* mce_inactivity_instance = NULL; + + if (mce_inactivity_instance) { + mce_inactivity_ref(mce_inactivity_instance); + } else { + mce_inactivity_instance = g_object_new(MCE_INACTIVITY_TYPE, NULL); + mce_inactivity_status_query(mce_inactivity_instance); + g_object_add_weak_pointer(G_OBJECT(mce_inactivity_instance), + (gpointer*)(&mce_inactivity_instance)); + } + return mce_inactivity_instance; +} + +MceInactivity* +mce_inactivity_ref( + MceInactivity* self) +{ + if (G_LIKELY(self)) { + g_object_ref(MCE_INACTIVITY(self)); + } + return self; +} + +void +mce_inactivity_unref( + MceInactivity* self) +{ + if (G_LIKELY(self)) { + g_object_unref(MCE_INACTIVITY(self)); + } +} + +gulong +mce_inactivity_add_valid_changed_handler( + MceInactivity* self, + MceInactivityFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_VALID_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +gulong +mce_inactivity_add_status_changed_handler( + MceInactivity* self, + MceInactivityFunc fn, + void* arg) +{ + return (G_LIKELY(self) && G_LIKELY(fn)) ? g_signal_connect(self, + SIGNAL_STATUS_CHANGED_NAME, G_CALLBACK(fn), arg) : 0; +} + +void +mce_inactivity_remove_handler( + MceInactivity* self, + gulong id) +{ + if (G_LIKELY(self) && G_LIKELY(id)) { + g_signal_handler_disconnect(self, id); + } +} + +void +mce_inactivity_remove_handlers( + MceInactivity* self, + gulong* ids, + guint count) +{ + gutil_disconnect_handlers(self, ids, count); +} + +/*==========================================================================* + * Internals + *==========================================================================*/ + +static +void +mce_inactivity_init( + MceInactivity* self) +{ + MceInactivityPriv* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MCE_INACTIVITY_TYPE, + MceInactivityPriv); + + self->priv = priv; + self->status = FALSE; + priv->proxy = mce_proxy_new(); + priv->proxy_valid_id = mce_proxy_add_valid_changed_handler(priv->proxy, + mce_inactivity_valid_changed, self); +} + +static +void +mce_inactivity_finalize( + GObject* object) +{ + MceInactivity* self = MCE_INACTIVITY(object); + MceInactivityPriv* priv = self->priv; + + if (priv->inactivity_status_ind_id) { + g_signal_handler_disconnect(priv->proxy->signal, + priv->inactivity_status_ind_id); + } + mce_proxy_remove_handler(priv->proxy, priv->proxy_valid_id); + mce_proxy_unref(priv->proxy); + G_OBJECT_CLASS(PARENT_CLASS)->finalize(object); +} + +static +void +mce_inactivity_class_init( + MceInactivityClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS(klass); + + object_class->finalize = mce_inactivity_finalize; + g_type_class_add_private(klass, sizeof(MceInactivityPriv)); + mce_inactivity_signals[SIGNAL_VALID_CHANGED] = + g_signal_new(SIGNAL_VALID_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + mce_inactivity_signals[SIGNAL_STATUS_CHANGED] = + g_signal_new(SIGNAL_STATUS_CHANGED_NAME, + G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, G_TYPE_NONE, 0); +} + +/* + * Local Variables: + * status: C + * c-basic-offset: 4 + * indent-tabs-status: nil + * End: + */ diff --git a/src/mce_log_p.h b/src/mce_log_p.h index 4f688fc..ea4efd3 100644 --- a/src/mce_log_p.h +++ b/src/mce_log_p.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/src/mce_proxy.c b/src/mce_proxy.c index 500b9de..a5f0d3d 100644 --- a/src/mce_proxy.c +++ b/src/mce_proxy.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -61,6 +61,7 @@ enum mce_proxy_signal { static guint mce_proxy_signals[SIGNAL_COUNT] = { 0 }; typedef GObjectClass MceProxyClass; +GType mce_proxy_get_type() MCE_INTERNAL; G_DEFINE_TYPE(MceProxy, mce_proxy, G_TYPE_OBJECT) #define PARENT_CLASS mce_proxy_parent_class #define MCE_PROXY_TYPE (mce_proxy_get_type()) diff --git a/src/mce_proxy.h b/src/mce_proxy.h index 3111208..8aa2641 100644 --- a/src/mce_proxy.h +++ b/src/mce_proxy.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2016 Jolla Ltd. - * Contact: Slava Monich + * Copyright (C) 2016-2022 Jolla Ltd. + * Copyright (C) 2016-2022 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -13,9 +13,9 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Jolla Ltd nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -37,7 +37,9 @@ #ifndef MCE_PROXY_H #define MCE_PROXY_H -#include "mce_types.h" +#include "mce_types_p.h" + +#include typedef struct mce_proxy_priv MceProxyPriv; struct _ComCanonicalUnityScreen; @@ -57,26 +59,31 @@ typedef void MceProxy* mce_proxy_new( - void); + void) + MCE_INTERNAL; MceProxy* mce_proxy_ref( - MceProxy* proxy); + MceProxy* proxy) + MCE_INTERNAL; void mce_proxy_unref( - MceProxy* proxy); + MceProxy* proxy) + MCE_INTERNAL; gulong mce_proxy_add_valid_changed_handler( MceProxy* proxy, MceProxyFunc fn, - void* arg); + void* arg) + MCE_INTERNAL; void mce_proxy_remove_handler( MceProxy* proxy, - gulong id); + gulong id) + MCE_INTERNAL; #endif /* MCE_PROXY_H */ diff --git a/src/mce_types_p.h b/src/mce_types_p.h new file mode 100644 index 0000000..1df72af --- /dev/null +++ b/src/mce_types_p.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020-2022 Jolla Ltd. + * Copyright (C) 2020-2022 Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * any official policies, either expressed or implied. + */ + +#ifndef MCE_TYPES_PRIVATE_H +#define MCE_TYPES_PRIVATE_H + +#include + +/* Macros */ +#define MCE_INTERNAL G_GNUC_INTERNAL + +#endif /* MCE_TYPES_PRIVATE_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */