Logo Search packages:      
Sourcecode: yudit version File versions

bool SX11Impl::doX (  ) 

Process one X11 event

Returns:
true if at least one event was found.

-------------------------------------------------------------------- Nothing is perfect. This is my if block... TODO: major cleanup. --------------------------------------------------------------------

Map and unmap has fuxxy modal processing. TODO: cleanup

-------------------------------------------------------------------- Modal Checks --------------------------------------------------------------------

Not yet on stack add to stack

Check what we got...

-------------------------------------------------------------------- X11 event switch --------------------------------------------------------------------

Definition at line 185 of file SX11Impl.cpp.

References addRedrawChildrenEvent(), addRedrawEvent(), SBinVector< Type >::append(), SString::append(), clipEvent(), SEncoder::decode(), dndEvent(), SEncoder::encode(), SBinHashtable< Type >::get(), SX11Window::getIC(), SX11Window::getICEncoding(), SX11Window::getID(), SXEventHandler::handleEvent(), SX11Window::isAsciiInput(), SX11Window::isChild, SX11Window::isKInput(), isOKToDeliver(), SX11Window::isVisible(), SX11Window::mapNotified, SBinVector< Type >::remove(), and SBinVector< Type >::size().

Referenced by doXLoop().

{
  if (display == 0)
  {
     return false;
  }
  if (!XPending(display)) 
  {
     return false;
  }

  /* block - true */
  {
    /* we dont process things in a nomral socket event looop. */
    /* everything is moved to job - done. */
    XEvent event;
    /* NextEvent sucks in all events from socket, and pass the first queued. */
    XNextEvent (display, &event);

    /* XIC needs this  */

    if (keyboardFocusWindow != 0 && 
        (event.type == KeyPress || event.type == KeyRelease))
    {
      event.xkey.window = (Window)keyboardFocusWindow->getID();
      event.xkey.subwindow = None;
      /* This precaution is because if input method dies....*/
      if (!keyboardFocusWindow->isAsciiInput())
      {
        if (XFilterEvent (&event, event.xkey.window))
        {
          return true;
        }
      }
    }
    else if (XFilterEvent(&event, None))
    {
      return true;
    }

    /* Pixmap Copy */
    if (event.xany.type == NoExpose) return true;

    /* event handlers are our first priority */
    SString ekey((long)event.xany.window);
    ekey.append (SString ((long) event.xany.type));
    
    /* process all drag and drop thingy here */
    if (event.xany.type == PropertyNotify || event.xany.type==ClientMessage)
    {
      if (dndEvent (event))
      {
        return true;
      }
    }

    SXEventHandler*h = eventHandlerTable.get (ekey);
    if (h != 0)
    {
      /* if false is returned we need to process this event */
      if (h->handleEvent (event))
      {
         return true;
      }
    }

    Window w = event.xany.window;
    SX11Window* sw = (SX11Window*) windowHashtable.get((long)w);
    XEvent peekEvent;
    XEvent lastEvent;
    int butt = 0;
    /**
     * --------------------------------------------------------------------
     *     Nothing is perfect. This is my if block... 
     *     TODO: major cleanup.
     * --------------------------------------------------------------------
     */
    if (event.type == KeyPress || event.type == KeyRelease)
    {
      if (keyboardFocusWindow != 0)
      {
         sw = keyboardFocusWindow; 
      }
      else
      {
         sw = 0;
      }
    }
    /* ConfigureNotify window is false. we need the window that changed. */
    else if (event.type == ConfigureNotify)
    {
      sw = (SX11Window*) windowHashtable.get((long) event.xconfigure.window);
    }
    /**
     * Map and unmap has fuxxy modal processing. TODO: cleanup 
     */
    else if (event.type == UnmapNotify || event.type ==  MapNotify)
    {
      sw = (SX11Window*) windowHashtable.get((long) event.xunmap.window);
      if (sw!=0)
      {
         //TODO remove mapNotified totally
        sw->mapNotified = (event.type ==  MapNotify);

        /* for child windows we dont get redraw, only Map. */
        if (sw->mapNotified && !sw->isChild)
        {
           addRedrawChildrenEvent (sw->getID(),
             SRedrawEvent (false, 0,  0,  sw->getWidth(), sw->getHeight()));
        }
      }

      /**
       *--------------------------------------------------------------------
       *      Modal Checks
       *--------------------------------------------------------------------
       */
      if (sw !=0 && sw->isModal())
      {
         /* add to modal stack, or remove from it */
         unsigned int modalIndex=0;
         /* earch foir this modal box... */
         for (modalIndex=0; modalIndex<modalStack.size(); modalIndex++)
         {
           if (modalStack[modalIndex] == sw->getID())
           {
             break;
           }
         }
         /* modalIndex is model index. */
         if (event.type ==  MapNotify)
         {
           SX11Window* foc = (keyboardFocusWindow==0) ?
              lastKeyboardFocusWindow : keyboardFocusWindow;
           long fid = (foc==0) ? 0 : foc->getID();
           /**
            * Not yet on stack  add to stack
            */
           if (modalIndex==modalStack.size())
           {
             modalStack.append (sw->getID());
             modalFocusStack.append (fid); 
             getKeyboardFocus (sw);
           }
         }
         else
         {
           /*
            * Remove from modal stack 
            */
           if (modalIndex<modalStack.size())
           {
             modalStack.remove (modalIndex);
             long lf = modalFocusStack[modalIndex]; 
             modalFocusStack.remove (modalIndex); 
             if (lf != 0)
             {
                SX11Window* kw = (SX11Window*) windowHashtable.get(lf);
                if (kw) getKeyboardFocus (kw);
             }
           }
         }
      }
    }
    else if (event.type == Expose)
    {
      sw = (SX11Window*) windowHashtable.get((long) event.xexpose.window);
    }

    /**
     * Check what we got...
     */
    if (sw == 0) /* nothing */
    {
      return true;
    }
    SWindowListener* l = listenerHashtable.get(sw->getID());
    if (l == 0)
    {
      return true;
    }
    SWindowListener* lf = 0;    

    /**
     * --------------------------------------------------------------------
     *                          X11 event switch
     * --------------------------------------------------------------------
     */
    switch (event.type)
    {
    case EnterNotify:
      if (l && sw)
      {
        l->enterWindow(sw);
      }
      break;
    case LeaveNotify:
      if (l && sw)
      {
        l->leaveWindow(sw);
      }
      break;
    case SelectionClear:
    case SelectionNotify:
    case SelectionRequest:
      clipEvent (event);
      break;
    case KeyPress:
    case KeyRelease:
      {
        /* events that hapen during conversion that dont have sent_event
         * set should be ignored */

        /* Don't try to make this bigger because it will screw up 
           Xutf8LookupString at and above 65 (try newline in ami) */
        char asci[64]; 
        KeySym key = 0;
        XIC ic = sw->getIC();
        SString enc = sw->getICEncoding();
        Status status_return;
        int cnt = 0; 
        SString s;
        if (sw->isAsciiInput() || ic==0)
        {
           cnt = XLookupString (&event.xkey, 
              asci, sizeof (asci), &key, 0);
           status_return = 1;
           s = SString (asci, (unsigned int)cnt);
        }
        else if (enc.size()>0)
        {
          cnt = XmbLookupString (ic, &event.xkey, 
             asci, sizeof (asci), &key, &status_return);
          if (status_return==XLookupChars || XLookupBoth)
          {
             SEncoder dec (enc);
             SString str (asci, (unsigned int)cnt);
             SV_UCS4 sv = dec.decode (str);
             SEncoder enc ("utf-8-s");
             s = enc.encode (sv);
          }
        }
        else
        {
#ifdef X_HAVE_UTF8_STRING
          cnt = Xutf8LookupString (ic, &event.xkey, 
             asci, sizeof (asci), &key, &status_return);
          if (status_return==XLookupChars || XLookupBoth)
          {
             s = SString (asci, (unsigned int)cnt);
          }

#else
          cnt = XmbLookupString (ic, &event.xkey, 
             asci, sizeof (asci), &key, &status_return);
          if (status_return==XLookupChars || status_return==XLookupBoth)
          {
             s = SString (asci, (unsigned int)cnt);
          }
#endif
        }
        if (cnt == 0 && (key & 0xff000000) == 0x01000000)
        {
           SV_UCS4 ucs4;
           ucs4.append ((SS_UCS4)(key & 0x00ffffff));
           SEncoder enc ("utf-8-s");
           s = enc.encode (ucs4);
           status_return = 0;
        }
        bool ctrl = (event.xkey.state & ControlMask) ? true : false;
        bool shift = (event.xkey.state & ShiftMask) ? true : false;
        bool meta = (event.xkey.state & Mod1Mask) ? true : false;
        SWindowListener::SKey skey =  status_return
         ? keySymOf(key) : SWindowListener::Key_Undefined;
        if (event.type==KeyPress) 
        {
          /* Let kinput2 deal with the event. */
          /* FIXME: Works fine, but too naive.  Ideally, we should devise
           * a mechanism that harmonizes the key bindings of yudit with
           * those of an XIM. */
          if (sw->isKInput() && (ctrl || meta)) break;

          if (sendAcceleratorPressed ((int) skey, ctrl, shift, meta)) break;
          /* in case we forgot to get this. */
          if (sendAcceleratorReleased ()) break;
        }
        else
        {
          if (sendAcceleratorReleased ()) break;
        }
        if (!event.xkey.send_event && sw->isKInput() 
              && sw == keyboardFocusWindow)
        {
          //fprintf (stderr, "Ignoreing keys.\n");
          if (event.type==KeyRelease)
          {
            l->keyReleased (sw, skey, s, ctrl, shift, meta);
          }
          break;
        }
        if (isOKToDeliver (sw->getID()))
        {
          if (event.type==KeyPress) 
          {
            l->keyPressed (sw, skey, s, ctrl, shift, meta);
          } else {
            l->keyReleased (sw, skey, s, ctrl, shift, meta);
          }
        }
      }
      break;
      
    case ConfigureNotify:
      if (needFocusWhenMapped == sw->getID())
      {
        if (getKeyboardFocus (sw)) needFocusWhenMapped = 0;
      }
      if (sw->isChild) break;
      sw->setPosition( event.xconfigure.x, event.xconfigure.y);
      sw->setSize( event.xconfigure.width, event.xconfigure.height);
      l->resized (sw, event.xconfigure.x, event.xconfigure.y,
         event.xconfigure.width, event.xconfigure.height);

      break;
    case FocusIn:
      /* Return the focus */
      if (lastKeyboardFocusWindow != 0 && keyboardFocusWindow == 0)
      {
          keyboardFocusWindow = lastKeyboardFocusWindow;
          lf = listenerHashtable.get(lastKeyboardFocusWindow->getID());
          if (lf != 0)
          {
             lf->gainedKeyboardFocus (lastKeyboardFocusWindow);
          }
      }
      if (lastKeyboardFocusWindow != 0)
      {
        keyboardFocusWindow = lastKeyboardFocusWindow;
      }
      if (keyboardFocusWindow != sw && keyboardFocusWindow!=0)
      {
        /* wierd eh? we receive a gained focus event, but it is not us! */
        if (keyboardFocusWindow->isVisible())
        {
          XSetInputFocus (display, (Window) keyboardFocusWindow->getID(), 
             RevertToNone, CurrentTime);
        }
      }
      break;
    case FocusOut:
      if (keyboardFocusWindow != 0)
      {
          lf = listenerHashtable.get(keyboardFocusWindow->getID());
          if (lf != 0)
          {
             lf->lostKeyboardFocus (keyboardFocusWindow);
          }
          keyboardFocusWindow = 0;
      }
      break;
    case ClientMessage:
        if ((Atom)event.xclient.message_type == wmProtocols
          && (Atom)event.xclient.data.l[0] == wmDeleteWindow
          && event.xclient.format == 32)
        {
          if (l->windowClose (sw) == true)
          {
              delete sw;
          }
        }
      break;
    case Expose:
       //TODO remove mapNotified totally
       //if (!sw->mapNotified) return true;
       addRedrawEvent ((long) event.xexpose.window,
         SRedrawEvent (false, event.xexpose.x, 
          event.xexpose.y, event.xexpose.width, event.xexpose.height)); 
       break;
    case GraphicsExpose:
       //TODO remove mapNotified totally
       if (!sw->mapNotified) return true;
       addRedrawEvent (event.xany.window,
         SRedrawEvent (false, event.xgraphicsexpose.x, 
         event.xgraphicsexpose.y, event.xgraphicsexpose.width, 
         event.xgraphicsexpose.height)); 
       break;
    case MotionNotify:
       if (!isOKToDeliver (sw->getID())) break;
       if (event.xmotion.state & Button2MotionMask) {
          butt = 0;
       } else if (event.xmotion.state & Button2MotionMask) {
          butt = 1;
       } else if (event.xmotion.state & Button3MotionMask) {
          butt = 2;
       }
       /* Event compression */
       lastEvent = event;
       while (XEventsQueued (display, QueuedAfterFlush)) {
         XPeekEvent (display, &peekEvent); 
         if (peekEvent.type == MotionNotify
            && peekEvent.xmotion.window == event.xmotion.window
            && peekEvent.xmotion.state == event.xmotion.state) {
            XNextEvent (display, &lastEvent);
          } else {
            break;
          }
       }
       l->buttonDragged (sw, butt, lastEvent.xbutton.x, lastEvent.xbutton.y);
       break;
    case ButtonRelease:
       if (!isOKToDeliver (sw->getID())) break;
       if (event.xbutton.button == Button1) {
         l->buttonReleased (sw, 0, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button2) {
         l->buttonReleased (sw, 1, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button3) {
         l->buttonReleased (sw, 2, event.xbutton.x, event.xbutton.y);
       }
       break;
    case ButtonPress:
       if (!isOKToDeliver (sw->getID())) break;
       //Enable Mousewheel functions (Addition by Maarten van Gompel <proycon@anaproy.homeip.net>
       if (event.xbutton.button == Button1) {
         l->buttonPressed (sw, 0, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button2) {
         l->buttonPressed (sw, 1, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button3) {
         l->buttonPressed (sw, 2, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button4) {
         l->buttonPressed (sw, 3, event.xbutton.x, event.xbutton.y);
       } else if (event.xbutton.button == Button5) {
         l->buttonPressed (sw, 4, event.xbutton.x, event.xbutton.y);
      }
       break;
    case DestroyNotify:
      break;
    }
  } 
  return true;
}


Generated by  Doxygen 1.6.0   Back to index