]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/xforms/XWorkArea.C
get rid of broken_header.h and some unneeded tests
[lyx.git] / src / frontends / xforms / XWorkArea.C
index 4d9893b49c471a3ea54ed0e0fb29e4a20a445ea8..51f9a4e405b439b75818cbdeacb50ee1f926a4f8 100644 (file)
 #include <config.h>
 
 #include "XWorkArea.h"
+
+#include "Color.h"
 #include "XFormsView.h"
+#include "XLyXKeySym.h"
 
 #include "debug.h"
-#include "XLyXKeySym.h"
 #include "funcrequest.h"
+#include "LColor.h"
 #include "Timeout.h"
 
 #include <boost/bind.hpp>
 
-using lyx::frontend::Box;
-using lyx::frontend::BoxList;
-using lyx::frontend::WidgetMap;
+using boost::shared_ptr;
 
 using std::abs;
 using std::dec;
@@ -31,6 +32,8 @@ using std::endl;
 using std::hex;
 using std::string;
 
+namespace lyx {
+namespace frontend {
 
 namespace {
 
@@ -116,6 +119,12 @@ XWorkArea::XWorkArea(LyXView & owner, int w, int h)
        fl_set_object_resize(obj, FL_RESIZE_ALL);
        fl_set_object_gravity(obj, NorthWestGravity, SouthEastGravity);
 
+       unsigned int r, g, b;
+       if (getRGBColor(LColor::background, r, g, b)) {
+               fl_mapcolor(FL_FREE_COL12, r, g, b);
+               fl_set_object_color(obj, FL_FREE_COL12, FL_MCOL);
+       }
+
        // The scrollbar.
        scrollbar = obj = fl_add_scrollbar(FL_VERT_SCROLLBAR, 0, 0, w, h, "");
        fl_set_object_boxtype(obj, FL_UP_BOX);
@@ -140,17 +149,17 @@ XWorkArea::XWorkArea(LyXView & owner, int w, int h)
        // Hand control of the layout of these widgets to the
        // Layout Engine.
        XFormsView & xview = dynamic_cast<XFormsView &>(owner);
-       BoxList & boxlist = xview.getBox(XFormsView::Center).children();
+       BoxList & boxlist = xview.getBox(XFormsView::Center)->children();
 
-       wa_box_ = &boxlist.push_back(Box(0,0));
+       wa_box_ = boxlist.push_back(Box(0,0));
        wa_box_->set(Box::Horizontal);
 
-       Box & frame_box = widgets_.add(frame, wa_box_->children(), 0, 0);
-       frame_box.set(Box::Expand);
+       shared_ptr<Box> frame_box = widgets_.add(frame, wa_box_->children(), 0, 0);
+       frame_box->set(Box::Expand);
 
        int const bw = int(abs(fl_get_border_width()));
-       Box & wa_box = embed(work_area, frame_box.children(), widgets_, bw);
-       wa_box.set(Box::Expand);
+       shared_ptr<Box> wa_box = embed(work_area, frame_box->children(), widgets_, bw);
+       wa_box->set(Box::Expand);
 
        widgets_.add(scrollbar, wa_box_->children(), 17, 0);
 
@@ -166,8 +175,9 @@ XWorkArea::XWorkArea(LyXView & owner, int w, int h)
        XGCValues val;
 
        val.function = GXcopy;
+       val.graphics_exposures = false;
        copy_gc = XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0),
-                           GCFunction, &val);
+                           GCFunction | GCGraphicsExposures, &val);
 }
 
 
@@ -179,17 +189,13 @@ XWorkArea::~XWorkArea()
 }
 
 
-void XWorkArea::redraw(int width, int height)
+void XWorkArea::updateGeometry(int width, int height)
 {
        static int cur_width = -1;
        static int cur_height = -1;
 
-       if (cur_width == width && cur_height == height && workareapixmap) {
-               XCopyArea(fl_get_display(),
-                         getPixmap(), getWin(), copy_gc,
-                         0, 0, width, height, xpos(), ypos());
+       if (cur_width == width && cur_height == height && workareapixmap)
                return;
-       }
 
        cur_width = width;
        cur_height = height;
@@ -213,6 +219,20 @@ void XWorkArea::redraw(int width, int height)
 }
 
 
