1/* ------------------------------------------------------------------------- 2 * Project: GSocket (Generic Socket) for WX 3 * Name: src/gtk/gsockgtk.cpp 4 * Purpose: GSocket: GTK part 5 * Licence: The wxWindows licence 6 * CVSID: $Id: gsockgtk.cpp 67249 2011-03-19 20:35:11Z JS $ 7 * ------------------------------------------------------------------------- 8 */ 9// For compilers that support precompilation, includes "wx.h". 10#include "wx/wxprec.h" 11 12#if wxUSE_SOCKETS 13 14#include <assert.h> 15#include <stdlib.h> 16#include <stdio.h> 17 18// newer versions of glib define its own GSocket but we unfortunately use this 19// name in our own (semi-)public header and so can't change it -- rename glib 20// one instead 21#define GSocket GlibGSocket 22#include <gdk/gdk.h> 23#include <glib.h> 24#undef GSocket 25 26#include "wx/gsocket.h" 27#include "wx/unix/gsockunx.h" 28#if wxUSE_THREADS 29#include "wx/thread.h" 30#endif 31 32extern "C" { 33static 34void _GSocket_GDK_Input(gpointer data, 35 gint source, 36 GdkInputCondition condition) 37{ 38 GSocket *socket = (GSocket *)data; 39 40 if (condition & GDK_INPUT_READ) 41 socket->Detected_Read(); 42 if (condition & GDK_INPUT_WRITE) 43 socket->Detected_Write(); 44} 45} 46 47typedef struct { 48#if wxUSE_THREADS 49 wxMutex* m_mutex; 50#endif 51 gint m_id[2]; 52} GSocketGTKMutexProtected; 53 54bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop() 55{ return true; } 56 57bool GSocketGUIFunctionsTableConcrete::OnInit(void) 58{ 59 return 1; 60} 61 62void GSocketGUIFunctionsTableConcrete::OnExit(void) 63{ 64} 65 66bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket) 67{ 68 socket->m_gui_dependent = (char *)malloc(sizeof(GSocketGTKMutexProtected)); 69 70 GSocketGTKMutexProtected* guispecific = (GSocketGTKMutexProtected*)socket->m_gui_dependent; 71 72#if wxUSE_THREADS 73 guispecific->m_mutex = new wxMutex(wxMUTEX_RECURSIVE); 74#endif 75 76 guispecific->m_id[0] = -1; 77 guispecific->m_id[1] = -1; 78 79 return TRUE; 80} 81 82void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket *socket) 83{ 84 GSocketGTKMutexProtected* guispecific = (GSocketGTKMutexProtected*)socket->m_gui_dependent; 85 86#if wxUSE_THREADS 87 delete guispecific->m_mutex; 88#endif 89 90 free(guispecific); 91} 92 93void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket, GSocketEvent event) 94{ 95 GSocketGTKMutexProtected* guispecific = (GSocketGTKMutexProtected*)socket->m_gui_dependent; 96 97 assert(guispecific != NULL); 98 99 int c; 100 101 if (socket->m_fd == -1) 102 return; 103 104 switch (event) 105 { 106 case GSOCK_LOST: /* fall-through */ 107 case GSOCK_INPUT: c = 0; break; 108 case GSOCK_OUTPUT: c = 1; break; 109 case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break; 110 default: return; 111 } 112 113#if wxUSE_THREADS 114 guispecific->m_mutex->Lock(); 115#endif 116 gint current_id = guispecific->m_id[c]; 117 guispecific->m_id[c] = -1; 118#if wxUSE_THREADS 119 guispecific->m_mutex->Unlock(); 120#endif 121 122 if (current_id != -1) { 123 gdk_input_remove(current_id); 124 } 125 126 current_id = gdk_input_add(socket->m_fd, 127 (c ? GDK_INPUT_WRITE : GDK_INPUT_READ), 128 _GSocket_GDK_Input, 129 (gpointer)socket); 130 131#if wxUSE_THREADS 132 guispecific->m_mutex->Lock(); 133#endif 134 guispecific->m_id[c] = current_id; 135#if wxUSE_THREADS 136 guispecific->m_mutex->Unlock(); 137#endif 138 139} 140 141void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket, GSocketEvent event) 142{ 143 GSocketGTKMutexProtected* guispecific = (GSocketGTKMutexProtected*)socket->m_gui_dependent; 144 int c; 145 146 assert( guispecific != NULL ); 147 148 switch (event) 149 { 150 case GSOCK_LOST: /* fall-through */ 151 case GSOCK_INPUT: c = 0; break; 152 case GSOCK_OUTPUT: c = 1; break; 153 case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break; 154 default: return; 155 } 156 157#if wxUSE_THREADS 158 guispecific->m_mutex->Lock(); 159#endif 160 gint current_id = guispecific->m_id[c]; 161 guispecific->m_id[c] = -1; 162#if wxUSE_THREADS 163 guispecific->m_mutex->Unlock(); 164#endif 165 166 if (current_id != -1) 167 { 168 gdk_input_remove(current_id); 169 } 170} 171 172void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket) 173{ 174 Install_Callback(socket, GSOCK_INPUT); 175 Install_Callback(socket, GSOCK_OUTPUT); 176} 177 178void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket) 179{ 180 Uninstall_Callback(socket, GSOCK_INPUT); 181 Uninstall_Callback(socket, GSOCK_OUTPUT); 182} 183 184#else /* !wxUSE_SOCKETS */ 185 186/* some compilers don't like having empty source files */ 187static int wxDummyGsockVar = 0; 188 189#endif /* wxUSE_SOCKETS/!wxUSE_SOCKETS */ 190