foo-wm

(Archived) Experimental Zooming IPC-based WM
git clone http://milesalan.com/git/foo-wm
Log | Files | Refs | Mirror | README | LICENSE

commands.c (8922B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include "foo-wm.h"
      5 #include "commands.h"
      6 #include "lookup.h"
      7 #include "responses.h"
      8 #include "tree.h"
      9 #include "util.h"
     10 
     11 /* -----------------------------------------------------------------------------
     12  * Handeling Commands 
     13  * ---------------------------------------------------------------------------*/
     14 char * handleCommand(char * request) {
     15   fprintf(stderr, "Recv from Socket: %s", request);
     16 
     17   char *tokens[5]; char *token; int i = 0;
     18   while ((token = nextToken(&request))) {
     19     tokens[i] = token;
     20     i++;
     21   }
     22 
     23   char * response = "Some arbitrary response back to the socket\0";
     24 
     25   if (!strcmp(tokens[0], "dimensions"))
     26     dimensions(tokens[1], tokens[2]);
     27 
     28 
     29   if (!strcmp(tokens[0], "absorb"))
     30     absorb(tokens[1], tokens[2]);
     31   if (!strcmp(tokens[0], "containerize"))
     32     containerize();
     33   else if (!strcmp(tokens[0], "focus"))
     34     focus(tokens[1], tokens[2]);
     35   else if (!strcmp(tokens[0], "get"))
     36     response = get(tokens[1]);
     37   else if(!strcmp(tokens[0], "jump"))
     38     jump(tokens[1]);
     39   else if (!strcmp(tokens[0], "kill"))
     40     kill();
     41   else if (!strcmp(tokens[0], "layout"))
     42     layout(tokens[1]);
     43   else if (!strcmp(tokens[0], "mark"))
     44     mark(tokens[1]);
     45   else if (!strcmp(tokens[0], "set"))
     46     set(tokens[1], tokens[2]);
     47   else if (!strcmp(tokens[0], "shift"))
     48     shift(tokens[1], atoi(tokens[2]));
     49   else if (!strcmp(tokens[0], "swap"))
     50     swap(tokens[1], tokens[2]);
     51   else if (!strcmp(tokens[0], "zoom"))
     52     zoom(atoi(tokens[1]));
     53 
     54   XFlush(display);
     55   return response;
     56 }
     57 
     58 
     59 /* Extracts the next token from the tokenString */
     60 char * nextToken(char ** tokenString) {
     61   char *command;
     62   command = strsep(tokenString, " ");
     63   if (!command) return NULL;
     64 
     65   char *newLine = strchr(command, '\n');
     66   if (newLine) *newLine = '\0';
     67 
     68   return command;
     69 }
     70 
     71 
     72 /* -----------------------------------------------------------------------------
     73  * IPC Commands 
     74  * ---------------------------------------------------------------------------*/
     75 void dimensions(char * w, char * h) {
     76   int width  = atoi(w);
     77   int height = atoi(h);
     78   rootNode -> x = rootX = screenPaddingLeft;
     79   rootNode -> y = rootY = screenPaddingTop;
     80   rootNode -> width = rootWidth = width - screenPaddingLeft - screenPaddingRight;
     81   rootNode -> height = rootHeight = height - screenPaddingTop - screenPaddingBottom;
     82 }
     83 
     84 
     85 void absorb(char * argA, char * argB) {
     86   /* Absorbs the given node into the container of the focused node 
     87    * If the focused node is a client, containerize will be called then absorb
     88    * */
     89   if (!focusedNode) return;
     90 
     91   if (isClient(focusedNode)) containerize();
     92 
     93 }
     94 
     95 void containerize(void) {
     96   if (!focusedNode) return;
     97   if (focusedNode -> parent && focusedNode -> parent -> child && !isClient(focusedNode -> parent))
     98     if (isOnlyChild(focusedNode)) return;
     99 
    100   Node *insertNode, *newContainer = allocateNode(); int insertPosition;
    101   if (focusedNode -> parent && focusedNode -> parent -> focus == focusedNode)
    102     focusedNode -> parent -> focus = newContainer;
    103 
    104   if (focusedNode -> previous) {
    105     insertNode = focusedNode -> previous; insertPosition = NEXT;
    106   } else {
    107     insertNode = focusedNode -> next; insertPosition = PREVIOUS;
    108   }
    109 
    110   parentNode(focusedNode, newContainer);
    111   brotherNode(newContainer, insertNode, insertPosition);
    112   placeNode(viewNode, rootX, rootY, rootWidth, rootHeight);
    113 }
    114 
    115 
    116 void focus(char * argA, char * argB) {
    117   if (!focusedNode) return;
    118 
    119   int delta = atoi(argB);
    120   Node * newFocus = NULL;
    121 
    122   if (!strcmp(argA, "id")) {
    123     newFocus = getNodeById(delta);
    124 
    125   } else if (!strcmp(argA, "brother")) {
    126       newFocus = getBrother(focusedNode, delta);
    127   } else if (!strcmp(argA, "pc")) {
    128     while (delta != 0) {
    129       newFocus = (delta < 0) ? 
    130           focusedNode -> parent : focusOrChildOf(focusedNode);
    131       delta = delta + ( delta > 0 ? -1 : 1);  
    132       focusNode(newFocus, NULL, True, True);
    133     } return;
    134   }
    135 
    136   focusNode(newFocus, NULL, True, True);
    137 }
    138 
    139 char * get(char * property) {
    140   if (!strcmp(property, "tree"))
    141     return jsonTree(rootNode, 0);
    142   else if (!strcmp(property, "view"))
    143     return jsonTree(viewNode, 0);
    144   else if (!strcmp(property, "focus"))
    145     return jsonTree(focusedNode, 0);
    146   else if (!strcmp(property, "marks"))
    147     return jsonMarks();
    148 
    149   return "";
    150 }
    151 
    152 void kill(void) {
    153   fprintf(stderr, "Destroying Client %p\n", focusedNode);
    154 
    155   if (isClient(focusedNode)) {
    156 
    157     /* Save closest client and destroy node */
    158     Node *newFocus = getClosestClient(focusedNode);
    159 
    160     if (focusedNode == viewNode) viewNode = viewNode -> parent;
    161 
    162     if ( isOnlyChild(focusedNode) && focusedNode -> parent) {
    163       viewNode = focusedNode -> parent -> parent ?
    164         focusedNode -> parent -> parent : focusedNode -> parent;
    165     }
    166 
    167     Node *oldFocus = focusedNode;
    168     focusNode(newFocus, NULL, True, True);
    169     destroyNode(oldFocus);
    170 
    171     rePlaceNode(viewNode);
    172   }
    173 }
    174 
    175 void jump(char * markName) {
    176   fprintf(stderr, "Finding a node");
    177 
    178   Mark *n = NULL;
    179   for(n = markTail; n; n = n -> previous) {
    180     if (!strcmp(n -> name, markName)) {
    181       fprintf(stderr, "Going to focus mark %p", n -> node);
    182       unmapNode(viewNode);
    183       viewNode = n -> node;
    184       placeNode(n -> node, rootX, rootY, rootWidth, rootHeight);
    185       focusNode(n -> node, NULL, True, True);
    186       while (!isClient(focusedNode)) focus("pc", "1");
    187     }
    188   }
    189 }
    190 
    191 
    192 void layout(char * l) {
    193   fprintf(stderr, "Setting layout to: %s", l);
    194 
    195   Node *setNode = isClient(focusedNode) ?  focusedNode -> parent : focusedNode;
    196   int newLayout = 0;
    197 
    198   if      (!strcmp(l, "vertical"))   newLayout = VERTICAL;
    199   else if (!strcmp(l, "horizontal")) newLayout = HORIZONTAL;
    200   else if (!strcmp(l, "grid"))       newLayout = GRID;
    201   else if (!strcmp(l, "max"))        newLayout = MAX;
    202   else if (!strcmp(l, "float"))      newLayout = FLOAT;
    203 
    204 
    205   setNode -> layout = newLayout;
    206   rePlaceNode(setNode);
    207 }
    208 
    209 
    210 /* Adds the current viewNode as a mark */
    211 void mark(char * markName) {
    212 
    213   Mark *m = malloc(sizeof(Mark));
    214   m -> name = malloc(sizeof(markName));
    215   strcpy(m -> name, markName);
    216   m -> node     = viewNode;
    217   m -> previous = markTail;
    218   markTail = m;
    219 
    220   fprintf(stderr, "\nAdded the mark::  %s // %s\n", markName, markTail -> name);
    221 }
    222 
    223 void set(char * property, char * value) {
    224 
    225   if (!strcmp(property, "client_border_width")) {
    226     border = atoi(value);
    227   } else if (!strcmp(property, "container_padding")) {
    228     containerPadding = atoi(value);
    229   } else if (!strcmp(property, "client_padding")) {
    230     clientPadding = atoi(value);
    231   } else if (!strcmp(property, "screen_padding_top")) {
    232     screenPaddingTop = atoi(value);
    233   } else if (!strcmp(property, "screen_padding_left")) {
    234     screenPaddingLeft = atoi(value);
    235   } else if (!strcmp(property, "screen_padding_right")) {
    236     screenPaddingRight = atoi(value);
    237   } else if (!strcmp(property, "screen_padding_bottom")) {
    238     screenPaddingBottom = atoi(value);
    239   }
    240 
    241   recalculateRootDimensions();
    242   rePlaceNode(viewNode);
    243 
    244 }
    245 
    246 //Moves the current selection given amount
    247 void shift(char * argA, int delta) {
    248 
    249   int brotherSwitch = -1;
    250   if (!strcmp(argA, "brother")) brotherSwitch = 1;
    251   else if (!strcmp(argA, "pc")) brotherSwitch = 0;
    252   else return;
    253 
    254   while (delta != 0) {
    255     if (brotherSwitch) {
    256       Node *swapNode = getBrother(focusedNode, delta);
    257       swapNodes(focusedNode, swapNode);
    258       focusNode(focusedNode, NULL, True, True);
    259       delta = 0;
    260     } else {
    261       if (delta > 0) { return; } else {
    262         if (focusedNode -> parent && focusedNode -> parent -> parent) {
    263           Node *newParent = focusedNode -> parent -> parent;
    264           parentNode(focusedNode, newParent);
    265           rePlaceNode(newParent);
    266         } else { return; }
    267         delta++;
    268       }
    269     }
    270   }
    271 
    272 }
    273 
    274 /* Swaps two nodes in place based on node ids */
    275 Bool swap(char * argA , char * argB) {
    276   int idA     = atoi(argA),
    277       idB     = atoi(argB);
    278   Node *nodeA = getNodeById(idA),
    279        *nodeB = getNodeById(idB);
    280 
    281   if (!nodeA || !nodeB) {
    282     return False;
    283   } else {
    284     swapNodes(nodeA, nodeB);
    285     return True;
    286   }
    287 }
    288 
    289 
    290 /* Updates the viewNode approximating the current focusNode */
    291 void zoom(int level) {
    292   while (level < 0) {
    293     if (viewNode -> parent) { 
    294       unmapNode(viewNode);
    295       viewNode = viewNode -> parent;
    296     } else { return; }
    297     placeNode(viewNode, rootX, rootY, rootWidth, rootHeight);
    298     focusNode(focusedNode, NULL, True, True);
    299     level++;
    300   }
    301   while (level > 0) {
    302     if (focusedNode == viewNode) return;
    303     Node *n = focusedNode;
    304     while (n && n -> parent != viewNode) n = n -> parent;
    305     if (!n) return;
    306 
    307     unmapNode(viewNode);
    308     viewNode = n;
    309     //TODO:: Need placeNode to be aware of focusnnode (in)active colors....
    310     
    311     fprintf(stderr, "placeing yo");
    312     placeNode(viewNode, rootX, rootY, rootWidth, rootHeight);
    313     if (focusedNode == viewNode && !isClient(focusedNode)) {
    314       focusNode(focusOrChildOf(focusedNode), NULL, True, True);
    315     }
    316     level--;
    317   }
    318 }