diff options
-rw-r--r-- | generic/tkInt.h | 2 | ||||
-rw-r--r-- | generic/tkListbox.c | 71 | ||||
-rw-r--r-- | generic/tkUtil.c | 66 | ||||
-rw-r--r-- | generic/ttk/ttkElements.c | 40 | ||||
-rw-r--r-- | library/print.tcl | 2 | ||||
-rw-r--r-- | win/tkWinDraw.c | 61 | ||||
-rw-r--r-- | win/tkWinGDI.c | 6 | ||||
-rw-r--r-- | win/tkWinInt.h | 34 | ||||
-rw-r--r-- | win/tkWinX.c | 2 |
9 files changed, 190 insertions, 94 deletions
diff --git a/generic/tkInt.h b/generic/tkInt.h index 6448c92..cf42eb6 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1268,6 +1268,8 @@ MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef, TkBusy busy); MODULE_SCOPE int TkBackgroundEvalObjv(Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const *objv, int flags); +MODULE_SCOPE void TkDrawDottedRect(Display *disp, Drawable d, GC gc, + int x, int y, int width, int height); MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp, const char *nsname, const char *name, void *clientData, const TkEnsemble *map); diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 4e4fa23..d676769 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -15,10 +15,6 @@ #include "tkInt.h" #include "default.h" -#ifdef _WIN32 -#include "tkWinInt.h" -#endif - typedef struct { Tk_OptionTable listboxOptionTable; /* Table defining configuration options @@ -1837,6 +1833,7 @@ DisplayListbox( { Listbox *listPtr = (Listbox *)clientData; Tk_Window tkwin = listPtr->tkwin; + Display *disp = listPtr->display; GC gc; int i, limit, x, y, prevSelected, freeGC; Tcl_Size stringLen; @@ -1892,7 +1889,7 @@ DisplayListbox( * screen). */ - pixmap = Tk_GetPixmap(listPtr->display, Tk_WindowId(tkwin), + pixmap = Tk_GetPixmap(disp, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); #else pixmap = Tk_WindowId(tkwin); @@ -1922,7 +1919,7 @@ DisplayListbox( int width = Tk_Width(tkwin); /* zeroth approx to silence warning */ x = listPtr->inset; - y = ((i - listPtr->topIndex) * listPtr->lineHeight) + listPtr->inset; + y = (i - listPtr->topIndex) * listPtr->lineHeight + listPtr->inset; gc = listPtr->textGC; freeGC = 0; @@ -2089,7 +2086,7 @@ DisplayListbox( - listPtr->xOffset + GetMaxOffset(listPtr)/2; } - Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, + Tk_DrawChars(disp, pixmap, gc, listPtr->tkfont, stringRep, stringLen, x, y); /* @@ -2102,71 +2099,34 @@ DisplayListbox( * Underline the text. */ - Tk_UnderlineChars(listPtr->display, pixmap, gc, - listPtr->tkfont, stringRep, x, y, 0, stringLen); + Tk_UnderlineChars(disp, pixmap, gc, listPtr->tkfont, + stringRep, x, y, 0, stringLen); } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) { -#ifdef _WIN32 - /* - * This provides for exact default look and feel on Windows. - */ - - TkWinDCState state; - HDC dc; - RECT rect; - - dc = TkWinGetDrawableDC(listPtr->display, pixmap, &state); - rect.left = listPtr->inset; - rect.top = ((i - listPtr->topIndex) * listPtr->lineHeight) - + listPtr->inset; - rect.right = rect.left + width; - rect.bottom = rect.top + listPtr->lineHeight; - DrawFocusRect(dc, &rect); - TkWinReleaseDrawableDC(pixmap, dc, &state); -#else /* !_WIN32 */ /* * Draw a dotted box around the text. */ x = listPtr->inset; - y = ((i - listPtr->topIndex) * listPtr->lineHeight) + y = (i - listPtr->topIndex) * listPtr->lineHeight + listPtr->inset; - width = Tk_Width(tkwin) - 2*listPtr->inset - 1; - - gcValues.line_style = LineOnOffDash; - gcValues.line_width = listPtr->selBorderWidth; - if (gcValues.line_width <= 0) { - gcValues.line_width = 1; - } - gcValues.dash_offset = 0; - gcValues.dashes = 1; + width = Tk_Width(tkwin) - 2*listPtr->inset; - /* - * You would think the XSetDashes was necessary, but it - * appears that the default dotting for just saying we want - * dashes appears to work correctly. - static char dashList[] = { 1 }; - static int dashLen = sizeof(dashList); - XSetDashes(listPtr->display, gc, 0, dashList, dashLen); - */ + TkDrawDottedRect(disp, pixmap, gc, x, y, + width, listPtr->lineHeight); - mask = GCLineWidth | GCLineStyle | GCDashList | GCDashOffset; - XChangeGC(listPtr->display, gc, mask, &gcValues); - XDrawRectangle(listPtr->display, pixmap, gc, x, y, - (unsigned) width, (unsigned) listPtr->lineHeight - 1); if (!freeGC) { /* * Don't bother changing if it is about to be freed. */ gcValues.line_style = LineSolid; - XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues); + XChangeGC(disp, gc, GCLineStyle, &gcValues); } -#endif /* _WIN32 */ } } if (freeGC) { - Tk_FreeGC(listPtr->display, gc); + Tk_FreeGC(disp, gc); } } @@ -2194,10 +2154,9 @@ DisplayListbox( } } #ifndef TK_NO_DOUBLE_BUFFERING - XCopyArea(listPtr->display, pixmap, Tk_WindowId(tkwin), - listPtr->textGC, 0, 0, (unsigned) Tk_Width(tkwin), - (unsigned) Tk_Height(tkwin), 0, 0); - Tk_FreePixmap(listPtr->display, pixmap); + XCopyArea(disp, pixmap, Tk_WindowId(tkwin), listPtr->textGC, 0, 0, + (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0); + Tk_FreePixmap(disp, pixmap); #endif /* TK_NO_DOUBLE_BUFFERING */ } diff --git a/generic/tkUtil.c b/generic/tkUtil.c index 3c99a4b..80a6f25 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -23,7 +23,7 @@ */ const TkObjType tkStateKeyObjType = { - {"statekey", /* name */ + {"statekey", /* name */ NULL, /* freeIntRepProc */ NULL, /* dupIntRepProc */ NULL, /* updateStringProc */ @@ -622,6 +622,70 @@ Tk_DrawFocusHighlight( /* *---------------------------------------------------------------------- * + * TkDrawDottedRect -- + * + * This function draws a dotted rectangle, used as focus ring of Ttk + * widgets and for rendering the active element of a listbox. + * + * Results: + * None. + * + * Side effects: + * A dotted rectangle is drawn in the specified Drawable. On the + * windowing systems x11 and aqua the GC components line_style, + * line_width, dashes, and dash_offset are modified as needed. + * + *---------------------------------------------------------------------- + */ + +void +TkDrawDottedRect( + Display *disp, /* Display containing the dotted rectangle. */ + Drawable d, /* Where to draw the rectangle (typically a + * pixmap for double buffering). */ + GC gc, /* Graphics context to use for drawing the + * rectangle. */ + int x, int y, /* Coordinates of the top-left corner. */ + int width, int height) /* Width & height, _including the border_. */ +{ +#ifdef _WIN32 + TkWinDrawDottedRect(disp, d, gc->foreground, x, y, width, height); + +#else + XGCValues gcValues; + int widthMod2 = width % 2, heightMod2 = height % 2; + int x2 = x + width - 1, y2 = y + height - 1; + + gcValues.line_style = LineOnOffDash; + gcValues.line_width = 1; + gcValues.dashes = 1; +#ifdef MAC_OSX_TK + gcValues.dash_offset = 1; +#else + gcValues.dash_offset = 0; +#endif + XChangeGC(disp, gc, GCLineStyle | GCLineWidth | GCDashList | GCDashOffset, + &gcValues); + + if (widthMod2 == 0 && heightMod2 == 0) { + XDrawLine(disp, d, gc, x+1, y, x2-1, y); /* N */ + XDrawLine(disp, d, gc, x+2, y2, x2, y2); /* S */ + XDrawLine(disp, d, gc, x, y+2, x, y2); /* W */ + XDrawLine(disp, d, gc, x2, y+1, x2, y2-1); /* E */ + } else { + int dx = 1 - widthMod2, dy = 1 - heightMod2; + + XDrawLine(disp, d, gc, x+1, y, x2-dx, y); /* N */ + XDrawLine(disp, d, gc, x+1, y2, x2-dx, y2); /* S */ + XDrawLine(disp, d, gc, x, y+1, x, y2-dy); /* W */ + XDrawLine(disp, d, gc, x2, y+1, x2, y2-dy); /* E */ + } +#endif +} + +/* + *---------------------------------------------------------------------- + * * Tk_GetScrollInfo -- * * This function is invoked to parse "xview" and "yview" scrolling diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c index ad856e3..2ba85c9 100644 --- a/generic/ttk/ttkElements.c +++ b/generic/ttk/ttkElements.c @@ -247,6 +247,7 @@ static void FieldElementDraw( int x1 = b.x, x2 = b.x + b.width - 1; int y1 = b.y, y2 = b.y + b.height - 1; int w = WIN32_XDRAWLINE_HACK; + GC bgGC; /* * Draw the outer rounded rectangle @@ -265,7 +266,7 @@ static void FieldElementDraw( /* * Fill the inner rectangle */ - GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); + bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2); } else { /* @@ -371,33 +372,40 @@ static void DrawFocusRing( Ttk_Box b) { XColor *color = Tk_GetColorFromObj(tkwin, colorObj); - unsigned long mask = 0UL; - XGCValues gcvalues; + XGCValues gcValues; GC gc; + Display *disp = Tk_Display(tkwin); + + if (thickness < 1 && solid) { + thickness = 1; + } + + gcValues.foreground = color->pixel; + gc = Tk_GetGC(tkwin, GCForeground, &gcValues); - gcvalues.foreground = color->pixel; - gcvalues.line_width = thickness < 1 ? 1 : thickness; if (solid) { - gcvalues.line_style = LineSolid; - mask = GCForeground | GCLineStyle | GCLineWidth; + XRectangle rects[4] = { + {b.x, b.y, b.width, thickness}, /* N */ + {b.x, b.y + b.height - thickness, b.width, thickness}, /* S */ + {b.x, b.y + thickness, thickness, b.height - 2*thickness}, /* W */ + {b.x + b.width - thickness, b.y + thickness, /* E */ + thickness, b.height - 2*thickness} + }; + + XFillRectangles(disp, d, gc, rects, 4); } else { - gcvalues.line_style = LineOnOffDash; - gcvalues.dashes = 1; - gcvalues.dash_offset = 1; - mask = GCForeground | GCLineStyle | GCDashList | GCDashOffset | GCLineWidth; + TkDrawDottedRect(disp, d, gc, b.x, b.y, b.width, b.height); } - gc = Tk_GetGC(tkwin, mask, &gcvalues); - XDrawRectangle(Tk_Display(tkwin), d, gc, b.x, b.y, b.width-1, b.height-1); Tk_FreeGC(Tk_Display(tkwin), gc); } static const Ttk_ElementOptionSpec FocusElementOptions[] = { - { "-focuscolor",TK_OPTION_COLOR, + { "-focuscolor", TK_OPTION_COLOR, offsetof(FocusElement,focusColorObj), "black" }, - { "-focusthickness",TK_OPTION_PIXELS, + { "-focusthickness", TK_OPTION_PIXELS, offsetof(FocusElement,focusThicknessObj), "1" }, - { "-focussolid",TK_OPTION_BOOLEAN, + { "-focussolid", TK_OPTION_BOOLEAN, offsetof(FocusElement,focusSolidObj), "0" }, { NULL, TK_OPTION_BOOLEAN, 0, NULL } }; diff --git a/library/print.tcl b/library/print.tcl index 5908b41..3319306 100644 --- a/library/print.tcl +++ b/library/print.tcl @@ -830,7 +830,7 @@ if {[tk windowingsystem] eq "x11"} { lappend printargs -P $printer # open temp file set fd [file tempfile fname tk_print] - chan configure $fd -encoding binary -translation binary + chan configure $fd -translation binary chan puts $fd $data chan close $fd # add -r to automatically delete temp files diff --git a/win/tkWinDraw.c b/win/tkWinDraw.c index 1022be4..7f96164 100644 --- a/win/tkWinDraw.c +++ b/win/tkWinDraw.c @@ -1488,6 +1488,67 @@ Tk_DrawHighlightBorder( /* *---------------------------------------------------------------------- * + * TkWinDrawDottedRect -- + * + * This function draws a dotted rectangle, used as focus ring of Ttk + * widgets and for rendering the active element of a listbox. + * + * Results: + * None. + * + * Side effects: + * A dotted rectangle is drawn in the specified Drawable. + * + *---------------------------------------------------------------------- + */ + +void +TkWinDrawDottedRect( + Display *disp, /* Display containing the dotted rectangle. */ + Drawable d, /* Where to draw the rectangle (typically a + * pixmap for double buffering). */ + unsigned long pixel, /* color to use for drawing the rectangle. */ + int x, int y, /* Coordinates of the top-left corner. */ + int width, int height) /* Width & height, _including the border_. */ +{ + TkWinDCState state; + HDC dc; + LOGBRUSH lb; + HPEN pen; + int widthMod2 = width % 2, heightMod2 = height % 2; + int x2 = x + width - 1, y2 = y + height - 1; + + dc = TkWinGetDrawableDC(disp, d, &state); + + lb.lbStyle = BS_SOLID; + lb.lbColor = (COLORREF)pixel; + lb.lbHatch = 0; + + pen = ExtCreatePen(PS_COSMETIC | PS_ALTERNATE, 1, &lb, 0, NULL); + SelectObject(dc, pen); + SelectObject(dc, GetStockObject(NULL_BRUSH)); + + if (widthMod2 == 0 && heightMod2 == 0) { + MoveToEx(dc, x+1, y, NULL); LineTo(dc, x2, y); /* N */ + MoveToEx(dc, x+2, y2, NULL); LineTo(dc, x2, y2+1); /* S */ + MoveToEx(dc, x, y+2, NULL); LineTo(dc, x, y2+1); /* W */ + MoveToEx(dc, x2, y+1, NULL); LineTo(dc, x2, y2); /* E */ + } else { + int dx = widthMod2, dy = heightMod2; + + MoveToEx(dc, x+1, y, NULL); LineTo(dc, x2+dx, y); /* N */ + MoveToEx(dc, x+1, y2, NULL); LineTo(dc, x2+dx, y2); /* S */ + MoveToEx(dc, x, y+1, NULL); LineTo(dc, x, y2+dy); /* W */ + MoveToEx(dc, x2, y+1, NULL); LineTo(dc, x2, y2+dy); /* E */ + } + + DeleteObject(pen); + TkWinReleaseDrawableDC(d, dc, &state); +} + +/* + *---------------------------------------------------------------------- + * * TkpDrawFrameEx -- * * This function draws the rectangular frame area. diff --git a/win/tkWinGDI.c b/win/tkWinGDI.c index 2cded45..4d0c129 100644 --- a/win/tkWinGDI.c +++ b/win/tkWinGDI.c @@ -955,9 +955,9 @@ static int GdiOval( hDC = printDC; if ((Tcl_GetIntFromObj(interp, objv[2], &x1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[2], &y1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[3], &x2) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y2) != TCL_OK)) { + || (Tcl_GetIntFromObj(interp, objv[3], &y1) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[4], &x2) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[5], &y2) != TCL_OK)) { return TCL_ERROR; } if (x1 > x2) { diff --git a/win/tkWinInt.h b/win/tkWinInt.h index 03cd825..3f363cd 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -194,48 +194,50 @@ MODULE_SCOPE void TkWinSetupSystemFonts(TkMainInfo *mainPtr); * The following is implemented in tkWinWm and used by tkWinEmbed.c */ -MODULE_SCOPE void TkpWinToplevelWithDraw(TkWindow *winPtr); -MODULE_SCOPE void TkpWinToplevelIconify(TkWindow *winPtr); -MODULE_SCOPE void TkpWinToplevelDeiconify(TkWindow *winPtr); -MODULE_SCOPE long TkpWinToplevelIsControlledByWm(TkWindow *winPtr); -MODULE_SCOPE long TkpWinToplevelMove(TkWindow *winPtr, int x, int y); -MODULE_SCOPE long TkpWinToplevelOverrideRedirect(TkWindow *winPtr, +MODULE_SCOPE void TkpWinToplevelWithDraw(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelIconify(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelDeiconify(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelIsControlledByWm(TkWindow *winPtr); +MODULE_SCOPE long TkpWinToplevelMove(TkWindow *winPtr, int x, int y); +MODULE_SCOPE long TkpWinToplevelOverrideRedirect(TkWindow *winPtr, int reqValue); -MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); -MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); +MODULE_SCOPE void TkpWinToplevelDetachWindow(TkWindow *winPtr); +MODULE_SCOPE int TkpWmGetState(TkWindow *winPtr); -MODULE_SCOPE int TkTranslateWinEvent(HWND hwnd, UINT message, +MODULE_SCOPE int TkTranslateWinEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); -MODULE_SCOPE void TkWinPointerEvent(HWND hwnd, int x, int y); +MODULE_SCOPE void TkWinPointerEvent(HWND hwnd, int x, int y); /* * The following is implemented in tkWinPointer.c and also used in tkWinWindow.c */ -MODULE_SCOPE void TkSetCursorPos(int x, int y); +MODULE_SCOPE void TkSetCursorPos(int x, int y); /* * The following is implemented in tkWinSysTray.c */ -MODULE_SCOPE int WinIcoInit (Tcl_Interp* interp); +MODULE_SCOPE int WinIcoInit (Tcl_Interp* interp); /* * The following is implemented in tkWinGDI.c */ -MODULE_SCOPE int Winprint_Init(Tcl_Interp* interp); +MODULE_SCOPE int Winprint_Init(Tcl_Interp* interp); /* - * The following is implemented in tkWinSysTray.c + * The following is implemented in tkWinDraw.c and used in tkUtil.c */ -MODULE_SCOPE int WinIcoInit (Tcl_Interp* interp); +MODULE_SCOPE void TkWinDrawDottedRect (Display *disp, Drawable d, + unsigned long pixel, int x, int y, + int width, int height); /* * Common routines used in Windows implementation */ -MODULE_SCOPE Tcl_Obj * TkWin32ErrorObj(HRESULT hrError); +MODULE_SCOPE Tcl_Obj * TkWin32ErrorObj(HRESULT hrError); /* diff --git a/win/tkWinX.c b/win/tkWinX.c index 656e142..c61601b 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -1165,7 +1165,7 @@ GenerateXEvent( event.key.nbytes = 0; event.x.xkey.state = state; event.x.xany.serial = scrollCounter++; - event.x.xkey.keycode = (unsigned int) delta; + event.x.xkey.keycode = (unsigned int) (delta & 0xffff); } else { event.x.type = MouseWheelEvent; event.x.xany.send_event = -1; |