| /****************************************************************************** |
| * |
| * tweak.c |
| * |
| * Windows 95 style interface tweaks. |
| * Copyright (c) 1997 Dave Cuthbert. |
| * |
| * FIXME: This file is, unfortunately, aptly named: the method of |
| * displaying Win95 style windows is a tweak. Lots of stuff does not yet |
| * work -- and probably never will unless some of this code is |
| * incorporated into the mainstream Wine code. |
| * |
| * DEVELOPERS, PLEASE NOTE: Before delving into the mainstream code and |
| * altering it, consider how your changes will affect the Win3.1 interface |
| * (which has taken a major effort to create!). After you make any sort of |
| * non-trivial change, *test* the Wine code running in Win3.1 mode! The |
| * object here is to make it so that the person who tests the latest version |
| * of Wine without adding the tweaks into wine.conf notices nothing out of |
| * the ordinary. |
| * |
| * Revision history |
| * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| #include <malloc.h> |
| #include "ts_xlib.h" |
| #include <string.h> |
| #include "dc.h" |
| #include "debug.h" |
| #include "graphics.h" |
| #include "options.h" |
| #include "stackframe.h" |
| #include "tweak.h" |
| #include "windows.h" |
| |
| /* Parameters for windows/nonclient.c */ |
| extern int NC_CaptionLeftNudge; |
| extern int NC_CaptionTopNudge; |
| extern int NC_SysControlNudge; |
| extern int NC_MaxControlNudge; |
| extern int NC_MinControlNudge; |
| extern UINT32 NC_CaptionTextFlags; |
| extern HBRUSH32 NC_WinHighlight95; |
| extern HBRUSH32 NC_WinShadow95; |
| |
| /* Parameters for controls/menu.c */ |
| extern UINT32 MENU_BarItemTopNudge; |
| extern UINT32 MENU_BarItemLeftNudge; |
| extern UINT32 MENU_ItemTopNudge; |
| extern UINT32 MENU_ItemLeftNudge; |
| extern UINT32 MENU_HighlightTopNudge; |
| extern UINT32 MENU_HighlightLeftNudge; |
| extern UINT32 MENU_HighlightBottomNudge; |
| extern UINT32 MENU_HighlightRightNudge; |
| |
| /* General options */ |
| HPEN32 TWEAK_PenFF95; |
| HPEN32 TWEAK_PenE095; |
| HPEN32 TWEAK_PenC095; |
| HPEN32 TWEAK_Pen8095; |
| HPEN32 TWEAK_Pen0095; |
| |
| #if defined(WIN_95_LOOK) |
| int TWEAK_Win95Look = 1; |
| #else |
| int TWEAK_Win95Look = 0; |
| #endif |
| |
| int TWEAK_WineInitialized = 0; |
| |
| |
| /****************************************************************************** |
| * |
| * int TWEAK_MenuInit() |
| * |
| * Initializes the Win95 tweaks to the menu code. See controls/menu.c. |
| * Return value indicates success (non-zero) or failure. |
| * |
| * Revision history |
| * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| static int TWEAK_MenuInit() |
| { |
| MENU_BarItemTopNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemTopNudge", 0); |
| MENU_BarItemLeftNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemLeftNudge", 0); |
| MENU_ItemTopNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemTopNudge", 0); |
| MENU_ItemLeftNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemLeftNudge", 0); |
| MENU_HighlightTopNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightTopNudge", 0); |
| MENU_HighlightLeftNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightLeftNudge", 0); |
| MENU_HighlightBottomNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightBottomNudge", 0); |
| MENU_HighlightRightNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightRightNudge", 0); |
| |
| return 1; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * int TWEAK_NonClientInit() |
| * |
| * Initializes the Win95 tweaks to the non-client drawing functions. See |
| * windows/nonclient.c. Return value indicates success (non-zero) or |
| * failure. |
| * |
| * Revision history |
| * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| static int TWEAK_NonClientInit() |
| { |
| char key_value[2]; |
| |
| NC_CaptionLeftNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "CaptionLeftNudge", 0); |
| NC_CaptionTopNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "CaptionTopNudge", 0); |
| NC_SysControlNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "SysControlNudge", 0); |
| NC_MaxControlNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MaxControlNudge", 0); |
| NC_MinControlNudge = |
| PROFILE_GetWineIniInt("Tweak.Layout", "MinControlNudge", 0); |
| |
| NC_WinHighlight95 = CreateSolidBrush32(RGB(0xc0, 0xc0, 0xc0)); |
| NC_WinShadow95 = CreateSolidBrush32(RGB(0x00, 0x00, 0x00)); |
| |
| NC_CaptionTextFlags = DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX; |
| |
| PROFILE_GetWineIniString("Tweak.Layout", "CaptionAlignment", |
| TWEAK_Win95Look ? "l" : "c", key_value, 2); |
| |
| switch(key_value[0]) { |
| case 'l': |
| case 'L': |
| NC_CaptionTextFlags |= DT_LEFT; |
| break; |
| |
| case 'r': |
| case 'R': |
| NC_CaptionTextFlags |= DT_RIGHT; |
| break; |
| |
| default: |
| NC_CaptionTextFlags |= DT_CENTER; |
| } |
| |
| return 1; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * int TWEAK_VarInit() |
| * |
| * Initializes the miscellaneous variables which are used in the tweak |
| * routines. Return value is non-zero on success. |
| * |
| * Revision history |
| * 07-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| static int TWEAK_VarInit() |
| { |
| TWEAK_Win95Look = PROFILE_GetWineIniBool("Tweak.Layout", "Win95Look", 0); |
| |
| /* FIXME: Each color should really occupy a single entry in the wine.conf |
| file, but I couldn't settle on a good (intuitive!) format. */ |
| |
| TWEAK_PenFF95 = CreatePen32( |
| PS_SOLID, 1, |
| RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Red", 0xff), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Grn", 0xff), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Blu", 0xff))); |
| TWEAK_PenE095 = CreatePen32( |
| PS_SOLID, 1, |
| RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Red", 0xe0), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Grn", 0xe0), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Blu", 0xe0))); |
| TWEAK_PenC095 = CreatePen32( |
| PS_SOLID, 1, |
| RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Red", 0xc0), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Grn", 0xc0), |
| PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Blu", 0xc0))); |
| TWEAK_Pen8095 = CreatePen32( |
| PS_SOLID, 1, |
| RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Red", 0x80), |
| PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Grn", 0x80), |
| PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Blu", 0x80))); |
| TWEAK_Pen0095 = CreatePen32( |
| PS_SOLID, 1, |
| RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Red", 0x00), |
| PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Grn", 0x00), |
| PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Blu", 0x00))); |
| |
| TRACE(tweak, "Using %s look and feel.\n", |
| TWEAK_Win95Look ? "Win95" : "Win3.1"); |
| return 1; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * int TWEAK_Init() |
| * |
| * Does the full initialization of the Win95 tweak subsystem. Return value |
| * indicates success. Called by loader/main.c's MAIN_Init(). |
| * |
| * Revision history |
| * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| int TWEAK_Init() |
| { |
| TWEAK_VarInit(); |
| TWEAK_NonClientInit(); |
| TWEAK_MenuInit(); |
| return 1; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * int TWEAK_CheckConfiguration() |
| * |
| * Examines wine.conf for old/bad entries and recommends changes to the user. |
| * |
| * Revision history |
| * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| int TWEAK_CheckConfiguration() |
| { |
| return 1; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * Tweak graphic subsystem. |
| * |
| *****************************************************************************/ |
| |
| /****************************************************************************** |
| * |
| * void TWEAK_DrawReliefRect95( |
| * HDC32 hdc, // Device context on which to draw |
| * RECT32 const *rect ) // Rectangle to use |
| * |
| * Draws the double-bordered Win95-style relief rectangle. |
| * |
| * Bugs |
| * There are some checks missing from this function. Perhaps the |
| * SelectObject32 calls should be examined? Hasn't failed on me (yet). |
| * |
| * Should I really be calling X functions directly from here? It is |
| * an optimization, but should I be optimizing alpha code? Probably |
| * not. |
| * |
| * Revision history |
| * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| void TWEAK_DrawReliefRect95( |
| HDC32 hdc, |
| RECT32 const *rect ) |
| { |
| DC *dc; |
| HPEN32 prevpen; |
| |
| if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { |
| |
| /* Draw the top/left lines first */ |
| prevpen = SelectObject32(hdc, TWEAK_PenE095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, |
| rect->right - 1, rect->top); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, |
| rect->left, rect->bottom - 1); |
| |
| SelectObject32(hdc, TWEAK_PenFF95); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->top + 1, rect->right - 2, rect->top + 1); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->top + 1, rect->left + 1, rect->bottom - 2); |
| |
| |
| /* Now the bottom/right lines */ |
| SelectObject32(hdc, TWEAK_Pen0095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, |
| rect->bottom - 1, rect->right - 1, rect->bottom - 1); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1, |
| rect->top, rect->right - 1, rect->bottom - 1); |
| |
| SelectObject32(hdc, TWEAK_Pen8095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->bottom - 2, rect->right - 2, rect->bottom - 2); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2, |
| rect->top + 1, rect->right - 2, rect->bottom - 2); |
| |
| SelectObject32(hdc, prevpen); |
| } |
| |
| return; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * void TWEAK_DrawRevReliefRect95( |
| * HDC32 hdc, // Device context on which to draw |
| * RECT32 const *rect ) // Rectangle to use |
| * |
| * Draws the double-bordered Win95-style relief rectangle. |
| * |
| * Bugs |
| * There are some checks missing from this function. Perhaps the |
| * SelectObject32 calls should be examined? Hasn't failed on me (yet). |
| * |
| * Should I really be calling X functions directly from here? It is |
| * an optimization, but should I be optimizing alpha code? Probably |
| * not. |
| * |
| * Revision history |
| * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| void TWEAK_DrawRevReliefRect95( |
| HDC32 hdc, |
| RECT32 const *rect ) |
| { |
| DC *dc; |
| HPEN32 prevpen; |
| |
| if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { |
| |
| /* Draw the top/left lines first */ |
| prevpen = SelectObject32(hdc, TWEAK_Pen8095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, |
| rect->right - 1, rect->top); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, |
| rect->left, rect->bottom - 1); |
| |
| SelectObject32(hdc, TWEAK_Pen0095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->top + 1, rect->right - 2, rect->top + 1); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->top + 1, rect->left + 1, rect->bottom - 2); |
| |
| |
| /* Now the bottom/right lines */ |
| SelectObject32(hdc, TWEAK_PenFF95); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, |
| rect->bottom - 1, rect->right - 1, rect->bottom - 1); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1, |
| rect->top, rect->right - 1, rect->bottom - 1); |
| |
| SelectObject32(hdc, TWEAK_PenE095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, |
| rect->bottom - 2, rect->right - 2, rect->bottom - 2); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2, |
| rect->top + 1, rect->right - 2, rect->bottom - 2); |
| |
| SelectObject32(hdc, prevpen); |
| } |
| |
| return; |
| } |
| |
| |
| |
| /****************************************************************************** |
| * |
| * void TWEAK_DrawMenuSeparatorHoriz95( |
| * HDC32 hdc, // Device context on which to draw |
| * UINT32 xc1, // Left x-coordinate |
| * UINT32 yc, // Y-coordinate of the LOWER line |
| * UINT32 xc2 ) // Right x-coordinate |
| * |
| * Draws a horizontal menu separator bar Win 95 style. |
| * |
| * Bugs |
| * Same as those for DrawReliefRect95. |
| * |
| * Revision history |
| * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * 11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Changed name from DrawMenuSeparator95 |
| * |
| *****************************************************************************/ |
| |
| void TWEAK_DrawMenuSeparatorHoriz95( |
| HDC32 hdc, |
| UINT32 xc1, |
| UINT32 yc, |
| UINT32 xc2 ) |
| { |
| DC *dc; |
| HPEN32 prevpen; |
| |
| if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { |
| |
| /* Draw the top line */ |
| prevpen = SelectObject32(hdc, TWEAK_Pen8095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2, |
| yc - 1); |
| |
| /* And the bottom line */ |
| SelectObject32(hdc, TWEAK_PenFF95); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc); |
| |
| SelectObject32(hdc, prevpen); |
| } |
| |
| return; |
| } |
| |
| |
| /****************************************************************************** |
| * |
| * void TWEAK_DrawMenuSeparatorVert95( |
| * HDC32 hdc, // Device context on which to draw |
| * UINT32 xc, // X-coordinate of the RIGHT line |
| * UINT32 yc1, // top Y-coordinate |
| * UINT32 yc2 ) // bottom Y-coordinate |
| * |
| * Draws a vertical menu separator bar Win 95 style. |
| * |
| * Bugs |
| * Same as those for DrawReliefRect95. |
| * |
| * Revision history |
| * 11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) |
| * Original implementation. |
| * |
| *****************************************************************************/ |
| |
| void TWEAK_DrawMenuSeparatorVert95( |
| HDC32 hdc, |
| UINT32 xc, |
| UINT32 yc1, |
| UINT32 yc2 ) |
| { |
| DC *dc; |
| HPEN32 prevpen; |
| |
| if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { |
| |
| /* Draw the top line */ |
| prevpen = SelectObject32(hdc, TWEAK_Pen8095); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc, yc1, xc, |
| yc2); |
| |
| /* And the bottom line */ |
| SelectObject32(hdc, TWEAK_PenFF95); |
| DC_SetupGCForPen(dc); |
| TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc + 1, yc1, xc + 1, |
| yc2); |
| |
| SelectObject32(hdc, prevpen); |
| } |
| |
| return; |
| } |