?? fl.cxx
字號:
#include <stdio.h>//// "$Id: Fl.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $"//// Main event handling code for the Fast Light Tool Kit (FLTK).//// Copyright 1998-1999 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@easysw.com".//#include <FL/x.H>#include <FL/Fl.H>#include <FL/Fl_Window.H>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <stdio.h>//// Globals...//Fl_Widget *Fl::belowmouse_, *Fl::pushed_, *Fl::focus_, *Fl::selection_owner_;int Fl::damage_, Fl::e_x, Fl::e_y, Fl::e_x_root, Fl::e_y_root, Fl::e_state, Fl::e_clicks, Fl::e_is_click, Fl::e_keysym;char *Fl::e_text = "";int Fl::e_length;static double fl_elapsed();//// 'Fl:event_inside()' - Return whether or not the mouse event is inside// the given rectangle.//int Fl::event_inside(int x,int y,int w,int h) /*const*/ { int mx = event_x() - x; int my = event_y() - y; return (mx >= 0 && mx < w && my >= 0 && my < h);}int Fl::event_inside(const Fl_Widget *o) /*const*/ { return event_inside(o->x(),o->y(),o->w(),o->h());}// Timeouts are insert-sorted into order. This works good if there// are only a small number:static struct Timeout { double time; void (*cb)(void*); void* arg;} * timeout;static int numtimeouts;static int timeout_array_size;void Fl::add_timeout(double t, void (*cb)(void *), void *v) { fl_elapsed(); if (numtimeouts >= timeout_array_size) { timeout_array_size = 2*timeout_array_size+1; timeout = (Timeout*)realloc(timeout, timeout_array_size*sizeof(Timeout)); } // insert-sort the new timeout: int i; for (i=0; i<numtimeouts; i++) { if (timeout[i].time > t) { for (int j=numtimeouts; j>i; j--) timeout[j] = timeout[j-1]; break; } } timeout[i].time = t; timeout[i].cb = cb; timeout[i].arg = v; numtimeouts++;}void Fl::remove_timeout(void (*cb)(void *), void *v) { int i,j; for (i=j=0; i<numtimeouts; i++) { if (timeout[i].cb == cb && timeout[i].arg==v) ; else {if (j<i) timeout[j]=timeout[i]; j++;} } numtimeouts = j;}static int call_timeouts() { int expired = 0; while (numtimeouts) { if (timeout[0].time > 0) break; // we must remove timeout from array before doing the callback: void (*cb)(void*) = timeout[0].cb; void *arg = timeout[0].arg; numtimeouts--; expired++; if (numtimeouts) memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout)); // now it is safe for the callback to do add_timeout: cb(arg); } return expired;}void Fl::flush() { if (damage()) { damage_ = 0; for (Fl_X* x = Fl_X::first; x; x = x->next) { if (x->w->damage() && x->w->visible_r()) {// if (1) { if (x->wait_for_expose) { // leave Fl::damage() set so programs can tell damage still exists damage_ = 1; x->wait_for_expose=0;//tanghao } else { x->flush(); x->w->clear_damage(); } } } }#ifndef WIN32#ifdef NANO_X if (fl_display)GrFlush();#else if (fl_display) XFlush(fl_display);#endif#endif}extern double fl_wait(int timeout_flag, double timeout);extern int fl_ready();static int initclock; // if false we didn't call fl_elapsed() last time#ifndef WIN32#include <sys/time.h>#endif// fl_elapsed must return the amount of time since the last time it was// called. To reduce the number of system calls to get the// current time, the "initclock" symbol is turned on by an indefinite// wait. This should then reset the measured-from time and return zerostatic double fl_elapsed() {#ifdef WIN32 unsigned long newclock = GetTickCount(); const int TICKS_PER_SECOND = 1000; // divisor of the value to get seconds static unsigned long prevclock; if (!initclock) {prevclock = newclock; initclock = 1; return 0.0;} else if (newclock < prevclock) return 0.0; double t = double(newclock-prevclock)/TICKS_PER_SECOND; prevclock = newclock;#else static struct timeval prevclock; struct timeval newclock; gettimeofday(&newclock, NULL); if (!initclock) { prevclock.tv_sec = newclock.tv_sec; prevclock.tv_usec = newclock.tv_usec; initclock = 1; return 0.0; } double t = newclock.tv_sec - prevclock.tv_sec + (newclock.tv_usec - prevclock.tv_usec)/1000000.0; prevclock.tv_sec = newclock.tv_sec; prevclock.tv_usec = newclock.tv_usec;#endif // expire any timeouts: if (t > 0.0) for (int i=0; i<numtimeouts; i++) timeout[i].time -= t; return t;}void (*Fl::idle)();static char in_idle;static void callidle() { if (!Fl::idle || in_idle) return; in_idle = 1; Fl::idle(); in_idle = 0;}int Fl::wait() { callidle(); int expired = 0; if (numtimeouts) {fl_elapsed(); expired = call_timeouts();} flush(); //if (!Fl_X::first) return 0; // no windows if (!Fl_X::first) { fl_wait(1,1); return 0; } else if ((idle && !in_idle) || expired) { fl_wait(1,0.0); } else if (numtimeouts) { fl_wait(1, timeout[0].time); } else { initclock = 0; //if (!Fl_X::first) { // fl_wait(1,1); // return 0; //} else { fl_wait(0,0); //} } return 1;}double Fl::wait(double time) { callidle(); int expired = 0; if (numtimeouts) {time -= fl_elapsed(); expired = call_timeouts();} flush(); double wait_time = (idle && !in_idle) || expired ? 0.0 : time; if (numtimeouts && timeout[0].time < wait_time) wait_time = timeout[0].time; fl_wait(1, wait_time); return time - fl_elapsed();}int Fl::check() { callidle(); if (numtimeouts) {fl_elapsed(); call_timeouts();} fl_wait(1, 0.0); flush(); return Fl_X::first != 0; // return true if there is a window}int Fl::ready() { // if (idle && !in_idle) return 1; // should it do this? if (numtimeouts) {fl_elapsed(); if (timeout[0].time <= 0) return 1;} return fl_ready();}int Fl::run() { while (wait()); return 0;}////////////////////////////////////////////////////////////////// Window list management:Fl_X* Fl_X::first;Fl_Window* fl_find(Window xid) { Fl_X *window; for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) if (window->xid == xid) { if (window != Fl_X::first && !Fl::modal()) { // make this window be first to speed up searches // this is not done if modal is true to avoid messing up modal stack *pp = window->next; window->next = Fl_X::first; Fl_X::first = window; } return window->w; } return 0;}void Fl::redraw() { for (Fl_X* x = Fl_X::first; x; x = x->next) x->w->redraw();}Fl_Window* Fl::first_window() {Fl_X* x = Fl_X::first; return x ? x->w : 0;}Fl_Window* Fl::next_window(const Fl_Window* w) { Fl_X* x = Fl_X::i(w)->next; return x ? x->w : 0;}////////////////////////////////////////////////////////////////// Event handlers:struct handler_link { int (*handle)(int); const handler_link *next;};static const handler_link *handlers = 0;void Fl::add_handler(int (*h)(int)) { handler_link *l = new handler_link; l->handle = h; l->next = handlers; handlers = l;}static int send_handlers(int event) { for (const handler_link *h = handlers; h; h = h->next) if (h->handle(event)) return 1; return 0;}////////////////////////////////////////////////////////////////Fl_Widget* fl_oldfocus; // kludge for Fl_Group...void Fl::focus(Fl_Widget *o) { if (grab()) return; // don't do anything while grab is on Fl_Widget *p = focus_; if (o != p) { focus_ = o; fl_oldfocus = 0; for (; p && !p->contains(o); p = p->parent()) { p->handle(FL_UNFOCUS); fl_oldfocus = p; } }}void Fl::belowmouse(Fl_Widget *o) { if (grab()) return; // don't do anything while grab is on Fl_Widget *p = belowmouse_; if (o != p) { event_is_click(0); belowmouse_ = o; for (; p && !p->contains(o); p = p->parent()) p->handle(FL_LEAVE); }}void Fl::pushed(Fl_Widget *o) { pushed_ = o;}Fl_Window *fl_xfocus; // which window X thinks has focusFl_Window *fl_xmousewin;// which window X thinks has FL_ENTERFl_Window *Fl::grab_; // most recent Fl::grab()Fl_Window *Fl::modal_; // topmost modal() window// Update modal(), focus() and other state according to system state,// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events.// This is the only function that produces these events in response// to system activity.// This is called whenever a window is added or hidden, and whenever// X says the focus or mouse window have changed.void fl_fix_focus() { if (Fl::grab()) return; // don't do anything while grab is on. // set focus based on Fl::modal() and fl_xfocus Fl_Widget* w = fl_xfocus; if (w) { while (w->parent()) w = w->parent(); if (Fl::modal()) w = Fl::modal(); if (!w->contains(Fl::focus())) if (!w->take_focus()) Fl::focus(w); } else Fl::focus(0); if (!Fl::pushed()) { // set belowmouse based on Fl::modal() and fl_xmousewin: w = fl_xmousewin; if (w) { if (Fl::modal()) w = Fl::modal(); if (!w->contains(Fl::belowmouse())) { Fl::belowmouse(w); w->handle(FL_ENTER); } else { // send a FL_MOVE event so the enter/leave state is up to date Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); Fl::e_y = Fl::e_y_root-fl_xmousewin->y();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -