BailDetector.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:3k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // BailDetector.cc    interface for peeking at events,
  2. //                    and bailing out of long operations
  3. // created 2/5/99     magi@cs
  4. #include <tk.h>
  5. #include <iostream.h>
  6. #include "BailDetector.h"
  7. #include "Timer.h"
  8. // static member var declarations
  9. int  BailDetector::s_iBailDepth = 0;
  10. int  BailDetector::s_iLastChecked = 0;
  11. bool BailDetector::s_bBail = false;
  12. bool BailDetector::s_bBailNoticed = false;
  13. BailDetector::BailDetector()
  14. {
  15.   // if we're the first one,
  16.   if (!s_iBailDepth++) {
  17.     s_bBail = false;       // initialize bail flag
  18.     s_bBailNoticed = false;
  19.     s_iLastChecked = 0;
  20.   }
  21. }
  22. BailDetector::~BailDetector()
  23. {
  24.   // and uncount us from bail stack
  25.   if (--s_iBailDepth == 0) {
  26.     if (s_bBail) {
  27.       if (s_bBailNoticed)
  28. cerr << "command cancelled." << endl;
  29.       else
  30. cerr << "but command completed anyway." << endl;
  31.     }
  32.   }
  33. }
  34. Tk_RestrictAction
  35. BailDetector::filterproc (ClientData clientData, XEvent* eventPtr)
  36. {
  37.   if (!s_bBail) {
  38.     if (eventPtr->type == KeyPress) {
  39.       //cerr << (((XKeyPressedEvent*)eventPtr)->keycode) << endl;
  40.       // escape, as empirically evinced by the previous line, is 16:
  41.       if ((((XKeyPressedEvent*)eventPtr)->keycode & 0xFF) == 16) {
  42.       /* could also use:
  43.  || (eventPtr->type == MotionNotify
  44.  && ((XMotionEvent*)eventPtr)->state & (Button1Mask | Button2Mask)))
  45.  
  46.  to bail out of a render that's already unwanted because you've
  47.  moved the trackball since it started.
  48.  but we'd want to be more careful than that, maybe look for a few in 
  49.  a row, otherwise it's too sensitive.
  50.       */
  51.       
  52. s_bBail = true;
  53. cerr << "Cancel request noted... " << flush;
  54. return TK_DISCARD_EVENT;
  55.       }
  56.     }
  57.   }
  58.   // no matter what, don't process this event right now
  59.   return TK_DEFER_EVENT;
  60. }
  61. bool
  62. BailDetector::bail (void)
  63. {
  64.   // quick out if flag is already set
  65.   unsigned int iTimeStamp = Timer::get_system_tick_count();
  66.   if (!s_bBail && (iTimeStamp - s_iLastChecked  > 100)) {
  67.     // ok, pump events
  68.     s_iLastChecked = iTimeStamp;
  69.     // set up message filter, so we can be notified if messages arrive
  70.     Tk_RestrictProc* old_filter_proc;
  71.     ClientData old_filter_data;
  72.     old_filter_proc = Tk_RestrictEvents (filterproc, NULL, &old_filter_data);
  73.     
  74.     // both file and x events are necessary to hear keystrokes... they first 
  75.     // occur as a file event, which when processed becomes an X event.
  76.     // careful not to specify idle events, or TK_ALL_EVENTS, because
  77.     // that will interfere with the redraw itself and break it.
  78.     if (Tk_DoOneEvent (TK_WINDOW_EVENTS | TK_FILE_EVENTS | TK_DONT_WAIT))
  79.       // call again, because the first event could have been a file event
  80.       // which queued the window event we actually care about
  81.       Tk_DoOneEvent (TK_WINDOW_EVENTS | TK_DONT_WAIT);
  82.     // remove message filter
  83.     Tk_RestrictEvents (old_filter_proc, old_filter_data, &old_filter_data);
  84.   }
  85.   // then, need to check flag again since filter proc might have set it
  86.   if (s_bBail)
  87.     s_bBailNoticed = true;
  88.   return s_bBail;
  89. }
  90. int PlvBailDetectCmd(ClientData clientData, Tcl_Interp *interp, 
  91.      int argc, char *argv[])
  92. {
  93.   BailDetector bail;
  94.   int result = Tcl_Eval (interp, argv[1]);
  95.   if (argc > 2) {
  96.     Tcl_SetVar (interp, argv[2], interp->result, 0);
  97.   }
  98.   interp->result = (bail() ? "1" : "0");
  99.   return result;
  100. }