Repository: matplotlib/matplotlib
Pull request: Fix building on MINGW
## PR Summary

Fix building matplotlib on MINGW. Recent changes in https://github.com/matplotlib/matplotlib/commit/e1fcc90c13b037da1501aa53b3491d27081598ca broke it.

Fixes #23943

## PR Checklist

**Tests and Styling**
- [ ] Has pytest style unit tests (and `pytest` passes).
- [ ] Is [Flake 8](https://flake8.pycqa.org/en/latest/) compliant (install `flake8-docstrings` and run `flake8 --docstring-convention=all`).

**Documentation**
- [ ] New features are documented, with examples if plot related.
- [ ] New features have an entry in `doc/users/next_whats_new/` (follow instructions in README.rst there).
- [ ] API changes documented in `doc/api/next_api_changes/` (follow instructions in README.rst there).
- [ ] Documentation is sphinx and numpydoc compliant (the docs should [build](https://matplotlib.org/devel/documenting_mpl.html#building-the-docs) without error).


Problem statement:
[Bug]: Couldn't build matplotlib 3.6.0 with both Clang-15 and GCC-12
### Bug summary

It fails to build with Clang-15 and GCC-12
Clang:
```
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O2 -pipe -O3 -march=x86-64 -mtune=generic -O2 -pipe -O3 -march=x86-64 -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -DPY_ARRAY_UNIQUE_SYMBOL=MPL_matplotlib_backends__tkagg_ARRAY_API -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -D__STDC_FORMAT_MACROS=1 -Iextern/agg24-svn/include -Isrc -ID:/M/msys64/clang64/lib/python3.10/site-packages/numpy/core/include -ID:/M/msys64/clang64/include/python3.10 -c src/_tkagg.cpp -o build/temp.mingw_x86_64_clang-3.10/matplotlib.backends._tkagg/src/_tkagg.o
  src/_tkagg.cpp:234:15: error: cannot initialize a variable of type 'void *' with an rvalue of type 'FARPROC' (aka 'long long (*)()')
      if (void* ptr = dlsym(lib, "Tcl_SetVar")) {
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~
  src/_tkagg.cpp:273:13: note: in instantiation of function template specialization 'load_tcl_tk<HINSTANCE__ *>' requested here
          if (load_tcl_tk(modules[i])) {
              ^
  src/_tkagg.cpp:237:15: error: cannot initialize a variable of type 'void *' with an rvalue of type 'FARPROC' (aka 'long long (*)()')
      if (void* ptr = dlsym(lib, "Tk_FindPhoto")) {
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~
  src/_tkagg.cpp:240:15: error: cannot initialize a variable of type 'void *' with an rvalue of type 'FARPROC' (aka 'long long (*)()')
      if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
                ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3 errors generated.
```
GCC:
```
  gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O2 -pipe -O3 -march=x86-64 -mtune=generic -O2 -pipe -O3 -march=x86-64 -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -DPY_ARRAY_UNIQUE_SYMBOL=MPL_matplotlib_backends__tkagg_ARRAY_API -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -D__STDC_FORMAT_MACROS=1 -Iextern/agg24-svn/include -Isrc -ID:/M/msys64/ucrt64/lib/python3.10/site-packages/numpy/core/include -ID:/M/msys64/ucrt64/include/python3.10 -c src/_tkagg.cpp -o build/temp.mingw_x86_64_ucrt-3.10/matplotlib.backends._tkagg/src/_tkagg.o
  src/_tkagg.cpp: In instantiation of 'bool load_tcl_tk(T) [with T = HINSTANCE__*]':
  src/_tkagg.cpp:273:24:   required from here
  src/_tkagg.cpp:234:26: error: invalid conversion from 'FARPROC' {aka 'long long int (*)()'} to 'void*' [-fpermissive]
    234 |     if (void* ptr = dlsym(lib, "Tcl_SetVar")) {
        |                          ^
        |                          |
        |                          FARPROC {aka long long int (*)()}
  src/_tkagg.cpp:237:26: error: invalid conversion from 'FARPROC' {aka 'long long int (*)()'} to 'void*' [-fpermissive]
    237 |     if (void* ptr = dlsym(lib, "Tk_FindPhoto")) {
        |                          ^
        |                          |
        |                          FARPROC {aka long long int (*)()}
  src/_tkagg.cpp:240:26: error: invalid conversion from 'FARPROC' {aka 'long long int (*)()'} to 'void*' [-fpermissive]
    240 |     if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
        |                          ^
        |                          |
        |                          FARPROC {aka long long int (*)()}
```

### Code for reproduction

```python
No code required
```


### Actual outcome

Building succeeds

### Expected outcome

Building fails

### Additional information

_No response_

### Operating system

_No response_

### Matplotlib Version

3.6.0

### Matplotlib Backend

_No response_

### Python version

3.10.7

### Jupyter version

_No response_

### Installation

_No response_

Hints from issue discussion:
I have been compiling in linux with gcc 12 without a problem.

It seems that `FARPROC` is a windows thing: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-callwindowprocw

@MehdiChinoune Do you understand what changed in gcc / clang to make this code fail?  Do we need a windows specific version of this function?
> It seems that `FARPROC` is a windows thing: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-callwindowprocw
> 
> @MehdiChinoune Do you understand what changed in gcc / clang to make this code fail? Do we need a windows specific version of this function?

Nothing has changed. the previous version (3.5.3) could be built by both gcc-12 and clang-14, It is matplotlib that changed in https://github.com/matplotlib/matplotlib/commit/e1fcc90c13b037da1501aa53b3491d27081598ca
proposed patch
```diff
--- a/src/_tkagg.cpp
+++ b/src/_tkagg.cpp
@@ -231,13 +231,13 @@
 {
     // Try to fill Tcl/Tk global vars with function pointers.  Return whether
     // all of them have been filled.
-    if (void* ptr = dlsym(lib, "Tcl_SetVar")) {
+    if (auto ptr = dlsym(lib, "Tcl_SetVar")) {
         TCL_SETVAR = (Tcl_SetVar_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_FindPhoto")) {
+    if (auto ptr = dlsym(lib, "Tk_FindPhoto")) {
         TK_FIND_PHOTO = (Tk_FindPhoto_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
+    if (auto ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
         TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)ptr;
     }
     return TCL_SETVAR && TK_FIND_PHOTO && TK_PHOTO_PUT_BLOCK;
```

Commit message: Fix building on MINGW

Patch to review:
diff --git a/src/_tkagg.cpp b/src/_tkagg.cpp
index bbca8e8d066c..86d54ca61c30 100644
--- a/src/_tkagg.cpp
+++ b/src/_tkagg.cpp
@@ -231,13 +231,13 @@ bool load_tcl_tk(T lib)
 {
     // Try to fill Tcl/Tk global vars with function pointers.  Return whether
     // all of them have been filled.
-    if (void* ptr = dlsym(lib, "Tcl_SetVar")) {
+    if (auto ptr = dlsym(lib, "Tcl_SetVar")) {
         TCL_SETVAR = (Tcl_SetVar_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_FindPhoto")) {
+    if (auto ptr = dlsym(lib, "Tk_FindPhoto")) {
         TK_FIND_PHOTO = (Tk_FindPhoto_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
+    if (auto* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
         TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)ptr;
     }
     return TCL_SETVAR && TK_FIND_PHOTO && TK_PHOTO_PUT_BLOCK;


Code review comments:
diff_hunk: @@ -231,13 +231,13 @@ bool load_tcl_tk(T lib)
 {
     // Try to fill Tcl/Tk global vars with function pointers.  Return whether
     // all of them have been filled.
-    if (void* ptr = dlsym(lib, "Tcl_SetVar")) {
+    if (auto ptr = dlsym(lib, "Tcl_SetVar")) {
         TCL_SETVAR = (Tcl_SetVar_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_FindPhoto")) {
+    if (auto ptr = dlsym(lib, "Tk_FindPhoto")) {
         TK_FIND_PHOTO = (Tk_FindPhoto_t)ptr;
     }
-    if (void* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
+    if (auto* ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
path: src/_tkagg.cpp
text: @user1:
remove the star here too while you're at it.

@author:
fixed