diff -uNr GMT4.4.0/src/GMT.1 GMT4.4.0_barb/src/GMT.1
--- GMT4.4.0/src/GMT.1	2009-02-17 16:18:45.000000000 +0900
+++ GMT4.4.0_barb/src/GMT.1	2009-02-24 08:26:26.000000000 +0900
@@ -53,6 +53,8 @@
 .br
 \fBgrd2xyz\fP		Conversion from 2-D grid file to table data
 .br
+\fBgrdbarb\fP		Plot wind barbs from grdfiles
+.br
 \fBgrdblend\fP		Blend several partially over-lapping grid files onto one grid
 .br
 \fBgrdclip\fP		Limit the z-range in gridded data
diff -uNr GMT4.4.0/src/GMT.in GMT4.4.0_barb/src/GMT.in
--- GMT4.4.0/src/GMT.in	2009-02-13 10:30:36.000000000 +0900
+++ GMT4.4.0_barb/src/GMT.in	2009-02-24 08:26:26.000000000 +0900
@@ -76,6 +76,7 @@
 	gmtselect	Extract data subsets based on spatial criteria
 	grd2cpt		Make color palette table from grid files
 	grd2xyz		Conversion from 2-D grid file to table data
+	grdbarb		Plot wind barbs from grdfiles
 	grdblend	Blend several partially over-lapping grid files onto one grid
 	grdclip		Limit the z-range in gridded data
 	grdcontour	Contouring of 2-D gridded data
diff -uNr GMT4.4.0/src/gmt_init.c GMT4.4.0_barb/src/gmt_init.c
--- GMT4.4.0/src/gmt_init.c	2009-02-06 07:12:12.000000000 +0900
+++ GMT4.4.0_barb/src/gmt_init.c	2009-02-24 08:26:26.000000000 +0900
@@ -4919,6 +4919,7 @@
 	char symbol_type, txt_a[GMT_LONG_TEXT], txt_b[GMT_LONG_TEXT], txt_c[GMT_LONG_TEXT], text_cp[GMT_LONG_TEXT], *c;
 	static char *allowed_symbols[2] = {"-+aAbBCcDdeEfGgHhIijJNnpqrSsTtVvwWxy", "-+aAbCcDdeEfGgHhIijJNnoOpqrSsTtuUVvwWxy"};
 	static char *bar_symbols[2] = {"bB", "-bBoOuU"};
+	static char *barb_symbols[2] = {"wW", "wW"};
 
 	p->n_required = p->convert_angles = 0;
 	p->user_unit = p->shrink = p->read_vector = p->base_set = FALSE;
@@ -4989,6 +4990,12 @@
 		if (p->size_y == 0.0) p->size_y = p->given_size_y;
 		p->equal_area = FALSE;
 	}
+	else if (strchr (barb_symbols[mode], (int) text[0]) && (text[1] == 'b' || text[1] == 'B')){
+		n = sscanf (text, "%c", &symbol_type);
+		if (p->size_x == 0.0) p->size_x = p->given_size_x;
+		if (p->size_y == 0.0) p->size_y = p->given_size_y;
+		p->equal_area = FALSE;
+	}
 	else if (strchr (bar_symbols[mode], (int) text[0])) {	/* Bar, column, cube with size */
 
 		/* Bar:		-Sb|B<size_x|y>[c|i|m|p|u][b<base>]				*/
@@ -5337,8 +5344,23 @@
 		case 'W':
 			p->convert_angles = 1;
 		case 'w':
-			p->symbol = GMT_SYMBOL_PIE;
-			p->n_required = 2;
+                       switch (text[1]) {
+                        case 'B': /* wind barb */
+                        case 'b':
+                                p->symbol = GMT_SYMBOL_BARB;
+                                if (text[2]) {
+                                        sscanf (&text[2], "%[^/]/%[^/]/%lf/%lf", txt_a, txt_b, &p->b_angle, &p->b_scale);
+                                        p->b_width  = GMT_convert_units (txt_a, GMT_INCH);
+                                        p->b_length = GMT_convert_units (txt_b, GMT_INCH);
+                                }
+                                p->read_barb = TRUE;
+                                p->n_required = 2;
+                                check = FALSE;
+                                break;
+                        default:  /* wedge */
+                                p->symbol = GMT_SYMBOL_PIE;
+                                p->n_required = 2;
+                        }
 			break;
 		case 'r':
 			p->symbol = GMT_SYMBOL_RECT;
diff -uNr GMT4.4.0/src/gmt_plot.c GMT4.4.0_barb/src/gmt_plot.c
--- GMT4.4.0/src/gmt_plot.c	2009-02-09 20:00:03.000000000 +0900
+++ GMT4.4.0_barb/src/gmt_plot.c	2009-02-24 08:26:26.000000000 +0900
@@ -2754,6 +2754,100 @@
 		ps_textbox (x, y, size, label, angle, just, outline, dx, dy, rgb);
 }
 
