Initial callback support

This commit is contained in:
LAGonauta 2021-02-18 06:24:53 -03:00
parent 95051d304a
commit ce0deed0dc
22 changed files with 437 additions and 133 deletions

View file

@ -12,20 +12,28 @@ vala_precompile(WINDOWS_NOTIFICATION_VALA_C
SOURCES
src/plugin.vala
src/register_plugin.vala
# src/win_notification_provider.vala
CUSTOM_VAPIS
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
${CMAKE_BINARY_DIR}/exports/dino.vapi
${CMAKE_BINARY_DIR}/exports/qlite.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/win32.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/winrt.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/shortcutcreator.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/toastnotification.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/enums.vapi
${CMAKE_CURRENT_SOURCE_DIR}/vapi/callbacks.vapi
PACKAGES
${WINDOWS_NOTIFICATION_PACKAGES}
)
set(WINDOWS_API_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/api/src/win32.cpp
${CMAKE_CURRENT_SOURCE_DIR}/api/src/winrt.cpp
${CMAKE_CURRENT_SOURCE_DIR}/api/src/converter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/api/src/shortcutcreator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/api/src/toastnotification.cpp
${CMAKE_CURRENT_SOURCE_DIR}/api/src/callbacks.cpp
)
add_library(windows-notification SHARED ${WINDOWS_NOTIFICATION_VALA_C} ${WINDOWS_API_SOURCES})
@ -33,6 +41,7 @@ add_library(windows-notification SHARED ${WINDOWS_NOTIFICATION_VALA_C} ${WINDOWS
target_include_directories(windows-notification
PRIVATE
${PROJECT_SOURCE_DIR}/api/include
${PROJECT_SOURCE_DIR}/yolort/include
)
find_library(shlwapi_LIBRARY shlwapi libshlwapi libshlwapi.a HINTS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
@ -57,8 +66,7 @@ endif(NOT mincore_LIBRARY)
target_link_libraries(windows-notification libdino ${shlwapi_LIBRARY} ${propsys_LIBRARY} ${ntdll_LIBRARY} ${mincore_LIBRARY} ${WINDOWS_NOTIFICATION_PACKAGES})
target_compile_features(windows-notification PRIVATE cxx_std_20)
# target_compile_options(windows-notification PRIVATE -municode -DUNICODE -fcoroutines -iquote ../../include/winrt/yolort_impl)
target_compile_options(windows-notification PRIVATE -municode -DUNICODE -fcoroutines)
target_compile_options(windows-notification PRIVATE -municode -DUNICODE -fcoroutines -iquote ${PROJECT_SOURCE_DIR}/yolort/include/winrt/yolort_impl)
set_target_properties(windows-notification PROPERTIES PREFIX "")
set_target_properties(windows-notification PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/)

View file

@ -0,0 +1,48 @@
#pragma once
#include "enums.h"
#ifdef __cplusplus
extern "C"
{
#endif
// simple
typedef void(*Notification_Callback_Simple)(void* userdata);
typedef struct {
Notification_Callback_Simple callback;
void* context;
void(*free)(void*);
} SimpleNotificationCallback;
SimpleNotificationCallback* NewSimpleNotificationCallback();
void DestroySimpleNotificationCallback(SimpleNotificationCallback* callback);
// with index
typedef void(*Notification_Callback_ActivatedWithActionIndex)(int action_id, void* userdata);
typedef struct {
Notification_Callback_ActivatedWithActionIndex callback;
void* context;
void(*free)(void*);
} ActivatedWithActionIndexNotificationCallback;
ActivatedWithActionIndexNotificationCallback* NewActivatedWithActionIndexNotificationCallback();
void DestroyActivatedWithActionIndexNotificationCallback(ActivatedWithActionIndexNotificationCallback* callback);
// with dismissed reason
typedef void(*Notification_Callback_Dismissed)(Dismissed_Reason reason, void* userdata);
typedef struct {
Notification_Callback_Dismissed callback;
void* context;
void(*free)(void*);
} DismissedNotificationCallback;
DismissedNotificationCallback* NewDismissedNotificationCallback();
void DestroyDismissedNotificationCallback(DismissedNotificationCallback* callback);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,16 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum {
Dismissed_Reason_Activated = 0,
Dismissed_Reason_ApplicationHidden,
Dismissed_Reason_TimedOut
} Dismissed_Reason;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,18 @@
#pragma once
#include "typedefinitions.h"
class NotificationHandler {
private:
dinoWinToastLib_Notification_Callbacks callbacks{};
public:
WinToastHandler(dinoWinToastLib_Notification_Callbacks callbacks);
~WinToastHandler();
// Public interfaces
void toastActivated() const;
void toastActivated(int actionIndex) const;
void toastDismissed(WinToastLib::IWinToastHandler::WinToastDismissalReason state) const;
void toastFailed() const;
};

View file

@ -7,7 +7,7 @@ extern "C"
{
#endif
gboolean TryCreateShortcut(gchar* aumid);
gboolean TryCreateShortcut(const gchar* aumid);
#ifdef __cplusplus
}

View file

@ -0,0 +1,52 @@
#pragma once
#include <glib.h>
#include "callbacks.h"
#ifdef __cplusplus
#include <memory>
class DinoToastNotification {
private:
SimpleNotificationCallback activated;
ActivatedWithActionIndexNotificationCallback activatedWithIndex;
DismissedNotificationCallback dismissed;
SimpleNotificationCallback failed;
public:
DinoToastNotification() = default;
~DinoToastNotification();
void SetActivated(const SimpleNotificationCallback& callback);
void SetActivatedWithIndex(const ActivatedWithActionIndexNotificationCallback& callback);
void SetDismissed(const DismissedNotificationCallback& callback);
void SetFailed(const SimpleNotificationCallback& callback);
// default move
DinoToastNotification(DinoToastNotification&& other) = default;
DinoToastNotification& operator=(DinoToastNotification&& other) = default;
// delete copy
DinoToastNotification(const DinoToastNotification& other) = delete;
DinoToastNotification& operator=(const DinoToastNotification& other) = delete;
};
extern "C" {
#endif
#ifdef __cplusplus
typedef std::shared_ptr<DinoToastNotification>* DinoToastNotification_t;
#else
typedef void* DinoToastNotification_t;
#endif
DinoToastNotification_t NewNotification();
void DestroyNotification(DinoToastNotification_t notification);
DinoToastNotification_t CopyNotification();
void set_Activated(DinoToastNotification_t notification, const SimpleNotificationCallback* callback);
void set_ActivatedWithIndex(DinoToastNotification_t notification, const ActivatedWithActionIndexNotificationCallback* callback);
void set_Dismissed(DinoToastNotification_t notification, const DismissedNotificationCallback* callback);
void set_Failed(DinoToastNotification_t notification, const SimpleNotificationCallback* callback);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -19,7 +19,7 @@ extern "C"
{
#endif
gboolean SupportsModernNotifications();
gboolean SetAppModelID(gchar* aumid);
gboolean SetAppModelID(const gchar* aumid);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,37 @@
#include "callbacks.h"
SimpleNotificationCallback* NewSimpleNotificationCallback()
{
return new SimpleNotificationCallback();
}
void DestroySimpleNotificationCallback(SimpleNotificationCallback* callback)
{
if (callback != nullptr)
{
delete callback;
}
}
ActivatedWithActionIndexNotificationCallback* NewActivatedWithActionIndexNotificationCallback()
{
return new ActivatedWithActionIndexNotificationCallback();
}
void DestroyActivatedWithActionIndexNotificationCallback(ActivatedWithActionIndexNotificationCallback* callback)
{
if (callback != nullptr)
{
delete callback;
}
}
DismissedNotificationCallback* NewDismissedNotificationCallback()
{
return new DismissedNotificationCallback();
}
void DestroyDismissedNotificationCallback(DismissedNotificationCallback* callback)
{
if (callback != nullptr)
{
delete callback;
}
}

View file

@ -148,7 +148,7 @@ int32_t TryCreateShortcutInternal(const std::wstring& aumid)
extern "C"
{
gboolean TryCreateShortcut(gchar* aumid)
gboolean TryCreateShortcut(const gchar* aumid)
{
auto result = char_to_wstr(aumid);
if (result.empty())

View file

@ -0,0 +1,106 @@
#include "toastnotification.h"
DinoToastNotification_t NewNotification() {
return new std::shared_ptr<DinoToastNotification>();
}
void DestroyNotification(DinoToastNotification_t notification) {
if (notification != nullptr) {
delete notification;
}
}
DinoToastNotification_t CopyNotification(DinoToastNotification_t notification)
{
if (notification == nullptr) {
return nullptr;
}
return new std::shared_ptr(*notification);
}
void set_Activated(DinoToastNotification_t notification, const SimpleNotificationCallback* callback)
{
(*notification)->SetActivated(*callback);
}
void set_ActivatedWithIndex(DinoToastNotification_t notification, const ActivatedWithActionIndexNotificationCallback* callback)
{
(*notification)->SetActivatedWithIndex(*callback);
}
void set_Dismissed(DinoToastNotification_t notification, const DismissedNotificationCallback* callback)
{
(*notification)->SetDismissed(*callback);
}
void set_Failed(DinoToastNotification_t notification, const SimpleNotificationCallback* callback)
{
(*notification)->SetFailed(*callback);
}
void DinoToastNotification::SetActivated(const SimpleNotificationCallback& callback)
{
if (activated.callback != nullptr)
{
activated.free(activated.context);
activated = SimpleNotificationCallback { 0 };
}
activated = callback;
}
void DinoToastNotification::SetActivatedWithIndex(const ActivatedWithActionIndexNotificationCallback& callback)
{
if (activatedWithIndex.callback != nullptr)
{
activatedWithIndex.free(activatedWithIndex.context);
activatedWithIndex = ActivatedWithActionIndexNotificationCallback { 0 };
}
activatedWithIndex = callback;
}
void DinoToastNotification::SetDismissed(const DismissedNotificationCallback& callback)
{
if (dismissed.callback != nullptr)
{
dismissed.free(dismissed.context);
dismissed = DismissedNotificationCallback { 0 };
}
dismissed = callback;
}
void DinoToastNotification::SetFailed(const SimpleNotificationCallback& callback)
{
if (failed.callback != nullptr)
{
failed.free(failed.context);
failed = SimpleNotificationCallback { 0 };
}
failed = callback;
}
DinoToastNotification::~DinoToastNotification()
{
if (activated.context != nullptr &&
activated.free != nullptr) {
activated.free(activated.context);
}
if (activatedWithIndex.context != nullptr &&
activatedWithIndex.free != nullptr) {
activatedWithIndex.free(activatedWithIndex.context);
}
if (dismissed.context != nullptr &&
dismissed.free != nullptr) {
dismissed.free(dismissed.context);
}
if (failed.context != nullptr &&
failed.free != nullptr) {
failed.free(failed.context);
}
}

View file

@ -47,7 +47,7 @@ extern "C"
return FALSE;
}
gboolean SetAppModelID(gchar* aumid)
gboolean SetAppModelID(const gchar* aumid)
{
auto result = char_to_wstr(aumid);
if (result.empty())

View file

@ -1,2 +1,8 @@
#include <winrt/base.h>
#include "winrt.h"
gboolean Initialize()
{
winrt::init_apartment();
}

View file

@ -1,11 +0,0 @@
#pragma once
#ifdef _WIN32
#ifdef DINOWINTOASTLIB_EXPORTS
#define DINOWINTOASTLIB_API __declspec(dllexport)
#else
#define DINOWINTOASTLIB_API __declspec(dllimport)
#endif
#else
#define DINOWINTOASTLIB_API
#endif

View file

@ -1,46 +0,0 @@
#pragma once
#include "DinoWinToastDllExport.h"
#include "DinoWinToastTemplate.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
Reason_Activated = 0,
Reason_ApplicationHidden,
Reason_TimedOut
} dinoWinToastLib_Notification_Reason;
typedef void(*dinoWinToastLib_Notification_Callback_Simple)(void* userdata);
typedef void(*dinoWinToastLib_Notification_Callback_ActivatedWithActionIndex)(int action_id, void* userdata);
typedef void(*dinoWinToastLib_Notification_Callback_Dismissed)(dinoWinToastLib_Notification_Reason reason, void* userdata);
typedef struct {
dinoWinToastLib_Notification_Callback_Simple activated;
void* activated_context;
void(*activated_free)(void*);
dinoWinToastLib_Notification_Callback_ActivatedWithActionIndex activatedWithIndex;
void* activatedWithIndex_context;
void(*activatedWithIndex_free)(void*);
dinoWinToastLib_Notification_Callback_Dismissed dismissed;
void* dismissed_context;
void(*dismissed_free)(void*);
dinoWinToastLib_Notification_Callback_Simple failed;
void* failed_context;
void(*failed_free)(void*);
} dinoWinToastLib_Notification_Callbacks;
DINOWINTOASTLIB_API dinoWinToastLib_Notification_Callbacks* dinoWinToastLib_NewCallbacks();
DINOWINTOASTLIB_API void dinoWinToastLib_DestroyCallbacks(dinoWinToastLib_Notification_Callbacks* callbacks);
DINOWINTOASTLIB_API int dinoWinToastLib_Init();
DINOWINTOASTLIB_API int64_t dinoWinToastLib_ShowMessage(dino_wintoasttemplate templ, dinoWinToastLib_Notification_Callbacks* callbacks);
DINOWINTOASTLIB_API int dinoWinToastLib_RemoveNotification(int64_t notification_id);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1,54 +0,0 @@
#pragma once
#include <stdint.h>
#include "DinoWinToastDllExport.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* dino_wintoasttemplate;
typedef enum {
Duration_System,
Duration_Short,
Duration_Long
} dino_wintoasttemplate_duration;
typedef enum {
AudioOption_Default = 0,
AudioOption_Silent = 1,
AudioOption_Loop = 2
} dino_wintoasttemplate_audiooption;
typedef enum {
TextField_FirstLine = 0,
TextField_SecondLine,
TextField_ThirdLine
} dino_wintoasttemplate_textfield;
typedef enum {
TemplateType_ImageAndText01 = 0,
TemplateType_ImageAndText02,
TemplateType_ImageAndText03,
TemplateType_ImageAndText04,
TemplateType_Text01,
TemplateType_Text02,
TemplateType_Text03,
TemplateType_Text04,
TemplateType_WinToastTemplateTypeCount
} dino_wintoasttemplate_wintoasttemplatetype;
DINOWINTOASTLIB_API dino_wintoasttemplate dino_wintoasttemplate_new(dino_wintoasttemplate_wintoasttemplatetype templ);
DINOWINTOASTLIB_API void dino_wintoasttemplate_destroy(dino_wintoasttemplate templ);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setTextField(dino_wintoasttemplate templ, const char* txt, dino_wintoasttemplate_textfield pos);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setImagePath(dino_wintoasttemplate templ, const char* imgPath);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setAudioPath(dino_wintoasttemplate templ, const char* audioPath);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setAttributionText(dino_wintoasttemplate templ, const char* attributionText);
DINOWINTOASTLIB_API void dino_wintoasttemplate_addAction(dino_wintoasttemplate templ, const char* label);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setAudioOption(dino_wintoasttemplate templ, dino_wintoasttemplate_audiooption audioOption);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setDuration(dino_wintoasttemplate templ, dino_wintoasttemplate_duration duration);
DINOWINTOASTLIB_API void dino_wintoasttemplate_setExpiration(dino_wintoasttemplate templ, int64_t millisecondsFromNow);
#ifdef __cplusplus
} // extern C
#endif

View file

@ -1,29 +1,62 @@
using Gee;
using Dino.Entities;
using Win32Api;
using ShortcutCreator;
using Dino.Plugins.WindowsNotification.Vapi;
namespace Dino.Plugins.WindowsNotification {
public class Plugin : RootInterface, Object {
private static string AUMID = "org.dino.Dino";
public int m { get; set; }
public void registered(Dino.Application app) {
var created = ShortcutCreator.TryCreateShortcut("org.dino.Dino");
if (!created)
if (!WinRTApi.Initialize())
{
// log somewhere, return
// log error, return
}
var initialized =
if (!Win32Api.SupportsModernNotifications())
if (!Win32Api.SetAppModelID(AUMID))
{
// limit types of notifications on template builder
// log error, return
}
// var provider = WindowsNotificationProvider.try_create(app);
// if (provider != null) {
if (!ShortcutCreator.TryCreateShortcut(AUMID))
{
// log error, return
}
var notification = new ToastNotification.ToastNotification();
int test = 2;
notification.Activated = new Callbacks.SimpleNotificationCallback()
{
callback = () => {
test = 3;
}
};
notification.ActivatedWithIndex = new Callbacks.ActivatedWithActionIndexNotificationCallback()
{
callback = (index) => {
test = index;
}
};
notification.Dismissed = new Callbacks.DismissedNotificationCallback()
{
callback = (reason) => {
var m = reason;
}
};
notification.Failed = new Callbacks.SimpleNotificationCallback()
{
callback = () => {
var m = 2;
}
};
// var provider = new WindowsNotificationProvider(app, Win32Api.SupportsModernNotifications());
// app.stream_interactor.get_module(NotificationEvents.IDENTITY).register_notification_provider(provider);
// }
}
public void shutdown() {

View file

@ -0,0 +1,43 @@
using Dino.Plugins.WindowsNotification.Vapi.Enums;
[CCode (cheader_filename = "callbacks.h")]
namespace Dino.Plugins.WindowsNotification.Vapi.Callbacks {
[CCode (cname = "Notification_Callback_Simple", has_target = true)]
public delegate void NotificationCallbackSimple();
[CCode (cname = "Notification_Callback_ActivatedWithActionIndex", has_target = true)]
public delegate void NotificationCallbackWithActionIndex(int actionId);
[CCode (cname = "Notification_Callback_Dismissed", has_target = true)]
public delegate void NotificationCallbackDismissed(DismissedReason reason);
[CCode (cname = "SimpleNotificationCallback", free_function = "DestroySimpleNotificationCallback")]
[Compact]
public class SimpleNotificationCallback {
[CCode (cname = "NewSimpleNotificationCallback")]
public SimpleNotificationCallback();
[CCode (delegate_target_cname = "context", destroy_notify_cname = "free")]
public NotificationCallbackSimple callback;
}
[CCode (cname = "ActivatedWithActionIndexNotificationCallback", free_function = "DestroyActivatedWithActionIndexNotificationCallback")]
[Compact]
public class ActivatedWithActionIndexNotificationCallback {
[CCode (cname = "NewActivatedWithActionIndexNotificationCallback")]
public ActivatedWithActionIndexNotificationCallback();
[CCode (delegate_target_cname = "context", destroy_notify_cname = "free")]
public NotificationCallbackWithActionIndex callback;
}
[CCode (cname = "DismissedNotificationCallback", free_function = "DestroyDismissedNotificationCallback")]
[Compact]
public class DismissedNotificationCallback {
[CCode (cname = "NewDismissedNotificationCallback")]
public DismissedNotificationCallback();
[CCode (delegate_target_cname = "context", destroy_notify_cname = "free")]
public NotificationCallbackDismissed callback;
}
}

View file

@ -0,0 +1,9 @@
[CCode (cheader_filename = "enums.h")]
namespace Dino.Plugins.WindowsNotification.Vapi.Enums {
[CCode (cname = "Dismissed_Reason", cprefix = "Dismissed_Reason_")]
public enum DismissedReason {
Activated,
ApplicationHidden,
TimedOut
}
}

View file

@ -1,5 +1,5 @@
[CCode (cheader_filename = "shortcutcreator.h")]
namespace ShortcutCreator {
namespace Dino.Plugins.WindowsNotification.Vapi.ShortcutCreator {
[CCode (cname = "TryCreateShortcut")]
public bool TryCreateShortcut(string aumid);
}

View file

@ -0,0 +1,36 @@
using Dino.Plugins.WindowsNotification.Vapi.Callbacks;
[CCode (cheader_filename = "toastnotification.h")]
namespace Dino.Plugins.WindowsNotification.Vapi.ToastNotification {
[CCode (cname = "DinoToastNotification_t", copy_function = "CopyNotification", free_function = "DestroyNotification")]
[Compact]
public class ToastNotification {
[CCode (cname = "NewNotification")]
public ToastNotification();
public SimpleNotificationCallback Activated
{
[CCode (cname = "set_Activated")]
set;
}
public ActivatedWithActionIndexNotificationCallback ActivatedWithIndex
{
[CCode (cname = "set_ActivatedWithIndex")]
set;
}
public DismissedNotificationCallback Dismissed
{
[CCode (cname = "set_Dismissed")]
set;
}
public SimpleNotificationCallback Failed
{
[CCode (cname = "set_Failed")]
set;
}
}
}

View file

@ -1,6 +1,9 @@
[CCode (cheader_filename = "win32.h")]
namespace Win32Api {
namespace Dino.Plugins.WindowsNotification.Vapi.Win32Api {
[CCode (cname = "SupportsModernNotifications")]
public bool SupportsModernNotifications();
[CCode (cname = "SetAppModelID")]
public bool SetAppModelID(string aumid);
}

View file

@ -1,5 +1,5 @@
[CCode (cheader_filename = "winrt.h")]
namespace WinRTApi {
namespace Dino.Plugins.WindowsNotification.Vapi.WinRTApi {
[CCode (cname = "Initialize")]
public bool Initialize();
}