4 * \author Alejandro Aguilar Sierra
5 * \author Angus Leeming
7 * This is a rewrite of Alejandro's C++ Combox class, originally written
8 * for LyX in 1996. The rewrite turns it into a native xforms widget.
12 #include FORMS_H_LOCATION
13 #include "freebrowser.h"
14 #include <ctype.h> /* isprint */
16 extern void fl_hide_tooltip(void);
18 static void browser_cb(FL_OBJECT * ob, long data);
20 static int peek_event(FL_FORM * form, void * xev);
23 FL_FREEBROWSER * fl_create_freebrowser(void * parent)
25 FL_FORM * current_form = fl_current_form;
26 FL_FREEBROWSER * fb = fl_calloc(1, sizeof(FL_FREEBROWSER));
30 FL_Coord const w = 100;
31 FL_Coord const h = 100;
35 fb->want_printable = 0;
36 fb->last_printable = 0;
38 if (current_form) fl_end_form();
39 fb->form = fl_bgn_form(FL_NO_BOX, w, h);
41 fb->form->u_vdata = fb;
42 fl_register_raw_callback(fb->form, ButtonPressMask|KeyPressMask,
45 ob = fb->browser = fl_add_browser(FL_HOLD_BROWSER, 0, 0, w, h, "");
47 fl_set_object_boxtype(ob, FL_UP_BOX);
48 fl_set_object_color(ob, FL_MCOL, FL_YELLOW);
49 fl_set_object_gravity(ob, NorthWestGravity, SouthEastGravity);
50 fl_set_object_callback(ob, browser_cb, 0);
54 fl_addto_form(current_form);
60 void fl_free_freebrowser(FL_FREEBROWSER * fb)
66 fl_free_form(fb->form);
73 void fl_show_freebrowser(FL_FREEBROWSER * fb,
74 FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h)
77 int const pos = fl_get_browser(fb->browser);
79 fl_set_form_geometry(fb->form, x, y, w, h);
81 XGetInputFocus(fl_get_display(), &fb->save_window, &tmp);
82 XFlush(fl_get_display());
84 fl_show_form(fb->form, FL_PLACE_POSITION, FL_NOBORDER, "");
86 fl_select_browser_line(fb->browser, pos);
87 fl_set_browser_topline(fb->browser, pos);
89 XGrabPointer(fl_get_display(), fb->form->window, 0,
90 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
91 GrabModeAsync, GrabModeAsync,
93 XFlush(fl_get_display());
99 void fl_hide_freebrowser(FL_FREEBROWSER * fb)
101 XUngrabPointer(fl_get_display(), 0);
102 XFlush(fl_get_display());
104 if (fb->form->visible)
105 fl_hide_form(fb->form);
107 XSetInputFocus(fl_get_display(), fb->save_window,
108 RevertToParent, CurrentTime);
109 XFlush(fl_get_display());
116 FL_OBJECT * fl_get_freebrowser_browser(FL_FREEBROWSER * fb)
122 static void browser_cb(FL_OBJECT * ob, long data)
124 FL_FREEBROWSER * fb = ob->u_vdata;
125 fl_hide_freebrowser(fb);
131 static int peek_event(FL_FORM * form, void * ev)
134 FL_FREEBROWSER * fb = form->u_vdata;
135 FL_OBJECT * browser = fb->browser;
137 fb->last_printable = 0;
140 if (xev->type == ButtonPress &&
141 ((int)(xev->xbutton.x) - (int)(browser->x) < 0 ||
142 (int)(xev->xbutton.x) - (int)(browser->x) > (int)(browser->w) ||
143 (int)(xev->xbutton.y) - (int)(browser->y) < 0 ||
144 (int)(xev->xbutton.y) - (int)(browser->y) > (int)(browser->h))) {
145 fl_hide_freebrowser(fb);
149 if (xev->type == KeyPress) {
150 char s_r[10]; s_r[9] = '\0';
151 KeySym keysym_return;
152 XLookupString(&xev->xkey, s_r, 10, &keysym_return, 0);
154 XFlush(fl_get_display());
156 switch (keysym_return) {
162 int sel = fl_get_browser(browser);
163 int const top = fl_get_browser_topline(browser);
164 int const screenlines = fl_get_browser_screenlines(browser);
166 if (sel < 1 || sel >= fl_get_browser_maxline(browser))
170 fl_select_browser_line(browser, sel);
172 if (sel >= top + screenlines)
173 fl_set_browser_topline(browser, sel - screenlines + 1);
176 fl_set_browser_topline(browser, sel);
186 int sel = fl_get_browser(browser);
187 int const top = fl_get_browser_topline(browser);
188 int const screenlines = fl_get_browser_screenlines(browser);
190 if (sel <= 1 || sel > fl_get_browser_maxline(browser))
194 fl_select_browser_line(browser, sel);
196 if (sel >= top + screenlines)
197 fl_set_browser_topline(browser, sel - screenlines + 1);
200 fl_set_browser_topline(browser, sel);
209 fl_hide_freebrowser(fb);
215 fl_hide_freebrowser(fb);
218 if (fb->want_printable && s_r[0] && isprint(s_r[0])) {
219 fb->last_printable = s_r[0];
220 fl_hide_freebrowser(fb);