[comp.sources.x] v04i024: xcursor, Patch2

argv@island.uu.net (Dan Heller) (06/12/89)

Submitted-by: thor@stout.UCAR.EDU (Rich Neitzel)
Posting-number: Volume 4, Issue 24
Patch-To: Volume 4, Issues 2,8
Archive-name: xcursor/patch2

[ These patches applied to the orignally posted sources plus the first posted
  patch to xcursor from this newsgroup.  This patch is the 2nd official patch
  to this posting.  The patch sent to me consisted of three files.  I combined
  them into one file.  You can simply pipe this article thru patch or save it
  to a file and run patch using this file.
  Note the Patch-To: line above. --argv ]

Excerpt from Rich's original note
-------
This set of patches addes support to xcursor for setting the
background and/or foreground color of the cursor and for specifying
bitmapped cursors.

*** xcursor.c2	Thu Jun  8 11:07:45 1989
--- xcursor.c	Thu Jun  8 10:55:50 1989
***************
*** 8,13 ****
--- 8,14 ----
  1.0,12may89,rekn      Written.
  2.0,25may89,rekn      Added support for named windows and selection by 
                        pointer.
+ 3.0,8june89,rekn      Added color and bitmap support.
  
    This is a quick program that reads the header file defining cursors
    and lets one change the cursor for a specified window. Window
***************
*** 24,29 ****
--- 25,31 ----
  "           ====> pointer in that window.",
  0};
  
+ 
  main(argc,argv)
  int argc;
  char **argv;
***************
*** 40,46 ****
  
      opterr = 0;			/* No error msgs from getopt */
  
!     while ((opt = getopt(argc,argv,"lvd:n:i:r")) != -1)
        {
  	  switch(opt)
  	    {
--- 42,48 ----
  
      opterr = 0;			/* No error msgs from getopt */
  
!     while ((opt = getopt(argc,argv,"lvb:f:d:n:i:rp")) != -1)
        {
  	  switch(opt)
  	    {
***************
*** 52,57 ****
--- 54,71 ----
  		print_vers();
  		break;
  
+ 	      case 'f':		/* Foreground color */
+ 		fcolor = argv[optind++];
+ 		if (*fcolor == '-')
+ 		  local_help();
+ 		break;
+ 
+ 	      case 'b':		/* Background color */
+ 		bcolor = argv[optind++];
+ 		if (*bcolor == '-')
+ 		  local_help();
+ 		break;
+ 
  	      case 'd':		/* Get display name */
  		disp_str = argv[optind++];
  		if (*disp_str == '-') /* Check to see if user skipped */
***************
*** 77,82 ****
--- 91,103 ----
  		uflag++;
  		break;
  
+ 	      case 'p':		/* Change to named bitmap */
+ 		source = argv[optind++];
+ 		mask = argv[optind++];
+ 		if (*source == '-' || *mask == '-')
+ 		  local_help();
+ 		break;
+ 
  	      case '?':		/* Ooops! */
  		fprintf(stderr,"xcursor - bad option\n\n");
  		local_help();
***************
*** 83,95 ****
  		break;
  	    }
        }
!     
      if ((display = XOpenDisplay(disp_str)) == NULL)
        {
  	  fprintf(stderr,"Cannot open display %s\n",disp_str);
  	  exit(1);
        }
!    
      if (name_str != NULL)
        {
  	  if ((window = window_by_name(DefaultRootWindow(display),name_str)) 
--- 104,118 ----
  		break;
  	    }
        }
! 
      if ((display = XOpenDisplay(disp_str)) == NULL)
        {
  	  fprintf(stderr,"Cannot open display %s\n",disp_str);
  	  exit(1);
        }
! 
!     screen = DefaultScreen(display);
! 
      if (name_str != NULL)
        {
  	  if ((window = window_by_name(DefaultRootWindow(display),name_str)) 
***************
*** 116,122 ****
      else
        find_cursor = default_cursor;
  
!     work();
  
      exit(0);
  }
--- 139,148 ----
      else
        find_cursor = default_cursor;
  
!     if (source)
!       pixCursor();
!     else
!       work();
  
      exit(0);
  }
***************
*** 132,138 ****
  "xcursor is a small tool to set the cursor for a specified window.",
  "The syntax is:",
  "",
! "    xcursor [-l] [-v] [-r] [-display display][-name name] [-id id] [cursor]",
  "",
  "the -l flag lists all known cursors; the -name option sets the cursor for",
  "the named window; the -id option sets the cursor for the window with the",
--- 158,165 ----
  "xcursor is a small tool to set the cursor for a specified window.",
  "The syntax is:",
  "",
! "    xcursor [-l] [-v] [-r] [-display display][-name name] [-id id]",
! "            [-fg color] [-bg color] [-p cursorfile maskfile] [cursor]",
  "",
  "the -l flag lists all known cursors; the -name option sets the cursor for",
  "the named window; the -id option sets the cursor for the window with the",
***************
*** 141,147 ****
  "number of xcursor. The -r option causes the root window to be effected.",
  "Cursor is the name (XC_ prefix optional) of the cursor you want (defaults",
  "to whatever the local builder desired). If none of -r, -id or -name are",
! "used, xcursor prompts you to use the pointer to select a window.",
  0};
  
  void local_help()
--- 168,178 ----
  "number of xcursor. The -r option causes the root window to be effected.",
  "Cursor is the name (XC_ prefix optional) of the cursor you want (defaults",
  "to whatever the local builder desired). If none of -r, -id or -name are",
! "used, xcursor prompts you to use the pointer to select a window. Colors may",
! "be selected by using -bg and -fg. The defaults are a white background and",
! "a black foreground. The cursor may be specified as a pixmap using -p. This",
! "takes two file names, one for the cursor and one for the mask. The hot spot",
! "is taken from the cursor file.",
  0};
  
  void local_help()