+void XWorkArea::paint(int x, int y, int w, int h)
+{
+       lyxerr[Debug::WORKAREA]
+               << "XWorkarea::paint " << w << 'x' << h
+               << '+' << x << '+' << y << endl;
+
+       updateGeometry(workWidth(), workHeight());
+       XCopyArea(fl_get_display(),
+                 getPixmap(), getWin(),
+                 copy_gc, x, y, w, h,
+                 work_area->x + x, work_area->y + y);
+}
+
+
 void XWorkArea::setScrollbarParams(int height, int pos, int line_height)
 {
        // we need to cache this for scroll_cb
@@ -275,6 +295,9 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
                                 FL_Coord, FL_Coord,
                                 int key, void * xev)
 {
+       if (event != 11)
+               lyxerr[Debug::WORKAREA] << "Workarea event: EVENT: " << event << endl;
+
        XEvent * ev = static_cast<XEvent*>(xev);
        XWorkArea * area = static_cast<XWorkArea*>(ob->u_vdata);
 
@@ -283,15 +306,62 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
 
        switch (event) {
 
-       case FL_DRAW:
+       case FL_DRAW: {
                if (!area->work_area || !area->work_area->form->visible)
                        return 1;
-               lyxerr[Debug::WORKAREA] << "Workarea event: DRAW" << endl;
-               area->redraw(area->workWidth(), area->workHeight());
+
+               if (ev) {
+                       lyxerr[Debug::WORKAREA]
+                               << "work_area_handler, handling X11 "
+                               "expose event "
+                               << ev->xexpose.width << 'x'
+                               << ev->xexpose.height << '+'
+                               << ev->xexpose.x << '+'
+                               << ev->xexpose.y << endl;
+
+                       // X11 generates XEvents with x, y relative to the
+                       // top left corner of the window.
+                       // XScreen::expose emulates this behaviour.
+                       // We therefore need to remove this offset before
+                       // generating the pixmap.
+                        int const x = ev->xexpose.x - ob->x;
+                        int const y = ev->xexpose.y - ob->y;
+
+                       area->paint(x, y,
+                                   ev->xexpose.width, ev->xexpose.height);
+               } else
+                       area->paint(0, 0,
+                                   area->workWidth(), area->workHeight());
+
                break;
+       }
 
        case FL_PUSH:
                if (!ev || ev->xbutton.button == 0) break;
+
+               if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+                       static long last_wheel;
+
+                       long cur_wheel = ev->xbutton.time;
+                       if (last_wheel == cur_wheel)
+                               break;
+
+                       last_wheel = cur_wheel;
+
+                       float l, r;
+                       fl_get_scrollbar_increment(area->scrollbar, &l, &r);
+
+                       if (ev->xbutton.button == 4)
+                               l *= -1.0;
+
+                       fl_set_scrollbar_value(
+                               area->scrollbar,
+                               fl_get_scrollbar_value(area->scrollbar) + l);
+
+                       area->scroll_cb();
+                       break;
+               }
+
                // Should really have used xbutton.state
                lyxerr[Debug::WORKAREA] << "Workarea event: PUSH" << endl;
                area->dispatch(
@@ -304,7 +374,14 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
        case FL_RELEASE:
                if (!ev || ev->xbutton.button == 0) break;
                // Should really have used xbutton.state
+
+               if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+                       // We ingnore wheel event here
+                       break;
+               }
+
                lyxerr[Debug::WORKAREA] << "Workarea event: RELEASE" << endl;
+
                area->dispatch(
                        FuncRequest(LFUN_MOUSE_RELEASE,
                                    ev->xbutton.x - ob->x,
@@ -313,6 +390,8 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
                break;
 
        case FL_DRAG: {
+               lyxerr[Debug::WORKAREA] << "Workarea event: DRAG 0" << endl;
+
                if (!ev || !area->scrollbar)
                        break;
 
@@ -485,6 +564,12 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
 
        case FL_DBLCLICK:
                if (ev) {
+                       if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+                               // Ignore wheel events
+                               break;
+                       }
+
+
                        lyxerr[Debug::WORKAREA] << "Workarea event: DBLCLICK" << endl;
                        FuncRequest cmd(LFUN_MOUSE_DOUBLE,
                                        ev->xbutton.x - ob->x,
@@ -496,6 +581,11 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event,
 
        case FL_TRPLCLICK:
                if (ev) {
+                       if (ev->xbutton.button == 4 || ev->xbutton.button == 5) {
+                               // Ignore wheel events
+                               break;
+                       }
+
                        lyxerr[Debug::WORKAREA] << "Workarea event: TRPLCLICK" << endl;
                        FuncRequest cmd(LFUN_MOUSE_TRIPLE,
                                        ev->xbutton.x - ob->x,
@@ -591,3 +681,6 @@ void XWorkArea::putClipboard(string const & s) const
 
        fl_stuff_clipboard(work_area, 0, hold.data(), hold.size(), 0);
 }
+
+} // namespace frontend
+} // namespace lyx