Index: configh.in
===================================================================
--- configh.in	(revision 8014)
+++ configh.in	(working copy)
@@ -320,5 +320,10 @@
 #undef HAVE_DLSYM
 
 /*
+ * Do we want ctrl+a select all text on Fl_Input ?
+ */
+#define CTRL_A_SELECT_ALL 1
+
+/*
  * End of "$Id$".
  */
Index: FL/Fl_Input.H
===================================================================
--- FL/Fl_Input.H	(revision 8014)
+++ FL/Fl_Input.H	(working copy)
@@ -97,9 +97,23 @@
   void handle_mouse(int keepmark=0);
 protected:
   void draw();
+  int right_to_left_;
+  /*[0] = decimal_places, [1] = decimal_separator, [3] = thousands_separator*/
+  static char default_number_format_[4];
+  char *number_format_;
 public:
   int handle(int);
   Fl_Input(int,int,int,int,const char * = 0);
+  ~Fl_Input();
+  int right_to_left() {return right_to_left_;};
+  void right_to_left(int bool_right_to_left) {right_to_left_ = bool_right_to_left;};
+  static const char *default_number_format();
+  static void default_number_format(const char *format);
+  const char *number_format() {return number_format_;};
+  void number_format(const char *format);
+  int decimal_places();
+  void decimal_places(int count);
+
 };
 
 #endif 
Index: FL/Fl_Input_.H
===================================================================
--- FL/Fl_Input_.H	(revision 8014)
+++ FL/Fl_Input_.H	(working copy)
@@ -246,6 +246,11 @@
   */
   const char* value() const {return value_;}
 
+  int value_int(int v);
+  int value_int();
+  int value_float(double v);
+  double value_float();
+
   /* Returns the character at index \p i. */
   Fl_Char index(int i) const;
 
@@ -300,6 +305,12 @@
     \see position(), position(int, int) */
   int mark(int m) {return position(position(), m);}
 
+  /** Selects all text
+    markall() is  the same as <tt>position(0); return position(size(),mark())</tt>.
+    \return 0 if the mark did not change
+    \see position(), position(int, int) */
+  int markall() {position(0); return position(size(), mark());}
+
   /* Deletes text from b to e and inserts the new string text. */
   int replace(int, int, const char*, int=0);
 
Index: src/Fl_Input.cxx
===================================================================
--- src/Fl_Input.cxx	(revision 8014)
+++ src/Fl_Input.cxx	(working copy)
@@ -44,13 +44,181 @@
 # include <locale.h>
 #endif
 
