Subject: Re: Viewport position in functions

From: Will French <[email-masked]>
Date: Mon, 8 Mar 1999 12:59:10 -0500 (EST)

This compiles, but don't bother; just look over the code if you like.

/* FvwmStreets Module for Fvwm.
 * hacked from
 * FvwmBacker Module for Fvwm.
 *
 *  Copyright 1994,  Mike Finger ([email-masked] or
 *                               [email-masked])
 *
 * The author makes not guarantees or warantees, either express or
 * implied.  Feel free to use any contained here for any purpose, as long
 * and this and any other applicible copyrights are kept intact.

 * The functions in this source file that are based on part of the FvwmIdent
 * module for Fvwm are noted by a small copyright atop that function, all others
 * are copyrighted by Mike Finger.  For those functions modified/used, here is
 *  the full, origonal copyright:
 *
 * Copyright 1994, Robert Nation and Nobutaka Suzuki.
 * No guarantees or warantees or anything
 * are provided or implied in any way whatsoever. Use this program at your
 * own risk. Permission to use this program for any purpose is given,
 * as long as the copyright is kept intact. */

/* Modified to directly manipulate the X server if a solid color
 * background is requested. To use this, usr "-solid <color_name>"
 * as the command to be executed.
 *
 * A. Davison
 * Septmber 1994.
 */
#include "config.h"

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/time.h>

#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#include <unistd.h>
#include <ctype.h>

#if HAVE_SYS_BSDTYPES_H
#include <sys/bsdtypes.h> /* Saul */
#endif /* Saul */

#include <stdlib.h>

#include "../../fvwm/module.h"
#include "FvwmStreets.h"
#include "Mallocs.h"

FILE *log;
char *Module;
int Fvwm_fd[2];
int fd_width;
int latest_grid_id = 0;

#define LOGFILE "/tmp/FvwmStreets.log"

typedef struct Village_Command_Function

  {
  char *name;
  int (*V)(char *);
  } VillageCommandFunction;

typedef struct Village_Grid

  {
  /* TODO: replace linked list with realloc'd array */
  int d, d_cycle, d_max, d_min;
  int c, c_cycle, c_max, c_min;
  int x, x_cycle, x_max, x_min;
  int y, y_cycle, y_max, y_min;
  int id;
  char *name;
  struct Village_Grid *next;
  } VillageGrid;

VillageGrid *grid = NULL;
int cur_channel;
char command [1024];

#define MAXINT 2147483647

char *next_word (char *args)

  {
  /* TODO: Deprecated */
  while (*args && !isspace (*args)) args++;
  while (*args &&  isspace (*args)) args++;
  return args;
  }

/* Add a grid.  All grid parameters must be specified. */

int AddGridV (char *args)

  {
  VillageGrid *temp;
  char *word;

  temp = malloc (sizeof (VillageGrid));
  /* TODO: replace this crap with a scanf */
  word = next_word (args); /* ignore title */
  temp->x       = atoi (word); word = next_word (word);
  temp->x_min   = atoi (word); word = next_word (word);
  temp->x_max   = atoi (word); word = next_word (word);
  temp->x_cycle = atoi (word); word = next_word (word);
  temp->y       = atoi (word); word = next_word (word);
  temp->y_min   = atoi (word); word = next_word (word);
  temp->y_max   = atoi (word); word = next_word (word);
  temp->y_cycle = atoi (word); word = next_word (word);
  temp->d       = atoi (word); word = next_word (word);
  temp->d_min   = atoi (word); word = next_word (word);
  temp->d_max   = atoi (word); word = next_word (word);
  temp->d_cycle = atoi (word); word = next_word (word);
  temp->c       = atoi (word); word = next_word (word);
  temp->c_min   = atoi (word); word = next_word (word);
  temp->c_max   = atoi (word); word = next_word (word);
  temp->c_cycle = atoi (word);
  #if 0
    printf ("AddGridV: \"%s\"\n", args);
    printf ("AddGridV x: %d, %d, %d, %d\n",
     temp->x, temp->x_min, temp->x_max, temp->x_cycle);
    printf ("AddGridV y: %d, %d, %d, %d\n",
     temp->y, temp->y_min, temp->y_max, temp->y_cycle);
    printf ("AddGridV d: %d, %d, %d, %d\n",
     temp->d, temp->d_min, temp->d_max, temp->d_cycle);
    printf ("AddGridV l: %d, %d, %d, %d\n",
     temp->c, temp->c_min, temp->c_max, temp->c_cycle);
    #endif
  temp->next = grid;
  grid = temp;
  return 0;
  }