+void GMT_draw_barb (double x0, double y0, double z0, double theta, double spd, double barbwidth, double barblength, double barbangle, double barbscale, struct GMT_PEN *pen, struct GMT_FILL *fill, BOOLEAN outline)
+{
+       double w1, dx, dy, y;
+       double s, c;
+       int i, ispd, n, n_pennant, n_feather;
+       struct GMT_CUSTOM_SYMBOL symbol;
+       struct GMT_CUSTOM_SYMBOL_ITEM bs[256];
+
+       if (spd == 0.) return;
+
+       /* make struct of custom symbol for barbs */
+       strcpy (symbol.name, "barb");
+       symbol.first = bs;
+
+       /* spine of barb */
+       ispd = (int) (spd / barbscale * 2. + 0.0001);
+       n_pennant =  ispd / 10;
+       n_feather = (ispd % 10) / 2;
+       if (ispd % 2) n_feather ++;
+       w1 = 1./6.;
+       y = w1 * (n_pennant + n_feather + 1);
+       if (y < 1.) y = 1.;
+
+       bs[0].x = 0.;
+       bs[0].y = 0.;
+       bs[0].action = GMT_ACTION_MOVE;
+       bs[0].next   = bs+1;
+
+       bs[1].x = 0.;
+       bs[1].y = y;
+       bs[1].action = GMT_ACTION_DRAW;
+       bs[1].next   = bs+2;
+
+       /* pennants and feathers */
+       n = 2;
+       if (ispd == 1) y -= w1;  /* space for 5kt barb */
+
+       sincos (barbangle * D2R, &s, &c);
+       dx =  s * barbwidth / barblength;
+       dy = -c * barbwidth / barblength;
+
+       while (ispd > 0) {
+               bs[n].x = 0.;
+               bs[n].y = y;
+               bs[n].action = GMT_ACTION_MOVE;
+               bs[n].next   = bs+n+1;
+               n ++;
+
+               /* pennants */
+               if (ispd >= 10) {
+                       bs[n].x = dx;
+                       bs[n].y = y - w1 + dy;
+                       bs[n].action = GMT_ACTION_DRAW;
+                       bs[n].next   = bs+n+1;
+                       n ++;
+
+                       y -= w1;
+                       bs[n].x = 0;
+                       bs[n].y = y;
+
+                       ispd -= 10;
+                       if (ispd < 10) y -= w1; /* space between pennant and feather */
+               } else if (ispd >= 2) {
+                       bs[n].x =     dx;
+                       bs[n].y = y + dy;
+                       ispd -= 2;
+                       y -= w1;
+               } else {        /* 5kt feather */
+                       bs[n].x =     dx/2.;
+                       bs[n].y = y + dy/2.;
+                       ispd --;
+               }
+               bs[n].action = GMT_ACTION_DRAW;
+               bs[n].next   = bs+n+1;
+               n ++;
+       }
+
+       /* rotate */
+       sincos (theta * D2R, &s, &c);
+
+       for(i = 0; i < n; i ++) {
+                     y =  c * bs[i].x - s * bs[i].y;
+               bs[i].x = -s * bs[i].x - c * bs[i].y;
+               bs[i].y = y;
+
+               bs[i].fill = NULL;
+               bs[i].pen  = NULL;
+       }
+       bs[n-1].next = NULL;
+
+       GMT_draw_custom_symbol (x0, y0, z0, barblength, &symbol, pen, fill, outline);
+}
+
+
 void GMT_draw_map_scale (struct GMT_MAP_SCALE *ms)
 {
 	int i, j, jj, k, *rgb, n_a_ticks[9], n_f_ticks[9], unit;
diff -uNr GMT4.4.0/src/gmt_plot.h GMT4.4.0_barb/src/gmt_plot.h
--- GMT4.4.0/src/gmt_plot.h	2009-01-23 20:00:03.000000000 +0900
+++ GMT4.4.0_barb/src/gmt_plot.h	2009-02-24 08:26:26.000000000 +0900
@@ -52,6 +52,7 @@
 #define GMT_SYMBOL_CUSTOM	25
 #define GMT_SYMBOL_ROTATERECT	26
 #define GMT_SYMBOL_PLUS		27
+#define GMT_SYMBOL_BARB		28
 
 #define GMT_SYMBOL_FRONT	-100
 #define GMT_SYMBOL_QUOTED_LINE	-200
@@ -105,12 +106,17 @@
 
 	int convert_angles;	/* If 2, convert azimuth to angle on map, 1 special case for -JX, 0 plain case */
 	BOOLEAN read_vector;	/* if TRUE must read vector attributes */
+	BOOLEAN read_barb;	/* if TRUE must read wind barb attributes */
 	BOOLEAN shrink;		/* If TRUE, shrink vector attributes for small lengths */
 	double v_norm;		/* shrink when lengths are smaller than this */
 	double v_shrink;	/* Required scale factor */
 	double v_width;		/* Width of vector stem in inches */
 	double h_length;	/* Length of vector head in inches */
 	double h_width;		/* Width of vector head in inches */
+        double b_width;         /* Width of wind barb in inches */
+        double b_length;        /* Length of wind barb in inches */
+        double b_angle;         /* Angle of wind barb in degree */
+        double b_scale;         /* Scale of each wind barbs */
 	int v_just;		/* How to justify vector: head point given (3), head (2), center(1), tail (0 - Default) */
 	BOOLEAN v_double_heads;		/* If TRUE, Add 8 (|= 8) to outline to specify double-headed vector (FALSE is single-headed) */
 
@@ -166,5 +172,6 @@
 EXTERN_MSC void GMT_pie (double x, double y, double z, double size[], struct GMT_FILL *fill, BOOLEAN outline);
 EXTERN_MSC void GMT_rotrect (double x, double y, double z, double size[], struct GMT_FILL *fill, BOOLEAN outline);
 EXTERN_MSC void GMT_vector (double x0, double y0, double x1, double y1, double z0, double tailwidth, double headlength, double headwidth, double shape, struct GMT_FILL *fill, BOOLEAN outline);
+EXTERN_MSC void GMT_draw_barb (double x0, double y0, double z0, double theta, double spd, double barbwidth, double barblength, double barbangle, double barbscale, struct GMT_PEN *pen, struct GMT_FILL *fill, BOOLEAN outline);
 EXTERN_MSC char *GMT_export2proj4(char *pStrOut);
 #endif /* _GMT_PLOT_H */
diff -uNr GMT4.4.0/src/grdbarb.1 GMT4.4.0_barb/src/grdbarb.1
--- GMT4.4.0/src/grdbarb.1	1970-01-01 09:00:00.000000000 +0900
+++ GMT4.4.0_barb/src/grdbarb.1	2009-02-24 08:26:26.000000000 +0900
@@ -0,0 +1,239 @@
+.TH GRDBARB l "11 Dec 2007" "GMT4.2.1" "Generic Mapping Tools"
+.SH NAME
+grdbarb \- Plot wind barbs from grid files
+.SH SYNOPSIS
+\fBgrdbarb\fP \fIcompx.grd\fP \fIcompy.grd\fP \fB\-J\fP\fIparameters\fP [ \fB\-A\fP ]
+[ \fB\-B\fP\fItickinfo\fP ] [ \fB\-C\fP\fIcptfile\fP ] [ \fB\-E\fP ]
+[ \fB\-G\fP\fIfill\fP] [ \fB\-I\fP\fIx_inc\fP[\fBm|c\fP][/\fIy_inc\fP[\fBm|c\fP]] ] [ \fB\-K\fP ] [ \fB\-N\fP ] [ \fB\-O\fP ] [ \fB\-P\fP ]
+[ \fB\-Q\fP\fIparameters\fP ] [ \fB\-R\fP\fIwest/east/south/north\fP[\fBr\fP] ] [ \fB\-S\fP[\fBl\fP]\fIscale\fP ]
+[ \fB\-T\fP ] [ \fB\-U\fP[\fI/dx/dy/\fP][\fIlabel\fP] ] [ \fB\-V\fP ] [ \fB\-W\fP\fIcontourpen\fP ] [ \fB\-X\fP\fIx-shift\fP ]
+[ \fB\-Y\fP\fIy-shift\fP ] [ \fB\-Z\fP ] [ \fB\-c\fP\fIcopies\fP ]
+.SH DESCRIPTION
+\fBgrdbarb\fP reads two 2-D gridded files which represents the x- and y-components of a vector field and
+produces a wind field plot by
+drawing barbs with orientation and length according to the information in the files. Alternatively,
+polar coordinate components may be used (r, theta).
+\fBgrdbarb\fP is basically a short-hand for using 2 calls to \fBgrd2xyz\fP and pasting the output through
+\fBpsxy \-SU\fP.
+.TP
+\fIcompx.grd\fP
+Contains the x-component of the vector field.
+.TP
+\fIcompy.grd\fP
+Contains the y-component of the vector field.
+.TP
+.B \-J
+Selects the map projection. Scale is UNIT/degree, 1:xxxxx, or width in UNIT (upper case modifier).
+UNIT is cm, inch, or m, depending on the MEASURE_UNIT setting in \.gmtdefaults4, but this can be
+overridden on the command line by appending \fBc\fP, \fBi\fP, or \fBm\fP to the scale/width value.
+For map height, max dimension, or min dimension, append \fBh\fP, \fB+\fP, or \fB-\fP to the width,
+respectively.
+.br
+.sp
+\fBCYLINDRICAL PROJECTIONS:\fP
+.br
+.sp
+\fB\-Jc\fP\fIlon0/lat0/scale\fP (Cassini)
+.br
+\fB\-Jj\fP\fIlon0/scale\fP (Miller)
+.br
+\fB\-Jm\fP\fIscale\fP (Mercator - Greenwich and Equator as origin)
+.br
+\fB\-Jm\fP\fIlon0/lat0/scale\fP (Mercator - Give meridian and standard parallel)
+.br
+\fB\-Joa\fP\fIlon0/lat0/azimuth/scale\fP (Oblique Mercator - point and azimuth)
+.br
+\fB\-Job\fP\fIlon0/lat0/lon1/lat1/scale\fP (Oblique Mercator - two points)
+.br
+\fB\-Joc\fP\fIlon0/lat0/lonp/latp/scale\fP (Oblique Mercator - point and pole)
+.br
+\fB\-Jq\fP\fIlon0/scale\fP (Equidistant Cylindrical Projection (Plate Carree))
+.br
+\fB\-Jt\fP\fIlon0/scale\fP (TM - Transverse Mercator, with Equator as y = 0)
+.br
+\fB\-Jt\fP\fIlon0/lat0/scale\fP (TM - Transverse Mercator, set origin)
+.br
+\fB\-Ju\fP\fIzone/scale\fP (UTM - Universal Transverse Mercator)
+.br
+\fB\-Jy\fP\fIlon0/lats/scale\fP (Basic Cylindrical Projection)
+.br
+.sp
+\fBAZIMUTHAL PROJECTIONS:\fP
+.br
+.sp
+\fB\-Ja\fP\fIlon0/lat0/scale\fP (Lambert).
+.br
+\fB\-Je\fP\fIlon0/lat0/scale\fP (Equidistant).
+.br
+\fB\-Jf\fP\fIlon0/lat0/horizon/scale\fP (Gnomonic).
+.br
+\fB\-Jg\fP\fIlon0/lat0/scale\fP (Orthographic).
+.br
+\fB\-Jg\fP\fIlon0/lat0/altitude/azimuth/tilt/twist/Width/Height/scale\fP (General Perspective).
+.br
+\fB\-Js\fP\fIlon0/lat0/\fP[\fIslat/\fP]\fIscale\fP (General Stereographic)
+.br
+.sp
+\fBCONIC PROJECTIONS:\fP
+.br
+.sp
+\fB\-Jb\fP\fIlon0/lat0/lat1/lat2/scale\fP (Albers)
+.br
+\fB\-Jd\fP\fIlon0/lat0/lat1/lat2/scale\fP (Equidistant)
+.br
+\fB\-Jl\fP\fIlon0/lat0/lat1/lat2/scale\fP (Lambert)
+.br
+.sp
+\fBMISCELLANEOUS PROJECTIONS:\fP
+.br
+.sp
+\fB\-Jh\fP\fIlon0/scale\fP (Hammer)
+.br
+\fB\-Ji\fP\fIlon0/scale\fP (Sinusoidal)
+.br
+\fB\-Jk\fP[\fBf|s\fP]\fIlon0/scale\fP (Eckert IV (f) and VI (s))
+.br
+\fB\-Jn\fP\fIlon0/scale\fP (Robinson)
+.br
+\fB\-Jr\fP\fIlon0/scale\fP (Winkel Tripel)
+.br
+\fB\-Jv\fP\fIlon0/scale\fP (Van der Grinten)
+.br
+\fB\-Jw\fP\fIlon0/scale\fP (Mollweide)
+.br
+.sp
+\fBNON-GEOGRAPHICAL PROJECTIONS:\fP
+.br
+.sp
+\fB\-Jp\fP[\fBa\fP]\fIscale\fP[\fI/origin\fP] (polar (theta,r) coordinates, optional \fBa\fP for azimuths and offset theta [0])
+.br
+\fB\-Jx\fP\fIx-scale\fP[\fBl|p\fP\fIpow\fP][\fI/y-scale\fP[\fBl|p\fP\fIpow\fP]][\fBd\fP] (Linear, log, and power scaling)
+.br
+More details can be found in the \fBpsbasemap\fP man pages.
+.br
+.SH OPTIONS
+No space between the option flag and the associated arguments.
+.TP
+.B \-A
+Means grid files have polar (r, theta) components instead of Cartesian (x, y).
+.TP
+.B \-B
+Sets map boundary annotation and tickmark intervals; see the
+\fBpsbasemap\fP man page for all the details.
+.TP
+.B \-C
+Use \fIcptfile\fP to assign colors based on vector length.
+.TP
+.B \-E
+Center wind barbs on grid nodes [Default draws from grid node].
+.TP
+.B \-G
+Sets color or shade for barb interiors [Default is no fill].
+(See SPECIFYING FILL below).
+.TP
+.B \-I
+Only plot barbs at nodes every \fIx_inc, y_inc\fP apart (must be multiples of
+original grid spacing). Append \fBm\fP for minutes or \fBc\fP for seconds. [Default plots every node].
+.TP
+.B \-K
+More \fIPostScript\fP code will be appended later [Default terminates the plot system].
+.TP
+.B \-N
+Do NOT clip barbs at map boundaries [Default will clip].
+.TP
+.B \-O
+Selects Overlay plot mode [Default initializes a new plot system].
+.TP
+.B \-P
+Selects Portrait plotting mode [\fBGMT\fP Default is Landscape, see \fBgmtdefaults\fP to change this].
+.TP
+.B \-Q
+Select barb plot. Optionally, specify \fIparameters\fP which
+are \fIbarbwidth/barblength/barbangle/barbscale\fP [Default is 0.025\fBc\fP/0.051\fBc\fP/120/5 (or 0.1\fBi\fP/0.2\fBi\fP/120/5)]. 
+.TP
+.B \-R
+\fIxmin, xmax, ymin,\fP and \fIymax\fP specify the Region of interest. For geographic
+regions, these limits correspond to \fIwest, east, south,\fP and \fInorth\fP and you may specify them
+in decimal degrees or in [+-]dd:mm[:ss.xxx][W|E|S|N] format. Append \fBr\fP if lower left and upper right
+map coordinates are given instead of wesn. The two shorthands \fB\-Rg \-Rd\fP stand for global domain
+(0/360 or -180/+180 in longitude respectively, with -90/+90 in latitude).
+For calendar time coordinates you may either give relative
+time (relative to the selected TIME_EPOCH and in the selected TIME_UNIT; append \fBt\fP to \fB\-JX|x\fP),
+or absolute time of the form [\fIdate\fP]\fBT[\fP\fIclock\fP] (append \fBT\fP to \fB\-JX|x\fP). At least one of \fIdate\fP and \fIclock\fP
+must be present; the \fBT\fP is always required. The \fIdate\fP string must be of the form [-]yyyy[-mm[-dd]]
+(Gregorian calendar) or yyyy[-Www[-d]] (ISO week calendar), while the \fIclock\fP string must be of
+the form hh:mm:ss[.xxx]. The use of delimiters and their type and positions must be as indicated
+(however, input/output and plotting formats are flexible).
+Specify a subset of the grid.
+.TP
+.B \-T
+Means azimuth should be converted to angles based on the selected map projection.
+.TP
+.B \-U
+Draw Unix System time stamp on plot. User may specify where the lower left corner
+of the stamp should fall on the page relative to lower left corner of plot. Optionally,
+append a label, or \fBc\fP (which will plot the command string.). The \fBGMT\fP parameters
+UNIX_TIME and UNIX_TIME_POS can affect the appearance; see the \fBgmtdefaults\fP man
+page for details.
+.TP
+.B \-V
+Selects verbose mode, which will send progress reports to stderr [Default runs "silently"].
+.TP
+.B \-W
+Set pen attributes used for vector outlines [Default: width = 1, color = 0/0/0, texture = solid]. (See SPECIFYING PENS below).
+.TP
+.B \-X \-Y
+Shift origin of plot by (\fIx-shift,y-shift\fP).
+Prepend \fBa\fP for absolute coordinates;
+the default (\fBr\fP) will reset plot origin.
+Give \fBc\fP to center plot using current page size.
+.TP
+.B \-Z
+Means the angles provided are azimuths rather than direction (requires \fB\-A\fP).
+.TP
+.B \-c
+Specifies the number of plot copies. [Default is 1].
+.SS SPECIFYING PENS
+.TP
+\fIpen\fP
+The attributes of lines and symbol outlines as defined by \fIpen\fP is a comma delimetered list of
+\fIwidth\fP, \fIcolor\fP and \fItexture\fP, each of which is optional.
+\fIwidth\fP can be indicated as a measure (points, centimeters, inches) or as \fBfaint\fP, \fBthin\fP[\fBner\fP|\fBnest\fP],
+\fBthick\fP[\fBer\fP|\fBest\fP], \fBfat\fP[\fBter\fP|\fBtest\fP], or \fBobese\fP.
+\fIcolor\fP specifies a grey shade or color (see SPECIFYING COLOR below).
+\fItexture\fP is a combination of dashes `-' and dots `.'.
+.SS SPECIFYING FILL
+.TP
+\fIfill\fP
+The attribute \fIfill\fP specifies the solid shade or solid \fIcolor\fP
+(see SPECIFYING COLOR below) or the pattern used for filling polygons.
+Patterns are specified as \fBp\fP\fIdpi/pattern\fP, where \fIpattern\fP gives
+the number of the built-in pattern (1-90) \fIor\fP the name of a Sun 1-, 8-,
+or 24-bit raster file. The \fIdpi\fP sets the resolution of the image. For
+1-bit rasters: use \fBP\fP\fIdpi/pattern\fP for inverse video, or append
+\fB:F\fP\fIcolor\fP[\fBB\fP[\fIcolor\fP]] to specify fore- and background
+colors (use \fIcolor\fP = - for transparency).
+See \fBGMT\fP Cookbook & Technical Reference Appendix E for information
+on individual patterns.
+.SS SPECIFYING COLOR
+.TP
+\fIcolor\fP
+The \fIcolor\fP of lines, areas and patterns can be specified by a valid color name
+(from the system's X11/rgb.txt file),\"'
+by a grey shade (in the range 0\-255) or by a numerical color code (r/g/b, each in range 0\-255; h-s-v, ranges
+0\-360, 0\-1, 0\-1; or c/m/y/k, each in range 0\-100%).
+
+.SH EXAMPLES
+To draw the vector field given by the files r.grd and theta.grd on a linear plot
+with scale 5 cm per data unit,
+using vector rather than stick plot, and scale vector magnitudes so that 10 units
+equal 1 inch, run
+.br
+.sp
+\fBgrdvector\fP r.grd theta.grd \fB\-Jx\fP5\fBc\fP \fB\-A \-Q\fP \fB\-S\fP10\fBi\fP > gradient.ps
+.br
+.sp
+.SH "SEE ALSO"
+.IR gmt (l),
+.IR grdcontour (l),
+.IR psxy (l)
diff -uNr GMT4.4.0/src/grdbarb.c GMT4.4.0_barb/src/grdbarb.c
--- GMT4.4.0/src/grdbarb.c	1970-01-01 09:00:00.000000000 +0900
+++ GMT4.4.0_barb/src/grdbarb.c	2009-02-24 08:26:26.000000000 +0900
@@ -0,0 +1,411 @@
+/*--------------------------------------------------------------------
+ *	$Id: grdvector.c,v 1.52 2009/01/09 04:02:34 guru Exp $
+ *
+ *	Copyright (c) 1991-2009 by P. Wessel and W. H. F. Smith
+ *	See COPYING file for copying and redistribution conditions.
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; version 2 of the License.
+ *
+ *	This program is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *	GNU General Public License for more details.
+ *
+ *	Contact info: gmt.soest.hawaii.edu
+ *--------------------------------------------------------------------*/
+/*
+   grdvector reads 2 grid files that contains the 2 components of a vector
+   field (cartesian or polar) and plots vectors at the grid positions.
+   This is basically a short-hand for using grd2xyz | psxy -SV and is
+   more convenient for such plots on a grid.
+
+   Author:	Paul Wessel
+   Date:	12-JUN-1995
+   Revised:	15-FEB-2000
+   Version:	4
+ 
+ */
+
+
+#include "gmt.h"
+#include "pslib.h"
+
+struct GRDBARB_CTRL {
+	struct A {	/* -A */
+		BOOLEAN active;
+	} A;
+	struct C {	/* -C<cpt> */
+		BOOLEAN active;
+		char *file;
+	} C;
+	struct E {	/* -E */
+		BOOLEAN active;
+	} E;
+	struct G {	/* -G<fill> */
+		BOOLEAN active;
+		struct GMT_FILL fill;
+	} G;
+	struct I {	/* -Idx[/dy] */
+		BOOLEAN active;
+		double xinc, yinc;
+	} I;
+	struct N {	/* -N */
+		BOOLEAN active;
+	} N;
+	struct Q {	/* -Q<params> */
+		BOOLEAN active;
+		double width, length, angle, scale;
+	} Q;
+	struct T {	/* -T */
+		BOOLEAN active;
+	} T;
+	struct W {	/* -W<pen> */
+		BOOLEAN active;
+		struct GMT_PEN pen;
+	} W;
+	struct Z {	/* -Z */
+		BOOLEAN active;
+	} Z;
+};
+
+int main (int argc, char **argv)
+{
+	int	i, j, n = 0, nx, ny, i0, j0, di, dj;
+
+	GMT_LONG ij, nm;
+	
+	BOOLEAN shrink_properties = FALSE, error = FALSE;
+
+	char *file[2], txt_a[GMT_LONG_TEXT], txt_b[GMT_LONG_TEXT], txt_c[GMT_LONG_TEXT];
+
+	float *r, *theta;
+
+	double v_w, h_l, h_w, v_shrink = 1.0, tmp, x, y, plot_x, plot_y, x_off, y_off;
+	double west, east, south, north, x2, y2;
+	double data_west, data_east, data_south, data_north, value, c, s;
+
+	struct GRD_HEADER h[2];
+	struct GRDBARB_CTRL *Ctrl;
+
+	void *New_Grdbarb_Ctrl (), Free_Grdbarb_Ctrl (struct GRDBARB_CTRL *C);
+
+	argc = GMT_begin (argc, argv);
+
+	Ctrl = (struct GRDBARB_CTRL *)New_Grdbarb_Ctrl ();	/* Allocate and initialize a new control structure */
+	
+	west = east = south = north = 0.0;
+	di = dj = 1;
+	i0 = j0 = 0;
+
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-') {
+			switch (argv[i][1]) {
+				/* Common parameters */
+
+				case 'B':
+				case 'J':
+				case 'K':
+				case 'O':
+				case 'P':
+				case 'R':
+				case 'U':
+				case 'V':
+				case 'X':
+				case 'x':
+				case 'Y':
+				case 'y':
+				case 'c':
+				case 'f':
+				case '\0':
+					error += GMT_parse_common_options (argv[i], &west, &east, &south, &north);
+					break;
+
+				/* Supplemental parameters */
+
+				case 'A':
+					Ctrl->A.active = TRUE;
+					break;
+				case 'C':	/* Vary symbol color with z */
+					Ctrl->C.active = TRUE;
+					Ctrl->C.file = strdup (&argv[i][2]);
+					break;
+				case 'E':
+					Ctrl->E.active = TRUE;
+					break;
+				case 'G':		/* Set Gray shade for polygon */
+					Ctrl->G.active = TRUE;
+					if (GMT_getfill (&argv[i][2], &Ctrl->G.fill)) {
+						GMT_fill_syntax ('G', " ");
+						error++;
+					}
+					break;
+				case 'I':	/* Only use gridnodes Ctrl->I.xinc,Ctrl->I.yinc apart */
+					Ctrl->I.active = TRUE;
+					if (GMT_getinc (&argv[i][2], &Ctrl->I.xinc, &Ctrl->I.yinc)) {
+						GMT_inc_syntax ('I', 1);
+						error = TRUE;
+					}
+					break;
+				case 'N':	/* Do not clip at border */
+					Ctrl->N.active = TRUE;
+					break;
+				case 'Q':
+					Ctrl->Q.active = TRUE;
+                                        if (argv[i][2]) {
+                                                if (sscanf (&argv[i][2], "%[^/]/%[^/]/%lf/%lf", txt_a, txt_b, &Ctrl->Q.angle, &Ctrl->Q.scale) != 4) {
+                                                        fprintf (stderr, "%s: GMT SYNTAX ERROR -Q option:  Could not decode barbwidth/barblength/barbangle/barbscale\n", GMT_program);
+                                                        error++;
+                                                }
+                                                else {
+                                                        Ctrl->Q.width  = GMT_convert_units (txt_a, GMT_INCH);
+                                                        Ctrl->Q.length = GMT_convert_units (txt_b, GMT_INCH);
+                                                }
+                                        }
+                                        break;
+				case 'T':
+					Ctrl->T.active = TRUE;
+					break;
+				case 'W':		/* Set line attributes */
+					Ctrl->W.active = TRUE;
+					if (argv[i][2] && GMT_getpen (&argv[i][2], &Ctrl->W.pen)) {
+						GMT_pen_syntax ('W', " ");
+						error++;
+					}
+					break;
+				case 'Z':
+					Ctrl->Z.active = TRUE;
+					break;
+				default:
+					error = TRUE;
+					GMT_default_error (argv[i][1]);
+					break;
+			}
+		}
+		else if (n < 2)
+			file[n++] = argv[i];
+		else
+			n++;
+	}
+
+	if (argc == 1 || GMT_give_synopsis_and_exit) {
+		fprintf (stderr, "grdbarb %s - Plot wind barb fields from grid files\n\n", GMT_VERSION);
+		fprintf (stderr, "usage: grdbarb compx.grd compy.grd %s %s [-A]\n", GMT_J_OPT, GMT_Rgeo_OPT);
+		fprintf (stderr, "\t[%s] [-C<cpt>] [-E] [-G<fill>] [-I<dx/dy>] [-K] [-N] [-O] [-P] [-Q<params>]\n", GMT_B_OPT);
+		fprintf (stderr, "\t[-T] [%s] [-V] [-W<pen>] [%s] [%s] [-Z] [%s]\n\n", GMT_U_OPT, GMT_X_OPT, GMT_Y_OPT, GMT_c_OPT);
+
+		if (GMT_give_synopsis_and_exit) exit (EXIT_FAILURE);
+
+		fprintf (stderr, "\tcompx & compy are grid files with the 2 vector components.\n");
+		GMT_explain_option ('j');
+		fprintf (stderr, "\n\tOPTIONS:\n");
+		fprintf (stderr, "\t-A means grids have polar (r, theta) components [Default is Cartesian]\n");
+		GMT_explain_option ('b');
+		fprintf (stderr, "\t-C Use cpt-file to assign colors based on vector length\n");
+		fprintf (stderr, "\t-E cEnter vectors on grid nodes [Default draws from grid node]\n");
+		GMT_fill_syntax ('G', "Select vector fill [Default is outlines only].");
+		fprintf (stderr, "\t-I plots only those nodes that are <dx/dy> apart [Default is all nodes]\n");
+		GMT_explain_option ('K');
+		fprintf (stderr, "\t-N Do Not clip vectors that exceed the map boundaries [Default will clip]\n");
+		GMT_explain_option ('O');
+		GMT_explain_option ('P');
+		fprintf (stderr, "\t-Q Specify wind barb parameters.\n");
+		fprintf (stderr, "\t   <params> are barbwidth/barblength/barbangle/barbscale [Default is 0.1i/0.2i/120/5]\n");
+		GMT_explain_option ('R');
+		fprintf (stderr, "\t-T means azimuth should be converted to angles based on map projection\n");
+		GMT_explain_option ('U');
+		GMT_explain_option ('V');
+		GMT_pen_syntax ('W', "sets pen attributes.");
+		fprintf (stderr, "\t   Default pen attributes [width = %gp, color = (%d/%d/%d), solid line].\n", 
+			Ctrl->W.pen.width, Ctrl->W.pen.rgb[0], Ctrl->W.pen.rgb[1], Ctrl->W.pen.rgb[2]);
+		GMT_explain_option ('X');
+		fprintf (stderr, "\t-Z means the angles provided are azimuths rather than direction\n");
+		GMT_explain_option ('c');
+		GMT_explain_option ('f');
+		GMT_explain_option ('.');
+		exit (EXIT_FAILURE);
+	}
+
+	GMT_check_lattice (&Ctrl->I.xinc, &Ctrl->I.yinc, NULL, &Ctrl->I.active);
+
+	if (Ctrl->I.active && (Ctrl->I.xinc <= 0.0 || Ctrl->I.yinc <= 0.0)) {
+		fprintf (stderr, "%s: GMT SYNTAX ERROR -I option:  Must specify positive increments\n", GMT_program);
+		error++;
+	}
+	if (Ctrl->Z.active && !Ctrl->A.active) {
+		fprintf (stderr, "%s: GMT SYNTAX ERROR -Z option:  Azimuths not valid input for Cartesian data\n", GMT_program);
+		error++;
+	}
+	if (Ctrl->C.active && !Ctrl->C.file) {
+		fprintf (stderr, "%s: GMT SYNTAX ERROR -C option:  Must specify a color palette table\n", GMT_program);
+		error++;
+	}
+	if (!(Ctrl->G.active || Ctrl->W.active || Ctrl->C.active)) {
+		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify at least one of -G, -W, -C\n", GMT_program);
+		error++;
+	}
+	if (n != 2) {
+		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify two input grid files\n", GMT_program);
+		error++;
+	}
+
+	if (error) exit (EXIT_FAILURE);
+
+	if (Ctrl->C.active) GMT_read_cpt (Ctrl->C.file);
+
+	if (!(strcmp (file[0], "=") || strcmp (file[1], "="))) {
+		fprintf (stderr, "%s: Piping of grid files not supported!\n", GMT_program);
+		exit (EXIT_FAILURE);
+	}
+
+	for (i = 0; i < 2; i++) {
+		GMT_grd_init (&h[i], argc, argv, FALSE);
+		GMT_err_fail (GMT_read_grd_info (file[i], &h[i]), file[i]);
+	}
+
+	if (!(h[0].nx == h[1].nx && h[0].ny == h[1].ny && h[0].x_min == h[1].x_min && h[0].y_min == h[1].y_min 
+		&& h[0].x_inc == h[1].x_inc && h[0].y_inc == h[1].y_inc)) {
+		fprintf (stderr, "%s: files %s and %s does not match!\n", GMT_program, file[0], file[1]);
+		exit (EXIT_FAILURE);
+	}
+
+	/* Determine what wesn to pass to map_setup */
+
+	if (!project_info.region_supplied) {
+		west = h[0].x_min;
+		east = h[0].x_max;
+		south = h[0].y_min;
+		north = h[0].y_max;
+	}
+
+	GMT_err_fail (GMT_map_setup (west, east, south, north), "");
+
+	/* Determine the wesn to be used to read the grid file */
+
+	if (GMT_grd_setregion (&h[0], &data_west, &data_east, &data_south, &data_north)) {	/* No grid to plot; just do empty map and exit */
+		GMT_plotinit (argc, argv);
+		GMT_map_basemap ();
+		GMT_plotend ();
+		GMT_end (argc, argv);
+		exit (EXIT_SUCCESS);
+	}
+
+	/* Read data */
+
+	nx = GMT_get_n (data_west, data_east, h[0].x_inc, h[0].node_offset);
+	ny = GMT_get_n (data_south, data_north, h[0].y_inc, h[0].node_offset);
+	nm = GMT_get_nm (nx, ny);
+	r = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
+	theta = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
+	GMT_err_fail (GMT_read_grd (file[0], &h[0], r, data_west, data_east, data_south, data_north, GMT_pad, FALSE), file[0]);
+	GMT_err_fail (GMT_read_grd (file[1], &h[1], theta, data_west, data_east, data_south, data_north, GMT_pad, FALSE), file[1]);
+
+	GMT_plotinit (argc, argv);
+
+	GMT_setpen (&Ctrl->W.pen);
+
+        if (!Ctrl->N.active) GMT_map_clip_on (GMT_no_rgb, 3);
+
+	if (Ctrl->I.xinc != 0.0 && Ctrl->I.yinc != 0.0) {
+		struct GRD_HEADER tmp_h;
+		tmp_h = h[0];
+		tmp_h.x_inc = Ctrl->I.xinc;
+		tmp_h.y_inc = Ctrl->I.yinc;
+		GMT_RI_prepare (&tmp_h);	/* Convert to make sure we have correct increments */
+		Ctrl->I.xinc = tmp_h.x_inc;
+		Ctrl->I.yinc = tmp_h.y_inc;
+		dj = irint (Ctrl->I.yinc / h[0].y_inc);
+		di = irint (Ctrl->I.xinc / h[0].x_inc);
+		tmp = ceil (h[0].y_max / Ctrl->I.yinc) * Ctrl->I.yinc;
+		if (tmp > h[0].y_max) tmp -= Ctrl->I.yinc;
+		j0 = irint ((h[0].y_max - tmp) / h[0].y_inc);
+		tmp = floor (h[0].x_min / Ctrl->I.xinc) * Ctrl->I.xinc;
+		if (tmp < h[0].x_min) tmp += Ctrl->I.xinc;
+		i0 = irint ((tmp - h[0].x_min) / h[0].x_inc);
+	}
+
+	for (j = j0; j < h[1].ny; j += dj) {
+		y = GMT_j_to_y (j, h[0].y_min, h[0].y_max, h[0].y_inc, h[0].xy_off, h[0].ny);
+		for (i = i0; i < h[1].nx; i += di) {
+
+			ij = GMT_IJ (j, i, h[0].nx);
+			if (GMT_is_fnan (r[ij]) || GMT_is_fnan (theta[ij])) continue;	/* Cannot plot NaN-vectors */
+
+			value = r[ij];
+
+			if (!Ctrl->A.active) {
+				value = hypot (theta[ij], r[ij]);
+				if (value == 0.0) continue;
+				theta[ij] = (float)(R2D * atan2 (theta[ij], r[ij]));
+				r[ij] = (float)value;
+			}
+			else if (r[ij] < 0.0) {
+				r[ij] = -r[ij];
+				theta[ij] += 180.0;
+			}
+			else if (r[ij] == 0.0) continue;
+
+			if (Ctrl->C.active) GMT_get_rgb_from_z (value, Ctrl->G.fill.rgb);
+
+			x = GMT_i_to_x (i, h[0].x_min, h[0].x_max, h[0].x_inc, h[0].xy_off, h[0].nx);
+			GMT_geo_to_xy (x, y, &plot_x, &plot_y);
+
+			if (Ctrl->T.active) {
+				if (!Ctrl->Z.active) theta[ij] = (float)90.0 - theta[ij];
+				GMT_azim_to_angle (x, y, 0.1, (double)theta[ij], &tmp);
+				theta[ij] = (float)tmp;
+			}
+
+			if (Ctrl->E.active) {
+			        sincos (theta[ij], &s, &c);
+				plot_x += 0.5 * Ctrl->Q.length * c;
+				plot_y += 0.5 * Ctrl->Q.length * s;
+			}
+
+			if (!Ctrl->Q.active) {
+				if (Ctrl->C.active) ps_setpaint (Ctrl->G.fill.rgb);
+				/* ps_segment (plot_x, plot_y, x2, y2); */
+				continue;
+			}
+
+
+                       GMT_draw_barb (plot_x, plot_y, 0., theta[ij], r[ij], Ctrl->Q.width, Ctrl->Q.length, copysign(Ctrl->Q.angle, y), Ctrl->Q.scale, &Ctrl->W.pen, &Ctrl->G.fill, Ctrl->W.active);
+		}
+	}
+
+        if (!Ctrl->N.active) GMT_map_clip_off ();
+
+	GMT_map_basemap ();
+
+	GMT_plotend ();
+
+	GMT_free ((void *)r);
+	GMT_free ((void *)theta);
+
+	Free_Grdbarb_Ctrl (Ctrl);	/* Deallocate control structure */
+
+	GMT_end (argc, argv);
+
+	exit (EXIT_SUCCESS);
+}
+
+void *New_Grdbarb_Ctrl () {	/* Allocate and initialize a new control structure */
+	struct GRDBARB_CTRL *C;
+	
+	C = (struct GRDBARB_CTRL *) GMT_memory (VNULL, (size_t)1, sizeof (struct GRDBARB_CTRL), "New_Grdbarb_Ctrl");
+	
+	/* Initialize values whose defaults are not 0/FALSE/NULL */
+	GMT_init_fill (&C->G.fill, -1, -1, -1);
+	GMT_init_pen (&C->W.pen, GMT_PENWIDTH);
+        C->Q.width  = 0.1;
+        C->Q.length = 0.2;
+        C->Q.angle  = 120.;
+        C->Q.scale  = 5.;
+	return ((void *)C);
+}
+
+void Free_Grdbarb_Ctrl (struct GRDBARB_CTRL *C) {	/* Deallocate control structure */
+	if (C->C.file) free ((void *)C->C.file);	
+	GMT_free ((void *)C);	
+}
diff -uNr GMT4.4.0/src/makefile GMT4.4.0_barb/src/makefile
--- GMT4.4.0/src/makefile	2009-01-09 13:02:34.000000000 +0900
+++ GMT4.4.0_barb/src/makefile	2009-02-24 08:26:08.000000000 +0900
@@ -59,7 +59,7 @@
 
 PROGSPS_O	= gmt2rgb.o grdcontour.o grdimage.o grdvector.o grdview.o psbasemap.o psclip.o \
 	  	pscoast.o pscontour.o pshistogram.o psimage.o pslegend.o psmask.o psrose.o \