***************
*** 184,190 ****
  		      if (lflg)
  			{
  			    flag++;
! 			    printf("%s\n",start);
  			}
  		      else if (!strcmp(start, find_cursor) ||
  			       !strcmp(&start[3], find_cursor))
--- 215,222 ----
  		      if (lflg)
  			{
  			    flag++;
! 			    if (strcmp(start,"XC_num_glyphs"))
! 			      printf("%s\n",start);
  			}
  		      else if (!strcmp(start, find_cursor) ||
  			       !strcmp(&start[3], find_cursor))
***************
*** 191,197 ****
  			{
  			    curs = XCreateFontCursor(display,cursor);
  			    XDefineCursor(display,window,curs);
- 			    XCloseDisplay(display);
  			    flag++;
  			    break;
  			}
--- 223,228 ----
***************
*** 200,209 ****
--- 231,341 ----
        }
      if (!flag)
        fprintf(stderr,"xcursor - Cannot find %s\n",find_cursor);
+     else if (bcolor || fcolor)	/* Only if needed */
+       {
+ 	  setCursorColor();
+ 	  XRecolorCursor(display,curs,&fg,&bg);
+       }
  
+     XCloseDisplay(display);
      fclose(fp);
  }
  
+ void setCursorColor()
+ {
+     Colormap cmp;
+ 
+     if (!bcolor)
+       bcolor = "white";
+     
+     if (!fcolor)
+       fcolor = "black";
+ 
+     cmp = DefaultColormap(display,screen);
+ 
+     if (!XParseColor(display,cmp,bcolor,&bg))
+       {
+ 	  fprintf(stderr,"Cannot locate color %s in color database.\n",bcolor);
+ 	  return;
+       }
+ 
+     if (!XParseColor(display,cmp,fcolor,&fg))
+       {
+ 	  fprintf("stderr,Cannot locate color %s in color database.\n",fcolor);
+ 	  return;
+       }
+ }
+ 
+ void pixCursor()
+ {
+     Pixmap *psource;		/* Cursor pixmap */
+     Pixmap *pmask;		/* Mask pixmap */
+     int width;			/* Guess */
+     int height;			/*   " */
+     int xhot;			/* X location of hot spot */
+     int yhot;			/* Y location of hot spot */
+     Cursor cursor;		/* Our new cursor */
+     int status;			/* Error return */
+     int dummy;			/* Junk holder */
+     Colormap cmp;		/* Ibid. */
+ 
+ /* Read the bitmap files and check for errors*/
+     status = XReadBitmapFile(display,window,source,&width,&height,
+ 			    &psource,&xhot,&yhot);
+ 
+     switch(status)
+       {
+ 	case BitmapOpenFailed:
+ 	  fprintf(stderr,"Sorry, but cannot open file %s\n",source);
+ 	  return;
+ 	  break;
+ 
+ 	case BitmapFileInvalid:
+ 	  fprintf(stderr,"Sorry, but file %s is not is bitmap format\n",
+ 		  source);
+ 	  return;
+ 	  break;
+ 
+ 	case BitmapNoMemory:
+ 	  fprintf(stderr,"Sorry, but the server ran out of memory\n");
+ 	  return;
+ 	  break;
+       }
+ 
+     status = XReadBitmapFile(display,window,mask,&width,&height,
+ 			    &pmask,&dummy,&dummy);
+ 
+     switch(status)
+       {
+ 	case BitmapOpenFailed:
+ 	  fprintf(stderr,"Sorry, but cannot open file %s\n",mask);
+ 	  return;
+ 	  break;
+ 
+ 	case BitmapFileInvalid:
+ 	  fprintf(stderr,"Sorry, but file %s is not is bitmap format\n",
+ 		  mask);
+ 	  return;
+ 	  break;
+ 
+ 	case BitmapNoMemory:
+ 	  fprintf(stderr,"Sorry, but the server ran out of memory\n");
+ 	  return;
+ 	  break;
+       }
+ 
+     setCursorColor();		/* Need some color */
+ 
+     if ((cursor = XCreatePixmapCursor(display,psource,pmask,&fg,&bg,xhot,yhot))
+ 	== 0)
+       {
+ 	  fprintf(stderr,"Sorry, cannot create your cursor\n");
+ 	  return;
+       }
+ 
+     XDefineCursor(display,window,cursor);
+ }
+ 
  /* Code for the next two routines was lifted from dsimple.c in 
     xwininfo */
  