/* Delete a grid.  All grid parameters must be specified, but -1 may be
 given as a wildcard.  Grids will be deleted in the order they are found
 (TODO: this will be predictable with grid arrays), up to a maximum
 specified in an extra parameter, which can be -1 to delete all matching
 grids. */

int DeleteGridV (char *args)

  {
  VillageGrid **temp;
  VillageGrid *temp2;
  VillageGrid pat;
  char *word;
  int limit;

  /* TODO: replace this crap with a scanf */
  word = next_word (args); /* ignore title */
  pat.x       = atoi (word); word = next_word (word);
  pat.x_min   = atoi (word); word = next_word (word);
  pat.x_max   = atoi (word); word = next_word (word);
  pat.x_cycle = atoi (word); word = next_word (word);
  pat.y       = atoi (word); word = next_word (word);
  pat.y_min   = atoi (word); word = next_word (word);
  pat.y_max   = atoi (word); word = next_word (word);
  pat.y_cycle = atoi (word); word = next_word (word);
  pat.d       = atoi (word); word = next_word (word);
  pat.d_min   = atoi (word); word = next_word (word);
  pat.d_max   = atoi (word); word = next_word (word);
  pat.d_cycle = atoi (word); word = next_word (word);
  pat.c       = atoi (word); word = next_word (word);
  pat.c_min   = atoi (word); word = next_word (word);
  pat.c_max   = atoi (word); word = next_word (word);
  pat.c_cycle = atoi (word); word = next_word (word);
  limit = atoi (word);
  if (limit == -1) limit = MAXINT;
  #if 0
    TODO: logging
    #endif
  /* Traverse to find grid to delete */
  for (temp = &grid; limit && *temp; temp = &((*temp)->next))
    {
    /* TODO: replace overgrown if statement w/for loop */
    if ((pat.x       == -1 || pat.x       == (*temp)->x)
     && (pat.x_min   == -1 || pat.x_min   == (*temp)->x_min)
     && (pat.x_max   == -1 || pat.x_max   == (*temp)->x_max)
     && (pat.x_cycle == -1 || pat.x_cycle == (*temp)->x_cycle)
     && (pat.y       == -1 || pat.y       == (*temp)->y)
     && (pat.y_min   == -1 || pat.y_min   == (*temp)->y_min)
     && (pat.y_max   == -1 || pat.y_max   == (*temp)->y_max)
     && (pat.y_cycle == -1 || pat.y_cycle == (*temp)->y_cycle)
     && (pat.d       == -1 || pat.d       == (*temp)->d)
     && (pat.d_min   == -1 || pat.d_min   == (*temp)->d_min)
     && (pat.d_max   == -1 || pat.d_max   == (*temp)->d_max)
     && (pat.d_cycle == -1 || pat.d_cycle == (*temp)->d_cycle)
     && (pat.c       == -1 || pat.c       == (*temp)->c)
     && (pat.c_min   == -1 || pat.c_min   == (*temp)->c_min)
     && (pat.c_max   == -1 || pat.c_max   == (*temp)->c_max)
     && (pat.c_cycle == -1 || pat.c_cycle == (*temp)->c_cycle))
      {
      temp2 = *temp;
      *temp = (*temp)->next;
      free (temp2);
      limit--;
      }
    }
  return 0;
  }

int DeleteNearestLotV (char *args)

  {
  VillageGrid **temp;
  VillageGrid *temp2;
  VillageGrid cur;
  char *word;
  int least_distance = MAXINT;
  int temp_distance;

  /* TODO: replace this crap with a scanf */
  word = next_word (args); /* ignore title */
  cur.d = atoi (word); word = next_word (word);
  cur.x = atoi (word); word = next_word (word);
  cur.y = atoi (word);
  #if 0
    printf ("DeleteNearestLotV: \"%s\", %d, %d, %d\n", args, cur.d, cur.x, cur.y);
    #endif
  /* Traverse to find the closest lot on this desk */
  for (temp = &grid;; temp = &((*temp)->next))
    {
    if (temp == NULL)
      {
      if (least_distance < MAXINT)
        {
        temp2 = *temp;
        *temp = (*temp)->next;
        free (temp2);
        break;
        }
      else
        {
        /* No lots on this desk; do nothing */
        }
      break;
      }
    if (cur.d > (*temp)->d_min && cur.d < (*temp)->d_max
     && cur.c > (*temp)->c_min && cur.c < (*temp)->c_max
     && (cur.d - (*temp)->d) % (*temp)->d_cycle == 0
     && (cur.c - (*temp)->c) % (*temp)->c_cycle == 0)
      {
      temp_distance = ((*temp)->x - cur.x) * ((*temp)->x - cur.x)
                    + ((*temp)->y - cur.y) * ((*temp)->y - cur.y);
      if (temp_distance < least_distance) least_distance = temp_distance;
      }
    }
  return 0;
  }