-		psscale.o pstext.o pswiggle.o psxy.o psxyz.o
+		psscale.o pstext.o pswiggle.o psxy.o psxyz.o grdbarb.o
 
 ALLPROGS	= GMT gmt_shell_functions.sh isogmt $(PROGS) $(PROGSPS)
 
@@ -225,6 +225,7 @@
 grd2cpt$(EXE):		grd2cpt.o
 grd2xyz$(EXE):		grd2xyz.o
 grdblend$(EXE):		grdblend.o
+grdbarb$(EXE):		grdbarb.o
 grdclip$(EXE):		grdclip.o
 grdcontour$(EXE):	grdcontour.o
 grdcut$(EXE):		grdcut.o
diff -uNr GMT4.4.0/src/psxy.1 GMT4.4.0_barb/src/psxy.1
--- GMT4.4.0/src/psxy.1	2009-02-17 16:18:47.000000000 +0900
+++ GMT4.4.0_barb/src/psxy.1	2009-02-24 08:26:26.000000000 +0900
@@ -492,6 +492,12 @@
 Same as \fB\-Sw\fP, except azimuths (in degrees east of north) should be given instead of the two directions.  The azimuths will
 be mapped into angles based on the chosen map projection (\fB\-Sw\fP leaves the directions unchanged.)
 .TP
