예제 #1
0
파일: hint.c 프로젝트: Miteam/jwm
/** Read the protocols hint for a window. */
void ReadWMProtocols(Window w, ClientState *state)
{

   unsigned long count, x;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *temp;
   Atom *p;

   Assert(w != None);

   state->status &= ~STAT_TAKEFOCUS;
   state->status &= ~STAT_DELETE;
   status = JXGetWindowProperty(display, w, atoms[ATOM_WM_PROTOCOLS],
                                0, 32, False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   p = (Atom*)temp;
   if(status != Success || realFormat == 0 || !p) {
      return;
   }

   for(x = 0; x < count; x++) {
      if(p[x] == atoms[ATOM_WM_DELETE_WINDOW]) {
         state->status |= STAT_DELETE;
      } else if(p[x] == atoms[ATOM_WM_TAKE_FOCUS]) {
         state->status |= STAT_TAKEFOCUS;
      }
   }

   JXFree(p);

}
예제 #2
0
파일: hint.c 프로젝트: Miteam/jwm
/** Read the WM state for a window. */
void ReadWMState(Window win, ClientState *state)
{

   Status status;
   unsigned long count;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned long *temp;

   status = JXGetWindowProperty(display, win, atoms[ATOM_WM_STATE], 0, 2,
                                False, atoms[ATOM_WM_STATE],
                                &realType, &realFormat,
                                &count, &extra, (unsigned char**)&temp);
   if(JLIKELY(status == Success && realFormat == 32 && count == 2)) {
      switch(temp[0]) {
      case IconicState:
         state->status |= STAT_MINIMIZED;
         break;
      case WithdrawnState:
         state->status &= ~STAT_MAPPED;
         break;
      default:
         break;
      }
      JXFree(temp);
   }

}
예제 #3
0
파일: hint.c 프로젝트: Miteam/jwm
/** Read a window atom. */
char GetWindowAtom(Window window, AtomType atom, Window *value)
{

   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   char ret;

   Assert(window != None);
   Assert(value);

   status = JXGetWindowProperty(display, window, atoms[atom], 0, 1, False,
                                XA_WINDOW, &realType, &realFormat,
                                &count, &extra, &data);
   ret = 0;
   if(status == Success && realFormat != 0 && data) {
      if(count == 1) {
         *value = *(Window*)data;
         ret = 1;
      }
      JXFree(data);
   }

   return ret;

}
예제 #4
0
파일: hint.c 프로젝트: Miteam/jwm
/** Read _MOTIF_WM_HINTS */
void ReadMotifHints(Window win, ClientState *state)
{

   PropMwmHints *mhints;
   Atom type;
   unsigned long itemCount, bytesLeft;
   unsigned char *data;
   int format;

   Assert(win != None);
   Assert(state);

   if(JXGetWindowProperty(display, win, atoms[ATOM_MOTIF_WM_HINTS], 0L, 20L,
                          False, atoms[ATOM_MOTIF_WM_HINTS], &type, &format,
                          &itemCount, &bytesLeft, &data) != Success
         || format == 0) {
      return;
   }

   mhints = (PropMwmHints*)data;
   if(mhints) {

      if((mhints->flags & MWM_HINTS_FUNCTIONS)
         && !(mhints->functions & MWM_FUNC_ALL)) {

         if(!(mhints->functions & MWM_FUNC_RESIZE)) {
            state->border &= ~BORDER_RESIZE;
         }
         if(!(mhints->functions & MWM_FUNC_MOVE)) {
            state->border &= ~BORDER_MOVE;
         }
         if(!(mhints->functions & MWM_FUNC_MINIMIZE)) {
            state->border &= ~BORDER_MIN;
         }
         if(!(mhints->functions & MWM_FUNC_MAXIMIZE)) {
            state->border &= ~BORDER_MAX;
         }
         if(!(mhints->functions & MWM_FUNC_CLOSE)) {
            state->border &= ~BORDER_CLOSE;
         }
      }

      if((mhints->flags & MWM_HINTS_DECORATIONS)
         && !(mhints->decorations & MWM_DECOR_ALL)) {

         if(!(mhints->decorations & MWM_DECOR_BORDER)) {
            state->border &= ~BORDER_OUTLINE;
         }
         if(!(mhints->decorations & MWM_DECOR_TITLE)) {
            state->border &= ~BORDER_TITLE;
         }
      }

      JXFree(mhints);
   }
}
예제 #5
0
파일: icon.c 프로젝트: harryhaaren/jwm
/** Read the icon property from a client. */
void ReadNetWMIcon(ClientNode *np)
{
   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   status = JXGetWindowProperty(display, np->window, atoms[ATOM_NET_WM_ICON],
                                0, 256 * 256 * 4, False, XA_CARDINAL,
                                &realType, &realFormat, &count, &extra, &data);
   if(status == Success && realFormat != 0 && data) {
      np->icon = CreateIconFromBinary((unsigned long*)data, count);
      JXFree(data);
   }
}
예제 #6
0
파일: icon.c 프로젝트: Miteam/jwm
/** Read the icon property from a client. */
IconNode *ReadNetWMIcon(Window win)
{
   static const long MAX_LENGTH = 1 << 20;
   IconNode *icon = NULL;
   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *data;
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_ICON],
                                0, MAX_LENGTH, False, XA_CARDINAL,
                                &realType, &realFormat, &count, &extra, &data);
   if(status == Success && realFormat != 0 && data) {
      icon = CreateIconFromBinary((unsigned long*)data, count);
      JXFree(data);
   }
   return icon;
}
예제 #7
0
파일: hint.c 프로젝트: Miteam/jwm
/** Determine the title to display for a client. */
void ReadWMName(ClientNode *np)
{

   unsigned long count;
   int status;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *name;

   if(np->name) {
      Release(np->name);
   }

   status = JXGetWindowProperty(display, np->window,
                                atoms[ATOM_NET_WM_NAME], 0, 1024, False,
                                atoms[ATOM_UTF8_STRING], &realType,
                                &realFormat, &count, &extra, &name);
   if(status != Success || realFormat == 0) {
      np->name = NULL;
   } else {
      const size_t size = strlen((char*)name) + 1;
      np->name = Allocate(size);
      memcpy(np->name, name, size);
      JXFree(name);
      np->name = ConvertFromUTF8(np->name);
   }

#ifdef USE_XUTF8
   if(!np->name) {
      status = JXGetWindowProperty(display, np->window,
                                   XA_WM_NAME, 0, 1024, False,
                                   atoms[ATOM_COMPOUND_TEXT],
                                   &realType, &realFormat, &count,
                                   &extra, &name);
      if(status == Success && realFormat == 8) {
         char **tlist;
         XTextProperty tprop;
         int tcount;
         tprop.value = name;
         tprop.encoding = atoms[ATOM_COMPOUND_TEXT];
         tprop.format = realFormat;
         tprop.nitems = strlen((char*)name);
         if(XmbTextPropertyToTextList(display, &tprop, &tlist, &tcount)
            == Success && tcount > 0) {
            const size_t len = strlen(tlist[0]) + 1;
            np->name = Allocate(len);
            memcpy(np->name, tlist[0], len);
            XFreeStringList(tlist);
         }
         JXFree(name);
      }
   }
#endif

   if(!np->name) {
      char *temp = NULL;
      if(JXFetchName(display, np->window, &temp)) {
         const size_t len = strlen(temp) + 1;
         np->name = Allocate(len);
         memcpy(np->name, temp, len);
         JXFree(temp);
      }
   }

}
예제 #8
0
파일: hint.c 프로젝트: Miteam/jwm
/** Read all hints needed to determine the current window state. */
ClientState ReadWindowState(Window win, char alreadyMapped)
{

   ClientState result;
   Status status;
   unsigned long count, x;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned char *temp;
   Atom *state;
   unsigned long card;
   Window utwin;

   Assert(win != None);

   result.status = STAT_MAPPED;
   result.maxFlags = MAX_NONE;
   result.border = BORDER_DEFAULT;
   result.layer = LAYER_NORMAL;
   result.defaultLayer = LAYER_NORMAL;
   result.desktop = currentDesktop;
   result.opacity = UINT_MAX;

   ReadWMProtocols(win, &result);
   ReadWMHints(win, &result, alreadyMapped);
   ReadWMState(win, &result);
   ReadMotifHints(win, &result);
   ReadWMOpacity(win, &result.opacity);

   /* _NET_WM_DESKTOP */
   if(GetCardinalAtom(win, ATOM_NET_WM_DESKTOP, &card)) {
      if(card == ~0UL) {
         result.status |= STAT_STICKY;
      } else if(card < settings.desktopCount) {
         result.desktop = card;
      } else {
         result.desktop = settings.desktopCount - 1;
      }
   }

   /* _NET_WM_STATE */
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_STATE], 0, 32,
                                False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   if(status == Success && realFormat != 0) {
      if(count > 0) {
         state = (Atom*)temp;
         for(x = 0; x < count; x++) {
            if(state[x] == atoms[ATOM_NET_WM_STATE_STICKY]) {
               result.status |= STAT_STICKY;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SHADED]) {
               result.status |= STAT_SHADED;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT]) {
               result.maxFlags |= MAX_VERT;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
               result.maxFlags |= MAX_HORIZ;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_TOP]) {
               result.maxFlags |= MAX_TOP;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_BOTTOM]) {
               result.maxFlags |= MAX_BOTTOM;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_LEFT]) {
               result.maxFlags |= MAX_LEFT;
            } else if(state[x] == atoms[ATOM_JWM_WM_STATE_MAXIMIZED_RIGHT]) {
               result.maxFlags |= MAX_RIGHT;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_FULLSCREEN]) {
               result.status |= STAT_FULLSCREEN;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_HIDDEN]) {
               result.status |= STAT_MINIMIZED;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SKIP_TASKBAR]) {
               result.status |= STAT_NOLIST;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_SKIP_PAGER]) {
               result.status |= STAT_NOPAGER;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_ABOVE]) {
               result.layer = LAYER_ABOVE;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_BELOW]) {
               result.layer = LAYER_BELOW;
            } else if(state[x] == atoms[ATOM_NET_WM_STATE_DEMANDS_ATTENTION]) {
               result.status |= STAT_URGENT;
            }
         }
      }
      if(temp) {
         JXFree(temp);
      }
   }

   /* _NET_WM_WINDOW_TYPE */
   status = JXGetWindowProperty(display, win, atoms[ATOM_NET_WM_WINDOW_TYPE],
                                0, 32, False, XA_ATOM, &realType, &realFormat,
                                &count, &extra, &temp);
   if(status == Success && realFormat != 0) {
      /* Loop until we hit a window type we recognize. */
      state = (Atom*)temp;
      for(x = 0; x < count; x++) {
         if(         state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_NORMAL]) {
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DESKTOP]) {
            result.defaultLayer  = LAYER_DESKTOP;
            result.border        = BORDER_NONE;
            result.status       |= STAT_STICKY;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DOCK]) {
            result.border        = BORDER_NONE;
            result.defaultLayer  = LAYER_ABOVE;
            result.status       |= STAT_NOFOCUS;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_SPLASH]) {
            result.border = BORDER_NONE;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_DIALOG]) {
            result.border &= ~BORDER_MIN;
            result.border &= ~BORDER_MAX;
            break;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_MENU]) {
            result.border       &= ~BORDER_MAX;
            result.status       |= STAT_NOLIST;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION]) {
            result.border        = BORDER_NONE;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_TOOLBAR]) {
            result.border       &= ~BORDER_MAX;
            result.defaultLayer  = LAYER_ABOVE;
            result.status       |= STAT_STICKY;
            result.status       |= STAT_NOLIST;
            result.status       |= STAT_NOFOCUS;
         } else if(  state[x] == atoms[ATOM_NET_WM_WINDOW_TYPE_UTILITY]) {
            result.border       &= ~BORDER_MAX;
            result.status       |= STAT_NOFOCUS;
         } else {
            Debug("Unknown _NET_WM_WINDOW_TYPE: %lu", state[x]);
         }
      }
      if(temp) {
         JXFree(temp);
      }
   }

   /* _NET_WM_USER_TIME_WINDOW */
   if(!GetWindowAtom(win, ATOM_NET_WM_USER_TIME_WINDOW, &utwin)) {
      utwin = win;
   }

   /* _NET_WM_USER_TIME */
   if(GetCardinalAtom(utwin, ATOM_NET_WM_USER_TIME, &card)) {
      if(card == 0) {
         result.status |= STAT_NOFOCUS;
      }
   }

   /* Use the default layer if the layer wasn't set explicitly. */
   if(result.layer == LAYER_NORMAL) {
      result.layer = result.defaultLayer;
   }

   /* Check if this window uses the shape extension. */
   if(CheckShape(win)) {
      result.status |= STAT_SHAPED;
   }

   return result;

}
예제 #9
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Add client specified struts to our list. */
void ReadClientStrut(ClientNode *np)
{

   BoundingBox box;
   int status;
   Atom actualType;
   int actualFormat;
   unsigned long count;
   unsigned long bytesLeft;
   unsigned char *value;
   long *lvalue;
   long leftWidth, rightWidth, topHeight, bottomHeight;
   char updated;

   updated = DoRemoveClientStrut(np);

   box.x = 0;
   box.y = 0;
   box.width = 0;
   box.height = 0;

   /* First try to read _NET_WM_STRUT_PARTIAL */
   /* Format is:
    *   left_width, right_width, top_width, bottom_width,
    *   left_start_y, left_end_y, right_start_y, right_end_y,
    *   top_start_x, top_end_x, bottom_start_x, bottom_end_x
    */
   status = JXGetWindowProperty(display, np->window,
                                atoms[ATOM_NET_WM_STRUT_PARTIAL],
                                0, 12, False, XA_CARDINAL, &actualType,
                                &actualFormat, &count, &bytesLeft, &value);
   if(status == Success && actualFormat != 0) {
      if(count == 12) {

         long leftStart, leftStop;
         long rightStart, rightStop;
         long topStart, topStop;
         long bottomStart, bottomStop;

         lvalue = (long*)value;
         leftWidth      = lvalue[0];
         rightWidth     = lvalue[1];
         topHeight      = lvalue[2];
         bottomHeight   = lvalue[3];
         leftStart      = lvalue[4];
         leftStop       = lvalue[5];
         rightStart     = lvalue[6];
         rightStop      = lvalue[7];
         topStart       = lvalue[8];
         topStop        = lvalue[9];
         bottomStart    = lvalue[10];
         bottomStop     = lvalue[11];

         if(leftWidth > 0) {
            box.x = 0;
            box.y = leftStart;
            box.height = leftStop - leftStart;
            box.width = leftWidth;
            InsertStrut(&box, np);
         }

         if(rightWidth > 0) {
            box.x = rootWidth - rightWidth;
            box.y = rightStart;
            box.height = rightStop - rightStart;
            box.width = rightWidth;
            InsertStrut(&box, np);
         }

         if(topHeight > 0) {
            box.x = topStart;
            box.y = 0;
            box.height = topHeight;
            box.width = topStop - topStart;
            InsertStrut(&box, np);
         }

         if(bottomHeight > 0) {
            box.x = bottomStart;
            box.y = rootHeight - bottomHeight;
            box.width = bottomStop - bottomStart;
            box.height = bottomHeight;
            InsertStrut(&box, np);
         }

      }
      JXFree(value);
      SetWorkarea();
      return;
   }

   /* Next try to read _NET_WM_STRUT */
   /* Format is: left_width, right_width, top_width, bottom_width */
   status = JXGetWindowProperty(display, np->window, atoms[ATOM_NET_WM_STRUT],
                                0, 4, False, XA_CARDINAL, &actualType,
                                &actualFormat, &count, &bytesLeft, &value);
   if(status == Success && actualFormat != 0) {
      if(count == 4) {
         lvalue = (long*)value;
         leftWidth = lvalue[0];
         rightWidth = lvalue[1];
         topHeight = lvalue[2];
         bottomHeight = lvalue[3];

         if(leftWidth > 0) {
            box.x = 0;
            box.y = 0;
            box.width = leftWidth;
            box.height = rootHeight;
            InsertStrut(&box, np);
         }

         if(rightWidth > 0) {
            box.x = rootWidth - rightWidth;
            box.y = 0;
            box.width = rightWidth;
            box.height = rootHeight;
            InsertStrut(&box, np);
         }

         if(topHeight > 0) {
            box.x = 0;
            box.y = 0;
            box.width = rootWidth;
            box.height = topHeight;
            InsertStrut(&box, np);
         }

         if(bottomHeight > 0) {
            box.x = 0;
            box.y = rootHeight - bottomHeight;
            box.width = rootWidth;
            box.height = bottomHeight;
            InsertStrut(&box, np);
         }

      }
      JXFree(value);
      SetWorkarea();
      return;
   }

   /* Struts were removed. */
   if(updated) {
      SetWorkarea();
   }

}