***************
*** 244,250 ****
      XEvent event;
      Window target_win = None;
      int buttons = 0;
-     int screen = DefaultScreen(display);
      
      /* Make the target cursor */
      cursor = XCreateFontCursor(display, XC_crosshair);
--- 376,381 ----
*** xcursor.h2	Thu Jun  8 11:16:11 1989
--- xcursor.h	Thu Jun  8 11:13:27 1989
***************
*** 8,13 ****
--- 8,14 ----
  1.0,12may89,rekn      Written.
  2.0,25may89,rekn      Added support for named windows and selection by 
                        pointer.
+ 3.0,8june89,rekn      Added color and bitmap support.
  */
  #ifndef INCxcursor
  #define INCxcursor
***************
*** 15,30 ****
  #include <stdio.h>
  #include <string.h>
  #include <X11/Xlib.h>
  #include <X11/cursorfont.h>
  
  Display *display;
  Window window;
  
  char cursor_file[] = "/usr/include/X11/cursorfont.h";
  
  char default_cursor[] = "XC_gumby";
  
! char version_number[] = "2.0";
  
  char *find_cursor;
  
--- 16,34 ----
  #include <stdio.h>
  #include <string.h>
  #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+ #include <X11/Xos.h>
  #include <X11/cursorfont.h>
  
  Display *display;
  Window window;
+ int screen;
  
  char cursor_file[] = "/usr/include/X11/cursorfont.h";
  
  char default_cursor[] = "XC_gumby";
  
! char version_number[] = "3.0";
  
  char *find_cursor;
  
***************
*** 32,40 ****
  
  int wflg = 0;
  
  #define BUFSIZE 100
  
! void print_vers(), local_help(), work();
  Window window_by_name(), point_to_window();
  
  #endif
--- 36,53 ----
  
  int wflg = 0;
  
+ char *bcolor = 0;
+ char *fcolor = 0;
+ 
+ char *source = 0;
+ char *mask = 0;
+ 
+ XColor bg;
+ XColor fg;
+ 
  #define BUFSIZE 100
  
! void print_vers(), local_help(), work(), setCursorColor(), pixCursor();
  Window window_by_name(), point_to_window();
  
  #endif
*** xcursor.l2	Thu Jun  8 11:10:18 1989
--- xcursor.l	Thu Jun  8 11:03:46 1989
***************
*** 2,18 ****
  .SH NAME
  xcursor \- set cursor in an X window
  .SH SYNOPSIS
! xcursor [-v][-l][-id id] [-name name] [-display display][-r] [cursor]
  .SH DESCRIPTION
  .I Xcursor
  allows the cursor for a window to be set to one of the standard X
! cursors or lists the available cursors. If no window id or name is specified,
  .I xcursor
  will prompt the user to selct a window with the pointer. If no cursor
  name is given, the default cursor selected at the time
  .I xcursor 
  was built will be used. Cursors are extracted from the file
! cursorfont.h.
  .SH OPTIONS
  .nf
  \-l 		This causes a list of the standard X cursors to be
--- 2,22 ----
  .SH NAME
  xcursor \- set cursor in an X window
  .SH SYNOPSIS
! .nf
! xcursor [-v][-l][-id id] [-name name] [-display display] [-r] [-fg color]
!         [-bg color] [-p cursor_file mask_file] [cursor]
! .fi
  .SH DESCRIPTION
  .I Xcursor
  allows the cursor for a window to be set to one of the standard X
! cursors, a user supplied bitmap or lists the available cursors. If no
! window id or name is specified,
  .I xcursor
  will prompt the user to selct a window with the pointer. If no cursor
  name is given, the default cursor selected at the time
  .I xcursor 
  was built will be used. Cursors are extracted from the file
! cursorfont.h. Both foreground and background colors may be specified.
  .SH OPTIONS
  .nf
  \-l 		This causes a list of the standard X cursors to be
***************
*** 29,41 ****
  \-name          Denotes that named window should be operated on.
  
  \-r             Selects the root window.
  .fi
  .SH FILES
  Requires read access to the cursorfonts.h file (located in the X
  includes path).
! .SH BUGS
! Not all windows will allow their cursor to be reset in this fashion.
! Does not understand user defined cursors.
  .SH AUTHOR
  .nf
  Richard Neitzel
--- 33,57 ----
  \-name          Denotes that named window should be operated on.
  
  \-r             Selects the root window.
+ 
+ \-fg            Selects the cursor's foreground color. The 
+                 default is black.
+ 
+ \-bg            Selects the cursor's background color. The 
+                 default is white.
+ 
+ \-p             The next two items are the names of the cursor bitmap
+                 file and the mask bitmap file. The hot spot for the
+                 cursor is taken from the cursor file.
  .fi
  .SH FILES
  Requires read access to the cursorfonts.h file (located in the X
  includes path).
! .SH BUGS AND WARNINGS
! Not all windows will allow their cursor to be reset in this fashion
! and some will only function with one of the methods. Since the hot
! spot location is taken from the cursor bitmap file, cursors may not
! "point" as exspected.
  .SH AUTHOR
  .nf
  Richard Neitzel