Menu.C

Index

      
      #include "Menu.h"
      #include "Manager.h"
      #include "Client.h"
      
      #include <sys/types.h>
      #include <dirent.h>
      #include <sys/stat.h>
      #include <X11/keysym.h>
  10  
      Boolean       Menu::m_initialised = False;
      GC            Menu::m_menuGC;
      #if I18N
      XFontSet      Menu::m_fontset;
      #endif
      XFontStruct  *Menu::m_font;
      unsigned long Menu::m_foreground;
      unsigned long Menu::m_background;
      unsigned long Menu::m_border;
  20  Window        Menu::m_window;
      
      
      Menu::Menu(WindowManager *manager, XEvent *e)
          : m_items(0), m_nItems(0), m_nHidden(0),
            m_windowManager(manager), m_event(e),
            m_hasSubmenus(False)
      {
          if (!m_initialised)
          {
  30          m_foreground = m_windowManager->allocateColour
                  (CONFIG_MENU_FOREGROUND, "menu foreground");
              m_background = m_windowManager->allocateColour
                  (CONFIG_MENU_BACKGROUND, "menu background");
              m_border = m_windowManager->allocateColour
                  (CONFIG_MENU_BORDERS, "menu border");
      
      #if I18N
              char **ml;
              int mc;
  40          char *ds;
      
              m_fontset = XCreateFontSet(display(), CONFIG_NICE_MENU_FONT,
                                         &ml, &mc, &ds);
              if (!m_fontset)
                  m_fontset = XCreateFontSet(display(), CONFIG_NASTY_FONT,
                                             &ml, &mc, &ds);
              if (m_fontset) {
                  XFontStruct **fs_list;
                  XFontsOfFontSet(m_fontset, &fs_list, &ml);
  50              m_font = fs_list[0];
              } else {
                  m_font = NULL;
              }
      #define XTextWidth(x,y,z)     XmbTextEscapement(m_fontset,y,z)
      #define XDrawString(t,u,v,w,x,y,z) XmbDrawString(t,u,m_fontset,v,w,x,y,z)
      #else
              m_font = XLoadQueryFont(display(), CONFIG_NICE_MENU_FONT);
              if (!m_font) m_font = XLoadQueryFont(display(), CONFIG_NASTY_FONT);
      #endif
  60          if (!m_font) m_windowManager->fatal("couldn't load menu font\n");
      
              XGCValues values;
              values.background = m_background;
              values.foreground = m_foreground ^ m_background;
              values.function = GXxor;
              values.line_width = 0;
              values.subwindow_mode = IncludeInferiors;
              values.font = m_font->fid;
              
  70          m_menuGC = XCreateGC
                  (display(), root(),
                   GCForeground | GCBackground | GCFunction |
                   GCLineWidth | GCSubwindowMode, &values);
      
              XChangeGC(display(), Border::drawGC(m_windowManager), GCFont, &values);
      
              m_window = XCreateSimpleWindow
                  (display(), root(), 0, 0, 1, 1, 1,
                   m_border, m_background);
  80  
              XSetWindowAttributes attr;
      
      #if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False )
              attr.background_pixmap = Border::backgroundPixmap(manager);
      #endif
              attr.save_under =
                  (DoesSaveUnders(ScreenOfDisplay(display(), screen())) ?
                   True : False);
      
  90  #if ( CONFIG_USE_PIXMAPS != False ) && ( CONFIG_USE_PIXMAP_MENUS != False ) 
              XChangeWindowAttributes
                  (display(), m_window, CWBackPixmap, &attr);
      #endif
              XChangeWindowAttributes
                  (display(), m_window, CWSaveUnder, &attr);
      
              m_initialised = True;
          }
      }
 100  
      Menu::~Menu()
      {
          XUnmapWindow(display(), m_window);
      }
      
      void Menu::cleanup(WindowManager *const wm)
      {
          if (m_initialised) { // fix due to Eric Marsden
      #if I18N
 110          XFreeFontSet(wm->display(), m_fontset);
      #else
              XFreeFont(wm->display(), m_font);
      #endif
              XFreeGC(wm->display(), m_menuGC);
          }
      }
      
      int nobuttons(XButtonEvent *e) // straight outta 9wm
      {
 120      int state;
          state = (e->state & AllButtonMask);
          return (e->type == ButtonRelease) && (state & (state - 1)) == 0;
      }
      
      int Menu::getSelection()
      {
          m_items = getItems(&m_nItems, &m_nHidden);
          XButtonEvent *xbev = (XButtonEvent *)m_event; // KeyEvent is similar enough
              
 130      if (xbev->window == m_window || m_nItems == 0) return -1;
          
          int width, maxWidth = 10;
          for(int i = 0; i < m_nItems; i++) {
              width = XTextWidth(m_font, m_items[i], strlen(m_items[i]));
              if (width > maxWidth) maxWidth = width;
          }
          maxWidth += 32;
      
          Boolean isKeyboardMenu =
 140          (CONFIG_WANT_KEYBOARD_MENU && (xbev->type == KeyPress));
          int selecting = isKeyboardMenu ? 0 : -1, prev = -1;
          int entryHeight = m_font->ascent + m_font->descent + 4;
          int totalHeight = entryHeight * m_nItems + 13;
      
          int mx = DisplayWidth (display(), screen()) - 1;
          int my = DisplayHeight(display(), screen()) - 1;
      
          int x, y;
      
 150      if (isKeyboardMenu) {
              x = mx / 2 - maxWidth / 2;
              y = my / 2 - totalHeight / 2;
          } else {
      
              x = xbev->x - maxWidth/2;
              y = xbev->y - 2;
      
              Boolean warp = False;
      
 160          if (x < 0) {
                  xbev->x -= x;
                  x = 0;
                  warp = True;
              } else if (x + maxWidth >= mx) {
                  xbev->x -= x + maxWidth - mx;
                  x = mx - maxWidth;
                  warp = True;
              }
          
 170          if (y < 0) {
                  xbev->y -= y;
                  y = 0;
                  warp = True;
              } else if (y + totalHeight >= my) {
                  xbev->y -= y + totalHeight - my;
                  y = my - totalHeight;
                  warp = True;
              }
      
 180          if (warp) XWarpPointer(display(), None, root(), None, None,
                                     None, None, xbev->x, xbev->y);
          }
      
          XMoveResizeWindow(display(), m_window, x, y, maxWidth, totalHeight);
          XSelectInput(display(), m_window, MenuMask);
          XMapRaised(display(), m_window);
      
          if (m_windowManager->attemptGrab(m_window, None,
                                           MenuGrabMask, xbev->time)
 190          != GrabSuccess) {
              XUnmapWindow(display(), m_window);
              return -1;
          }
          
          if (isKeyboardMenu) {
              if (m_windowManager->attemptGrabKey(m_window, xbev->time)
                  != GrabSuccess) {
                  XUnmapWindow(display(), m_window);
                  return -1;
 200          }
          }       
      
          Boolean done = False;
          Boolean drawn = False;
          XEvent event;
          struct timeval sleepval;
          unsigned long tdiff = 0L;
          Boolean speculating = False;
          Boolean foundEvent;
 210  
          while (!done)
          {
              int i;
              foundEvent = False;
      
              if (CONFIG_FEEDBACK_DELAY >= 0 &&
                  tdiff > CONFIG_FEEDBACK_DELAY &&
                  !isKeyboardMenu && // removeFeedback didn't seem to work for it
                  !speculating) {
 220  
                  if (selecting >= 0 && selecting < m_nItems) {
                      raiseFeedbackLevel(selecting);
                      XRaiseWindow(display(), m_window);
                  }
      
                  speculating = True;
              }
      
              //!!! MenuMask | ??? suggests MenuMask is wrong
 230          while (XCheckMaskEvent
                     (display(), MenuMask | StructureNotifyMask |
                      KeyPressMask | KeyReleaseMask, &event)) {
                  foundEvent = True;
                  if (event.type != MotionNotify) break;
              }
      
              if (!foundEvent) {
                  sleepval.tv_sec = 0;
                  sleepval.tv_usec = 10000;
 240              select(0, 0, 0, 0, &sleepval);
                  tdiff += 10;
                  continue;
              }
              
              switch (event.type)
              {
              case ButtonPress:
                  break;
                  
 250          case ButtonRelease:
                  if (isKeyboardMenu) break;
      
                  if (drawn) {
      
                      if (event.xbutton.button != xbev->button) break;
                      x = event.xbutton.x;
                      y = event.xbutton.y - 11;
                      i = y / entryHeight;
                      
 260                  if (selecting >= 0 && y >= selecting * entryHeight - 3 &&
                          y <= (selecting + 1) * entryHeight - 3) i = selecting;
      
                      if (m_hasSubmenus && (i >= 0 && i < m_nHidden)) i = -i;
                      
                      if (x < 0 || x > maxWidth || y < -3) i = -1;
                      else if (i < 0 || i >= m_nItems) i = -1;
                      
                  } else {
                      i = -1;
 270              }
                  
                  if (!nobuttons(&event.xbutton)) i = -1;
                  m_windowManager->releaseGrab(&event.xbutton);
                  XUnmapWindow(display(), m_window);
                  selecting = i;
                  done = True;
                  break;
      
              case MotionNotify:
 280              if (!drawn || isKeyboardMenu) break;
      
                  x = event.xbutton.x;
                  y = event.xbutton.y - 11;
                  prev = selecting;
                  selecting = y / entryHeight;
      
                  if (prev >= 0 && y >= prev * entryHeight - 3 &&
                      y <= (prev+1) * entryHeight - 3) selecting = prev;
      
 290              if (m_hasSubmenus && (selecting >= 0 && selecting < m_nHidden) &&
                      x >= maxWidth-32 && x < maxWidth)
                  {
                      xbev->x += event.xbutton.x - 32;
                      xbev->y += event.xbutton.y;
                      
                      createSubmenu ((XEvent *)xbev, selecting);
                      done = True;
                      break;
                  }
 300              
                  if (x < 0 || x > maxWidth || y < -3) selecting = -1;
                  else if (selecting < 0 || selecting > m_nItems) selecting = -1;
      
                  if (selecting == prev) break;
                  tdiff = 0; speculating = False;
      
                  if (prev >= 0 && prev < m_nItems) {
                      removeFeedback(prev, speculating);
                      XFillRectangle(display(), m_window, m_menuGC,
 310                                 4, prev * entryHeight + 9,
                                     maxWidth - 8, entryHeight);
                  }
      
                  if (selecting >= 0 && selecting < m_nItems) {
                      showFeedback(selecting);
                      XRaiseWindow(display(), m_window);
                      XFillRectangle(display(), m_window, m_menuGC,
                                     4, selecting * entryHeight + 9,
                                     maxWidth - 8, entryHeight);
 320              }
                  
                  break;
                              
              case Expose:
      
                  if (CONFIG_MAD_FEEDBACK && event.xexpose.window != m_window) {
                      m_windowManager->dispatchEvent(&event);
                      break;
                  }
 330  
                  XClearWindow(display(), m_window);
                              
                  XDrawRectangle(display(), m_window, m_menuGC, 2, 7,
                                 maxWidth - 5, totalHeight - 10);
      
                  for (i = 0; i < m_nItems; i++) {
      
                      int dx = XTextWidth(m_font, m_items[i], strlen(m_items[i]));
                      int dy = i * entryHeight + m_font->ascent + 10;
 340  
                      if (i >= m_nHidden) {
                          XDrawString(display(), m_window,
                                      Border::drawGC(m_windowManager),
                                      maxWidth - 8 - dx, dy,
                                      m_items[i], strlen(m_items[i]));
                      } else {
                          XDrawString(display(), m_window,
                                      Border::drawGC(m_windowManager),
                                      8, dy, m_items[i], strlen(m_items[i]));
 350                  }
                  }
      
                  if (selecting >= 0 && selecting < m_nItems) {
                      XFillRectangle(display(), m_window, m_menuGC,
                                     4, selecting * entryHeight + 9,
                                     maxWidth - 8, entryHeight);
                  }
      
                  drawn = True;
 360              break;
      
              case KeyPress:
              {
                  if (!isKeyboardMenu) break;
      
                  KeySym key = XKeycodeToKeysym(display(), event.xkey.keycode, 0);
      
                  if (key == CONFIG_MENU_SELECT_KEY) {
      
 370                  if (!drawn) selecting = -1;
      
                      if (m_hasSubmenus && selecting >= 0 && selecting < m_nHidden)
                      {
                          createSubmenu((XEvent *)xbev, selecting);
                          selecting = -1;
                      }
                      m_windowManager->releaseGrabKeyMode(&event.xkey);
                      XUnmapWindow(display(), m_window);
                      done = True;
 380                  break;
      
                  } else if (key == CONFIG_MENU_CANCEL_KEY) {
      
                      m_windowManager->releaseGrabKeyMode(&event.xkey);
                      XUnmapWindow(display(), m_window);
                      if (selecting >= 0) removeFeedback(selecting, speculating);
                      selecting = -1;
                      done = True;
                      break;
 390  
                  } else if (key != CONFIG_MENU_UP_KEY &&
                             key != CONFIG_MENU_DOWN_KEY) {
                      break;
                  }
      
                  if (!drawn) break;
                  prev = selecting;
      
                  if (key == CONFIG_MENU_UP_KEY) {
 400  
                      if (prev <= 0) selecting = m_nItems - 1;
                      else selecting = prev - 1;
      
                  } else {
      
                      if (prev == m_nItems - 1 || prev < 0) selecting = 0;
                      else selecting = prev + 1;
                  }
      
 410              tdiff = 0; speculating = False;
                  
                  if (prev >= 0 && prev < m_nItems) {
                      removeFeedback(prev, speculating);
                      XFillRectangle(display(), m_window, m_menuGC,
                                     4, prev * entryHeight + 9,
                                     maxWidth - 8, entryHeight);
                  }
      
                  if (selecting >= 0 && selecting < m_nItems) {
 420                  showFeedback(selecting);
                      XRaiseWindow(display(), m_window);
                      XFillRectangle(display(), m_window, m_menuGC,
                                     4, selecting * entryHeight + 9,
                                     maxWidth - 8, entryHeight);
                  }
      
                  break;
              }
      
 430          case KeyRelease:
                  break;
      
              default:
                  if (event.xmap.window == m_window) break;
                  m_windowManager->dispatchEvent(&event);
              }
          }
      
          if (selecting >= 0) removeFeedback(selecting, speculating);
 440      return selecting;
      }
      
      
      ClientMenu::ClientMenu(WindowManager *manager, XEvent *e)
          : Menu(manager, e), m_allowExit(False)
      {
          int selecting = getSelection();
      
          if (selecting == m_nItems-1 && m_allowExit) { // getItems sets m_allowExit
 450          m_windowManager->setSignalled();
              return;
          }
          
          if (CONFIG_DISABLE_NEW_WINDOW_COMMAND && selecting >= 0) {
              ++selecting; // ha ha ha!
              ++m_nHidden;
          }
              
          if (selecting == 0) {
 460          m_windowManager->spawn(CONFIG_NEW_WINDOW_COMMAND, NULL);
              return;
          }
      
          if (selecting > 0) {
              
              Client *cl = m_clients.item(selecting - 1);
                  
              if (selecting < m_nHidden) cl->unhide(True);
              else if (selecting < m_nItems) {
 470              
                  if (CONFIG_CLICK_TO_FOCUS) cl->activate();
                  else cl->mapRaised();
                  cl->ensureVisible();
              }
      
              if (CONFIG_WANT_KEYBOARD_MENU && e->type == KeyPress)
                  cl->activateAndWarp();
          }
      
 480      --m_nHidden; // just in case
      }
      
      ClientMenu::~ClientMenu()
      {
          m_clients.remove_all();
          free(m_items);
      }
      
      char **ClientMenu::getItems(int *niR, int *nhR)
 490  {
          int i;
          XButtonEvent *xbev = (XButtonEvent *)m_event; // KeyEvent is similar enough
      
          for (i = 0; i < m_windowManager->hiddenClients().count(); ++i) {
              if (m_windowManager->hiddenClients().item(i)->channel() ==
                  m_windowManager->channel()) {
                  m_clients.append(m_windowManager->hiddenClients().item(i));
              }
          }
 500  
          int nh = m_clients.count();
          if (!CONFIG_DISABLE_NEW_WINDOW_COMMAND) ++nh;
      
          if (CONFIG_EVERYTHING_ON_ROOT_MENU) {
              for (i = 0; i < m_windowManager->clients().count(); ++i) {
                  if (m_windowManager->clients().item(i)->isNormal() &&
                      m_windowManager->clients().item(i)->channel() ==
                      m_windowManager->channel()) {
                      m_clients.append(m_windowManager->clients().item(i));
 510              }
              }
          }
      
          int n = m_clients.count();
          if (!CONFIG_DISABLE_NEW_WINDOW_COMMAND) ++n;
              
          int mx = DisplayWidth (display(), screen()) - 1;
          int my = DisplayHeight(display(), screen()) - 1;
      
 520      m_allowExit =
              ((CONFIG_EXIT_CLICK_SIZE_X != 0 ? 
                (CONFIG_EXIT_CLICK_SIZE_X > 0 ? 
                 (xbev->x < CONFIG_EXIT_CLICK_SIZE_X) : 
                 (xbev->x > mx + CONFIG_EXIT_CLICK_SIZE_X)) : 1) &&
               (CONFIG_EXIT_CLICK_SIZE_Y != 0 ? 
                (CONFIG_EXIT_CLICK_SIZE_Y > 0 ? 
                 (xbev->y < CONFIG_EXIT_CLICK_SIZE_Y) : 
                 (xbev->y > my + CONFIG_EXIT_CLICK_SIZE_Y)) : 1));
      
 530      if (m_allowExit) ++n;
      
          const char **items = (const char **)malloc(n * sizeof(char *));
      
          for (i = 0; i < n; ++i) {
      
              if (CONFIG_DISABLE_NEW_WINDOW_COMMAND == False) {
      
                  if (i == 0) items[i] = CONFIG_NEW_WINDOW_LABEL;
                  else if (m_allowExit && i > m_clients.count()) items[i] = "[Exit wmx]";
 540              else items[i] = m_clients.item(i-1)->label();
      
              } else {
      
                  if (m_allowExit && i >= m_clients.count()) items[i] = "[Exit wmx]";
                  else items[i] = m_clients.item(i)->label();
              }
          }
       
          *niR = n;
 550      *nhR = nh;
      
          return (char **)items;
      }
      
      
      Client *ClientMenu::checkFeedback(int item)
      {
          if (CONFIG_MAD_FEEDBACK == False) return NULL;
          
 560      if (CONFIG_DISABLE_NEW_WINDOW_COMMAND == False) {
      
              if (item <= 0 || item > m_clients.count()+1) return NULL;
              if (m_allowExit && item == m_clients.count() + 1) return NULL;
              return m_clients.item(item - 1);
      
          } else {
      
              if (item < 0 || item > m_clients.count()) return NULL;
              if (m_allowExit && item == m_clients.count()) return NULL;
 570          return m_clients.item(item);
          }
      }
      
      void ClientMenu::showFeedback(int item)
      {
          if (Client *c = checkFeedback(item)) c->showFeedback();
      }
      
      void ClientMenu::removeFeedback(int item, Boolean mapped)
 580  {
          if (Client *c = checkFeedback(item)) c->removeFeedback(mapped);
      }
       
      void ClientMenu::raiseFeedbackLevel(int item)
      {
          if (Client *c = checkFeedback(item)) c->raiseFeedbackLevel();
      }
      
      
 590  CommandMenu::CommandMenu(WindowManager *manager, XEvent *e,
                               char* otherdir = NULL)
          : Menu(manager, e)
      {
          const char *home = getenv("HOME");
          const char *wmxdir = getenv("WMXDIR");
      
          m_commandDir = NULL;
          m_hasSubmenus = True;
          
 600      if (otherdir == NULL)
          {
              if (wmxdir == NULL)
              {
                  if (home == NULL) return;
                  m_commandDir =
                      (char *)malloc(strlen(home) + strlen(CONFIG_COMMAND_MENU) + 2);
                  sprintf(m_commandDir, "%s/%s", home, CONFIG_COMMAND_MENU);
              }
              else
 610          {
                  if(wmxdir[0] == '/')
                  {
                      m_commandDir =
                          (char *)malloc(strlen(wmxdir) + 1);
                      strcpy(m_commandDir, wmxdir);
                  }
                  else
                  {
                      m_commandDir =
 620                      (char *)malloc(strlen(home) + strlen(wmxdir) + 2);
                      sprintf(m_commandDir, "%s/%s", home, wmxdir);
                  }
              }
          }
          else
          {
              m_commandDir = (char *)malloc(strlen(otherdir)+1);
              strcpy(m_commandDir, otherdir);
          }
 630  
          int i = getSelection();
              
          if (i >= 0 && i < m_nHidden) {
              // This should never happen.
          }
      
          if (i >= m_nHidden && i < m_nItems)
          {
              char *commandFile =
 640              (char *)malloc(strlen(m_commandDir) + strlen(m_items[i]) + 2);
      
              sprintf(commandFile, "%s/%s", m_commandDir, m_items[i]);
              m_windowManager->spawn(m_items[i], commandFile);
              free(commandFile);
          }
      }
      
      CommandMenu::~CommandMenu()
      {
 650      free(m_commandDir);
          for (int i = 0; i < m_nItems; i++) {
              free(m_items[i]);
          }
          free(m_items);
      }
      
      static int sortstrs(const void *va, const void *vb)
      {
          char **a = (char **)va;
 660      char **b = (char **)vb;    
          return strcmp(*a, *b);
      }
      
      void CommandMenu::createSubmenu (XEvent *e, int i)
      {
          char *new_directory;
          int dirlen = strlen (m_commandDir);
          
          new_directory = (char *)malloc (dirlen + strlen(m_items[i]) + 2);
 670      strcpy (new_directory, m_commandDir);
          new_directory[dirlen] = '/';
          strcpy (new_directory + dirlen + 1, m_items[i]);
          
          CommandMenu menu (m_windowManager, e, new_directory);
          free(new_directory);
      }
      
      char **CommandMenu::getItems(int *niR, int *nhR)
      {
 680      *niR = *nhR = 0;
          const char *home;
      
          if ((home = getenv("HOME")) == NULL) return NULL;
              
          int dirlen = strlen(m_commandDir);
          char *dirpath = (char *)malloc(dirlen + 1024 + 2); // NAME_MAX guess
          strcpy(dirpath, m_commandDir);
      
          DIR *dir = opendir(m_commandDir);
 690  
          if (dir == NULL) {
      
              free(dirpath);
              free(m_commandDir);
              m_commandDir =
                  (char *)malloc(strlen(CONFIG_SYSTEM_COMMAND_MENU) + 1);
              sprintf(m_commandDir, CONFIG_SYSTEM_COMMAND_MENU);
      
              dirlen = strlen(m_commandDir);
 700          dirpath = (char *)malloc(dirlen + 1024 + 2); // NAME_MAX guess
              strcpy(dirpath, m_commandDir);
      
              dir = opendir(m_commandDir);
      
              if (dir == NULL) {
                  free(dirpath);
                  return NULL;
              }
          }
 710  
          int count = 0;
          struct dirent *ent;
      
          // We already assume efficient realloc() in Border.C, so we may as
          // well assume it here too.
      
          char **items = 0;
      
          while ((ent = readdir(dir)) != NULL) {
 720  
              struct stat st;
              sprintf(dirpath + dirlen, "/%s", ent->d_name);
                      
              if (stat(dirpath, &st) == -1) continue;
              if (!S_ISDIR(st.st_mode) || !(st.st_mode & 0444)) continue;
              if (ent->d_name[0] == '.') continue;
      
              items = (!items ? (char **)malloc(sizeof(char *)) :
                       (char **)realloc(items, (count + 1) * sizeof(char *)));
 730  
              items[count++] = NewString(ent->d_name);
          }
      
          qsort(items, count, sizeof(char *), sortstrs);
          *nhR = count;
      
          rewinddir(dir);
      
          while ((ent = readdir(dir)) != NULL) {
 740  
              struct stat st;
              sprintf(dirpath + dirlen, "/%s", ent->d_name);
                      
              if (stat(dirpath, &st) == -1) continue;
              if (!S_ISREG(st.st_mode) || !(st.st_mode & 0111)) continue;
      
              items = (!items ? (char **)malloc(sizeof(char *)) :
                       (char **)realloc(items, (count + 1) * sizeof(char *)));
      
 750          items[count++] = NewString(ent->d_name);
          }
      
          *niR = count;
          qsort(items + *nhR, *niR - *nhR, sizeof(char *), sortstrs);
          
          free(dirpath);
          closedir(dir);
      
          return items;
 760  }
      
      
      // Fake geometry as a "menu" to save on code
      
      ShowGeometry::ShowGeometry(WindowManager *manager, XEvent *e)
          : Menu(manager, e)
      {
          // empty
      }
 770  
      void ShowGeometry::update(int x, int y)
      {
          char string[20];
      
          sprintf(string, "%d %d", x, y);
          int width = XTextWidth(m_font, string, strlen(string)) + 8;
          int height = m_font->ascent + m_font->descent + 8;
          int mx = DisplayWidth (display(), screen()) - 1;
          int my = DisplayHeight(display(), screen()) - 1;
 780    
          XMoveResizeWindow(display(), m_window,
                            (mx - width) / 2, (my - height) / 2, width, height);
          XClearWindow(display(), m_window);
          XMapRaised(display(), m_window);
          
          XDrawString(display(), m_window, Border::drawGC(m_windowManager),
                      4, 4 + m_font->ascent, string, strlen(string));
      }
      
 790  void ShowGeometry::remove()
      {
          XUnmapWindow(display(), m_window);
      }
      
      ShowGeometry::~ShowGeometry()
      {
          // empty
      }
      
 800  char **ShowGeometry::getItems(int *niR, int *nhR)
      {
          niR = nhR = 0;
          return NULL;
      }
      
      
      

Index

  • Menu::cleanup (function) returns void
  • nobuttons (function) returns int
  • Menu::getSelection (function) returns int
  • ClientMenu::getItems (function) returns char **
  • ClientMenu::checkFeedback (function) returns Client *
  • ClientMenu::showFeedback (function) returns void
  • ClientMenu::removeFeedback (function) returns void
  • ClientMenu::raiseFeedbackLevel (function) returns void
  • sortstrs (function) returns static int
  • CommandMenu::createSubmenu (function) returns void
  • CommandMenu::getItems (function) returns char **
  • ShowGeometry::update (function) returns void
  • ShowGeometry::remove (function) returns void
  • ShowGeometry::getItems (function) returns char **