Attachment "tkchelp.diff" to
ticket [845248ff]
added by
a_kovalenko
2007-10-25 09:34:12.
? history
? doc/man.macros
? unix/autom4te.cache
? unix/tkConfig.sh
? unix/wish
Index: generic/tkInt.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkInt.h,v
retrieving revision 1.80
diff -u -r1.80 tkInt.h
--- generic/tkInt.h 15 Oct 2007 20:52:47 -0000 1.80
+++ generic/tkInt.h 25 Oct 2007 02:13:38 -0000
@@ -940,6 +940,16 @@
#define ALT_MASK (AnyModifier<<2)
#define EXTENDED_MASK (AnyModifier<<3)
+/* The following special modifier is passed to Tk_UpdatePointer to specify
+ * that the cursor should not be changed.
+ * */
+#define NOCURSOR_MASK (AnyModifier<<4)
+
+/* The following special modifier is passed to Tk_UpdatePointer
+ * in order to update current position but not to generate button events
+ * */
+#define NOBUTTONEVENTS_MASK (AnyModifier<<4)
+
/*
* Object types not declared in tkObj.c need to be mentioned here so they can
* be properly registered with Tcl:
Index: generic/tkPointer.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/generic/tkPointer.c,v
retrieving revision 1.10
diff -u -r1.10 tkPointer.c
--- generic/tkPointer.c 15 Nov 2005 15:18:22 -0000 1.10
+++ generic/tkPointer.c 25 Oct 2007 02:13:39 -0000
@@ -239,9 +239,25 @@
TkWindow *targetWinPtr;
XPoint pos;
XEvent event;
- int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS;
+ int no_cursor = (state & NOCURSOR_MASK);
+ int no_button_events = (state & NOBUTTONEVENTS_MASK);
+ int changes;
int type, b, mask;
+ if (state & ALL_BUTTONS) {
+ tsdPtr->lastState &= ~NOCURSOR_MASK;
+ }
+ state &= ~NOCURSOR_MASK & ~NOBUTTONEVENTS_MASK;
+ if (no_cursor) {
+ tsdPtr->lastState = (tsdPtr->lastState & ~ALL_BUTTONS) |
+ (state & ALL_BUTTONS) | NOCURSOR_MASK;
+ return;
+ } else if (tsdPtr->lastState & NOCURSOR_MASK) {
+ tsdPtr->lastState = (tsdPtr->lastState & ~NOCURSOR_MASK & ~ALL_BUTTONS) |
+ (state & ALL_BUTTONS);
+ return;
+ }
+ changes = ( state ^ tsdPtr->lastState) & ALL_BUTTONS;
pos.x = x;
pos.y = y;
@@ -253,6 +269,9 @@
tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState
& ALL_BUTTONS);
+ if (no_button_events) {
+ return;
+ }
/*
* Generate Enter/Leave events. If the pointer has crossed window
* boundaries, update the current mouse position so we don't generate
@@ -278,7 +297,6 @@
* ButtonPress - Set restrict window if we aren't grabbed, or
* if this is the first button down.
*/
-
if (!tsdPtr->restrictWinPtr) {
if (!tsdPtr->grabWinPtr) {
/*
@@ -287,7 +305,6 @@
tsdPtr->restrictWinPtr = winPtr;
TkpSetCapture(tsdPtr->restrictWinPtr);
-
} else if ((tsdPtr->lastState & ALL_BUTTONS) == 0) {
/*
* Mouse is in a non-button grab, so ensure the button
@@ -303,7 +320,6 @@
TkpSetCapture(tsdPtr->restrictWinPtr);
}
}
-
} else {
type = ButtonRelease;
@@ -312,7 +328,6 @@
* restrict window when the last button is released and we
* aren't in a global grab.
*/
-
if ((tsdPtr->lastState & ALL_BUTTONS) == mask) {
if (!tsdPtr->grabWinPtr) {
TkpSetCapture(NULL);
Index: unix/tkUnixRFont.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixRFont.c,v
retrieving revision 1.20
diff -u -r1.20 tkUnixRFont.c
--- unix/tkUnixRFont.c 15 May 2007 19:37:58 -0000 1.20
+++ unix/tkUnixRFont.c 25 Oct 2007 02:13:42 -0000
@@ -35,6 +35,9 @@
XftDraw *ftDraw;
Drawable drawable;
XftColor color;
+
+ int underline_position;
+ int underline_thickness;
} UnixFtFont;
@@ -118,6 +121,7 @@
FcCharSet *charset;
FcResult result;
XftFont *ftFont;
+ FT_Face ftFace;
if (!fontPtr) {
fontPtr = (UnixFtFont *) ckalloc(sizeof(UnixFtFont));
@@ -167,9 +171,26 @@
fontPtr->color.color.blue = 0;
fontPtr->color.color.alpha = 0xffff;
fontPtr->color.pixel = 0xffffffff;
-
ftFont = GetFont(fontPtr, 0);
+ fontPtr->underline_position = -1;
+ fontPtr->underline_thickness = -1;
+
+ ftFace = XftLockFace(ftFont);
+ if (ftFace->face_flags & FT_FACE_FLAG_SCALABLE) {
+ fontPtr->underline_position =
+ - FT_MulFix(ftFace->underline_position,
+ ftFace->size->metrics.y_scale) / 64;
+ fontPtr->underline_thickness =
+ (32 + FT_MulFix(ftFace->underline_thickness,
+ ftFace->size->metrics.y_scale)) / 64;
+ }
+ if (fontPtr->underline_position <=0 || fontPtr->underline_thickness <=0) {
+ fontPtr->underline_position = ftFont->descent / 2;
+ fontPtr->underline_thickness = 1;
+ }
+ XftUnlockFace(ftFont);
+
/*
* Build the Tk font structure
*/
@@ -224,7 +245,7 @@
faPtr->weight = weight;
faPtr->slant = slant;
faPtr->underline = 0;
- faPtr->overstrike = 0;
+ faPtr->overstrike = 0;
fmPtr = &fontPtr->font.fm;
fmPtr->ascent = ftFont->ascent;
@@ -283,7 +304,10 @@
pattern = XftXlfdParse(name, FcFalse, FcFalse);
if (!pattern) {
- return NULL;
+ if (!strncmp("xft:",name,4))
+ pattern = FcNameParse(name+4);
+ if (!pattern)
+ return NULL;
}
/*
@@ -361,6 +385,8 @@
if (!fontPtr) {
return NULL;
}
+ fontPtr->font.fa.underline = faPtr->underline;
+ fontPtr->font.fa.overstrike = faPtr->overstrike;
return &fontPtr->font;
}
@@ -669,6 +695,16 @@
int clen, nspec;
XftGlyphFontSpec specs[NUM_SPEC];
XGlyphInfo metrics;
+ int underlinePos, overstrikePos, barHeight;
+
+ underlinePos = fontPtr->underline_position;
+ barHeight = fontPtr->underline_thickness;
+
+ if (underlinePos <= 0)
+ underlinePos = fontPtr->font.fm.descent / 2;
+ if (barHeight <= 0)
+ barHeight = 1;
+ overstrikePos = fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10;
if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
@@ -721,6 +757,18 @@
specs[nspec].y = y;
XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
&metrics);
+ if (fontPtr->font.fa.underline != 0) {
+ XftDrawRect(fontPtr->ftDraw, &fontPtr->color,
+ x, y + underlinePos,
+ (unsigned) metrics.xOff,
+ (unsigned) barHeight);
+ }
+ if (fontPtr->font.fa.overstrike != 0) {
+ XftDrawRect(fontPtr->ftDraw, &fontPtr->color,
+ x, y - overstrikePos,
+ (unsigned) metrics.xOff,
+ (unsigned) barHeight);
+ }
x += metrics.xOff;
y += metrics.yOff;
nspec++;
Index: win/tkWinCursor.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinCursor.c,v
retrieving revision 1.14
diff -u -r1.14 tkWinCursor.c
--- win/tkWinCursor.c 8 Sep 2007 16:13:45 -0000 1.14
+++ win/tkWinCursor.c 25 Oct 2007 02:13:42 -0000
@@ -246,6 +246,10 @@
TkpSetCursor(
TkpCursor cursor)
{
+ /* the hcursor_idc_help test is necessary for the CONTEXT HELP to work
+ by using wm attributes $window -contexthelp */
+
+ static HCURSOR hcursor_idc_help=NULL;
HCURSOR hcursor;
TkWinCursor *winCursor = (TkWinCursor *) cursor;
@@ -255,6 +259,8 @@
hcursor = winCursor->winCursor;
}
+ if (hcursor_idc_help==NULL) hcursor_idc_help=LoadCursor(NULL,IDC_HELP);
+ if (GetCursor()==hcursor_idc_help) return;
if (hcursor != NULL) {
SetCursor(hcursor);
}
Index: win/tkWinDialog.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinDialog.c,v
retrieving revision 1.46
diff -u -r1.46 tkWinDialog.c
--- win/tkWinDialog.c 8 Sep 2007 16:13:45 -0000 1.46
+++ win/tkWinDialog.c 25 Oct 2007 02:13:43 -0000
@@ -234,15 +234,9 @@
static void
EatSpuriousMessageBugFix(void)
{
- MSG msg;
- DWORD nTime = GetTickCount() + 250;
-
- while (GetTickCount() < nTime) {
- if (PeekMessage(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){
- break;
- }
- PeekMessage(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE);
- }
+ int state = TkWinGetModifierState();
+ Tk_UpdatePointer(NULL,0,0, state | NOBUTTONEVENTS_MASK);
+ return;
}
/*
@@ -790,7 +784,7 @@
winCode = GetSaveFileNameW(&ofn);
}
Tcl_SetServiceMode(oldMode);
- EatSpuriousMessageBugFix();
+ EatSpuriousMessageBugFix();
/*
* Ensure that hWnd is enabled, because it can happen that we have updated
Index: win/tkWinInt.h
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinInt.h,v
retrieving revision 1.28
diff -u -r1.28 tkWinInt.h
--- win/tkWinInt.h 4 May 2007 21:29:23 -0000 1.28
+++ win/tkWinInt.h 25 Oct 2007 02:13:43 -0000
@@ -40,6 +40,10 @@
#define WS_EX_TOOLWINDOW 0x00000080L
#endif
+#ifndef CS_DROPSHADOW
+#define CS_DROPSHADOW 0x00020000
+#endif
+
/*
* The TkWinDCState is used to save the state of a device context so that it
* can be restored later.
@@ -121,6 +125,7 @@
*/
#define TK_WIN_TOPLEVEL_CLASS_NAME "TkTopLevel"
+#define TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME "TkTopLevelShadow"
#define TK_WIN_TOPLEVEL_NOCDC_CLASS_NAME "TkTopLevelNoCDC"
#define TK_WIN_CHILD_CLASS_NAME "TkChild"
Index: win/tkWinWm.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinWm.c,v
retrieving revision 1.119
diff -u -r1.119 tkWinWm.c
--- win/tkWinWm.c 15 Oct 2007 20:52:48 -0000 1.119
+++ win/tkWinWm.c 25 Oct 2007 02:13:47 -0000
@@ -332,6 +332,7 @@
#define WM_HEIGHT_NOT_RESIZABLE (1<<11)
#define WM_WITHDRAWN (1<<12)
#define WM_FULLSCREEN (1<<13)
+#define WM_DROPSHADOW (1<<14)
/*
* Window styles for various types of toplevel windows.
@@ -946,9 +947,9 @@
*/
#ifdef TCL_THREADS
- class.style = CS_HREDRAW | CS_VREDRAW;
+ class.style = 0; //CS_HREDRAW | CS_VREDRAW;
#else
- class.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC;
+ class.style = /*CS_HREDRAW | CS_VREDRAW | */ CS_CLASSDC;
#endif
class.hInstance = Tk_GetHINSTANCE();
Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_CLASS_NAME, -1, &classString);
@@ -982,7 +983,7 @@
*/
if (setLayeredWindowAttributesProc != NULL) {
- class.style = CS_HREDRAW | CS_VREDRAW;
+ class.style = 0; // CS_HREDRAW | CS_VREDRAW;
Tcl_DStringFree(&classString);
Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_NOCDC_CLASS_NAME,
-1, &classString);
@@ -992,6 +993,14 @@
}
}
#endif
+ class.style = /* CS_HREDRAW | CS_VREDRAW | */ CS_DROPSHADOW;
+ Tcl_DStringFree(&classString);
+ Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME,
+ -1, &classString);
+ class.lpszClassName = (LPCTSTR) Tcl_DStringValue(&classString);
+ if (!(*tkWinProcs->registerClass)(&class)) {
+ Tcl_Panic("Unable to register TkTopLevelShadow class");
+ }
Tcl_DStringFree(&classString);
}
Tcl_MutexUnlock(&winWmMutex);
@@ -1988,6 +1997,7 @@
tsdPtr->initialized = 0;
UnregisterClass(TK_WIN_TOPLEVEL_CLASS_NAME, hInstance);
+ UnregisterClass(TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME, hInstance);
#ifndef TCL_THREADS
/*
@@ -2189,7 +2199,7 @@
if (! ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE))) {
wmPtr->style |= WS_THICKFRAME;
- }
+ }
} else {
wmPtr->style = WM_TOPLEVEL_STYLE;
wmPtr->exStyle = EX_TOPLEVEL_STYLE;
@@ -2244,6 +2254,10 @@
Tcl_WinUtfToTChar(((wmPtr->title != NULL) ?
wmPtr->title : winPtr->nameUid), -1, &titleString);
+ if (wmPtr->flags & WM_DROPSHADOW) {
+ Tcl_WinUtfToTChar(TK_WIN_TOPLEVEL_SHADOW_CLASS_NAME,
+ -1, &classString);
+ } else
#ifndef TCL_THREADS
/*
* Transparent windows require a non-CS_CLASSDC window class.
@@ -3166,19 +3180,22 @@
LONG style, exStyle, styleBit, *stylePtr = NULL;
char *string;
int i, boolean, length;
- int config_fullscreen = 0;
+ int config_fullscreen = 0, config_shadow = 0;
int fullscreen_attr_changed = 0, fullscreen_attr = 0;
+ int shadow_attr_changed = 0, shadow_attr = 0;
if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) {
configArgs:
Tcl_WrongNumArgs(interp, 2, objv,
"window"
" ?-alpha ?double??"
+ " ?-contexthelp ?bool??"
" ?-transparentcolor ?color??"
" ?-disabled ?bool??"
" ?-fullscreen ?bool??"
" ?-toolwindow ?bool??"
- " ?-topmost ?bool??");
+ " ?-topmost ?bool??"
+ " ?-shadow ?bool??");
return TCL_ERROR;
}
exStyle = wmPtr->exStyleConfig;
@@ -3208,6 +3225,14 @@
Tcl_NewStringObj("-topmost", -1));
Tcl_ListObjAppendElement(NULL, objPtr,
Tcl_NewBooleanObj((exStyle & WS_EX_TOPMOST)));
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_NewStringObj("-contexthelp", -1));
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_NewBooleanObj((style & WS_EX_CONTEXTHELP)));
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_NewStringObj("-shadow", -1));
+ Tcl_ListObjAppendElement(NULL, objPtr,
+ Tcl_NewBooleanObj((wmPtr->flags & WM_DROPSHADOW)));
Tcl_SetObjResult(interp, objPtr);
return TCL_OK;
}
@@ -3227,6 +3252,12 @@
} else if (strncmp(string, "-fullscreen", (unsigned) length) == 0) {
config_fullscreen = 1;
styleBit = 0;
+ } else if (strncmp(string, "-shadow", (unsigned) length) == 0) {
+ config_shadow = 1;
+ styleBit = 0;
+ } else if (strncmp(string,"-contexthelp", length) == 0) {
+ stylePtr=&exStyle;
+ styleBit=WS_EX_CONTEXTHELP;
} else if ((length > 3)
&& (strncmp(string, "-toolwindow", (unsigned) length) == 0)) {
stylePtr = &exStyle;
@@ -3334,6 +3365,15 @@
fullscreen_attr = boolean;
}
config_fullscreen = 0;
+ } else if (config_shadow) {
+ if (objc == 4) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->flags & WM_DROPSHADOW));
+ } else {
+ shadow_attr_changed = 1;
+ shadow_attr = boolean;
+ }
+ config_shadow = 0;
} else if (objc == 4) {
Tcl_SetIntObj(Tcl_GetObjResult(interp),
((*stylePtr & styleBit) != 0));
@@ -3408,6 +3448,16 @@
TkpWmSetFullScreen(winPtr, fullscreen_attr);
}
+ if (shadow_attr_changed) {
+ if (shadow_attr) {
+ wmPtr->flags |= WM_DROPSHADOW;
+ } else {
+ wmPtr->flags &= ~WM_DROPSHADOW;
+ }
+ if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
+ UpdateWrapper(winPtr);
+ }
+ }
return TCL_OK;
}
@@ -7845,6 +7895,8 @@
* one level deep. */
LRESULT result;
TkWindow *winPtr = NULL;
+ POINT point;
+ int state;
switch (message) {
case WM_KILLFOCUS:
@@ -7968,6 +8020,19 @@
break;
}
+ case WM_NCLBUTTONDOWN:
+ case WM_NCLBUTTONDBLCLK:
+ case WM_NCLBUTTONUP:
+ case WM_NCMBUTTONDOWN:
+ case WM_NCMBUTTONDBLCLK:
+ case WM_NCMBUTTONUP:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCRBUTTONDBLCLK:
+ case WM_NCRBUTTONUP:
+ Tk_UpdatePointer(NULL, 0, 0, TkWinGetModifierState() | NOCURSOR_MASK);
+ result = (*tkWinProcs->defWindowProc)(hwnd, message, wParam, lParam);
+ goto done;
+
case WM_MOUSEACTIVATE: {
ActivateEvent *eventPtr;
winPtr = GetTopLevel((HWND) wParam);
Index: win/tkWinX.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinX.c,v
retrieving revision 1.55
diff -u -r1.55 tkWinX.c
--- win/tkWinX.c 11 Jan 2007 15:35:41 -0000 1.55
+++ win/tkWinX.c 25 Oct 2007 02:13:48 -0000
@@ -284,9 +284,9 @@
*/
#ifdef TCL_THREADS
- childClass.style = CS_HREDRAW | CS_VREDRAW;
+ childClass.style = 0; // CS_HREDRAW | CS_VREDRAW;
#else
- childClass.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC;
+ childClass.style = /* CS_HREDRAW | CS_VREDRAW | */ CS_CLASSDC;
#endif
childClass.cbClsExtra = 0;
@@ -794,6 +794,62 @@
/*
*----------------------------------------------------------------------
*
+ * HelpEvent --
+ *
+ * Generates a "Help" virtual event. This can be used to do
+ * context-sensitive help.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Places a virtual event on the event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HelpEvent (hwnd, message, wParam, lParam)
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+{
+ TkWindow *winPtr = (TkWindow *)Tk_HWNDToWindow(hwnd);
+ XVirtualEvent event;
+ POINTS rootPoint;
+ POINT clientPoint;
+ DWORD msgPos;
+
+ event.type = VirtualEvent;
+ event.serial = winPtr->display->request;
+ event.send_event = 0;
+ event.display = winPtr->display;
+ event.event = Tk_WindowId(winPtr);
+ event.root = XRootWindow(winPtr->display, 0);
+ event.subwindow = None;
+ event.time = TkpGetMS();
+
+ msgPos = GetMessagePos();
+ rootPoint = MAKEPOINTS(msgPos);
+ clientPoint.x = rootPoint.x;
+ clientPoint.y = rootPoint.y;
+ ScreenToClient(hwnd, &clientPoint);
+ event.x = clientPoint.x;
+ event.y = clientPoint.y;
+ event.x_root = rootPoint.x;
+ event.y_root = rootPoint.y;
+ event.state = TkWinGetModifierState();
+ event.same_screen = 1;
+ event.name = Tk_GetUid("Help");
+ event.user_data = NULL;
+ Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkWinChildProc --
*
* Callback from Windows whenever an event occurs on a child window.
@@ -817,6 +873,13 @@
LRESULT result;
switch (message) {
+
+ case WM_HELP:
+ Tk_UpdatePointer(NULL, 0, 0, TkWinGetModifierState() | NOBUTTONEVENTS_MASK);
+ HelpEvent(hwnd, message, wParam, lParam);
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ break;
+
case WM_INPUTLANGCHANGE:
UpdateInputLanguage((int) wParam);
result = 1;
@@ -962,6 +1025,7 @@
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_MOUSEMOVE:
+
Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam));
return 1;