source: rtems-graphics-toolkit/fltk-1.1.10/src/fl_shortcut.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 7.1 KB
Line 
1//
2// "$Id$"
3//
4// Shortcut support routines for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2005 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25//     http://www.fltk.org/str.php
26//
27
28// Code to test and parse fltk shortcut numbers.
29//
30// A shortcut is a keysym or'd with shift flags.  In the simplest
31// sense a shortcut is matched if the shift state is exactly as
32// given and the key returning that keysym is pressed.
33//
34// To make it easier to match some things it is more complex:
35//
36// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off".  A
37// zero in the other shift flags indicates "dont care".
38//
39// It also checks against the first character of Fl::event_text(),
40// and zero for FL_SHIFT means "don't care".
41// This allows punctuation shortcuts like "#" to work (rather than
42// calling it "shift+3")
43
44#include <FL/Fl.H>
45#include <FL/Fl_Widget.H>
46#include <FL/Fl_Button.H>
47#include <FL/fl_draw.H>
48#include <ctype.h>
49#include "flstring.h"
50#if !defined(WIN32) && !defined(__APPLE__)
51#include <FL/x.H>
52#endif
53
54int Fl::test_shortcut(int shortcut) {
55  if (!shortcut) return 0;
56
57  int v = shortcut & 0xffff;
58#ifdef __APPLE__
59  if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) {
60#else
61  // most X11 use MSWindows Latin-1 if set to Western encoding, so 0x80 to 0xa0 are defined
62  if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) {
63#endif
64    if (isupper(v)) {
65      shortcut |= FL_SHIFT;
66    }
67  }
68
69  int shift = Fl::event_state();
70  // see if any required shift flags are off:
71  if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0;
72  // record shift flags that are wrong:
73  int mismatch = (shortcut^shift)&0x7fff0000;
74  // these three must always be correct:
75  if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0;
76
77  int key = shortcut & 0xffff;
78
79  // if shift is also correct, check for exactly equal keysyms:
80  if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1;
81
82  // try matching ascii, ignore shift:
83  if (key == event_text()[0]) return 1;
84
85  // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'):
86  if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F
87      && event_text()[0]==(key^0x40)) return 1;
88  return 0;
89}
90
91#if defined(WIN32) || defined(__APPLE__) // if not X
92// This table must be in numeric order by fltk (X) keysym number:
93struct Keyname {int key; const char* name;};
94static Keyname table[] = {
95  {' ', "Space"},
96  {FL_BackSpace, "Backspace"},
97  {FL_Tab,      "Tab"},
98  {0xff0b/*XK_Clear*/, "Clear"},
99  {FL_Enter,    "Enter"}, // X says "Enter"
100  {FL_Pause,    "Pause"},
101  {FL_Scroll_Lock, "Scroll_Lock"},
102  {FL_Escape,   "Escape"},
103  {FL_Home,     "Home"},
104  {FL_Left,     "Left"},
105  {FL_Up,       "Up"},
106  {FL_Right,    "Right"},
107  {FL_Down,     "Down"},
108  {FL_Page_Up,  "Page_Up"}, // X says "Prior"
109  {FL_Page_Down,"Page_Down"}, // X says "Next"
110  {FL_End,      "End"},
111  {FL_Print,    "Print"},
112  {FL_Insert,   "Insert"},
113  {FL_Menu,     "Menu"},
114  {FL_Num_Lock, "Num_Lock"},
115  {FL_KP_Enter, "KP_Enter"},
116  {FL_Shift_L,  "Shift_L"},
117  {FL_Shift_R,  "Shift_R"},
118  {FL_Control_L,"Control_L"},
119  {FL_Control_R,"Control_R"},
120  {FL_Caps_Lock,"Caps_Lock"},
121  {FL_Meta_L,   "Meta_L"},
122  {FL_Meta_R,   "Meta_R"},
123  {FL_Alt_L,    "Alt_L"},
124  {FL_Alt_R,    "Alt_R"},
125  {FL_Delete,   "Delete"}
126};
127#endif
128
129const char * fl_shortcut_label(int shortcut) {
130  static char buf[20];
131  char *p = buf;
132  if (!shortcut) {*p = 0; return buf;}
133  // fix upper case shortcuts
134  int v = shortcut & 0xffff;
135#ifdef __APPLE__
136  if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) {
137#else
138  if (v > 32 && v < 0x7f || v >= 0xa0 && v <= 0xff) {
139#endif
140    if (isupper(v)) {
141      shortcut |= FL_SHIFT;
142    }
143  }
144#ifdef __APPLE__
145  // \todo Mac :  we might want to change the symbols for Mac users - consider drawing Apple Symbols... .
146  if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} //: Mac hollow up arrow
147  if (shortcut & FL_META)  {strcpy(p,"Cmd+"); p += 4;}  //: Mac 'Apple' key
148  if (shortcut & FL_ALT)   {strcpy(p,"Option+"); p += 7;}   //: Mac 'Alt/Option' or fancy switch symbol
149  if (shortcut & FL_CTRL)  {strcpy(p,"Ctrl+"); p += 5;}  //: Mac ctrl key
150#else
151  if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
152  if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;}
153  if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;}
154  if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
155#endif // __APPLE__
156  int key = shortcut & 0xFFFF;
157#if defined(WIN32) || defined(__APPLE__) // if not X
158  if (key >= FL_F && key <= FL_F_Last) {
159    *p++ = 'F';
160    if (key > FL_F+9) *p++ = (key-FL_F)/10+'0';
161    *p++ = (key-FL_F)%10 + '0';
162  } else {
163    // binary search the table for a match:
164    int a = 0;
165    int b = sizeof(table)/sizeof(*table);
166    while (a < b) {
167      int c = (a+b)/2;
168      if (table[c].key == key) {
169        if (p > buf) {strcpy(p,table[c].name); return buf;}
170        return table[c].name;
171      }
172      if (table[c].key < key) a = c+1;
173      else b = c;
174    }
175    if (key >= FL_KP && key <= FL_KP_Last) {
176      // mark keypad keys with KP_ prefix
177      strcpy(p,"KP_"); p += 3;
178      *p++ = uchar(key & 127);
179    } else {
180      // if none found, use the keystroke as a match:
181      *p++ = uchar(toupper(key & 255));
182    }
183  }
184  *p = 0;
185  return buf;
186#else
187  const char* q;
188  if (key == FL_Enter || key == '\r') q="Enter";  // don't use Xlib's "Return":
189  else if (key > 32 && key < 0x100) q = 0;
190  else q = XKeysymToString(key);
191  if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;}
192  if (p > buf) {strcpy(p,q); return buf;} else return q;
193#endif
194}
195
196// Emulation of XForms named shortcuts
197#include <stdlib.h>
198int fl_old_shortcut(const char* s) {
199  if (!s || !*s) return 0;
200  int n = 0;
201  if (*s == '#') {n |= FL_ALT; s++;}
202  if (*s == '+') {n |= FL_SHIFT; s++;}
203  if (*s == '^') {n |= FL_CTRL; s++;}
204  if (*s && s[1]) return n | (int)strtol(s,0,0); // allow 0xf00 to get any key
205  return n | *s;
206}
207
208// Tests for &x shortcuts in button labels:
209
210char Fl_Widget::label_shortcut(const char *t) {
211  if (!t) return 0;
212  for (;;) {
213    if (*t==0) return 0;
214    if (*t=='&') {
215      char s = t[1];
216      if (s==0) return 0;
217      else if (s=='&') t++;
218      else return s;
219    }
220    t++;
221  }
222}
223
224int Fl_Widget::test_shortcut(const char *t) {
225  #ifdef WIN32
226  // on MSWindows, users expect shortcuts to work only when the Alt modifier is pressed
227  if (Fl::event_state(FL_ALT)==0) return 0;
228  #endif
229  char c = Fl::event_text()[0];
230  if (!c || !t) return 0;
231  if (c == label_shortcut(t))
232    return 1;
233  return 0;
234}
235
236int Fl_Widget::test_shortcut() {
237  if (!(flags()&SHORTCUT_LABEL)) return 0;
238  return test_shortcut(label());
239}
240
241//
242// End of "$Id$".
243//
Note: See TracBrowser for help on using the repository browser.