+.B \-Swb
+wind barb. Direction (in degrees counter-clockwise from horizontal) and length must be found in columns 3 and 4. \fIsize\fP,
+if present, will be interpreted as barbwidth/barblength/barbangle/barbscale [Default is 0.025\fBc\fP/0.051\fBc\fP/120/5 (or 0.1\fBi\fP/0.2\fBi\fP/120/5)].
+.B \-SWB
+Same as \fB\-Swb\fP, except azimuth (in degrees east of north) should be given instead of direction. The azimuth will be mapped into an angle based on the chosen map projection (\fB\-Swb\fP leaves the directions unchanged.)
+.TP
 \fB\-Sx\fP
 cross (x).  \fIsize\fP is diameter of circumscribing circle.
 .TP
diff -uNr GMT4.4.0/src/psxy.c GMT4.4.0_barb/src/psxy.c
--- GMT4.4.0/src/psxy.c	2009-01-11 20:00:05.000000000 +0900
+++ GMT4.4.0_barb/src/psxy.c	2009-02-24 08:26:26.000000000 +0900
@@ -121,14 +121,22 @@
 	memset ((void *)&S, 0, sizeof (struct GMT_SYMBOL));
 	GMT_contlabel_init (&S.G, 0);
 	
+	S.read_barb = FALSE;
 	S.v_width = 0.03;
 	S.h_length = 0.12;
 	S.h_width = 0.1;
 	S.font_no = gmtdefs.annot_font[0];
 
+        S.b_width  = 0.1;
+        S.b_length = 0.2;
+        S.b_angle  = 120.;
+        S.b_scale  = 5.;
+
 	if ((S.u = gmtdefs.measure_unit) == GMT_CM) {
 		S.v_width = 0.075 / 2.54;	S.h_length = 0.3 / 2.54;
 		S.h_width = 0.25 / 2.54; Ctrl->E.size = 0.25 / 2.54;
+                S.b_width = 0.25 / 2.54;
+                S.b_length = 0.50 / 2.54;
 	}
 
 	/* Check and interpret the command line arguments */
@@ -310,6 +318,7 @@
 		fprintf (stderr, "\t   -(xdash), +(plus), st(a)r, (b|B)ar, (c)ircle, (d)iamond, (e)llipse, (f)ront, octa(g)on, (h)exagon, (i)nvtriangle,\n");
 		fprintf (stderr, "\t   (j)rotated rectangle, (k)ustom, (l)etter, pe(n)tagon, (p)oint, (q)uoted line, (r)ect, (s)quare,\n");
 		fprintf (stderr, "\t   (t)riangle, (v)ector, (w)edge, (x)cross, (y)dash\n");
+                fprintf (stderr, "\t    (wb) wind barb\n");
 		fprintf (stderr, "\t   If no size is specified, psxy expects the 3rd column to have sizes.\n");
 		fprintf (stderr, "\t   If no symbol is specified, psxy expects the last column to have symbol code.\n");
 		fprintf (stderr, "\t   [Note: if -C is selected then 3rd means 4th column, etc.]\n");
