home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / WXWIN140.ZIP / SRC / WX_CANVS.CC < prev    next >
C/C++ Source or Header  |  1993-04-19  |  31KB  |  1,231 lines

  1. /*
  2.  * File:     wx_canvs.cc
  3.  * Purpose:  wxCanvas implementation
  4.  *
  5.  *                       wxWindows 1.40
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 18-4-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <windows.h>
  30. #include <math.h>
  31. #include "common.h"
  32. #include "wx_frame.h"
  33. #include "wx_dc.h"
  34. #include "wx_canvs.h"
  35. #include "wx_event.h"
  36. #include "wx_utils.h"
  37. #include "wx_privt.h"
  38.  
  39. #ifdef wx_motif
  40. #include "wx_main.h"
  41.  
  42. #include <Xm/DrawingA.h>
  43. #include <Xm/ScrolledW.h>
  44. #include <Xm/ScrollBar.h>
  45.  
  46. #define SCROLL_MARGIN 4
  47. void wxCanvasRepaintProc(Widget, XtPointer, XmDrawingAreaCallbackStruct *cbs);
  48. void wxCanvasKeyEvent(Widget, XKeyEvent *);
  49. void wxCanvasInputEvent(Widget, XButtonEvent *event);
  50. #endif
  51.  
  52. #ifdef wx_xview
  53. #include <xview/screen.h>
  54. extern Xv_Server xview_server;
  55. void wxCanvasRepaintProc(Canvas canvas, Xv_Window paint_window,
  56.                     Display *dpy, Window xwin, Xv_xrectlist *xrects);
  57. void wxCanvasResizeProc(Canvas canvas, int width, int height);
  58. void wxCanvasEventProc(Xv_Window window, Event *event, Notify_arg arg);
  59.  
  60. #endif
  61.  
  62. wxCanvas::wxCanvas(wxFrame *frame, int x, int y, int width, int height, int style)
  63. {
  64.   is_retained = ((style & wxRETAINED) == wxRETAINED);
  65.  
  66. #ifdef wx_motif
  67.   hScroll = FALSE;
  68.   vScroll = FALSE;
  69.   hScrollBar = NULL;
  70.   vScrollBar = NULL;
  71.   allowRepainting = TRUE;
  72.   hScrollingEnabled = TRUE;
  73.   vScrollingEnabled = TRUE;
  74.   // Can't rely on Xt to return these values, so must store.
  75.   canvasWidth = 0;
  76.   canvasHeight = 0;
  77.   canvasX = 0;
  78.   canvasY = 0;
  79.   backingPixmap = 0;
  80.   pixmapWidth = 0;
  81.   pixmapHeight = 0;
  82.   hExtent = 0;
  83.   vExtent = 0;
  84.   button1Pressed = FALSE;
  85.   button2Pressed = FALSE;
  86.   button3Pressed = FALSE;
  87.   pixmapOffsetX = 0;
  88.   pixmapOffsetY = 0;
  89.  
  90.   // New translations for getting mouse motion feedback - duh!
  91.   String translations =
  92.     "<Btn1Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
  93.      <Btn2Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
  94.      <Btn3Motion>: wxCanvasInputEvent() ManagerGadgetButtonMotion()\n\
  95.      <Btn1Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
  96.      <Btn2Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
  97.      <Btn3Down>: wxCanvasInputEvent() ManagerGadgetArm()\n\
  98.      <Btn1Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
  99.      <Btn2Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
  100.      <Btn3Up>: wxCanvasInputEvent() ManagerGadgetActivate()\n\
  101.      <Key>: wxCanvasKeyEvent()";
  102.  
  103.   XtActionsRec actions[2];
  104.   actions[0].string = "wxCanvasInputEvent";
  105.   actions[0].proc = (XtActionProc)wxCanvasInputEvent;
  106.   actions[1].string = "wxCanvasKeyEvent";
  107.   actions[1].proc = (XtActionProc)wxCanvasKeyEvent;
  108.   XtAppAddActions(wxTheApp->appContext, &actions, 2);
  109.  
  110.   Widget parentWidget = frame->workArea;
  111.   scrolledWindow = XtVaCreateManagedWidget("scrolled_window",
  112.                     xmScrolledWindowWidgetClass, parentWidget,
  113.                     XmNscrollingPolicy,          XmAPPLICATION_DEFINED,
  114.                     NULL);
  115.  
  116.   Widget drawingArea = XtVaCreateManagedWidget("drawing_area",
  117.                     xmDrawingAreaWidgetClass,    scrolledWindow,
  118.                     XmNunitType,                 XmPIXELS,
  119.                     XmNresizePolicy,             XmRESIZE_ANY,
  120.                     XmNtranslations,             XtParseTranslationTable(translations),
  121.                     NULL);
  122.  
  123.   handle = (char *)drawingArea;
  124.  
  125.   wxWidgetHashTable->Put((long)drawingArea, this);
  126.   wxWidgetHashTable->Put((long)scrolledWindow, this);
  127.  
  128.   XtOverrideTranslations(drawingArea,
  129.               XtParseTranslationTable("<Configure>: resize()"));
  130.  
  131.   XtAddCallback(drawingArea, XmNexposeCallback, wxCanvasRepaintProc, this);
  132.  
  133.   if (x > -1)
  134.   {
  135.     canvasX = x;
  136.     XtVaSetValues(scrolledWindow,
  137.                   XmNleftAttachment, XmATTACH_SELF,
  138.                   XmNx, x, 
  139.                   NULL);
  140.   }
  141.   if (y > -1)
  142.   {
  143.     canvasY = y;
  144.     XtVaSetValues(scrolledWindow,
  145.                   XmNtopAttachment, XmATTACH_SELF,
  146.                   XmNy, y,
  147.                   NULL);
  148.   }
  149.   if (width > -1)
  150.   {
  151.     canvasWidth = width;
  152.     XtVaSetValues(scrolledWindow, XmNwidth, width, NULL);
  153.     if (!hScroll)
  154.       XtVaSetValues(drawingArea, XmNwidth, width - SCROLL_MARGIN, NULL);
  155.   }
  156.   if (height > -1)
  157.   {
  158.     canvasHeight = height;
  159.     XtVaSetValues(scrolledWindow, XmNheight, height, NULL);
  160.     if (!vScroll)
  161.       XtVaSetValues(drawingArea, XmNheight, height - SCROLL_MARGIN, NULL);
  162.   }
  163.  
  164.   XtRealizeWidget(scrolledWindow);
  165.   XtRealizeWidget(drawingArea);
  166.  
  167.   if (!hScroll)
  168.   {
  169.     Widget hWidget;
  170.     XtVaGetValues(scrolledWindow, XmNhorizontalScrollBar, &hWidget, NULL);
  171.   }
  172.   if (!vScroll)
  173.   {
  174.     Widget vWidget;
  175.     XtVaGetValues(scrolledWindow, XmNverticalScrollBar, &vWidget, NULL);
  176.   }
  177.  
  178.   display = XtDisplay(scrolledWindow);
  179.   xwindow = XtWindow(drawingArea);
  180. //  SetSize(x, y, width, height);
  181. #endif
  182. #ifdef wx_xview
  183.   repaint_countdown = 0;
  184.  
  185.   // Since I have found that it's difficult to keep up with
  186.   // all XView drag events, this counts down to zero before sending
  187.   // an OnEvent message. If you want more sensitivity, reduce this value
  188.   // and recompile wxWindows.
  189.   DRAG_MAX = 0;
  190.  
  191.   int real_y = frame->y_offset;
  192.   if (y > -1)
  193.     real_y = y + frame->y_offset;  // Allow for possible menu bar
  194.  
  195.   Frame x_frame = (Frame)frame->handle;
  196.   Canvas x_canvas = (Canvas)xv_create(x_frame, CANVAS, 
  197. //                            CANVAS_REPAINT_PROC, wxCanvasRepaintProc,
  198. //                            CANVAS_RESIZE_PROC, wxCanvasResizeProc,
  199.                             CANVAS_X_PAINT_WINDOW, TRUE,
  200.                             WIN_CLIENT_DATA, (char *)this,
  201.                             CANVAS_RETAINED, is_retained,
  202.                             XV_SHOW, FALSE,
  203.                             NULL);
  204.  
  205.   xv_set(canvas_paint_window(x_canvas), WIN_EVENT_PROC, wxCanvasEventProc,
  206.          WIN_CONSUME_EVENTS,
  207.              WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
  208.              LOC_DRAG, LOC_WINENTER, LOC_WINEXIT, WIN_MOUSE_BUTTONS,
  209.              NULL,
  210.          WIN_CLIENT_DATA, (char *)this,  NULL);
  211.   handle = (char *)x_canvas;
  212.  
  213.  
  214.   xv_set(x_canvas, XV_SHOW, TRUE, NULL);
  215.  
  216.   horiz_scroll = NULL;
  217.   vert_scroll = NULL;
  218.  
  219.   Xv_Screen screen = xv_get(xview_server, SERVER_NTH_SCREEN, 0);
  220.   Xv_Window root_window = xv_get(screen, XV_ROOT);
  221.   xwindow = (Window)xv_get(canvas_paint_window(x_canvas), XV_XID);
  222.  
  223.   display = (Display *)xv_get(root_window, XV_DISPLAY);
  224.  
  225.   drag_count = DRAG_MAX;
  226.   xrects = NULL;
  227. #endif
  228. #ifdef wx_msw
  229.   wxWinType = wxTYPE_XWND;
  230.   is_retained = FALSE;
  231.   clipping = FALSE;
  232.   wxWnd *cparent = NULL;
  233.   if (frame)
  234.     cparent = (wxWnd *)frame->handle;
  235.  
  236.   DWORD msflags = 0;
  237.   if (style & wxBORDER)
  238.     msflags |= WS_BORDER;
  239.   msflags |= WS_CHILD | WS_VISIBLE;
  240.  
  241.   wxCanvasWnd *wnd = new wxCanvasWnd(cparent, this, x, y, width, height, msflags);
  242.   wnd->background_brush = GetStockObject(WHITE_BRUSH);
  243.   handle = (char *)wnd;
  244. #endif
  245.  
  246.   if (frame) frame->AddChild(this);
  247.   window_parent = frame;
  248.  
  249.   horiz_units = 0;
  250.   vert_units = 0;
  251.  
  252.   wx_dc = new wxDC(this);
  253.   context = wx_dc;
  254.  
  255. #ifdef wx_xview
  256.   xv_set(x_canvas,
  257.           CANVAS_REPAINT_PROC, wxCanvasRepaintProc,
  258.           CANVAS_RESIZE_PROC, wxCanvasResizeProc, NULL);
  259.   if (x > -1)
  260.     xv_set(x_canvas, XV_X, x, NULL);
  261.   if (y > -1)
  262.     xv_set(x_canvas, XV_Y, real_y, NULL);
  263.   if (width > -1)
  264.     xv_set(x_canvas, XV_WIDTH, width, NULL);
  265.   if (height > -1)
  266.     xv_set(x_canvas, XV_HEIGHT, height, NULL);
  267.  
  268. #endif
  269. }
  270.  
  271. wxCanvas::~wxCanvas(void)
  272. {
  273. #ifdef wx_motif
  274.   if (backingPixmap)
  275.     XFreePixmap(XtDisplay((Widget)handle), backingPixmap);
  276. #endif
  277. #ifdef wx_xview
  278.   Canvas x_canvas = (Canvas)handle;
  279.   Xv_window pw = canvas_paint_window(x_canvas);
  280.   (void)xv_set(pw, WIN_CLIENT_DATA, NULL, NULL);
  281.   xv_set(x_canvas, 
  282.          CANVAS_X_PAINT_WINDOW, FALSE, NULL);
  283.  
  284.   if (horiz_scroll)
  285.     xv_destroy_safe((Xv_opaque)horiz_scroll);
  286.   if (vert_scroll)
  287.     xv_destroy_safe((Xv_opaque)vert_scroll);
  288.   if (wx_dc)
  289.     delete wx_dc;
  290. #endif
  291. }
  292.  
  293. #ifdef wx_motif
  294. void wxCanvas::PreResize(void)
  295. {
  296. //  cout << "Canvas PreResize\n";
  297. //  OnPaint();
  298. }
  299. #endif
  300.  
  301. #ifdef wx_msw
  302. void wxCanvas::PreDelete(HDC dc)
  303. {
  304.   wx_dc->SelectOldObjects(dc);
  305.   delete wx_dc;
  306. }
  307. #endif
  308.  
  309. void wxCanvas::SetClippingRegion(float cx, float cy, float cw, float ch)
  310. {
  311.   wx_dc->SetClippingRegion(cx, cy, cw, ch);
  312. }
  313.  
  314. void wxCanvas::DestroyClippingRegion(void)
  315. {
  316.   wx_dc->DestroyClippingRegion();
  317. }
  318.  
  319. wxDC *wxCanvas::GetDC(void)
  320. {
  321.   return context;
  322. }
  323.  
  324. void wxCanvas::SetClientSize(int w, int h)
  325. {
  326. #ifdef wx_motif
  327.   Widget drawingArea = (Widget)handle;
  328.  
  329.   if (w > -1)
  330.   {
  331.     canvasWidth = w;
  332.     XtVaSetValues(scrolledWindow, XmNwidth, w, NULL);
  333.     if (!hScroll)
  334.       XtVaSetValues(drawingArea, XmNwidth, w - SCROLL_MARGIN, NULL);
  335.   }
  336.   if (h > -1)
  337.   {
  338.     canvasHeight = h;
  339.     XtVaSetValues(scrolledWindow, XmNheight, h, NULL);
  340.     if (!vScroll)
  341.       XtVaSetValues(drawingArea, XmNheight, h - SCROLL_MARGIN, NULL);
  342.   }
  343.   allowRepainting = FALSE;
  344.  
  345.   XSync(XtDisplay(drawingArea), FALSE);
  346.   XEvent event;
  347.   while (XtAppPending(wxTheApp->appContext))
  348.   {
  349.     XFlush(XtDisplay(drawingArea));
  350.     XtAppNextEvent(wxTheApp->appContext, &event);
  351.     XtDispatchEvent(&event);
  352.   }
  353.   allowRepainting = TRUE;
  354.   Refresh();
  355.   OnSize(w, h);
  356. #else
  357.   wxWindow::SetClientSize(w, h);
  358. #endif
  359. }
  360.  
  361. void wxCanvas::GetClientSize(int *w, int *h)
  362. {
  363. #ifdef wx_motif
  364.   // Doesn't return the right value!
  365. //  XtVaGetValues(scrolledWindow, XmNwidth, w, XmNheight, h, NULL);
  366.   *w = canvasWidth;
  367.   *h = canvasHeight;
  368. #else
  369.   wxWindow::GetClientSize(w, h);
  370. #endif
  371. }
  372.  
  373. void wxCanvas::SetSize(int x, int y, int w, int h)
  374. {
  375. #ifdef wx_motif
  376.   Widget drawingArea = (Widget)handle;
  377.   if (x > -1)
  378.   {
  379.     canvasX = x;
  380.     XtVaSetValues(scrolledWindow, 
  381.        XmNleftAttachment, XmATTACH_SELF,
  382.        XmNx, x, NULL);
  383.   }
  384.  
  385.   if (y > -1)
  386.   {
  387.     canvasY = y;
  388.     XtVaSetValues(scrolledWindow,
  389.        XmNtopAttachment, XmATTACH_SELF,
  390.        XmNy, y, NULL);
  391.   }
  392.  
  393.   if (w > -1)
  394.   {
  395.     canvasWidth = w;
  396.     XtVaSetValues(scrolledWindow, XmNwidth, w, NULL);
  397.     if (!hScroll)
  398.       XtVaSetValues(drawingArea, XmNwidth, w - SCROLL_MARGIN, NULL);
  399.   }
  400.   if (h > -1)
  401.   {
  402.     canvasHeight = h;
  403.     XtVaSetValues(scrolledWindow, XmNheight, h, NULL);
  404.     if (!vScroll)
  405.       XtVaSetValues(drawingArea, XmNheight, h - SCROLL_MARGIN, NULL);
  406.   }
  407.  
  408.   allowRepainting = FALSE;
  409.  
  410.   XSync(XtDisplay(drawingArea), FALSE);
  411.   XEvent event;
  412.   while (XtAppPending(wxTheApp->appContext))
  413.   {
  414.     XFlush(XtDisplay(drawingArea));
  415.     XtAppNextEvent(wxTheApp->appContext, &event);
  416.     XtDispatchEvent(&event);
  417.   }
  418.   allowRepainting = TRUE;
  419.   Refresh();
  420. #endif
  421. #ifdef wx_xview
  422.   int real_y = y;
  423.  
  424.   if (window_parent)
  425.     real_y += ((wxFrame *)window_parent)->y_offset;  // Allow for possible menu bar
  426.  
  427.   Xv_opaque object = (Xv_opaque)handle;
  428.   (void)xv_set(object, XV_X, x, XV_Y, real_y, XV_WIDTH, w, XV_HEIGHT, h, NULL);
  429. #endif
  430. #ifdef wx_msw
  431.   int currentX, currentY;
  432.   GetPosition(¤tX, ¤tY);
  433.   if (x == -1)
  434.     x = currentX;
  435.   if (y == -1)
  436.     y = currentY;
  437.  
  438.   wxWnd *wnd = (wxWnd *)handle;
  439.   if (wnd)
  440.     MoveWindow(wnd->handle, x, y, w, h, TRUE);
  441. #endif
  442.   OnSize(w, h);
  443. }
  444.  
  445. void wxCanvas::GetSize(int *w, int *h)
  446. {
  447. #ifdef wx_motif
  448. //  XtVaGetValues(scrolledWindow, XmNwidth, w, XmNheight, h, NULL);
  449.   *w = canvasWidth;
  450.   *h = canvasHeight;
  451. #else
  452.   wxWindow::GetSize(w, h);
  453. #endif
  454. }
  455.  
  456. void wxCanvas::GetPosition(int *x, int *y)
  457. {
  458. #ifdef wx_motif
  459. //  XtVaGetValues(scrolledWindow, XmNx, x, XmNy, y, NULL);
  460.   *x = canvasX;
  461.   *y = canvasY;
  462. #else
  463.   wxWindow::GetPosition(x, y);
  464. #endif
  465. }
  466.  
  467. #ifdef wx_motif
  468. /* Calls OnPaint or uses retained pixmap,
  469.  * as necessary
  470.  */
  471. void wxCanvas::Refresh(void)
  472. {
  473.   Dimension canvasWidth2, canvasHeight2;
  474.   XtVaGetValues(scrolledWindow, XmNwidth, &canvasWidth2, XmNheight, &canvasHeight2, NULL);
  475.   int canvasWidth1 = max(canvasWidth, canvasWidth2);
  476.   int canvasHeight1 = max(canvasHeight, canvasHeight2);
  477.  
  478.   if (hScroll)
  479.   {
  480.     XtVaSetValues(hScrollBar, XmNsliderSize,
  481.                       (int)(max(min(canvasWidth1/horiz_units, hExtent/horiz_units), 1)), NULL);
  482.   }
  483.   if (vScroll)
  484.   {
  485.     XtVaSetValues(vScrollBar, XmNsliderSize, 
  486.                        (int)(max(min(canvasHeight1/vert_units, vExtent/vert_units), 1)), NULL);
  487.   }
  488.   int x, y;
  489.   ViewStart(&x, &y);
  490.   if (is_retained && backingPixmap)
  491.   {
  492.     Widget drawingArea = (Widget)handle;
  493.     XCopyArea(XtDisplay(drawingArea), backingPixmap, XtWindow(drawingArea), GetDC()->gc,
  494.                pixmapOffsetX, pixmapOffsetY, 
  495.                pixmapWidth, pixmapHeight,
  496.                0, 0);
  497.   }
  498.   else
  499.   {
  500.     OnPaint();
  501.   }
  502. }
  503.  
  504. void wxScrollCallback(Widget scrollbar, int orientation, XmScrollBarCallbackStruct *cbs)
  505. {
  506.   Widget scrolledWindow = XtParent(scrollbar);
  507.   wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)scrolledWindow);
  508.   if (canvas)
  509.   {
  510.     if (orientation == XmHORIZONTAL)
  511.     {
  512.       if (canvas->hScrollingEnabled && !canvas->is_retained)
  513.         canvas->Clear();
  514.  
  515.       if (canvas->GetDC())
  516.         canvas->GetDC()->device_origin_x = -(cbs->value * canvas->horiz_units);
  517.       if (canvas->is_retained)
  518.         canvas->pixmapOffsetX = (cbs->value * canvas->horiz_units);
  519.     }
  520.     else
  521.     {
  522.       if (canvas->vScrollingEnabled && !canvas->is_retained)
  523.         canvas->Clear();
  524.  
  525.       if (canvas->GetDC())
  526.         canvas->GetDC()->device_origin_y = -(cbs->value * canvas->vert_units);
  527.       if (canvas->is_retained)
  528.         canvas->pixmapOffsetY = (cbs->value * canvas->vert_units);
  529.     }
  530.     canvas->Refresh();
  531.   }
  532. }
  533. #endif
  534.  
  535. /*
  536.  * horizontal/vertical: number of pixels per unit (e.g. pixels per text line)
  537.  * x/y_length:        : no. units per scrollbar
  538.  * x/y_page:          : no. units per page scrolled
  539.  */
  540. void wxCanvas::SetScrollbars(int horizontal, int vertical,
  541.                              int x_length, int y_length,
  542.                              int x_page, int y_page)
  543. {
  544.   horiz_units = horizontal;
  545.   vert_units = vertical;
  546.  
  547. #ifdef wx_motif
  548.   Bool scrollingInitialized = (hScrollBar || vScrollBar);
  549.   Dimension canvasWidth2, canvasHeight2;
  550.   XtVaGetValues(scrolledWindow, XmNwidth, &canvasWidth2, XmNheight, &canvasHeight2, NULL);
  551.   int canvasWidth1 = max(canvasWidth, canvasWidth2);
  552.   int canvasHeight1 = max(canvasHeight, canvasHeight2);
  553.  
  554.   Widget drawingArea = (Widget)handle;
  555.   if (horizontal > 0)
  556.   {
  557.     hExtent = horizontal*x_length;
  558.  
  559.     if (!hScroll)
  560.     {
  561.       hScrollBar = XtVaCreateManagedWidget("hsb", 
  562.                    xmScrollBarWidgetClass,    scrolledWindow,
  563.                    XmNorientation,            XmHORIZONTAL,
  564.                    NULL);
  565.       XtAddCallback(hScrollBar, XmNvalueChangedCallback, wxScrollCallback, XmHORIZONTAL);
  566.       XtAddCallback(hScrollBar, XmNdragCallback, wxScrollCallback, XmHORIZONTAL);
  567.     }
  568.  
  569.     XtVaSetValues(hScrollBar,
  570.                    XmNincrement, 1,
  571.                    XmNpageIncrement, x_page,
  572.                    XmNmaximum, x_length,
  573.                    XmNvalue, 0,
  574.                    XmNsliderSize, (int)(max(min(canvasWidth1/horizontal, x_length), 1)),
  575.                    NULL);
  576.  
  577.     if (GetDC())
  578.       GetDC()->device_origin_x = 0;
  579.     if (is_retained)
  580.       pixmapOffsetX = 0;
  581.  
  582.     hScroll = TRUE;
  583.   }
  584.   else
  585.   {
  586.     hExtent = 0;
  587.     hScroll = FALSE;
  588.   }
  589.   if (vertical > 0)
  590.   {
  591.     vExtent = vertical*y_length;
  592.  
  593.     if (!vScroll)
  594.     {
  595.       vScrollBar = XtVaCreateManagedWidget("vsb", 
  596.                    xmScrollBarWidgetClass,    scrolledWindow,
  597.                    XmNorientation,            XmVERTICAL,
  598.                    NULL);
  599.       XtAddCallback(vScrollBar, XmNvalueChangedCallback, wxScrollCallback, XmVERTICAL);
  600.       XtAddCallback(vScrollBar, XmNdragCallback, wxScrollCallback, XmVERTICAL);
  601.     }
  602.  
  603.     XtVaSetValues(vScrollBar,
  604.                    XmNincrement, 1,
  605.                    XmNpageIncrement, y_page,
  606.                    XmNmaximum, y_length,
  607.                    XmNvalue, 0,
  608.                    XmNsliderSize, (int)(max(min(canvasHeight1/vertical, y_length), 1)),
  609.                    NULL);
  610.  
  611.     if (GetDC())
  612.       GetDC()->device_origin_y = 0;
  613.     if (is_retained)
  614.       pixmapOffsetY = 0;
  615.  
  616.     vScroll = TRUE;
  617.   }
  618.   else
  619.   {
  620.     vExtent = 0;
  621.     vScroll = FALSE;
  622.   }
  623.  
  624.   if (!scrollingInitialized)
  625.   {
  626.     XmScrolledWindowSetAreas(scrolledWindow, hScrollBar, vScrollBar, drawingArea);
  627.     if (hScrollBar)
  628.       XtRealizeWidget(hScrollBar);
  629.     if (vScrollBar)
  630.       XtRealizeWidget(vScrollBar);
  631.   }
  632.  
  633.   /*
  634.    * Retained pixmap stuff
  635.    *
  636.    */
  637.  
  638.   if (is_retained && (hExtent > 0) && (vExtent > 0))
  639.   {
  640.     if ((hExtent != pixmapWidth) || (vExtent != pixmapHeight))
  641.     {
  642.       pixmapWidth = hExtent;
  643.       pixmapHeight = vExtent;
  644.  
  645.       if (backingPixmap)
  646.         XFreePixmap(XtDisplay(drawingArea), backingPixmap);
  647.  
  648.       backingPixmap = XCreatePixmap(XtDisplay(drawingArea),
  649.           RootWindowOfScreen(XtScreen(drawingArea)), hExtent, vExtent,
  650.           DefaultDepthOfScreen(XtScreen(drawingArea)));
  651.  
  652.       Clear();
  653.       OnPaint();
  654.     }
  655.   }
  656.  
  657.   // This necessary to make scrollbars appear, for some reason!
  658.   int w, h, x, y;
  659.   GetSize(&w, &h);
  660.   GetPosition(&x, &y);
  661.   SetSize(x, y, w, h);
  662. #endif
  663. #ifdef wx_xview
  664.   Canvas canvas = (Canvas)handle;
  665.   if (!horiz_scroll && horizontal > 0)
  666.     horiz_scroll = xv_create(canvas, SCROLLBAR,
  667.                              SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,NULL);
  668.   if (horizontal > 0)
  669.   {
  670.     int canvas_width = horizontal*x_length + 1;
  671.     (void)xv_set(horiz_scroll,
  672.                 SCROLLBAR_PIXELS_PER_UNIT, horizontal,
  673.                 SCROLLBAR_OBJECT_LENGTH, x_length,
  674.                 SCROLLBAR_PAGE_LENGTH, x_page,
  675.                 SCROLLBAR_VIEW_LENGTH, x_page,
  676.                 NULL);
  677.     (void)xv_set(canvas, CANVAS_WIDTH, canvas_width, 
  678.                          CANVAS_AUTO_EXPAND, FALSE,
  679.                          CANVAS_AUTO_SHRINK, FALSE,
  680.                          NULL);
  681.   }
  682.   if (vertical > 0 && !vert_scroll)
  683.     vert_scroll = xv_create(canvas, SCROLLBAR,
  684.                 SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL, NULL);
  685.   if (vertical > 0)
  686.   {
  687.     int canvas_height = vertical*y_length + 1;
  688.     (void)xv_set(vert_scroll,
  689.                 SCROLLBAR_PIXELS_PER_UNIT, vertical,
  690.                 SCROLLBAR_OBJECT_LENGTH, y_length,
  691.                 SCROLLBAR_PAGE_LENGTH, y_page,
  692.                 SCROLLBAR_VIEW_LENGTH, y_page,
  693.                 NULL);
  694.     (void)xv_set(canvas, CANVAS_HEIGHT, canvas_height, 
  695.                          CANVAS_AUTO_EXPAND, FALSE,
  696.                          CANVAS_AUTO_SHRINK, FALSE,
  697.                          NULL);
  698.  
  699.   }
  700.  
  701. #endif
  702. #ifdef wx_msw
  703.   wxWnd *wnd = (wxWnd *)handle;
  704.   if (wnd)
  705.   {
  706.     wnd->xscroll_pixels_per_line = horizontal;
  707.     wnd->yscroll_pixels_per_line = vertical;
  708.     wnd->xscroll_lines = x_length;
  709.     wnd->yscroll_lines = y_length;
  710.     wnd->xscroll_lines_per_page = x_page;
  711.     wnd->yscroll_lines_per_page = y_page;
  712.  
  713.     SetScrollRange(wnd->handle, SB_HORZ, 0, x_length, TRUE);
  714.     SetScrollRange(wnd->handle, SB_VERT, 0, y_length, TRUE);
  715.   }
  716.  
  717. #endif
  718. }
  719.  
  720. /*
  721.  * Scroll to given position (scroll position, not pixel position)
  722.  */
  723. void wxCanvas::Scroll(int x_pos, int y_pos)
  724. {
  725.   int old_x, old_y;
  726.   ViewStart(&old_x, &old_y);
  727.   if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
  728.     return;
  729.  
  730. #ifdef wx_motif
  731.   Bool clearCanvas = FALSE;
  732.  
  733.   if (hScroll)
  734.   {
  735.     XtVaSetValues(hScrollBar, XmNvalue, x_pos, NULL);
  736.     if (hScrollingEnabled && !is_retained)
  737.       clearCanvas = TRUE;
  738.  
  739.     if (GetDC())
  740.       GetDC()->device_origin_x = -(x_pos * horiz_units);
  741.     if (is_retained)
  742.       pixmapOffsetX = (x_pos * horiz_units);
  743.   }
  744.   if (vScroll)
  745.   {
  746.     XtVaSetValues(vScrollBar, XmNvalue, y_pos, NULL);
  747.  
  748.     if (vScrollingEnabled && !is_retained)
  749.       clearCanvas = TRUE;
  750.  
  751.     if (GetDC())
  752.       GetDC()->device_origin_y = -(y_pos * vert_units);
  753.     if (is_retained)
  754.       pixmapOffsetY = (y_pos * vert_units);
  755.   }
  756.  
  757.   if (clearCanvas)
  758.     Clear();
  759.   Refresh();
  760. #endif
  761. #ifdef wx_xview
  762.   if (x_pos > -1 && horiz_scroll)
  763.     (void)xv_set(horiz_scroll, SCROLLBAR_VIEW_START, x_pos, NULL);
  764.  
  765.   if (y_pos > -1 && vert_scroll)
  766.     (void)xv_set(vert_scroll, SCROLLBAR_VIEW_START, y_pos, NULL);
  767. #endif
  768. #ifdef wx_msw
  769.   wxWnd *wnd = (wxWnd *)handle;
  770.  
  771.   if (x_pos > -1)
  772.   {
  773.     wnd->xscroll_position = x_pos;
  774.     SetScrollPos(wnd->handle, SB_HORZ, x_pos, TRUE );
  775.   }
  776.   if (y_pos > -1)
  777.   {
  778.     wnd->yscroll_position = y_pos;
  779.     SetScrollPos(wnd->handle, SB_VERT, y_pos, TRUE );
  780.   }
  781.   InvalidateRect(wnd->handle, NULL, TRUE);
  782.   UpdateWindow(wnd->handle);
  783. #endif
  784. }
  785.  
  786. void wxCanvas::SetCountdown(int n)
  787. {
  788. #ifdef wx_xview
  789.   repaint_countdown = n;
  790. #endif
  791. }
  792.  
  793. void wxCanvas::EnableScrolling(Bool x_scroll, Bool y_scroll)
  794. {
  795. #ifdef wx_motif
  796.   hScrollingEnabled = x_scroll;
  797.   vScrollingEnabled = y_scroll;
  798. #endif
  799. #ifdef wx_msw
  800.   wxWnd *wnd = (wxWnd *)handle;
  801.   wnd->x_scrolling_enabled = x_scroll;
  802.   wnd->y_scrolling_enabled = y_scroll;
  803. #endif
  804. }
  805.  
  806. void wxCanvas::GetVirtualSize(int *x, int *y)
  807. {
  808. #ifdef wx_motif
  809.   if (hExtent == 0)
  810.     *x = canvasWidth;
  811.   else
  812.     *x = hExtent;
  813.  
  814.   if (vExtent == 0)
  815.     *y = canvasHeight;
  816.   else
  817.     *y = vExtent;
  818. #endif
  819. #ifdef wx_xview
  820.   Canvas canvas = (Canvas)handle;
  821.   *x = (int)xv_get(canvas, CANVAS_WIDTH);
  822.   *y = (int)xv_get(canvas, CANVAS_HEIGHT);
  823. #endif
  824. #ifdef wx_msw
  825.   wxWnd *wnd = (wxWnd *)handle;
  826.   if (wnd)
  827.   {
  828.     *x = wnd->xscroll_pixels_per_line * wnd->xscroll_lines;
  829.     *y = wnd->yscroll_pixels_per_line * wnd->yscroll_lines;
  830.   }
  831. #endif
  832. }
  833.  
  834. #ifdef wx_xview
  835. void wxCanvasRepaintProc(Canvas x_canvas, Xv_Window paint_win,
  836.                     Display *display, Window xwin, Xv_xrectlist *xrects)
  837. {
  838. //  cout << "Canvas paint: " << xrects->count << " rectangles\n";
  839.  
  840.   wxCanvas *canvas = (wxCanvas *)xv_get(x_canvas, WIN_CLIENT_DATA);
  841.   if (canvas && canvas->repaint_countdown > 0)
  842.   {
  843.     canvas->repaint_countdown --;
  844.     return;
  845.   }
  846.   if (canvas && display && xwin)
  847.   {
  848.     if (xrects && canvas->is_retained)
  849.     {
  850.       canvas->xrects = xrects;
  851.       XSetClipRectangles(canvas->display, canvas->GetDC()->gc, 0, 0, xrects->rect_array, xrects->count, Unsorted);
  852.     }
  853.  
  854.     canvas->paint_window = paint_win;
  855.     canvas->display = display;
  856.     canvas->xwindow = xwin;
  857.  
  858.     canvas->OnPaint();
  859.  
  860.     canvas->xrects = NULL;
  861.  
  862.     XGCValues gc_val;
  863.     gc_val.clip_mask = None;
  864.     XChangeGC(canvas->display, canvas->GetDC()->gc, GCClipMask, &gc_val);
  865.   }
  866. }
  867.  
  868. void wxCanvasResizeProc(Canvas x_canvas, int width, int height)
  869. {
  870.   wxCanvas *canvas = (wxCanvas *)xv_get(x_canvas, WIN_CLIENT_DATA);
  871.   if (canvas)
  872.   {
  873.     Xv_Window pw = canvas_paint_window(x_canvas);
  874.     canvas->paint_window = pw;
  875.     canvas->xwindow = (Window)xv_get(pw, XV_XID);
  876.     canvas->OnSize(width, height);
  877.   }
  878. }
  879.  
  880. void wxCanvasEventProc(Xv_Window window, Event *x_event, Notify_arg arg)
  881. {
  882.   wxCanvas *canvas = (wxCanvas *)xv_get(window, WIN_CLIENT_DATA);
  883.   if (canvas)
  884.   {
  885.     canvas->paint_window = window;
  886.     canvas->xwindow = (Window)xv_get(window, XV_XID);
  887.  
  888.     if (event_id(x_event) == KBD_USE)
  889.       canvas->OnSetFocus();
  890.     else if (event_id(x_event) == KBD_DONE)
  891.       canvas->OnKillFocus();
  892.     else if (event_is_ascii(x_event))
  893.     {
  894.       canvas->OnChar(x_event->ie_code);
  895.     }
  896.     else
  897.     {
  898.       wxEvent event(x_event);
  899.       if (canvas->GetDC())
  900.       {
  901.         event.x = canvas->GetDC()->DeviceToLogicalX(event_x(x_event));
  902.         event.y = canvas->GetDC()->DeviceToLogicalY(event_y(x_event));
  903.       }
  904.  
  905.       if (event.Dragging())
  906.       {
  907.         // Don't respond to ALL drag events since we can't necessarily
  908.         // keep up with them (dependent on application, really - define
  909.         // DRAG_MAX differently if necessary)
  910.         if (canvas->drag_count > 0)
  911.         {
  912.           canvas->drag_count --;
  913.         }
  914.         else
  915.         {
  916.           canvas->drag_count = canvas->DRAG_MAX;
  917.           canvas->OnEvent(event);
  918.         }
  919.       }
  920.       else canvas->OnEvent(event);
  921.     }
  922.   }
  923. }
  924. #endif
  925.  
  926. #ifdef wx_motif
  927. void wxCanvasRepaintProc(Widget drawingArea, XtPointer clientData, XmDrawingAreaCallbackStruct *cbs)
  928. {
  929.   wxCanvas *canvas = (wxCanvas *)clientData;
  930.  
  931.   if (canvas && (cbs->reason == XmCR_EXPOSE) && canvas->allowRepainting)
  932.   {
  933. //    cout << "Canvas repaint\n";
  934.     canvas->display = XtDisplay(drawingArea);
  935.     canvas->Refresh();
  936.   }
  937. }
  938.  
  939. void wxCanvasKeyEvent(Widget drawingArea, XKeyEvent *event)
  940. {
  941.   wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)drawingArea);
  942.  
  943.   switch (event->type)
  944.   {
  945.     case KeyPress:
  946.     {
  947.       KeySym keySym;
  948.       XComposeStatus compose;
  949.       (void)XLookupString(event, wxBuffer, 20, &keySym, &compose);
  950.       canvas->OnChar(wxBuffer[0]);
  951.       break;
  952.     }
  953.     case FocusIn:
  954.     {
  955.       canvas->OnSetFocus();
  956.       break;
  957.     }
  958.     case FocusOut:
  959.     {
  960.       canvas->OnKillFocus();
  961.     }
  962.   }
  963. }
  964.  
  965. void wxCanvasInputEvent(Widget drawingArea, XButtonEvent *event)
  966. {
  967.   wxCanvas *canvas = (wxCanvas *)wxWidgetHashTable->Get((long)drawingArea);
  968.  
  969.   switch (event->type)
  970.   {
  971.     case ButtonPress:
  972.     case ButtonRelease:
  973.     case MotionNotify:
  974.     {
  975.       wxEvent wxevent;
  976.       wxevent.event_handle = event;
  977.  
  978.       if (canvas->GetDC())
  979.       {
  980.         wxevent.x = canvas->GetDC()->DeviceToLogicalX(event->x);
  981.         wxevent.y = canvas->GetDC()->DeviceToLogicalY(event->y);
  982.       }
  983.  
  984.       if (event->type == ButtonPress)
  985.       {
  986.         if (event->button == Button1)
  987.           canvas->button1Pressed = TRUE;
  988.         else if (event->button == Button2)
  989.           canvas->button2Pressed = TRUE;
  990.         else if (event->button == Button3)
  991.           canvas->button3Pressed = TRUE;
  992.       }
  993.       else if (event->type == ButtonRelease)
  994.       {
  995.         if (event->button == Button1)
  996.           canvas->button1Pressed = FALSE;
  997.         else if (event->button == Button2)
  998.           canvas->button2Pressed = FALSE;
  999.         else if (event->button == Button3)
  1000.           canvas->button3Pressed = FALSE;
  1001.       }
  1002.  
  1003.       wxevent.button1Pressed = canvas->button1Pressed;
  1004.       wxevent.button2Pressed = canvas->button2Pressed;
  1005.       wxevent.button3Pressed = canvas->button3Pressed;
  1006.  
  1007.       canvas->OnEvent(wxevent);
  1008.       break;
  1009.     }
  1010.   }
  1011. }
  1012. #endif
  1013.  
  1014. // Where the current view starts from
  1015. void wxCanvas::ViewStart(int *x, int *y)
  1016. {
  1017. #ifdef wx_motif
  1018.   int xx, yy;
  1019.   if (hScroll)
  1020.     XtVaGetValues(hScrollBar, XmNvalue, &xx, NULL);
  1021.   else xx = 0;
  1022.   if (vScroll)
  1023.     XtVaGetValues(vScrollBar, XmNvalue, &yy, NULL);
  1024.   else yy = 0;
  1025.   *x = xx;
  1026.   *y = yy;
  1027. #endif
  1028. #ifdef wx_xview
  1029.   if (horiz_scroll)
  1030.     *x = (int)xv_get(horiz_scroll, SCROLLBAR_VIEW_START);
  1031.   else *x = 0;
  1032.  
  1033.   if (vert_scroll)
  1034.     *y = (int)xv_get(vert_scroll, SCROLLBAR_VIEW_START);
  1035.   else *y = 0;
  1036.   
  1037. #endif
  1038. #ifdef wx_msw
  1039.   wxWnd *wnd = (wxWnd *)handle;
  1040.   *x = wnd->xscroll_position;
  1041.   *y = wnd->yscroll_position;
  1042. #endif
  1043. }
  1044.  
  1045. // Use this to set the canvas's 'context' member to
  1046. // a user-supplied dc
  1047. void wxCanvas::SetContext(wxDC *dc)
  1048. {
  1049.   context = dc;
  1050. }
  1051.  
  1052. // Reset 'context' back to the canvas' context
  1053. void wxCanvas::ResetContext(void)
  1054. {
  1055.   context = wx_dc;
  1056. }
  1057.  
  1058. void wxCanvas::Clear(void)
  1059. {
  1060.   wx_dc->Clear();
  1061. }
  1062.  
  1063. void wxCanvas::DrawLine(float x1, float y1, float x2, float y2)
  1064. {
  1065.   wx_dc->DrawLine(x1, y1, x2, y2);
  1066. }
  1067.  
  1068. void wxCanvas::DrawPoint(float x, float y)
  1069. {
  1070.   wx_dc->DrawPoint(x, y);
  1071. }
  1072.  
  1073. void wxCanvas::DrawPolygon(int n, wxPoint points[], float xoffset, float yoffset)
  1074. {
  1075.   wx_dc->DrawPolygon(n, points, xoffset, yoffset);
  1076. }
  1077.  
  1078. void wxCanvas::DrawPolygon(wxList *list, float xoffset, float yoffset)
  1079. {
  1080.   wx_dc->DrawPolygon(list, xoffset, yoffset);
  1081. }
  1082.  
  1083. void wxCanvas::DrawLines(int n, wxPoint points[], float xoffset, float yoffset)
  1084. {
  1085.   wx_dc->DrawLines(n, points, xoffset, yoffset);
  1086. }
  1087.  
  1088. void wxCanvas::DrawLines(wxList *list, float xoffset, float yoffset)
  1089. {
  1090.   wx_dc->DrawLines(list, xoffset, yoffset);
  1091. }
  1092.  
  1093. void wxCanvas::DrawRectangle(float x, float y, float width, float height)
  1094. {
  1095.   wx_dc->DrawRectangle(x, y, width, height);
  1096. }
  1097.  
  1098. void wxCanvas::DrawRoundedRectangle(float x, float y, float width, float height, float radius)
  1099. {
  1100.   wx_dc->DrawRoundedRectangle(x, y, width, height, radius);
  1101. }
  1102.  
  1103. void wxCanvas::DrawEllipse(float x, float y, float width, float height)
  1104. {
  1105.   wx_dc->DrawEllipse(x, y, width, height);
  1106. }
  1107.  
  1108.  
  1109. void wxCanvas::SetFont(wxFont *the_font)
  1110. {
  1111.   wx_dc->SetFont(the_font);
  1112. }
  1113.  
  1114. void wxCanvas::SetPen(wxPen *pen)
  1115. {
  1116.   wx_dc->SetPen(pen);
  1117. }
  1118.  
  1119. void wxCanvas::SetTextForeground(wxColour *colour)
  1120. {
  1121.   wx_dc->SetTextForeground(colour);
  1122. }
  1123.  
  1124. void wxCanvas::SetTextBackground(wxColour *colour)
  1125. {
  1126.   wx_dc->SetTextBackground(colour);
  1127. }
  1128.  
  1129. void wxCanvas::SetBrush(wxBrush *brush)
  1130. {
  1131.   wx_dc->SetBrush(brush);
  1132. }
  1133.  
  1134. void wxCanvas::DrawText(char *text, float x, float y)
  1135. {
  1136.   wx_dc->DrawText(text, x, y);
  1137. }
  1138.  
  1139. void wxCanvas::SetBackground(wxBrush *brush)
  1140. {
  1141.   wx_dc->SetBackground(brush);
  1142. }
  1143.  
  1144. void wxCanvas::SetLogicalFunction(int function)
  1145. {
  1146.   wx_dc->SetLogicalFunction(function);
  1147. }
  1148.  
  1149. // Make a 3-point spline
  1150. void wxCanvas::DrawSpline(float x1, float y1, float x2, float y2, float x3, float y3)
  1151. {
  1152.   wx_dc->DrawSpline(x1, y1, x2, y2, x3, y3);
  1153. }
  1154.  
  1155. void wxCanvas::DrawSpline(wxList *list)
  1156. {
  1157.   wx_dc->DrawSpline(list);
  1158. }
  1159.  
  1160. int wxCanvas::GetTextFamily(void)
  1161. {
  1162.   return wx_dc->GetTextFamily();
  1163. }
  1164.  
  1165. int wxCanvas::GetTextStyle(void)
  1166. {
  1167.   return wx_dc->GetTextStyle();
  1168. }
  1169.  
  1170. int wxCanvas::GetTextWeight(void)
  1171. {
  1172.   return wx_dc->GetTextWeight();
  1173. }
  1174.  
  1175. float wxCanvas::GetTextHeight(void)
  1176. {
  1177.   return wx_dc->GetTextHeight();
  1178. }
  1179.  
  1180. float wxCanvas::GetTextWidth(void)
  1181. {
  1182.   return wx_dc->GetTextWidth();
  1183. }
  1184.  
  1185. void wxCanvas::GetTextExtent(char *string, float *x, float *y)
  1186. {
  1187.   wx_dc->GetTextExtent(string, x, y);
  1188. }
  1189.  
  1190. #ifdef wx_msw
  1191. void wxWnd::DeviceToLogical(float *x, float *y)
  1192. {
  1193.   if (is_canvas)
  1194.   {
  1195.     wxCanvas *canvas = (wxCanvas *)wx_window;
  1196.     *x = canvas->wx_dc->DeviceToLogicalX((int)*x);
  1197.     *y = canvas->wx_dc->DeviceToLogicalY((int)*y);
  1198.   }
  1199. }
  1200.  
  1201. wxCanvasWnd::wxCanvasWnd(wxWnd *parent, wxWindow *wx_win,
  1202.                        int x, int y, int width, int height, DWORD style):
  1203.   wxSubWnd(parent, "wxCanvasClass", wx_win, x, y, width, height, style)
  1204. {
  1205.   is_canvas = TRUE;
  1206. //  ShowScrollBar(handle, SB_BOTH, TRUE);
  1207. }
  1208.  
  1209.  
  1210. BOOL wxCanvasWnd::OnEraseBkgnd(HDC pDC)
  1211. {
  1212.   if (background_brush)
  1213.   {
  1214.     RECT rect;
  1215.     GetClientRect(handle, &rect);
  1216.     int mode = SetMapMode(pDC, MM_TEXT);
  1217.     FillRect(pDC, &rect, background_brush);
  1218.     SetMapMode(pDC, mode);
  1219.  
  1220.     wxCanvas *canvas = (wxCanvas *)wx_window;
  1221.     SetViewportExtEx(pDC, VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL);
  1222.     SetWindowExtEx(pDC, canvas->wx_dc->window_ext_x, canvas->wx_dc->window_ext_y, NULL);
  1223.  
  1224.     return TRUE;
  1225.   }
  1226.   else return FALSE;
  1227. }
  1228.  
  1229.  
  1230. #endif
  1231.