/[gzz]/gzz/gfx/libos/Os-GLX.cxx
ViewVC logotype

Diff of /gzz/gfx/libos/Os-GLX.cxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.20 by tjl, Thu Dec 19 09:12:39 2002 UTC revision 1.21 by tjl, Sat Jan 18 14:53:08 2003 UTC
# Line 31  Os-GLX.cxx Line 31  Os-GLX.cxx
31    
32  #include <sys/time.h>  #include <sys/time.h>
33  #include <time.h>  #include <time.h>
34    #include <unistd.h>
35    #include <fcntl.h>
36    
37  #include <libos/Os.hxx>  #include <libos/Os.hxx>
38    
# Line 155  namespace Os { Line 157  namespace Os {
157    
158      typedef ::Window Win; // work around a syntax error.      typedef ::Window Win; // work around a syntax error.
159    
160        /** Return the current time as milliseconds after some unit.
161         */
162      long curTime() {      long curTime() {
163          struct timeval t;          struct timeval t;
164          gettimeofday(&t, 0);          gettimeofday(&t, 0);
# Line 179  namespace Os { Line 183  namespace Os {
183      }      }
184    
185      struct LXWindowSystem : public Os::WindowSystem {      struct LXWindowSystem : public Os::WindowSystem {
186    
187            /** A pipe, used to interrupt waiting of eventloop.
188             */
189            int interruptPipe[2];
190    
191            fd_set readFds;
192            fd_set tmpReadFds;
193            int fdsMax;
194    
195          Display              *dpy;          Display              *dpy;
196          XSetWindowAttributes swa;          XSetWindowAttributes swa;
197          int swaMask;          int swaMask;
# Line 209  namespace Os { Line 222  namespace Os {
222          Drawable pixmapDrawable;          Drawable pixmapDrawable;
223    
224          LXWindowSystem() {          LXWindowSystem() {
225                if(pipe(interruptPipe) < 0) {
226                    perror("Making interrupt pipe");
227                    exit(1);
228                }
229                fcntl(interruptPipe[0], F_SETFL, O_NONBLOCK);
230                fcntl(interruptPipe[1], F_SETFL, O_NONBLOCK);
231    
232              if(!(dpy = XOpenDisplay( NULL ))) BARF("Can't start X");              if(!(dpy = XOpenDisplay( NULL ))) BARF("Can't start X");
233    
234                FD_ZERO(&readFds);
235                FD_SET(ConnectionNumber(dpy), &readFds);
236                FD_SET(interruptPipe[0], &readFds);
237                fdsMax = (ConnectionNumber(dpy) >? interruptPipe[0]) + 5;
238    
239    
240              int nel;              int nel;
241    
# Line 304  namespace Os { Line 329  namespace Os {
329              return f;              return f;
330          }          }
331    
332            void interrupt();
333          void eventLoop(bool wait);          void eventLoop(bool wait);
334    
335          /*          /*
# Line 313  namespace Os { Line 339  namespace Os {
339          */          */
340    
341      private:      private:
         bool tryRepaint();  
342                    
343      };      };
344    
# Line 411  namespace Os { Line 436  namespace Os {
436          virtual void setEventHandler(Eventhandler *h) {          virtual void setEventHandler(Eventhandler *h) {
437              eventhandler = h;              eventhandler = h;
438              DBG(dbg) << "Set window "<<xw<<" eventhandler to "<<((int)h)<<"\n";              DBG(dbg) << "Set window "<<xw<<" eventhandler to "<<((int)h)<<"\n";
             repaint();  
439          }          }
440    
441          LXWindow(LXWindowSystem *ws, int x, int y, int w, int h) : ws(ws),          LXWindow(LXWindowSystem *ws, int x, int y, int w, int h) : ws(ws),
# Line 477  namespace Os { Line 501  namespace Os {
501              glXSwapBuffers(ws->dpy, xw);              glXSwapBuffers(ws->dpy, xw);
502          }          }
503    
         virtual void repaint() {  
             needRepaint = true;  
         }  
   
         bool tryRepaint() {  
             // cout << "TryRepaint\n";  
             if(needRepaint) {  
                 needRepaint = false;  
                 if(eventhandler) {  
                     eventhandler->repaint();  
                     return true;  
                 }  
             }  
             return false;  
         }  
