From d38a1c18374319326e351bbdc377a31d92fd637f Mon Sep 17 00:00:00 2001 From: Lars Kanis <kanis@comcard.de> Date: Thu, 25 Jun 2015 15:15:57 +0200 Subject: [PATCH] Add a working version for FXApp#addInput event handling on Windows. This works for sockets only for now. --- ext/fox16_c/FXRuby.cpp | 39 ++++++++++++++++++++++++++++++++---- ext/fox16_c/include/FXRuby.h | 6 ++++-- swig-interfaces/FXApp.i | 36 +++++++++++++-------------------- 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/ext/fox16_c/FXRuby.cpp b/ext/fox16_c/FXRuby.cpp index 4d014fd..090e7ca 100644 --- a/ext/fox16_c/FXRuby.cpp +++ b/ext/fox16_c/FXRuby.cpp @@ -185,23 +185,38 @@ void* FXRbConvertPtr(VALUE obj,swig_type_info* ty){ FXbool FXRbCatchExceptions=FALSE; // Returns an FXInputHandle for this Ruby file object -FXInputHandle FXRbGetReadFileHandle(VALUE obj) { +FXInputHandle FXRbGetReadFileHandle(VALUE obj,FXuint mode) { int fd; fd = FIX2INT(rb_funcall(obj, rb_intern("fileno"), 0)); #ifdef WIN32 #ifdef __CYGWIN__ return (FXInputHandle) get_osfhandle(fd); #else - return (FXInputHandle) _get_osfhandle(fd); + WSAEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + long events = 0; + if(mode&INPUT_READ) events |= FD_READ|FD_ACCEPT|FD_OOB; + if(mode&INPUT_EXCEPT) events |= FD_CLOSE|FD_QOS|FD_GROUP_QOS|FD_ROUTING_INTERFACE_CHANGE|FD_ADDRESS_LIST_CHANGE; + if ( WSAEventSelect(_get_osfhandle(fd), hEvent, events) == SOCKET_ERROR ) { + WSACloseEvent( hEvent ); + rb_raise( rb_eRuntimeError, "WSAEventSelect sockett error: %d", WSAGetLastError() ); + } + rb_iv_set(obj, "FXRuby::FXRbGetReadFileHandle", ULL2NUM((intptr_t)hEvent)); + return (FXInputHandle) hEvent; #endif #else return (FXInputHandle) fd; #endif } +void FXRbRemoveReadFileHandle(VALUE obj,FXuint mode) { +#ifdef WIN32 + WSAEVENT hEvent = (HANDLE)NUM2ULL(rb_iv_get(obj, "FXRuby::FXRbGetReadFileHandle")); + CloseHandle( hEvent ); +#endif +} // Returns an FXInputHandle for this Ruby file object -FXInputHandle FXRbGetWriteFileHandle(VALUE obj) { +FXInputHandle FXRbGetWriteFileHandle(VALUE obj,FXuint mode) { int fd; #if defined(RUBINIUS) VALUE vwrite = rb_intern("@write"); @@ -223,13 +238,29 @@ FXInputHandle FXRbGetWriteFileHandle(VALUE obj) { #ifdef __CYGWIN__ return (FXInputHandle) get_osfhandle(fd); #else - return (FXInputHandle) _get_osfhandle(fd); + WSAEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + long events = 0; + if(mode&INPUT_WRITE) events |= FD_WRITE|FD_CONNECT; + if(mode&INPUT_EXCEPT) events |= FD_CLOSE|FD_QOS|FD_GROUP_QOS|FD_ROUTING_INTERFACE_CHANGE|FD_ADDRESS_LIST_CHANGE; + if ( WSAEventSelect(_get_osfhandle(fd), hEvent, events) == SOCKET_ERROR ) { + WSACloseEvent( hEvent ); + rb_raise( rb_eRuntimeError, "WSAEventSelect sockettt error: %d", WSAGetLastError() ); + } + rb_iv_set(obj, "FXRuby::FXRbGetWriteFileHandle", ULL2NUM((intptr_t)hEvent)); + return (FXInputHandle) hEvent; #endif #else return (FXInputHandle) fd; #endif } +void FXRbRemoveWriteFileHandle(VALUE obj,FXuint mode) { +#ifdef WIN32 + WSAEVENT hEvent = (HANDLE)NUM2ULL(rb_iv_get(obj, "FXRuby::FXRbGetWriteFileHandle")); + CloseHandle( hEvent ); +#endif +} + // Register this Ruby class instance void FXRbRegisterRubyObj(VALUE rubyObj,const void* foxObj) { diff --git a/ext/fox16_c/include/FXRuby.h b/ext/fox16_c/include/FXRuby.h index c601e36..b04f858 100644 --- a/ext/fox16_c/include/FXRuby.h +++ b/ext/fox16_c/include/FXRuby.h @@ -91,8 +91,10 @@ swig_type_info *FXRbTypeQuery(const char *name); void* FXRbConvertPtr(VALUE obj,swig_type_info* typeinfo); // Returns an FXInputHandle for this Ruby file object -FXInputHandle FXRbGetReadFileHandle(VALUE obj); -FXInputHandle FXRbGetWriteFileHandle(VALUE obj); +FXInputHandle FXRbGetReadFileHandle(VALUE obj,FXuint mode); +FXInputHandle FXRbGetWriteFileHandle(VALUE obj,FXuint mode); +void FXRbRemoveReadFileHandle(VALUE obj,FXuint mode); +void FXRbRemoveWriteFileHandle(VALUE obj,FXuint mode); // Register mapping from Ruby objects to FOX objects void FXRbRegisterRubyObj(VALUE rubyObj, const void* foxObj); diff --git a/swig-interfaces/FXApp.i b/swig-interfaces/FXApp.i index 9f20fca..f25f8b4 100644 --- a/swig-interfaces/FXApp.i +++ b/swig-interfaces/FXApp.i @@ -357,18 +357,13 @@ public: */ bool addInput(VALUE obj,FXuint mode,FXObject *tgt,FXSelector sel){ FXInputHandle fd; - FXuint m; - if(mode&INPUT_READ){ - m=INPUT_READ; - if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; - fd=FXRbGetReadFileHandle(obj); - self->addInput(fd,m,tgt,sel); + if(mode&(INPUT_READ|INPUT_EXCEPT)){ + fd=FXRbGetReadFileHandle(obj, mode); + self->addInput(fd,mode,tgt,sel); } - if(mode&INPUT_WRITE){ - m=INPUT_WRITE; - if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; - fd=FXRbGetWriteFileHandle(obj); - self->addInput(fd,m,tgt,sel); + if(mode&(INPUT_WRITE|INPUT_EXCEPT)){ + fd=FXRbGetWriteFileHandle(obj, mode); + self->addInput(fd,mode,tgt,sel); } return true; } @@ -379,18 +374,15 @@ public: */ bool removeInput(VALUE obj,FXuint mode){ FXInputHandle fd; - FXuint m; - if(mode&INPUT_READ){ - m=INPUT_READ; - if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; - fd=FXRbGetReadFileHandle(obj); - self->removeInput(fd,m); + if(mode&INPUT_READ|INPUT_EXCEPT){ + fd=FXRbGetReadFileHandle(obj, mode); + self->removeInput(fd,mode); + FXRbRemoveReadFileHandle(obj, mode); } - if(mode&INPUT_WRITE){ - m=INPUT_WRITE; - if(mode&INPUT_EXCEPT) m|=INPUT_EXCEPT; - fd=FXRbGetWriteFileHandle(obj); - self->removeInput(fd,m); + if(mode&(INPUT_WRITE|INPUT_EXCEPT)){ + fd=FXRbGetWriteFileHandle(obj, mode); + self->removeInput(fd,mode); + FXRbRemoveWriteFileHandle(obj, mode); } return true; } -- GitLab