@@ -353,6 +362,10 @@
 		fprintf (stderr, "\t     Upper case H, B, T, S will give double-headed vector [Default is t]\n");
 		fprintf (stderr, "\t   Wedges: the start and stop directions of pie wedge must be in input columns 3, 4.\n");
 		fprintf (stderr, "\t     If -SW rather than -Sw is selected, psxy will expect two azimuths instead.\n");
+                fprintf (stderr, "\t   Wind barbs: the direction and length must be in input columns 3 and 4.\n");
+                fprintf (stderr, "\t     Furthermore, <size> means barbwidth/barblength/barbangle/barbscale [Default is %g/%g/%g/%g]\n", S.b_width, S.b_length, S.b_angle, S.b_scale);
+                fprintf (stderr, "\t     If -SWB rather than -Swb is selected, psxy will expect azimuth and length\n");
+                fprintf (stderr, "\t     and convert azimuths based on the chosen map projection\n");
 		GMT_explain_option ('U');
 		GMT_explain_option ('V');
 		GMT_pen_syntax ('W', "sets pen attributes:");
@@ -375,8 +388,8 @@
 		error++;
 	}
 	if (S.symbol > 0 && Ctrl->C.active) get_rgb = TRUE;	/* Need to read z-vales from input data file */
-	if (Ctrl->E.active && (S.read_vector || S.symbol == GMT_SYMBOL_ELLIPSE || S.symbol == GMT_SYMBOL_FRONT || S.symbol == GMT_SYMBOL_QUOTED_LINE || S.symbol == GMT_SYMBOL_ROTATERECT)) {
-		fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: Incompatible with -Se, -Sf, -Sj, -Sq, -Sv\n", GMT_program);
+        if (Ctrl->E.active && (S.read_vector || S.read_barb || S.symbol == GMT_SYMBOL_ELLIPSE || S.symbol == GMT_SYMBOL_FRONT || S.symbol == GMT_SYMBOL_QUOTED_LINE || S.symbol == GMT_SYMBOL_ROTATERECT)) {
+                fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: Incompatible with -Se, -Sf, -Sj, -Sq, -Sv, -Swb\n", GMT_program);
 		error++;
 	}
 	if (Ctrl->C.active && S.symbol == 0 && !GMT_io.multi_segments[GMT_IN]) {
@@ -675,6 +688,10 @@
 					x_len = in[two+S.read_size] * GMT_u2u[S.u][GMT_INCH];
 					y_len = in[three+S.read_size] * GMT_u2u[S.u][GMT_INCH];
 				}
+                                else if (S.read_barb){
+                                        direction = in[two];
+                                        length = in[three];
+                                }
 		
 				/* Skip zero-size symbols */
 		
@@ -687,6 +704,10 @@
 					if (gmtdefs.verbose) fprintf (stderr, "%s: Warning: Vector length <= 0.0 near line %ld (skipped)\n", GMT_program, n_total_read);
 					continue;
 				}