int ExitV (char *args)

  {
  exit (0);
  }

int GotoNearestLotV (char *args)

  {
  VillageGrid *temp;
  VillageGrid new;
  VillageGrid old;
  char *word;
  int temp_distance;
  int least_distance = MAXINT;

  /* TODO: replace this crap with a scanf */
  word = next_word (args); /* ignore title */
  old.d = atoi (word); word = next_word (word);
  old.x = atoi (word); word = next_word (word);
  old.y = atoi (word);
  #if 0
    printf ("GotoNearestLotV: \"%s\", %d, %d, %d\n", args, old.d, old.x, old.y);
    #endif
  /* Traverse to find the closest lot on this desk */
  for (temp = grid;; temp = temp->next)
    {
    if (temp == NULL)
      {
      if (least_distance < MAXINT)
        {
        sprintf (command, "Scroll %dp %dp", new.x - old.x, new.y - old.y);
        SendFvwmPipe (command, 0);
        }
      else
        {
        /* No lots on this desk; do nothing */
        }
      break;
      }
    if (old.d > temp->d_min && old.d < temp->d_max
     && old.c > temp->c_min && old.c < temp->c_max
     && (old.d - temp->d) % temp->d_cycle == 0
     && (old.c - temp->c) % temp->c_cycle == 0)
      {
      temp_distance = (temp->x - old.x) * (temp->x - old.x)
                    + (temp->y - old.y) * (temp->y - old.y);
      if (temp_distance < least_distance)
        {
        new.x = temp->x;
        new.y = temp->y;
        least_distance = temp_distance;
        }
      }
    }
  return 0;
  }

int WhereIWasOnDeskV (char *args)

  {
  VillageGrid *temp;
  VillageGrid new;  
  VillageGrid old;
  char *word;
  static VillageGrid *switchaway = NULL;

  /* TODO: replace this crap with a scanf */
  word = next_word (args); /* ignore title */
  new.d = atoi (word); word = next_word (word);
  old.d = atoi (word); word = next_word (word);
  old.x = atoi (word); word = next_word (word);
  old.y = atoi (word);
  #if 0
    printf ("WhereIWasOnDeskV: \"%s\", %d, %d, %d, %d\n",
     args, new.d, old.d, old.x, old.y);
    #endif
  sprintf (command, "Desk 0 %d", new.d);
  SendFvwmPipe (command, 0);
  
  /* Traverse the list to see if we've been on the new desk before */
  for (temp = switchaway;; temp = temp->next)
    {
    if (temp == NULL)
      {
      /* We've never been here, so don't move the viewport */
      new.x = old.x;
      new.y = old.y;
      break;
      }
    if (temp->d == new.d)
      {
      /* We've been here before; return to last position on this desk */
      new.x = temp->x;
      new.y = temp->y;
      sprintf (command, "Scroll %dp %dp", new.x - old.x, new.y - old.y);
      SendFvwmPipe (command, 0);
      break;
      }
    }

  /* Traverse to see if there's already a record for the old desk */
  for (temp = switchaway;; temp = temp->next)
    {  
    if (temp == NULL)
      {   
      /* We never switched away from that desk before, so make a new record */
      temp = malloc (sizeof (VillageGrid));
      temp->x = old.x;
      temp->y = old.y;
      temp->d = old.d;
      temp->next = switchaway;
      switchaway = temp;
      break;
      }
    if (temp->d == old.d)
      {
      /* Use existing record */
      temp->x = old.x;
      temp->y = old.y;
      break;
      }
    }
  return 0;
  }

VillageCommandFunction subc [] =
  {
  {"AddGrid ",          AddGridV},
  {"DeleteGrid ",       DeleteGridV},
  {"DeleteNearestLot ", DeleteNearestLotV},
  {"Exit ",             ExitV},
  {"GotoNearestLot ",   GotoNearestLotV},
  {"WhereIWasOnDesk ",  WhereIWasOnDeskV},
  {"", 0},
  };

/******************************************************************************
  EndLessLoop -  Read until we get killed, blocking when can't read
  (c) 1994 Mike Finger
******************************************************************************/
void EndLessLoop()
{
fd_set readset;
struct timeval tv;

  while(1) {
    FD_ZERO(&readset);
    FD_SET(Fvwm_fd[1],&readset);
    tv.tv_sec=0;
    tv.tv_usec=0;

    if (!select(fd_width,SELECT_TYPE_ARG234 &readset,NULL,NULL,&tv)) {
      FD_ZERO(&readset);
      FD_SET(Fvwm_fd[1],&readset);
      select(fd_width,SELECT_TYPE_ARG234 &readset,NULL,NULL,NULL);
    }

    if (!FD_ISSET(Fvwm_fd[1],&readset)) continue;
    ReadFvwmPipe();
  }
}

/******************************************************************************
  ReadFvwmPipe - Read a single message from the pipe from Fvwm
    Originally Loop() from FvwmIdent:
      Copyright 1994, Robert Nation and Nobutaka Suzuki.
******************************************************************************/
void ReadFvwmPipe()
{
  int count;
  unsigned long header[HEADER_SIZE],*body;

  body = NULL;
  if((count = ReadFvwmPacket(Fvwm_fd[1],header,&body)) > 0)
    {  
      ProcessMessage(header[1],body);
      free(body);
    }
}

int subcommand (char *args)

  {
  int count;

  for (count = 0; (subc [count].name) [0]; count++)
    if (!strncmp (args, subc [count].name, strlen (subc [count].name)))
      return (subc [count].V (args));
  /* TODO: Unrecognized command */
  }

void ProcessMessage(unsigned long type,unsigned long *body)

  {
  if (type==M_STRING) subcommand ((char *)(&body[3]));
  }

/******************************************************************************
  SendFvwmPipe - Send a message back to fvwm
    Based on SendInfo() from FvwmIdent:
      Copyright 1994, Robert Nation and Nobutaka Suzuki.
******************************************************************************/
void SendFvwmPipe (char *message, unsigned long window)
{
int w;
char *hold,*temp,*temp_msg;
  hold=message;

  while(1) {
    temp=strchr(hold,',');
    if (temp!=NULL) {
      temp_msg=malloc(temp-hold+1);
      strncpy(temp_msg,hold,(temp-hold));
      temp_msg[(temp-hold)]='\0';
      hold=temp+1;
    } else temp_msg=hold;

    write(Fvwm_fd[0],&window, sizeof(unsigned long));

    w=strlen(temp_msg);
    write(Fvwm_fd[0],&w,sizeof(int));
    write(Fvwm_fd[0],temp_msg,w);

    /* keep going */
    w=1;
    write(Fvwm_fd[0],&w,sizeof(int));

    if(temp_msg!=hold) free(temp_msg);
    else break;
  }
}

void DeadPipe (int junk)

  {
  exit(1);
  }  

/******************************************************************************
  ParseConfig - Parse the configuration file fvwm to us to use
    Based on part of main() from FvwmIdent:
      Copyright 1994, Robert Nation and Nobutaka Suzuki.

******************************************************************************/
void ParseConfig () 

  {
/* STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB STUB
  char *line2;
  char *tline;

  line2 = malloc (strlen (Module) + strlen ("*Desk") + 1);
  sprintf (line2, "*%sDesk", Module);
  GetConfigLine (Fvwm_fd, &tline);
  while (tline != (char *)0)
    {
    if (strlen (tline) > 1)
      {
      if (strncasecmp (tline, line2, strlen (line2)) == 0)
        AddCommand (&tline [strlen (line2)]);
      }
    GetConfigLine (Fvwm_fd, &tline);
    }
*/
  }

int main (int argc, char **argv)

  {
  char *s;
  char *displayName = NULL;

  /* Save the program name for error messages and config parsing */
  s = strrchr (argv [0], '/');
  Module = s? s + 1: argv [0];
  if ((argc != 6) && (argc != 7))
    {
    fprintf (stderr, "%s Version %s should only be executed by fvwm!\n",
     Module, VERSION);
    exit(1);
    }  
  Fvwm_fd [0] = atoi (argv [1]);
  Fvwm_fd [1] = atoi (argv [2]);
  signal (SIGPIPE, DeadPipe);
  #ifdef LOGFILE
    log = fopen (LOGFILE, "a");
    fprintf (log, "Starting FvwmStreets\n");
    #endif
  cur_channel = 0;
  ParseConfig ();
  fd_width = GetFdWidth ();
  SetMessageMask (Fvwm_fd, M_STRING);
  EndLessLoop ();
  }
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Dominik Vogt <[email-masked]>
Date: Tue, 9 Mar 1999 02:04:32 +0100

On Mon, Mar 08, 1999 at 12:59:10PM -0500, Will French wrote:
>...

What is this module supposed to do?

Bye

Dominik

--
Dominik Vogt, [email-masked]
Reply-To: [email-masked]