From a4e0a9adb554a49385e3b269ba46293e8a2696f4 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Thu, 27 Jun 2002 23:18:12 +0000 Subject: Added Greg Ercolanos filedescripter support Fixed Text Width bug. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@2325 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_mac.cxx | 301 ++++++++++++++++++++++++++++++++++++++++++++++------ src/fl_font_mac.cxx | 11 +- 2 files changed, 270 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx index 3101d908b..b77f7d799 100644 --- a/src/Fl_mac.cxx +++ b/src/Fl_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_mac.cxx,v 1.1.2.27 2002/06/27 04:29:39 matthiaswm Exp $" +// "$Id: Fl_mac.cxx,v 1.1.2.28 2002/06/27 23:18:12 matthiaswm Exp $" // // MacOS specific code for the Fast Light Tool Kit (FLTK). // @@ -51,6 +51,17 @@ #include #include "flstring.h" #include +#include + +// #define DEBUG_SELECT // UNCOMMENT FOR SELECT()/THREAD DEBUGGING +#ifdef DEBUG_SELECT +#include // testing +#define DEBUGMSG(msg) fprintf(stderr, msg); +#define DEBUGPERRORMSG(msg) perror(msg) +#else +#define DEBUGMSG(msg) +#define DEBUGPERRORMSG(msg) +#endif /*DEBUGSELECT*/ // external functions extern Fl_Window* fl_find(Window); @@ -89,7 +100,7 @@ extern Fl_Window* fl_xmousewin; #endif enum { kEventClassFLTK = 'fltk' }; -enum { kEventFLTKBreakLoop = 1 }; +enum { kEventFLTKBreakLoop = 1, kEventFLTKDataReady }; /** * Mac keyboard lookup table @@ -128,56 +139,166 @@ void (*fl_lock_function)() = nothing; void (*fl_unlock_function)() = nothing; -/** - * \todo This funtion is not yet implemented! - */ -void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) +// +// Select interface +// +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 +struct FD +{ + int fd; + short events; + void (*cb)(int, void*); + void* arg; +}; +static int nfds = 0; +static int fd_array_size = 0; +static FD *fd = 0; +static int G_pipe[2] = { 0,0 }; // work around pthread_cancel() problem +enum GetSet { GET = 1, SET = 2 }; +static pthread_mutex_t select_mutex; // global data lock + +// MAXFD ACCESSOR (HANDLES LOCKING) +static void MaxFD(GetSet which, int& val) { -#pragma unused ( n ) -#pragma unused ( events ) -#pragma unused ( cb ) -#pragma unused ( v ) + static int maxfd = 0; + pthread_mutex_lock(&select_mutex); + if ( which == GET ) { val = maxfd; } + else { maxfd = val; } + pthread_mutex_unlock(&select_mutex); } - -/** - * \todo This funtion is not yet implemented! - */ -void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) +// FDSET ACCESSOR (HANDLES LOCKING) +static void Fdset(GetSet which, fd_set& r, fd_set &w, fd_set &x) { -#pragma unused ( fd ) -#pragma unused ( cb ) -#pragma unused ( v ) + static fd_set fdsets[3]; + pthread_mutex_lock(&select_mutex); + if ( which == GET ) { r = fdsets[0]; w = fdsets[1]; x = fdsets[2]; } + else { fdsets[0] = r; fdsets[1] = w; fdsets[2] = x; } + pthread_mutex_unlock(&select_mutex); } +void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) +{ + remove_fd(n, events); -/** - * \todo This funtion is not yet implemented! - */ -void Fl::remove_fd(int n, int events) + int i = nfds++; + + if (i >= fd_array_size) { + FD *temp; + fd_array_size = 2*fd_array_size+1; + + if (!fd) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); } + else { temp = (FD*)realloc(fd, fd_array_size*sizeof(FD)); } + + if (!temp) return; + fd = temp; + } + + fd[i].cb = cb; + fd[i].arg = v; + fd[i].fd = n; + fd[i].events = events; + + { + int maxfd; + fd_set r, w, x; + MaxFD(GET, maxfd); + Fdset(GET, r, w, x); + if (events & POLLIN) FD_SET(n, &r); + if (events & POLLOUT) FD_SET(n, &w); + if (events & POLLERR) FD_SET(n, &x); + if (n > maxfd) maxfd = n; + Fdset(SET, r, w, x); + MaxFD(SET, maxfd); + } +} + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { -#pragma unused ( n ) -#pragma unused ( events ) + Fl::add_fd(fd, POLLIN, cb, v); } +void Fl::remove_fd(int n, int events) +{ + int i,j; -/** - * \todo This funtion is not yet implemented! - */ -void Fl::remove_fd(int n) + for (i=j=0; i maxfd ) maxfd = G_pipe[0]; + + // FOREVER UNTIL THREAD CANCEL OR ERROR + while ( 1 ) + { + timeval t = { 1000, 0 }; // 1000 seconds; + int ret = ::select(maxfd+1, &r, &w, &x, &t); + pthread_testcancel(); // OSX 10.0.4 and under: need to do this + // so parent can cancel us :( + switch ( ret ) + { + case 0: // NO DATA + continue; + case -1: // ERROR + { + DEBUGPERRORMSG("CHILD THREAD: select() failed"); + return(NULL); // error? exit thread + } + default: // DATA READY + { + DEBUGMSG("DATA READY EVENT: SENDING\n"); + PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard ); + return(NULL); // done with thread + } + } + } +} + + /** * break the current event loop */ @@ -298,19 +491,48 @@ static double do_queued_events( double time = 0.0 ) { kEventClassMouse, kEventMouseMoved }, { kEventClassMouse, kEventMouseWheelMoved }, { kEventClassMouse, kEventMouseDragged }, - { kEventClassFLTK, kEventFLTKBreakLoop } }; - ret = InstallEventHandler( target, dispatchHandler, 15, dispatchEvents, 0, 0L ); + { kEventClassFLTK, kEventFLTKBreakLoop }, + { kEventClassFLTK, kEventFLTKDataReady } }; + ret = InstallEventHandler( target, dispatchHandler, 16, dispatchEvents, 0, 0L ); ret = InstallEventLoopTimer( GetMainEventLoop(), 0, 0, NewEventLoopTimerUPP( timerProcCB ), 0, &timer ); } got_events = 0; + // START A THREAD TO WATCH FOR DATA READY + static pthread_t dataready_tid = 0; + if ( nfds ) + { + void *userdata = (void*)GetCurrentEventQueue(); + + // PREPARE INTER-THREAD DATA + pthread_mutex_init(&select_mutex, NULL); + + if ( G_pipe[0] ) { close(G_pipe[0]); G_pipe[0] = 0; } + if ( G_pipe[1] ) { close(G_pipe[1]); G_pipe[1] = 0; } + pipe(G_pipe); + + DEBUGMSG("*** START THREAD\n"); + pthread_create(&dataready_tid, NULL, dataready_thread, userdata); + } + fl_unlock_function(); if ( time > 0.0 ) { SetEventLoopTimerNextFireTime( timer, time ); - RunApplicationEventLoop(); // will return after the previously set time + RunApplicationEventLoop(); // wil return after the previously set time + if ( dataready_tid != 0 ) + { + DEBUGMSG("*** CANCEL THREAD: "); + pthread_cancel(dataready_tid); // cancel first + write(G_pipe[1], "x", 1); // then wakeup thread from select + pthread_join(dataready_tid, NULL); // wait for thread to finish + if ( G_pipe[0] ) { close(G_pipe[0]); G_pipe[0] = 0; } + if ( G_pipe[1] ) { close(G_pipe[1]); G_pipe[1] = 0; } + dataready_tid = 0; + DEBUGMSG("OK\n"); + } } else { @@ -319,6 +541,17 @@ static double do_queued_events( double time = 0.0 ) PostEventToQueue( GetCurrentEventQueue(), breakEvent, kEventPriorityStandard ); RunApplicationEventLoop(); ReleaseEvent( breakEvent ); + if ( dataready_tid != 0 ) + { + DEBUGMSG("*** CANCEL THREAD: "); + pthread_cancel(dataready_tid); // cancel first + write(G_pipe[1], "x", 1); // then wakeup thread from select + pthread_join(dataready_tid, NULL); // wait for thread to finish + if ( G_pipe[0] ) { close(G_pipe[0]); G_pipe[0] = 0; } + if ( G_pipe[1] ) { close(G_pipe[1]); G_pipe[1] = 0; } + dataready_tid = 0; + DEBUGMSG("OK\n"); + } } fl_lock_function(); @@ -1450,6 +1683,6 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) { // -// End of "$Id: Fl_mac.cxx,v 1.1.2.27 2002/06/27 04:29:39 matthiaswm Exp $". +// End of "$Id: Fl_mac.cxx,v 1.1.2.28 2002/06/27 23:18:12 matthiaswm Exp $". // diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index 87a397d81..0e9b80341 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_mac.cxx,v 1.1.2.9 2002/06/27 04:29:39 matthiaswm Exp $" +// "$Id: fl_font_mac.cxx,v 1.1.2.10 2002/06/27 23:18:12 matthiaswm Exp $" // // MacOS font selection routines for the Fast Light Tool Kit (FLTK). // @@ -27,6 +27,7 @@ //: TextSize, TextFont //: GetFNum (theName: Str255; VAR familyID: Integer); //: FUNCTION FMSwapFont (inRec: FMInput): FMOutPtr; +//: SetFractEnable Fl_FontSize::Fl_FontSize(const char* name, int Size) { knowMetrics = 0; @@ -126,13 +127,7 @@ static Fl_FontSize* find(int fnum, int size) { //////////////////////////////////////////////////////////////// // Public interface: -int fl_font_ = 0; -int fl_size_ = 0; - void fl_font(int fnum, int size) { - if (fnum == fl_font_ && size == fl_size_) return; - fl_font_ = fnum; - fl_size_ = size; fl_font(find(fnum, size)); } @@ -159,5 +154,5 @@ void fl_draw(const char* str, int n, int x, int y) { } // -// End of "$Id: fl_font_mac.cxx,v 1.1.2.9 2002/06/27 04:29:39 matthiaswm Exp $". +// End of "$Id: fl_font_mac.cxx,v 1.1.2.10 2002/06/27 23:18:12 matthiaswm Exp $". // -- cgit v1.2.3