+				if (S.read_barb && length <= 0.0) {
+					if (gmtdefs.verbose) fprintf (stderr, "%s: Warning: Vector length <= 0.0 near line %ld (skipped)\n", GMT_program, n_total_read);
+					continue;
+				}
 				if (S.symbol == GMT_SYMBOL_ELLIPSE && (major <= 0.0 || minor <= 0.0)) {
 					if (gmtdefs.verbose) fprintf (stderr, "%s: Warning: Ellipse axes <= 0.0 near line %ld (skipped)\n", GMT_program, n_total_read);
 					continue;
@@ -924,6 +945,15 @@
 						dim[0] = x_len; dim[1] = y_len;
 						GMT_rect (plot_x - 0.5*x_len, plot_y - 0.5*y_len, 0.0, dim, &current_fill, outline_active);
 						break;
+                                        case GMT_SYMBOL_BARB:
+                                                if (S.convert_angles == 2) {
+                                                        GMT_azim_to_angle (in[0], in[1], 0.1, direction, &tmp);
+                                                        direction = tmp;
+                                                }
+                                                else if (S.convert_angles == 1) /* Cartesian azimuth */
+                                                        direction = 90.0 - direction;
+                                                GMT_draw_barb (plot_x, plot_y, 0., direction, length, S.b_width, S.b_length, copysign(S.b_angle, in[1]), S.b_scale, &Ctrl->W.pen, &Ctrl->G.fill, Ctrl->W.active);
+                                                break;
 					case GMT_SYMBOL_CUSTOM:
 						GMT_draw_custom_symbol (plot_x, plot_y, 0.0, S.size_x, S.custom, &current_pen, &current_fill, outline_active);
 						break;
diff -uNr GMT4.4.0/src/psxyz.1 GMT4.4.0_barb/src/psxyz.1
--- GMT4.4.0/src/psxyz.1	2009-02-17 16:18:47.000000000 +0900
+++ GMT4.4.0_barb/src/psxyz.1	2009-02-24 08:26:26.000000000 +0900
@@ -499,6 +499,12 @@
 Same as \fB\-Sw\fP, except azimuths (in degrees east of north) should be given instead of the two directions.  The azimuths will
 be mapped into angles based on the chosen map projection (\fB\-Sw\fP leaves the directions unchanged.)
 .TP
+.B \-Swb
+wind barb. Direction (in degrees counter-clockwise from horizontal) and length must be found in columns 3 and 4. \fIsize\fP,
+if present, will be interpreted as barbwidth/barblength/barbangle/barbscale [Default is 0.025\fBc\fP/0.051\fBc\fP/120/5 (or 0.1\fBi\fP/0.2\fBi\fP/120/5)].
+.B \-SWB
+Same as \fB\-Swb\fP, except azimuth (in degrees east of north) should be given instead of direction. The azimuth will be mapped into an angle based on the chosen map projection (\fB\-Swb\fP leaves the directions unchanged.)
+.TP
 \fB\-Sx\fP
 cross (x).  \fIsize\fP is diameter of circumscribing circle.
 .br
diff -uNr GMT4.4.0/src/psxyz.c GMT4.4.0_barb/src/psxyz.c
--- GMT4.4.0/src/psxyz.c	2009-01-12 07:39:15.000000000 +0900
+++ GMT4.4.0_barb/src/psxyz.c	2009-02-24 08:26:26.000000000 +0900
@@ -149,12 +149,19 @@
 	S.h_length = 0.12;
 	S.h_width = 0.1;
 	S.base = GMT_d_NaN;
+
+        S.b_width  = 0.1;
+        S.b_length = 0.2;
+        S.b_angle  = 120.;
+        S.b_scale  = 5.;
 	
 	lux[0] = lux[1] = lux[2] = 0.0;	/* Default is no shading */
 
 	if ((S.u = gmtdefs.measure_unit) == GMT_CM) {
 		S.v_width = 0.075 / 2.54;	S.h_length = 0.3 / 2.54;
 		S.h_width = 0.25 / 2.54;
+                S.b_width = 0.25 / 2.54;
+                S.b_length = 0.50 / 2.54;
 	}
 	/* Check and interpret the command line arguments */
 
@@ -294,6 +301,7 @@
 		fprintf (stderr, "\t   -(xdash), +(plus), st(a)r, (b|B)ar, (c)ircle, (d)iamond, (e)llipse, (f)ront, octa(g)on, (h)exagon\n");
 		fprintf (stderr, "\t   (i)nvtriangle, (j)rotated rectangle, (k)ustom, (%c)etter, pe(n)tagon, c(o)lumn, (p)oint, (q)uoted line,\n", 'l');
 		fprintf (stderr, "\t   (r)ect, (s)quare, (t)riangle, c(u)be, (v)ector, (w)edge, (x)cross, (y)dash, (z)dash\n");
+                fprintf (stderr, "\t   (wb) wind barb\n");
 		fprintf (stderr, "\t   If no size is specified, psxyz expects the 4th column to have sizes.\n");
 		fprintf (stderr, "\t   If no symbol is specified, psxyz expects the last column to have symbol code.\n");
 		fprintf (stderr, "\t   [Note: if -C is selected then 4th means 5th column, etc.]\n");
@@ -339,6 +347,10 @@
 		GMT_explain_option ('U');
 		fprintf (stderr, "\t   Wedges: the start and stop directions of pie wedge must be in input columns 4 and 5.\n");
 		fprintf (stderr, "\t     If -SW rather than -Sw is selected, psxy will expect two azimuths instead.\n");
+               fprintf (stderr, "\t   Wind barbs: the direction and length must be in input columns 3 and 4.\n");
+               fprintf (stderr, "\t     Furthermore, <size> means barbwidth/barblength/barbangle/barbscale [Default is %g/%g/%g/%g]\n", S.b_width, S.b_length, S.b_angle, S.b_scale);
+               fprintf (stderr, "\t     If -SWB rather than -Swb is selected, psxyz will expect azimuth and length\n");
+               fprintf (stderr, "\t     and convert azimuths based on the chosen map projection\n");
 		GMT_explain_option ('V');
 		GMT_pen_syntax ('W', "sets pen attributes:");
 		fprintf (stderr, "\t   Implicitly draws symbol outline with this pen.\n");
@@ -574,6 +586,11 @@
 					data1[n].flag = S.convert_angles;	/* Azim vs Dir. */
 					if (data1[n].y_size < S.v_norm) data1[n].flag |= 8;	/* Flag to shrink vector attributes */
 				}
