Skip to content

Commit

Permalink
Improve MinGW compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
AlienCowEatCake committed Dec 4, 2022
1 parent 05fb6e6 commit effc15b
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 4 deletions.
35 changes: 34 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ set_target_properties(
"MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

add_library(
wintoastlibc_lazy
SHARED
${CMAKE_CURRENT_LIST_DIR}/src/wintoastlibc_lazy.c
${CMAKE_CURRENT_LIST_DIR}/src/wintoastlibc.h
)
target_link_libraries(
wintoastlibc_lazy
kernel32
)
set_target_properties(
wintoastlibc_lazy
PROPERTIES
PUBLIC_HEADER
"${CMAKE_CURRENT_LIST_DIR}/src/wintoastlibc.h"
)

add_library(
wintoastlibc_static
STATIC
Expand Down Expand Up @@ -72,6 +89,22 @@ target_link_libraries(
ole32
)

add_executable(
example1_lazy
WIN32
${CMAKE_CURRENT_LIST_DIR}/example/example1.c
)
target_include_directories(
example1_lazy
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src
)
target_link_libraries(
example1_lazy
wintoastlibc_lazy
ole32
)

add_executable(
example2
WIN32
Expand All @@ -90,7 +123,7 @@ target_link_libraries(
)

install(
TARGETS wintoastlibc wintoastlibc_static example1 example2
TARGETS wintoastlibc wintoastlibc_static wintoastlibc_lazy example1 example2 example1_lazy
RUNTIME DESTINATION ${CMAKE_BINARY_DIR}/install/bin
ARCHIVE DESTINATION ${CMAKE_BINARY_DIR}/install/lib
LIBRARY DESTINATION ${CMAKE_BINARY_DIR}/install/lib
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,43 @@ Since this project is just bindings, documentation can be found in [WinToast](ht
* [example1.c](example/example1.c): minimal C code to show the toast notification
* [example2.c](example/example2.c): more complex example with image and basic AUMID registration

## MinGW integration

### Build as is
```bash
gcc example1.c wintoastlibc.lib -lole32 -mwindows
```

### Build with fake implib
```bash
mv wintoastlibc.lib libwintoastlibc.dll.a
gcc example1.c -L. -lwintoastlibc -lole32 -mwindows
```

### Build with true implib
```bash
gendef wintoastlibc.dll
dlltool.exe -d wintoastlibc.def -D wintoastlibc.dll -l libwintoastlibc.dll.a
gcc example1.c -L. -lwintoastlibc -lole32 -mwindows
```

### Build with delayed loader (dll)
Loader source: [wintoastlibc_lazy.c](src/wintoastlibc_lazy.c)
```bash
gcc -shared -o wintoastlibc_lazy.dll \
-Wl,--out-implib=libwintoastlibc.dll.a \
-Wl,--export-all-symbols -Wl,--enable-auto-import \
-Wl,--whole-archive wintoastlibc_lazy.c -Wl,--no-whole-archive
gcc example1.c -L. -lwintoastlibc -lole32 -mwindows
```

### Build with delayed loader (static)
Loader source: [wintoastlibc_lazy.c](src/wintoastlibc_lazy.c)
```bash
gcc -DWTLC_BUILD_STATIC -o wintoastlibc_lazy.o -c wintoastlibc_lazy.c
ar rcs -o libwintoastlibc.dll.a wintoastlibc_lazy.o
gcc example1.c -DWTLC_BUILD_STATIC -L. -lwintoastlibc -lole32 -mwindows
```

## Links
* https://github.com/mohabouje/WinToast
7 changes: 6 additions & 1 deletion example/example1.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include "wintoastlibc.h"

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow)
int main(int argc, char ** argv)
{
INT ret = EXIT_SUCCESS;
WTLC_Instance * instance = NULL;
Expand Down Expand Up @@ -56,3 +56,8 @@ INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLin
CoUninitialize();
return ret;
}

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow)
{
return main(0, NULL);
}
7 changes: 6 additions & 1 deletion example/example2.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static BOOL RegisterBasicAUMID(LPCWSTR aumid, LPCWSTR displayName, LPCWSTR iconU
return TRUE;
}

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow)
int main(int argc, char ** argv)
{
WTLC_Instance * instance = NULL;
WTLC_Template * templ = NULL;
Expand Down Expand Up @@ -205,3 +205,8 @@ INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLin
CoUninitialize();
return 0;
}

INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR lpCmdLine, INT nCmdShow)
{
return main(0, NULL);
}
2 changes: 1 addition & 1 deletion src/wintoastlibc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#endif

#if !defined (WTLCAPI)
#define WTLCAPI WINAPI
#define WTLCAPI __cdecl
#endif

#if !defined (_In_)
Expand Down
150 changes: 150 additions & 0 deletions src/wintoastlibc_lazy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/**
* Copyright (c) 2022 Peter Zhigalov <peter.zhigalov@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#if !defined (UNICODE)
#define UNICODE
#endif
#if !defined (_UNICODE)
#define _UNICODE
#endif
#if !defined (WTLC_BUILD_LIBRARY)
#define WTLC_BUILD_LIBRARY
#endif

#include "wintoastlibc.h"

#if !defined (WTLC_DLLNAME)
#define WTLC_DLLNAME "wintoastlibc.dll"
#endif

static HMODULE s_module = NULL;

#define LOAD(X) \
HMODULE X = s_module; \
if(!X) \
{ \
X = LoadLibraryA(WTLC_DLLNAME); \
if(!X) \
{ \
MessageBoxA(NULL, "FAILED TO LOAD " WTLC_DLLNAME, "Error", MB_OK | MB_ICONERROR); \
abort(); \
} \
s_module = X; \
}

#define SYMCHECK(NAME, SYM) \
if(!SYM) \
{ \
MessageBoxA(NULL, "FAILED TO FIND PROC " NAME " IN " WTLC_DLLNAME, "Error", MB_OK | MB_ICONERROR); \
abort(); \
}

#define FORWARD0(NAME, RTYPE) \
RTYPE WTLCAPI NAME (void) { \
typedef RTYPE (WTLCAPI * t)(void); \
t f; \
LOAD(h) \
f = (t)GetProcAddress(h, #NAME); \
SYMCHECK(#NAME, f) \
return f(); \
}
#define FORWARD1(NAME, RTYPE, A1TYPE) \
RTYPE WTLCAPI NAME (A1TYPE a1) { \
typedef RTYPE (WTLCAPI * t)(A1TYPE); \
t f; \
LOAD(h) \
f = (t)GetProcAddress(h, #NAME); \
SYMCHECK(#NAME, f) \
return f(a1); \
}
#define FORWARD2(NAME, RTYPE, A1TYPE, A2TYPE) \
RTYPE WTLCAPI NAME (A1TYPE a1, A2TYPE a2) { \
typedef RTYPE (WTLCAPI * t)(A1TYPE, A2TYPE); \
t f; \
LOAD(h) \
f = (t)GetProcAddress(h, #NAME); \
SYMCHECK(#NAME, f) \
return f(a1, a2); \
}
#define FORWARD3(NAME, RTYPE, A1TYPE, A2TYPE, A3TYPE) \
RTYPE WTLCAPI NAME (A1TYPE a1, A2TYPE a2, A3TYPE a3) { \
typedef RTYPE (WTLCAPI * t)(A1TYPE, A2TYPE, A3TYPE); \
t f; \
LOAD(h) \
f = (t)GetProcAddress(h, #NAME); \
SYMCHECK(#NAME, f) \
return f(a1, a2, a3); \
}
#define FORWARD8(NAME, RTYPE, A1TYPE, A2TYPE, A3TYPE, A4TYPE, A5TYPE, A6TYPE, A7TYPE, A8TYPE) \
RTYPE WTLCAPI NAME (A1TYPE a1, A2TYPE a2, A3TYPE a3, A4TYPE a4, A5TYPE a5, A6TYPE a6, A7TYPE a7, A8TYPE a8) { \
typedef RTYPE (WTLCAPI * t)(A1TYPE, A2TYPE, A3TYPE, A4TYPE, A5TYPE, A6TYPE, A7TYPE, A8TYPE); \
t f; \
LOAD(h) \
f = (t)GetProcAddress(h, #NAME); \
SYMCHECK(#NAME, f) \
return f(a1, a2, a3, a4, a5, a6, a7, a8); \
}

FORWARD1(WTLC_Template_Create, WTLC_Template *, WTLC_TemplateType)
FORWARD1(WTLC_Template_Destroy, void, WTLC_Template *)
FORWARD2(WTLC_Template_setFirstLine, void, WTLC_Template *, LPCWSTR)
FORWARD2(WTLC_Template_setSecondLine, void, WTLC_Template *, LPCWSTR)
FORWARD2(WTLC_Template_setThirdLine, void, WTLC_Template *, LPCWSTR)
FORWARD3(WTLC_Template_setTextField, void, WTLC_Template *, LPCWSTR, WTLC_TextField)
FORWARD2(WTLC_Template_setAttributionText, void, WTLC_Template *, LPCWSTR)
FORWARD2(WTLC_Template_setImagePath, void, WTLC_Template *, LPCWSTR)
FORWARD2(WTLC_Template_setAudioSystemFile, void, WTLC_Template *, WTLC_AudioSystemFile)
FORWARD2(WTLC_Template_setAudioPath, void, WTLC_Template *, LPCWSTR)
FORWARD2(WTLC_Template_setAudioOption, void, WTLC_Template *, WTLC_AudioOption)
FORWARD2(WTLC_Template_setDuration, void, WTLC_Template *, WTLC_Duration)
FORWARD2(WTLC_Template_setExpiration, void, WTLC_Template *, INT64)
FORWARD2(WTLC_Template_setScenario, void, WTLC_Template *, WTLC_Scenario)
FORWARD2(WTLC_Template_addAction, void, WTLC_Template *, LPCWSTR)
FORWARD1(WTLC_Template_textFieldsCount, size_t, WTLC_Template *)
FORWARD1(WTLC_Template_actionsCount, size_t, WTLC_Template *)
FORWARD1(WTLC_Template_hasImage, BOOL, WTLC_Template *)
FORWARD2(WTLC_Template_textField, LPCWSTR, WTLC_Template *, WTLC_TextField)
FORWARD2(WTLC_Template_actionLabel, LPCWSTR, WTLC_Template *, size_t);
FORWARD1(WTLC_Template_imagePath, LPCWSTR, WTLC_Template *);
FORWARD1(WTLC_Template_audioPath, LPCWSTR, WTLC_Template *);
FORWARD1(WTLC_Template_attributionText, LPCWSTR, WTLC_Template *);
FORWARD1(WTLC_Template_scenario, LPCWSTR, WTLC_Template *);
FORWARD1(WTLC_Template_expiration, INT64, WTLC_Template *);
FORWARD1(WTLC_Template_type, WTLC_TemplateType, WTLC_Template *);
FORWARD1(WTLC_Template_audioOption, WTLC_AudioOption, WTLC_Template *);
FORWARD1(WTLC_Template_duration, WTLC_Duration, WTLC_Template *);
FORWARD0(WTLC_Instance_Create, WTLC_Instance *);
FORWARD1(WTLC_Instance_Destroy, void, WTLC_Instance *);
FORWARD0(WTLC_isCompatible, BOOL);
FORWARD0(WTLC_isSupportingModernFeatures, BOOL);
FORWARD1(WTLC_strerror, LPCWSTR, WTLC_Error);
FORWARD2(WTLC_initialize, BOOL, WTLC_Instance *, WTLC_Error *);
FORWARD1(WTLC_isInitialized, BOOL, WTLC_Instance *);
FORWARD2(WTLC_hideToast, BOOL, WTLC_Instance *, INT64);
FORWARD8(WTLC_showToast, INT64, WTLC_Instance *, WTLC_Template *, void *, WTLC_CB_toastActivated, WTLC_CB_toastActivatedAction, WTLC_CB_toastDismissed, WTLC_CB_toastFailed, WTLC_Error *);
FORWARD1(WTLC_clear, void, WTLC_Instance *);
FORWARD1(WTLC_createShortcut, WTLC_ShortcutResult, WTLC_Instance *);
FORWARD1(WTLC_appName, LPCWSTR, WTLC_Instance *);
FORWARD1(WTLC_appUserModelId, LPCWSTR, WTLC_Instance *);
FORWARD2(WTLC_setAppUserModelId, void, WTLC_Instance *, LPCWSTR);
FORWARD2(WTLC_setAppName, void, WTLC_Instance *, LPCWSTR);
FORWARD2(WTLC_setShortcutPolicy, void, WTLC_Instance *, WTLC_ShortcutPolicy);

0 comments on commit effc15b

Please sign in to comment.