+char *do_number_format(char *resbuf, int resbuf_len, double d, int dec, char dec_point, char thousand_sep)
+{
+	char tmpbuf[64];
+	char *s, *t;  /* source, target */
+	char *dp;
+	int integral;
+	int tmplen, reslen=0;
+	int count=0;
+	int is_negative=0;
+	int trim_right_zeros=0;
 
+	if (d < 0) {
+		is_negative = 1;
+		d = -d;
+	}
+
+	if (dec < 0) {
+		trim_right_zeros = 1;
+		dec = -dec;
+	}
+
+	tmplen = snprintf(tmpbuf, sizeof(tmpbuf), "%.*f", dec, d);
+
+	if (!isdigit((int)tmpbuf[0])) {
+		return NULL;
+	}
+
+	/* find decimal point, if expected */
+	if (dec) {
+		dp = strpbrk(tmpbuf, ".,");
+	} else {
+		dp = NULL;
+	}
+
+	/* calculate the length of the return buffer */
+	if (dp) {
+		integral = dp - tmpbuf;
+	} else {
+		/* no decimal point was found */
+		integral = tmplen;
+	}
+
+	/* allow for thousand separators */
+	if (thousand_sep) {
+		integral += (integral-1) / 3;
+	}
+
+	reslen = integral;
+
+	if (dec) {
+		reslen += dec;
+
+		if (dec_point) {
+			reslen++;
+		}
+	}
+
+	/* add a byte for minus sign */
+	if (is_negative) {
+		reslen++;
+	}
+	if(resbuf_len < reslen+1) return NULL;
+
+	s = tmpbuf+tmplen-1;
+	t = resbuf+reslen;
+	*t-- = '\0';
+
+	/* copy the decimal places.
+	 * Take care, as the sprintf implementation may return less places than
+	 * we requested due to internal buffer limitations */
+	if (dec) {
+		int declen = dp ? s - dp : 0;
+		int topad = dec > declen ? dec - declen : 0;
+
+		/* pad with '0's */
+		while (topad--) {
+			*t-- = '0';
+		}
+
+		if (dp) {
+			s -= declen + 1; /* +1 to skip the point */
+			t -= declen;
+
+			/* now copy the chars after the point */
+			memcpy(t + 1, dp + 1, declen);
+		}
+
+		/* add decimal point */
+		if (dec_point) {
+			*t-- = dec_point;
+		}
+	}
+
+	/* copy the numbers before the decimal point, adding thousand
+	 * separator every three digits */
+	while(s >= tmpbuf) {
+		*t-- = *s--;
+		if (thousand_sep && (++count%3)==0 && s>=tmpbuf) {
+			*t-- = thousand_sep;
+		}
+	}
+
+	/* and a minus sign, if needed */
+	if (is_negative) {
+		*t-- = '-';
+	}
+
+	/* trim right zeros */
+	if (dec_point && trim_right_zeros) {
+		for(t=resbuf+reslen-1; *t != dec_point; t--){
+			if (*t == '0') *t = '\0';
+			else break;
+		}
+		if (*t == dec_point) *t = '\0';
+	}
+
+	return resbuf;
+}
+
+/*[0] = decimal_places, [1] = decimal_separator, [3] = thousands_separator*/
+char Fl_Input::default_number_format_[4] = "\2.,";
+
 void Fl_Input::draw() {
   if (input_type() == FL_HIDDEN_INPUT) return;
+
+  char num_buffer[64];
+  char saved_value[64];
+  int using_number_format = 0;
   Fl_Boxtype b = box();
+  int xo = x()+Fl::box_dx(b);
+  int yo = y()+Fl::box_dy(b);
+  int wo = w()-Fl::box_dw(b);
+  int ho = h()-Fl::box_dh(b);
+
+  if (right_to_left_ && (Fl::focus() != this)) {
+	  using_number_format = (input_type() == FL_FLOAT_INPUT || input_type() == FL_INT_INPUT);
+	  if (using_number_format) {
+		double d = atof(value());
+		int dec;
+		char dec_point;
+		char thousand_sep;
+		if(number_format_) {
+			dec = number_format_[0];
+			dec_point = number_format_[1] == -1 ? Fl_Input::default_number_format_[1] : number_format_[1];
+			thousand_sep = number_format_[2] == -1 ? Fl_Input::default_number_format_[2] : number_format_[2];
+		} else {
+			dec = Fl_Input::default_number_format_[0];
+			dec_point = Fl_Input::default_number_format_[1];
+			thousand_sep = Fl_Input::default_number_format_[2];
+		}
+		if(input_type() == FL_INT_INPUT) dec = 0;
+		if(do_number_format(num_buffer, sizeof(num_buffer), d, dec, dec_point, thousand_sep)){
+			memcpy(saved_value, value(), sizeof(saved_value));
+			value(num_buffer);
+		} else using_number_format = 0;
+	  }
+
+	// Simplest to just redraw the whole box every time...
+	damage(FL_DAMAGE_ALL);
+
+	int wt, ht;
+
+	// How long is the string to display?
+	wt = 0; ht = 0;
+	fl_measure(value(), wt, ht);
+
+	// Make the text window be at the right hand end
+	wt = wt + 5;
+	xo = xo + wo - wt;
+	wo = wt;
+  }
   if (damage() & FL_DAMAGE_ALL) draw_box(b, color());
-  Fl_Input_::drawtext(x()+Fl::box_dx(b), y()+Fl::box_dy(b),
-		      w()-Fl::box_dw(b), h()-Fl::box_dh(b));
+  // Update the text window
+  Fl_Input_::drawtext(xo, yo, wo, ho);
+  if (using_number_format) value(saved_value);
 }
 
 // kludge so shift causes selection to extend:
@@ -307,7 +475,11 @@
       } else return 1;
 #else
       if (mods==0) {
+#ifdef CTRL_A_SELECT_ALL
+        return shift_position(line_start(position())) + NORMAL_INPUT_MOVE;
+#else
         ascii = ctrl('A');
+#endif
       } else if (mods==FL_CTRL) {
         shift_position(0);
         return 1;
@@ -326,8 +498,12 @@
       if (mods==0) {
         ascii = ctrl('E');
       } else if (mods==FL_CTRL) {
+#ifdef CTRL_A_SELECT_ALL
+        ascii = ctrl('A');
+#else
         shift_position(size());
         return 1;
+#endif
       } else return 1;
 #endif
       break;
@@ -375,12 +551,22 @@
       //    printf("using '%c' (0x%02x)...\n", ascii, ascii);
       break;
 #endif // __APPLE__
+#ifdef CTRL_A_SELECT_ALL
+    case 'a':
+      if (mods==FL_CTRL) ascii = ctrl('A');
+      break;
+#endif
   }
   
   int i;
   switch (ascii) {
     case ctrl('A'): // go to the beginning of the current line
+#ifdef CTRL_A_SELECT_ALL
+      markall();
+      return 1;
+#else
       return shift_position(line_start(position())) + NORMAL_INPUT_MOVE;
+#endif
     case ctrl('B'): // go one character backward
       i = shift_position(position()-1) + NORMAL_INPUT_MOVE;
       return Fl::option(Fl::OPTION_ARROW_FOCUS) ? i : 1;
@@ -659,8 +845,43 @@
  */
 Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l)
 : Fl_Input_(X, Y, W, H, l) {
+	right_to_left_ = 0;
+	number_format_ = NULL;
 }
 
+Fl_Input::~Fl_Input(){
+	if(number_format_)
+		free((void*)number_format_);
+}
+
+void Fl_Input::default_number_format(const char *format){
+	memcpy(Fl_Input::default_number_format_, format, sizeof(Fl_Input::default_number_format_));
+}
+
+const char *Fl_Input::default_number_format(void){
+	return Fl_Input::default_number_format_;
+}
+
+void Fl_Input::number_format(const char *format){
+	if(!number_format_)
+		number_format_ = (char *)malloc(sizeof(Fl_Input::default_number_format_));
+	memcpy(number_format_, format, sizeof(Fl_Input::default_number_format_));
+}
+
+int Fl_Input::decimal_places(){
+	if(number_format_) return number_format_[0];
+	return Fl_Input::default_number_format_[0];
+}
+
+void Fl_Input::decimal_places(int count){
+	if(!number_format_){
+		number_format_ = (char *)malloc(sizeof(Fl_Input::default_number_format_));
+		number_format_[1] = -1;
+		number_format_[2] = -1;
+	}
+	number_format_[0] = count;
+}
+
 //
 // End of "$Id$".
 //
Index: src/Fl_Input_.cxx
===================================================================
--- src/Fl_Input_.cxx	(revision 8014)
+++ src/Fl_Input_.cxx	(working copy)
@@ -1018,7 +1018,7 @@
   case FL_SHORTCUT:
     if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut())) 
       return 0;
-    if (Fl::visible_focus() && handle(FL_FOCUS)) {
+    if (Fl::visible_focus() && visible_focus() && handle(FL_FOCUS)) {
       Fl::focus(this);
       return 1;
     } // else fall through
@@ -1201,6 +1201,40 @@
   return value(str, str ? strlen(str) : 0);
 }
 
+int Fl_Input_::value_int(int v) {
+  char buf[64];
+  snprintf(buf, sizeof(buf), "%d", v);
+  return value(buf);
+}
+
+int Fl_Input_::value_int() {
+    const char *s = value();
+    // Integer conversion
+    int ival = 0;
+    if ( sscanf(s, "%d", &ival) != 1 ) {
+      //fail = 1;		// "not an integer"
+      return(0);
+    }
+    return ival;
+}
+
+int Fl_Input_::value_float(double v) {
+  char buf[64];
+  snprintf(buf, sizeof(buf), "%f", v);
+  return value(buf);
+}
+
+double Fl_Input_::value_float() {
+    const char *s = value();
+    // Integer conversion
+    double dval = 0;
+    if ( sscanf(s, "%lf", &dval) != 1 ) {
+      //fail = 1;		// "not an integer"
+      return(0);
+    }
+    return dval;
+}
+
 /**
   Changes the size of the widget.
   This call updates the text layout so that the cursor is visible.
