X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FWorkArea.C;h=ea9324e037d1889905e6f870b78d77ec16bdf1cb;hb=32ef0d04c48a1751abbb5e3b17d1bec25f22c255;hp=7633b8362b1a77679a3bd2e3a02e121e4ed09a06;hpb=9062ce972e562477eb64c294769747ebf386fa6c;p=lyx.git diff --git a/src/WorkArea.C b/src/WorkArea.C index 7633b8362b..ea9324e037 100644 --- a/src/WorkArea.C +++ b/src/WorkArea.C @@ -4,13 +4,13 @@ * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich - * Copyright 1995-2000 The LyX Team. + * Copyright 1995-2001 The LyX Team. * * ====================================================== */ #include #include - +#include #ifdef __GNUG__ #pragma implementation #endif @@ -18,9 +18,11 @@ #include "WorkArea.h" #include "debug.h" #include "support/lstrings.h" -#include "BufferView.h" #include "LyXView.h" -#include "lyxfunc.h" + +#if FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5) +#include "lyxlookup.h" +#endif using std::endl; @@ -28,14 +30,19 @@ FL_OBJECT * figinset_canvas; // needed to make the c++ compiler find the correct version of abs. // This is at least true for g++. -using std::abs; +//using std::abs; + +namespace { -static inline +inline void waitForX() { XSync(fl_get_display(), 0); } +} // anon namespace + + extern "C" { // Just a bunch of C wrappers around static members of WorkArea void C_WorkArea_scroll_cb(FL_OBJECT * ob, long buf) @@ -53,9 +60,8 @@ extern "C" { } - -WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height) - : owner_(o), workareapixmap(0), painter_(*this) +WorkArea::WorkArea(int xpos, int ypos, int width, int height) + : workareapixmap(0), painter_(*this) { fl_freeze_all_forms(); @@ -67,7 +73,7 @@ WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height) << width << 'x' << height << endl; // FL_OBJECT * obj; - const int bw = int(std::abs(float(fl_get_border_width()))); + int const bw = int(std::abs(float(fl_get_border_width()))); // We really want to get rid of figinset_canvas. ::figinset_canvas = figinset_canvas = obj = @@ -116,15 +122,14 @@ WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height) << width - 15 - 2 * bw << 'x' << height - 2 * bw << endl; - work_area = obj = fl_add_free(FL_INPUT_FREE, + work_area = obj = fl_add_free(FL_ALL_FREE, xpos + bw, ypos + bw, width - 15 - 2 * bw, // scrollbarwidth height - 2 * bw, "", C_WorkArea_work_area_handler); - //obj->wantkey = FL_KEY_TAB; obj->wantkey = FL_KEY_ALL; obj->u_vdata = this; /* This is how we pass the WorkArea - to the work_area_handler. */ + to the work_area_handler. */ fl_set_object_boxtype(obj,FL_DOWN_BOX); fl_set_object_resize(obj, FL_RESIZE_ALL); fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity); @@ -136,7 +141,7 @@ WorkArea::WorkArea(BufferView * o, int xpos, int ypos, int width, int height) WorkArea::~WorkArea() { if (workareapixmap) - XFreePixmap(fl_display, workareapixmap); + XFreePixmap(fl_get_display(), workareapixmap); } @@ -165,7 +170,7 @@ void WorkArea::resize(int xpos, int ypos, int width, int height) { fl_freeze_all_forms(); - const int bw = int(std::abs(float(fl_get_border_width()))); + int const bw = int(std::abs(float(fl_get_border_width()))); // a box fl_set_object_geometry(backgroundbox, xpos, ypos, width - 15, height); @@ -201,14 +206,14 @@ void WorkArea::createPixmap(int width, int height) cur_height = height; if (workareapixmap) - XFreePixmap(fl_display, workareapixmap); + XFreePixmap(fl_get_display(), workareapixmap); if (lyxerr.debugging(Debug::GUI)) lyxerr << "Creating pixmap (" << width << 'x' << height << ")" << endl; - workareapixmap = XCreatePixmap(fl_display, - RootWindow(fl_display, 0), + workareapixmap = XCreatePixmap(fl_get_display(), + RootWindow(fl_get_display(), 0), width, height, fl_get_visual_depth()); @@ -257,10 +262,11 @@ void WorkArea::scroll_cb(FL_OBJECT * ob, long) // If we really want the accellerating scroll we can do that // from here. IMHO that is a waste of effort since we already // have other ways to move fast around in the document. (Lgb) - area->owner_->scrollCB(fl_get_scrollbar_value(ob)); + area->scrollCB(fl_get_scrollbar_value(ob)); waitForX(); } + bool Lgb_bug_find_hack = false; int WorkArea::work_area_handler(FL_OBJECT * ob, int event, @@ -288,7 +294,7 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, Lgb_bug_find_hack = false; break; case FL_PUSH: - if (!ev) break; + if (!ev || ev->xbutton.button == 0) break; // Should really have used xbutton.state lyxerr[Debug::GUI] << "Workarea event: PUSH" << endl; area->workAreaButtonPress(ev->xbutton.x - ob->x, @@ -297,14 +303,18 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, //area->workAreaKeyPress(XK_Pointer_Button1, ev->xbutton.state); break; case FL_RELEASE: - if (!ev) break; + if (!ev || ev->xbutton.button == 0) break; // Should really have used xbutton.state lyxerr[Debug::GUI] << "Workarea event: RELEASE" << endl; area->workAreaButtonRelease(ev->xbutton.x - ob->x, ev->xbutton.y - ob->y, ev->xbutton.button); break; +#if FL_REVISION < 89 case FL_MOUSE: +#else + case FL_DRAG: +#endif if (!ev || ! area->scrollbar) break; if (ev->xmotion.x != x_old || ev->xmotion.y != y_old || @@ -316,23 +326,29 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, ev->xbutton.state); } break; +#if FL_REVISION < 89 case FL_KEYBOARD: +#else + case FL_KEYPRESS: +#endif { - lyxerr[Debug::KEY] << "Workarea event: KEYBOARD"; - if (static_cast(ev)->type == KeyPress) - lyxerr << "KeyPress" << endl; - else - lyxerr << "KeyRelease" << endl; + lyxerr[Debug::KEY] << "Workarea event: KEYBOARD" << endl; KeySym keysym = 0; - char s_r[10]; + char dummy[1]; XKeyEvent * xke = reinterpret_cast(ev); - XLookupString(xke, s_r, 10, &keysym, 0); +#if FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5) + // XForms < 0.89.5 does not have compose support + // so we are using our own compose support + LyXLookupString(ev, dummy, 1, &keysym); +#else + XLookupString(xke, dummy, 1, &keysym, 0); +#endif if (lyxerr.debugging(Debug::KEY)) { char const * tmp = XKeysymToString(key); char const * tmp2 = XKeysymToString(keysym); - string stm = (tmp ? tmp : ""); - string stm2 = (tmp2 ? tmp2 : ""); + string const stm = (tmp ? tmp : ""); + string const stm2 = (tmp2 ? tmp2 : ""); lyxerr << "WorkArea: Key is `" << stm << "' [" << key << "]" << endl; @@ -340,20 +356,68 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, << keysym << "]" << endl; } - if (!key) break; - - KeySym ret_key = (keysym ? keysym : key); - unsigned int ret_state = xke->state; +#if FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5) + if (keysym == NoSymbol) { + lyxerr[Debug::KEY] + << "Empty kdb action (probably composing)" + << endl; + break; + } + KeySym ret_key = keysym; +#else + // Note that we need this handling because of a bug + // in XForms 0.89, if this bug is resolved in the way I hope + // we can just use the keysym directly with out looking + // at key at all. (Lgb) + KeySym ret_key = 0; + if (!key) { + // We migth have to add more keysyms here also, + // we will do that as the issues arise. (Lgb) + if (keysym == XK_space) { + ret_key = keysym; + lyxerr[Debug::KEY] << "Using keysym [A]" + << endl; + } else + break; + } else { + // It seems that this was a bit optimistic... + // With this hacking things seems to be better (Lgb) + //if (!iscntrl(key)) { + // ret_key = key; + // lyxerr[Debug::KEY] + // << "Using key [B]\n" + // << "Uchar[" + // << static_cast(key) + // << endl; + //} else { + ret_key = (keysym ? keysym : key); + lyxerr[Debug::KEY] << "Using keysym [B]" + << endl; + //} + } - static Time last_time_pressed = 0; - static unsigned int last_key_pressed = 0; - static unsigned int last_state_pressed = 0; - if (xke->time - last_time_pressed < 50 // should perhaps be tunable - && xke->state == last_state_pressed +#endif + unsigned int const ret_state = xke->state; + + // If you have a better way to handle "wild-output" of + // characters after the key has been released than the one + // below, please contact me. (Lgb) + static Time last_time_pressed; + static unsigned int last_key_pressed; + static unsigned int last_state_pressed; + lyxerr[Debug::KEY] << "Workarea Diff: " + << xke->time - last_time_pressed + << endl; + if (xke->time - last_time_pressed < 25 // should perhaps be tunable + && ret_state == last_state_pressed && xke->keycode == last_key_pressed) { lyxerr[Debug::KEY] << "Workarea: Purging X events." << endl; - XSync(fl_get_display(), 1); + //lyxerr << "Workarea Events: " + // << XEventsQueued(fl_get_display(), QueuedAlready) + // << endl; + if (XEventsQueued(fl_get_display(), QueuedAlready) > 0) + XSync(fl_get_display(), 1); // This purge make f.ex. scrolling stop immidiatly when // releasing the PageDown button. The question is if // this purging of XEvents can cause any harm... @@ -363,11 +427,18 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, } last_time_pressed = xke->time; last_key_pressed = xke->keycode; - last_state_pressed = xke->state; + last_state_pressed = ret_state; area->workAreaKeyPress(ret_key, ret_state); } break; + +#if FL_REVISION >= 89 + case FL_KEYRELEASE: + lyxerr << "Workarea event: KEYRELEASE" << endl; + break; +#endif + case FL_FOCUS: lyxerr[Debug::GUI] << "Workarea event: FOCUS" << endl; area->workAreaFocus(); @@ -409,11 +480,12 @@ int WorkArea::work_area_handler(FL_OBJECT * ob, int event, } -static string clipboard_selection; -static bool clipboard_read = false; +namespace { -extern "C" { - static +string clipboard_selection; +bool clipboard_read = false; + +extern "C" int request_clipboard_cb(FL_OBJECT * /*ob*/, long /*type*/, void const * data, long size) { @@ -426,9 +498,10 @@ int request_clipboard_cb(FL_OBJECT * /*ob*/, long /*type*/, clipboard_read = true; return 0; } -} -string WorkArea::getClipboard() const +} // namespace anon + +string const WorkArea::getClipboard() const { clipboard_read = false; @@ -452,5 +525,5 @@ void WorkArea::putClipboard(string const & s) const static string hold; hold = s; - fl_stuff_clipboard(work_area, 0, hold.c_str(), hold.size(), 0); + fl_stuff_clipboard(work_area, 0, hold.data(), hold.size(), 0); }