504    
505          virtual void move(int x, int y) {          virtual void move(int x, int y) {
506              XMoveWindow(ws->dpy, xw, x, y);              XMoveWindow(ws->dpy, xw, x, y);
# Line 593  namespace Os { Line 602  namespace Os {
602              }              }
603              case Expose:              case Expose:
604                  DBG(dbg) << "Expose\n";                  DBG(dbg) << "Expose\n";
605                  repaint();                  eventhandler->repaint();
606                  break;                  break;
607              case ConfigureNotify:              case ConfigureNotify:
608                  DBG(dbg) << "Configurenotify\n";                  DBG(dbg) << "Configurenotify\n";
609                  repaint();                  eventhandler->repaint();
610                  break;                  break;
611              case MapRequest:              case MapRequest:
612                  DBG(dbg) << "MapRequest\n";                  DBG(dbg) << "MapRequest\n";
613                  repaint();                  eventhandler->repaint();
614                  break;                  break;
615              case MapNotify:              case MapNotify:
616                  DBG(dbg) << "MapNotify\n";                  DBG(dbg) << "MapNotify\n";
617                  repaint();                  eventhandler->repaint();
618                  break;                  break;
619              default:              default:
620                      DBG(dbg) << "Unknown event "<<e->type<<"\n";                      DBG(dbg) << "Unknown event "<<e->type<<"\n";
# Line 636  namespace Os { Line 645  namespace Os {
645          return instance;          return instance;
646      }      }
647    
648        char intr = 'S';
649        void LXWindowSystem::interrupt() {
650            write(interruptPipe[1], &intr, 1);
651        }
652    
653    
654      void LXWindowSystem::eventLoop(bool wait) {      void LXWindowSystem::eventLoop(bool wait) {
655          DBG(dbg) << "In C++ eventloop : "<<wait<<"\n";          DBG(dbg) << "In C++ eventloop : "<<wait<<"\n";
656          // We don't want to block;          // We don't want to block;
657          while(1) {          while(1) {
658              DBG(dbg) << "Start loop\n";              DBG(dbg) << "Start loop\n";
             XEvent e;  
             if(tryRepaint()) {  
                 DBG(dbg) << "TryRepaint returned true, doing again... if no events (not now)\n";  
                 /*  
                 if(!XEventsQueued(dpy, QueuedAfterFlush))  
                     continue;  
                 */  
             }  
             /*  
             for(int i=0; i<idletasks.size(); i++) {  
                 donthang = (donthang || idletasks[i]->tick());  
             }  
             */  
             DBG(dbg) << "Repaint done\n";  
659    
660              bool eventsWaiting = XEventsQueued(dpy, QueuedAfterFlush);              bool eventsWaiting = XEventsQueued(dpy, QueuedAfterFlush);
661    
662                // If we should not wait and there are no events, return now
663              if(!wait && !eventsWaiting) return;              if(!wait && !eventsWaiting) return;
664                // We only wait once: on the next iteration of the loop,
665                // we'll return
666                wait = false;
667    
668              DBG(dbg) << "Get next event\n";              DBG(dbg) << "Wait for next event, interrupt or timeout\n";
669              // If we're waiting for a timeout, handle things  
670              // differently.              // If no events were waiting, now's the time to
671              if(timeouts.size() && !eventsWaiting) {              // wait for them.
672                  long t = curTime();              if(!eventsWaiting) {
673                  for(unsigned i=0; i<timeouts.size(); i++) {                  // Visit Java at least every .5 seconds
674                      if(timeouts[i].time < t) {                  timeval timeout;
675                          int id = timeouts[i].id;                  timeout.tv_sec = 0;
676                          LXWindow *w = windowsByX[timeouts[i].window];                  timeout.tv_usec = 500 * 1000;
677                          timeouts.erase(timeouts.begin()+i);  
678                          w->deliverTimeout(id);                  // If we're waiting for a timeout, sleep less.
679                          return;                  if(timeouts.size() && !eventsWaiting) {
680                        long t = curTime();
681                        for(unsigned i=0; i<timeouts.size(); i++) {
682                            if(timeouts[i].time < t) {
683                                int id = timeouts[i].id;
684                                LXWindow *w = windowsByX[timeouts[i].window];
685                                timeouts.erase(timeouts.begin()+i);
686                                w->deliverTimeout(id);
687                                return;
688                            } else {
689                                int ms = timeouts[i].time - t;
690                                if(ms < timeout.tv_usec / 1000)
691                                    timeout.tv_sec = 1000 * ms;
692                            }
693                      }                      }
694                  }                  }
695                  timespec ts;                  // Call select to wait for something to happen.
696                  ts.tv_sec = 0;                  tmpReadFds = readFds;
697                  ts.tv_nsec = 50000000;  // 50 ms - very bad                  select(fdsMax, &tmpReadFds, 0, 0, &timeout);
698                  nanosleep(&ts, &ts);                  char b[4];
699                  continue;                  DBG(dbg) << "Emptying interrupt pipe\n";
700                    while(read(interruptPipe[0], &b, 4) > 0) {
701                        DBG(dbg) << "Got "<<b[0]<<" "<<b[1]<<" "<<b[2]<< " "<<b[3]<<"\n";
702                    }
703                    DBG(dbg) << "Empty\n";
704              }              }
705              wait = false;  
706    
707                XEvent e;
708              XNextEvent(dpy, &e);              XNextEvent(dpy, &e);
709              //cout << "getWindow\n";              //cout << "getWindow\n";
710              LXWindow *w = windowsByX[e.xkey.window];              LXWindow *w = windowsByX[e.xkey.window];
# Line 694  namespace Os { Line 717  namespace Os {
717          }          }
718      }      }
719    
     bool LXWindowSystem::tryRepaint() {  
         for(unsigned i=0; i<windows.size(); i++) {  
             if(windows[i]->tryRepaint()) return true;  
         }  
         return false;  
     }  
   
720      /** Load an image into a raster using gdk-pixbuf.      /** Load an image into a raster using gdk-pixbuf.
721       */       */
722      ImageRaster loadImage(const char *filename) {      ImageRaster loadImage(const char *filename) {

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.21

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26