+                                else if (S.read_barb){
+                                        data1[n].x_size = (float)in[three];     /* direction */
+                                        data1[n].y_size = (float)in[four];      /* length */
+                                        data1[n].flag = S.convert_angles;       /* Azim vs Dir. */
+                                }
 				else if (S.symbol == GMT_SYMBOL_ELLIPSE) {
 					data1[n].x_size = (float)in[three];	/* direction */
 					data1[n].y_size = (float)in[four];	/* major */
@@ -631,7 +648,7 @@
 					if (gmtdefs.verbose) fprintf (stderr, "%s: Warning: Symbol size <= 0.0 near line %ld (skipped)\n", GMT_program, n_total_read);
 					continue;
 				}
-				if (S.read_vector && S.v_just < 3 && data1[n].y_size <= 0.0) {
+				if ( (S.read_vector || S.read_barb ) && S.v_just < 3 && data1[n].y_size <= 0.0) {
 					if (gmtdefs.verbose) fprintf (stderr, "%s: Warning: vector length <= 0.0 near line %ld (skipped)\n", GMT_program, n_total_read);
 					continue;
 				}
@@ -911,6 +928,16 @@
 							GMT_vector (data1[i].x, data1[i].y, x2, y2, data1[i].z, S.v_width, S.h_length, S.h_width, gmtdefs.vector_shape, &data1[i].f, this_outline);
 						}
 						break;
+                                         case GMT_SYMBOL_BARB:
+                                                if (data1[i].flag & 2) {
+                                                        GMT_azim_to_angle (data1[i].lon, data1[i].lat, 0.1, data1[i].x_size, &tmp);
+                                                        data1[i].x_size = (float)tmp;
+                                                }
+                                                else if (data1[i].flag & 1) {
+                                                        data1[i].x_size = (float)(90.0 - data1[i].x_size);
+                                                }
+                                                GMT_draw_barb (data1[i].x, data1[i].y, data1[i].z, data1[i].x_size, data1[i].y_size, S.b_width, S.b_length, copysign(S.b_angle, data1[i].lat), S.b_scale, &Ctrl->W.pen, &Ctrl->G.fill, Ctrl->W.active);
+                                                break;
 					case GMT_SYMBOL_PIE:
 						if (S.convert_angles == 2) {
 							GMT_azim_to_angle (data1[i].lon, data1[i].lat, 0.1, (double)(R2D*data1[i].y_size), &tmp);