home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume14 / xtoolplaces / part01 / get_geometry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-26  |  7.7 KB  |  238 lines

  1. /*Copyright (c) 1991 Xerox Corporation.  All Rights Reserved.
  2.  
  3.   Permission to use,  copy,  modify  and  distribute  without
  4.   charge this software, documentation, images, etc. is grant-
  5.   ed, provided that this copyright and the author's  name  is
  6.   retained.
  7.  
  8.   A fee may be charged for this program ONLY to recover costs
  9.   for distribution (i.e. media costs).  No profit can be made
  10.   on this program.
  11.  
  12.   The author assumes no responsibility for disasters (natural
  13.   or otherwise) as a consequence of use of this software.
  14.  
  15.   Adam Stein (stein.wbst129@xerox.com)
  16. */
  17.  
  18. #include <stdio.h>
  19. #include <X11/Xos.h>
  20. #include <X11/Xlib.h>
  21. #include <X11/Xutil.h>
  22.  
  23. extern char *program;
  24. extern Display *display;
  25.  
  26. /*This function will get the window and icon geometry and add them to the
  27.   command line.  For window geometry, it will add position and size.  For
  28.   icon geometry, it will only add position.  This function makes some
  29.   assumptions:
  30.  
  31.     1) windows use "-g" for window geometry (which is an abbreviation for
  32.        "-geom" or "-geometry")
  33.     2) normal applications use "-iconGeom" for icon geometry while
  34.        xterm uses "#"
  35.     3) normal applications take the geometry size in pixels while
  36.        xterm takes geometry size in characters
  37.  
  38.   Inputs:  command_line  - command line arguments
  39.        window        - ID of the window that we are going to check
  40.   Outputs: command_line  - command line arguments with geometry info added
  41.   Locals:  dummy     - dummary variable for return value we don't want
  42.        dummywin     - dummary variable for return value we don't want
  43.        geometry_args - geometry arguments to add to command line
  44.        height     - height of window (in pixels)
  45.        height_inc     - height increment
  46.        hints     - window size hints
  47.        icon_arg      - icon geometry argument
  48.        icon_hints    - icon position hints
  49.        icon_x     - X coordinate of icon
  50.        icon_y     - Y coordinate of icon
  51.        root         - root window of this window
  52.        status        - status of get call
  53.        supplied      - flag telling which size hints are available
  54.        tx         - translated X coordinate
  55.        ty         - translated Y coordinate
  56.        width     - width of window (in pixels)
  57.        width_inc     - width increment
  58.        x         - X coordinate of window
  59.        y         - Y coordinate of window
  60.   Globals: display       - interface info to X display
  61.        program     - name of currently executing program
  62.        NULL         - 0
  63.        PResizeInc    - flag bit to check if resize increment hint is avail.
  64. */
  65. char *get_geometry(window,command_line)
  66. register char *command_line;
  67. register Window window;
  68. {
  69.     register int width_inc,height_inc;
  70.     int x,y,tx,ty,icon_x,icon_y;
  71.     unsigned int width,height,dummy;
  72.     long supplied;
  73.     register char *icon_arg,geometry_args[100];
  74.     register Status status;
  75.     Window root,dummywin;
  76.     XSizeHints hints;
  77.     register XWMHints *icon_hints;
  78.     char *strip_geometry(),*strip_xterm_geometry(),*realloc(),*strdup();
  79.  
  80.     /*Get icon position*/
  81.     icon_x = icon_y = -1;
  82.     icon_hints = XGetWMHints(display,window);
  83.     if(icon_hints) {
  84.       icon_x = icon_hints->icon_x;
  85.       icon_y = icon_hints->icon_y;
  86.       XFree(hints);
  87.     }
  88.  
  89.     /*Get window geometry*/
  90.     status = XGetGeometry(display,window,&root,&x,&y,&width,&height,&dummy,
  91.                   &dummy);
  92.  
  93.     if(status) {
  94.       width_inc = 1;
  95.       height_inc = 1;
  96.       icon_arg = "-iconGeom ";
  97.  
  98.       /*Translate coordinate relative to root window*/
  99.       XTranslateCoordinates(display,window,root,0,0,&tx,&ty,&dummywin);
  100.  
  101.       /*Xterm is a special case (isn't it always?).  Unlike other programs,
  102.         xterm takes it's dimensions in characters, not pixels.  This
  103.         means we have to get it's increment size (i.e. font size) and
  104.         divide the size of the window (in pixels) by it's font size to
  105.         determine it's character size.  In addition, the argument to
  106.         specify icon position is different from normal*/
  107.       if(is_xterm(window) == 1) {
  108.         /*Get increment (i.e. font size)*/
  109.         status = XGetWMNormalHints(display,window,&hints,&supplied);
  110.         if(!status || !(supplied & PResizeInc)) return(command_line);
  111.  
  112.         width_inc = hints.width_inc;
  113.         height_inc = hints.height_inc;
  114.         icon_arg = "#";
  115.  
  116.         /*Strip old geometry arguments out of command line (if the
  117.           command line has any geometry arguments)*/
  118.         command_line = strip_xterm_geometry(command_line);
  119.       } else command_line = strip_geometry(command_line);
  120.  
  121.       /*Put geometry information together in a string.  Put in icon
  122.         information is there was icon information*/
  123.       if(icon_x == -1)
  124.         sprintf(geometry_args," -geom %dx%d+%d+%d",width/width_inc,height/height_inc,tx-x,ty-y);
  125.       else
  126.         sprintf(geometry_args," -geom %dx%d+%d+%d %s+%d+%d",width/width_inc,height/height_inc,tx-x,ty-y,icon_arg,icon_x,icon_y);
  127.  
  128.       /*Add window and icon geometry*/
  129.       if((command_line = realloc(command_line,strlen(command_line)+
  130.                      strlen(geometry_args)+1)) == NULL) {
  131.         perror(program);
  132.         exit(1);
  133.       }
  134.  
  135.       strcat(command_line,geometry_args);
  136.     }
  137.  
  138.     return(command_line);
  139. }
  140.  
  141. /*This will strip out the geometry arguments for a normal X application.
  142.  
  143.   Inputs:  command_line - command line arguments
  144.   Outputs: command_line - command line arguments without geometry info
  145.   Locals:  none
  146.   Globals: none
  147. */
  148. char *strip_geometry(command_line)
  149. register char *command_line;
  150. {
  151.     char *strip_arg();
  152.  
  153.     /*Strip window geometry*/
  154.     command_line = strip_arg(command_line,"-g");
  155.  
  156.     /*Strip icon geometry*/
  157.     command_line = strip_arg(command_line,"-iconGeom");
  158.  
  159.     return(command_line);
  160. }
  161.  
  162. /*This will strip out the geometry arguments for an xterm window.
  163.  
  164.   Inputs:  command_line - command line arguments
  165.   Outputs: command_line - command line arguments without geometry info
  166.   Locals:  none
  167.   Globals: none
  168. */
  169. char *strip_xterm_geometry(command_line)
  170. register char *command_line;
  171. {
  172.     char *strip_arg();
  173.  
  174.     /*Strip window geometry*/
  175.     command_line = strip_arg(command_line,"-g");
  176.  
  177.     /*Strip icon geometry*/
  178.     command_line = strip_arg(command_line,"#");
  179.  
  180.     return(command_line); 
  181. }
  182.  
  183. /*This function will strip an argument from a string.
  184.  
  185.   Inputs:  arg              - argument to strip
  186.        command_line     - command line arguments
  187.   Outputs: new_command_line - command line without 'arg'
  188.   Locals:  new_command_line - command line without 'arg'
  189.        numbytes        - number of bytes to copy from old command line
  190.        pointer1        - pointer to start of 'arg'
  191.        pointer2        - pointer to any arguments after 'arg'
  192.   Globals: program        - name of currently executing program
  193.        NULL            - 0
  194. */
  195. char *strip_arg(command_line,arg)
  196. register char *command_line,*arg;
  197. {
  198.     register int numbytes;
  199.     register char *pointer1,*pointer2,*new_command_line;
  200.     char *malloc(),*strstr();
  201.  
  202.     /*If the argument to strip isn't here, then just return the original
  203.       string*/
  204.     if((pointer1 = strstr(command_line,arg)) == NULL)
  205.       return(command_line);
  206.     else {
  207.            /*Find next character after argument*/
  208.            pointer2 = pointer1 + strlen(arg);
  209.            pointer2 = index(pointer2+1,' ');
  210.  
  211.            /*Find out how much space to allocate for command line minus
  212.          the argument to strip*/
  213.            /*Null out byte before argument to be able to use strlen()*/
  214.            *pointer1 = '\0';
  215.            numbytes = strlen(command_line);
  216.            /*Count bytes after argument (if there are any) plus 1 for NULL*/
  217.            /*Have to use pointer2+1 instead of doing ++pointer2 so we
  218.          can check if pointer2 = NULL (++pointer2 would have it = 1)*/
  219.            if(pointer2) numbytes += strlen(pointer2+1)+1;
  220.  
  221.            /*Allocate space and copy over all arguments except argument*/
  222.            if((new_command_line = malloc(numbytes)) == NULL) {
  223.          perror(program);
  224.          exit(1);
  225.            }
  226.            strcpy(new_command_line,command_line);
  227.            if(pointer2) strcat(new_command_line,pointer2+1);
  228.  
  229.            /*Restore command_line to it's original condition so we can
  230.          free up all the space it's using*/
  231.            *pointer1 = '-';
  232.            free(command_line);
  233.          }
  234.  
  235.     return(new_command_line);
  236. }
  237.  
  238.