tkMacOSXColor.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:28k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tkMacOSXColor.c --
  3.  *
  4.  * This file maintains a database of color values for the Tk
  5.  * toolkit, in order to avoid round-trips to the server to
  6.  * map color names to pixel values.
  7.  *
  8.  * Copyright (c) 1990-1994 The Regents of the University of California.
  9.  * Copyright (c) 1994-1996 Sun Microsystems, Inc.
  10.  * Copyright 2001, Apple Computer, Inc.
  11.  * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
  12.  *
  13.  * See the file "license.terms" for information on usage and redistribution
  14.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15.  *
  16.  * RCS: @(#) $Id: tkMacOSXColor.c,v 1.2.2.11 2007/11/09 06:26:55 das Exp $
  17.  */
  18. #include "tkMacOSXPrivate.h"
  19. #include "tkColor.h"
  20. #if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
  21. /* Undocumented CG API for creating CGPattern from CGImage */
  22. extern CGPatternRef CGPatternCreateWithImage(CGImageRef img, int i) WEAK_IMPORT_ATTRIBUTE;
  23. #endif
  24. struct SystemColorMapEntry {
  25.     const char *name;
  26.     ThemeBrush brush;
  27.     ThemeTextColor textColor;
  28.     ThemeBackgroundKind background;
  29. };  /* unsigned char pixelCode; */
  30. /*
  31.  * Array of system color definitions: the array index is required to equal the
  32.  * color's (pixelCode - MIN_PIXELCODE), i.e. the array order needs to be kept
  33.  * in sync with the public pixel code values in tkMacOSXPort.h !
  34.  */
  35. #define MIN_PIXELCODE  30
  36. static const struct SystemColorMapEntry systemColorMap[] = {
  37.     { "Transparent",     0, 0, 0 }, /*  30: TRANSPARENT_PIXEL */
  38.     { "Highlight",     kThemeBrushPrimaryHighlightColor, 0, 0 }, /*  31: HIGHLIGHT_PIXEL */
  39.     { "HighlightSecondary",     kThemeBrushSecondaryHighlightColor, 0, 0 }, /*  32: HIGHLIGHT_SECONDARY_PIXEL */
  40.     { "HighlightText",     kThemeBrushBlack, 0, 0 }, /*  33: HIGHLIGHT_TEXT_PIXEL */
  41.     { "HighlightAlternate",     kThemeBrushAlternatePrimaryHighlightColor, 0, 0 }, /*  34: HIGHLIGHT_ALTERNATE_PIXEL */
  42.     { "ButtonText",     0, kThemeTextColorPushButtonActive, 0 }, /*  35: CONTROL_TEXT_PIXEL */
  43.     { "PrimaryHighlightColor",     kThemeBrushPrimaryHighlightColor, 0, 0 }, /*  36 */
  44.     { "ButtonFace",     kThemeBrushButtonFaceActive, 0, 0 }, /*  37: CONTROL_BODY_PIXEL */
  45.     { "SecondaryHighlightColor",     kThemeBrushSecondaryHighlightColor, 0, 0 }, /*  38 */
  46.     { "ButtonFrame",     kThemeBrushButtonFrameActive, 0, 0 }, /*  39: CONTROL_FRAME_PIXEL */
  47.     { "AlternatePrimaryHighlightColor",     kThemeBrushAlternatePrimaryHighlightColor, 0, 0 }, /*  40 */
  48.     { "WindowBody",     kThemeBrushDocumentWindowBackground, 0, 0 }, /*  41: WINDOW_BODY_PIXEL */
  49.     { "SheetBackground",     kThemeBrushSheetBackground, 0, 0 }, /*  42 */
  50.     { "MenuActive",     kThemeBrushMenuBackgroundSelected, 0, 0 }, /*  43: MENU_ACTIVE_PIXEL */
  51.     { "Black",     kThemeBrushBlack, 0, 0 }, /*  44 */
  52.     { "MenuActiveText",     0, kThemeTextColorMenuItemSelected, 0 }, /*  45: MENU_ACTIVE_TEXT_PIXEL */
  53.     { "White",     kThemeBrushWhite, 0, 0 }, /*  46 */
  54.     { "Menu",     kThemeBrushMenuBackground, 0, 0 }, /*  47: MENU_BACKGROUND_PIXEL */
  55.     { "DialogBackgroundActive",     kThemeBrushDialogBackgroundActive, 0, 0 }, /*  48 */
  56.     { "MenuDisabled",     0, kThemeTextColorMenuItemDisabled, 0 }, /*  49: MENU_DISABLED_PIXEL */
  57.     { "DialogBackgroundInactive",     kThemeBrushDialogBackgroundInactive, 0, 0 }, /*  50 */
  58.     { "MenuText",     0, kThemeTextColorMenuItemActive, 0 }, /*  51: MENU_TEXT_PIXEL */
  59.     { "AppearanceColor",     0, 0, 0 }, /*  52: APPEARANCE_PIXEL */
  60.     { "AlertBackgroundActive",     kThemeBrushAlertBackgroundActive, 0, 0 }, /*  53 */
  61.     { "AlertBackgroundInactive",     kThemeBrushAlertBackgroundInactive, 0, 0 }, /*  54 */
  62.     { "ModelessDialogBackgroundActive",     kThemeBrushModelessDialogBackgroundActive, 0, 0 }, /*  55 */
  63.     { "ModelessDialogBackgroundInactive",   kThemeBrushModelessDialogBackgroundInactive, 0, 0 }, /*  56 */
  64.     { "UtilityWindowBackgroundActive",     kThemeBrushUtilityWindowBackgroundActive, 0, 0 }, /*  57 */
  65.     { "UtilityWindowBackgroundInactive",    kThemeBrushUtilityWindowBackgroundInactive, 0, 0 }, /*  58 */
  66.     { "ListViewSortColumnBackground",     kThemeBrushListViewSortColumnBackground, 0, 0 }, /*  59 */
  67.     { "ListViewBackground",     kThemeBrushListViewBackground, 0, 0 }, /*  60 */
  68.     { "IconLabelBackground",     kThemeBrushIconLabelBackground, 0, 0 }, /*  61 */
  69.     { "ListViewSeparator",     kThemeBrushListViewSeparator, 0, 0 }, /*  62 */
  70.     { "ChasingArrows",     kThemeBrushChasingArrows, 0, 0 }, /*  63 */
  71.     { "DragHilite",     kThemeBrushDragHilite, 0, 0 }, /*  64 */
  72.     { "DocumentWindowBackground",     kThemeBrushDocumentWindowBackground, 0, 0 }, /*  65 */
  73.     { "FinderWindowBackground",     kThemeBrushFinderWindowBackground, 0, 0 }, /*  66 */
  74.     { "ScrollBarDelimiterActive",     kThemeBrushScrollBarDelimiterActive, 0, 0 }, /*  67 */
  75.     { "ScrollBarDelimiterInactive",     kThemeBrushScrollBarDelimiterInactive, 0, 0 }, /*  68 */
  76.     { "FocusHighlight",     kThemeBrushFocusHighlight, 0, 0 }, /*  69 */
  77.     { "PopupArrowActive",     kThemeBrushPopupArrowActive, 0, 0 }, /*  70 */
  78.     { "PopupArrowPressed",     kThemeBrushPopupArrowPressed, 0, 0 }, /*  71 */
  79.     { "PopupArrowInactive",     kThemeBrushPopupArrowInactive, 0, 0 }, /*  72 */
  80.     { "AppleGuideCoachmark",     kThemeBrushAppleGuideCoachmark, 0, 0 }, /*  73 */
  81.     { "IconLabelBackgroundSelected",     kThemeBrushIconLabelBackgroundSelected, 0, 0 }, /*  74 */
  82.     { "StaticAreaFill",     kThemeBrushStaticAreaFill, 0, 0 }, /*  75 */
  83.     { "ActiveAreaFill",     kThemeBrushActiveAreaFill, 0, 0 }, /*  76 */
  84.     { "ButtonFrameActive",     kThemeBrushButtonFrameActive, 0, 0 }, /*  77 */
  85.     { "ButtonFrameInactive",     kThemeBrushButtonFrameInactive, 0, 0 }, /*  78 */
  86.     { "ButtonFaceActive",     kThemeBrushButtonFaceActive, 0, 0 }, /*  79 */
  87.     { "ButtonFaceInactive",     kThemeBrushButtonFaceInactive, 0, 0 }, /*  80 */
  88.     { "ButtonFacePressed",     kThemeBrushButtonFacePressed, 0, 0 }, /*  81 */
  89.     { "ButtonActiveDarkShadow",     kThemeBrushButtonActiveDarkShadow, 0, 0 }, /*  82 */
  90.     { "ButtonActiveDarkHighlight",     kThemeBrushButtonActiveDarkHighlight, 0, 0 }, /*  83 */
  91.     { "ButtonActiveLightShadow",     kThemeBrushButtonActiveLightShadow, 0, 0 }, /*  84 */
  92.     { "ButtonActiveLightHighlight",     kThemeBrushButtonActiveLightHighlight, 0, 0 }, /*  85 */
  93.     { "ButtonInactiveDarkShadow",     kThemeBrushButtonInactiveDarkShadow, 0, 0 }, /*  86 */
  94.     { "ButtonInactiveDarkHighlight",     kThemeBrushButtonInactiveDarkHighlight, 0, 0 }, /*  87 */
  95.     { "ButtonInactiveLightShadow",     kThemeBrushButtonInactiveLightShadow, 0, 0 }, /*  88 */
  96.     { "ButtonInactiveLightHighlight",     kThemeBrushButtonInactiveLightHighlight, 0, 0 }, /*  89 */
  97.     { "ButtonPressedDarkShadow",     kThemeBrushButtonPressedDarkShadow, 0, 0 }, /*  90 */
  98.     { "ButtonPressedDarkHighlight",     kThemeBrushButtonPressedDarkHighlight, 0, 0 }, /*  91 */
  99.     { "ButtonPressedLightShadow",     kThemeBrushButtonPressedLightShadow, 0, 0 }, /*  92 */
  100.     { "ButtonPressedLightHighlight",     kThemeBrushButtonPressedLightHighlight, 0, 0 }, /*  93 */
  101.     { "BevelActiveLight",     kThemeBrushBevelActiveLight, 0, 0 }, /*  94 */
  102.     { "BevelActiveDark",     kThemeBrushBevelActiveDark, 0, 0 }, /*  95 */
  103.     { "BevelInactiveLight",     kThemeBrushBevelInactiveLight, 0, 0 }, /*  96 */
  104.     { "BevelInactiveDark",     kThemeBrushBevelInactiveDark, 0, 0 }, /*  97 */
  105.     { "NotificationWindowBackground",     kThemeBrushNotificationWindowBackground, 0, 0 }, /*  98 */
  106.     { "MovableModalBackground",     kThemeBrushMovableModalBackground, 0, 0 }, /*  99 */
  107.     { "SheetBackgroundOpaque",     kThemeBrushSheetBackgroundOpaque, 0, 0 }, /* 100 */
  108.     { "DrawerBackground",     kThemeBrushDrawerBackground, 0, 0 }, /* 101 */
  109.     { "ToolbarBackground",     kThemeBrushToolbarBackground, 0, 0 }, /* 102 */
  110.     { "SheetBackgroundTransparent",     kThemeBrushSheetBackgroundTransparent, 0, 0 }, /* 103 */
  111.     { "MenuBackground",     kThemeBrushMenuBackground, 0, 0 }, /* 104 */
  112.     { "Pixel",     0, 0, 0 }, /* 105: PIXEL_MAGIC */
  113.     { "MenuBackgroundSelected",     kThemeBrushMenuBackgroundSelected, 0, 0 }, /* 106 */
  114.     { "ListViewOddRowBackground",     kThemeBrushListViewOddRowBackground, 0, 0 }, /* 107 */
  115.     { "ListViewEvenRowBackground",     kThemeBrushListViewEvenRowBackground, 0, 0 }, /* 108 */
  116.     { "ListViewColumnDivider",     kThemeBrushListViewColumnDivider, 0, 0 }, /* 109 */
  117.     { "BlackText",     0, kThemeTextColorBlack, 0 }, /* 110 */
  118.     { "DialogActiveText",     0, kThemeTextColorDialogActive, 0 }, /* 111 */
  119.     { "DialogInactiveText",     0, kThemeTextColorDialogInactive, 0 }, /* 112 */
  120.     { "AlertActiveText",     0, kThemeTextColorAlertActive, 0 }, /* 113 */
  121.     { "AlertInactiveText",     0, kThemeTextColorAlertInactive, 0 }, /* 114 */
  122.     { "ModelessDialogActiveText",     0, kThemeTextColorModelessDialogActive, 0 }, /* 115 */
  123.     { "ModelessDialogInactiveText",     0, kThemeTextColorModelessDialogInactive, 0 }, /* 116 */
  124.     { "WindowHeaderActiveText",     0, kThemeTextColorWindowHeaderActive, 0 }, /* 117 */
  125.     { "WindowHeaderInactiveText",     0, kThemeTextColorWindowHeaderInactive, 0 }, /* 118 */
  126.     { "PlacardActiveText",     0, kThemeTextColorPlacardActive, 0 }, /* 119 */
  127.     { "PlacardInactiveText",     0, kThemeTextColorPlacardInactive, 0 }, /* 120 */
  128.     { "PlacardPressedText",     0, kThemeTextColorPlacardPressed, 0 }, /* 121 */
  129.     { "PushButtonActiveText",     0, kThemeTextColorPushButtonActive, 0 }, /* 122 */
  130.     { "PushButtonInactiveText",     0, kThemeTextColorPushButtonInactive, 0 }, /* 123 */
  131.     { "PushButtonPressedText",     0, kThemeTextColorPushButtonPressed, 0 }, /* 124 */
  132.     { "BevelButtonActiveText",     0, kThemeTextColorBevelButtonActive, 0 }, /* 125 */
  133.     { "BevelButtonInactiveText",     0, kThemeTextColorBevelButtonInactive, 0 }, /* 126 */
  134.     { "BevelButtonPressedText",     0, kThemeTextColorBevelButtonPressed, 0 }, /* 127 */
  135.     { "PopupButtonActiveText",     0, kThemeTextColorPopupButtonActive, 0 }, /* 128 */
  136.     { "PopupButtonInactiveText",     0, kThemeTextColorPopupButtonInactive, 0 }, /* 129 */
  137.     { "PopupButtonPressedText",     0, kThemeTextColorPopupButtonPressed, 0 }, /* 130 */
  138.     { "IconLabelText",     0, kThemeTextColorIconLabel, 0 }, /* 131 */
  139.     { "ListViewText",     0, kThemeTextColorListView, 0 }, /* 132 */
  140.     { "DocumentWindowTitleActiveText",     0, kThemeTextColorDocumentWindowTitleActive, 0 }, /* 133 */
  141.     { "DocumentWindowTitleInactiveText",    0, kThemeTextColorDocumentWindowTitleInactive, 0 }, /* 134 */
  142.     { "MovableModalWindowTitleActiveText",  0, kThemeTextColorMovableModalWindowTitleActive, 0 }, /* 135 */
  143.     { "MovableModalWindowTitleInactiveText",0, kThemeTextColorMovableModalWindowTitleInactive, 0 }, /* 136 */
  144.     { "UtilityWindowTitleActiveText",     0, kThemeTextColorUtilityWindowTitleActive, 0 }, /* 137 */
  145.     { "UtilityWindowTitleInactiveText",     0, kThemeTextColorUtilityWindowTitleInactive, 0 }, /* 138 */
  146.     { "PopupWindowTitleActiveText",     0, kThemeTextColorPopupWindowTitleActive, 0 }, /* 139 */
  147.     { "PopupWindowTitleInactiveText",     0, kThemeTextColorPopupWindowTitleInactive, 0 }, /* 140 */
  148.     { "RootMenuActiveText",     0, kThemeTextColorRootMenuActive, 0 }, /* 141 */
  149.     { "RootMenuSelectedText",     0, kThemeTextColorRootMenuSelected, 0 }, /* 142 */
  150.     { "RootMenuDisabledText",     0, kThemeTextColorRootMenuDisabled, 0 }, /* 143 */
  151.     { "MenuItemActiveText",     0, kThemeTextColorMenuItemActive, 0 }, /* 144 */
  152.     { "MenuItemSelectedText",     0, kThemeTextColorMenuItemSelected, 0 }, /* 145 */
  153.     { "MenuItemDisabledText",     0, kThemeTextColorMenuItemDisabled, 0 }, /* 146 */
  154.     { "PopupLabelActiveText",     0, kThemeTextColorPopupLabelActive, 0 }, /* 147 */
  155.     { "PopupLabelInactiveText",     0, kThemeTextColorPopupLabelInactive, 0 }, /* 148 */
  156.     { "TabFrontActiveText",     0, kThemeTextColorTabFrontActive, 0 }, /* 149 */
  157.     { "TabNonFrontActiveText",     0, kThemeTextColorTabNonFrontActive, 0 }, /* 150 */
  158.     { "TabNonFrontPressedText",     0, kThemeTextColorTabNonFrontPressed, 0 }, /* 151 */
  159.     { "TabFrontInactiveText",     0, kThemeTextColorTabFrontInactive, 0 }, /* 152 */
  160.     { "TabNonFrontInactiveText",     0, kThemeTextColorTabNonFrontInactive, 0 }, /* 153 */
  161.     { "IconLabelSelectedText",     0, kThemeTextColorIconLabelSelected, 0 }, /* 154 */
  162.     { "BevelButtonStickyActiveText",     0, kThemeTextColorBevelButtonStickyActive, 0 }, /* 155 */
  163.     { "BevelButtonStickyInactiveText",     0, kThemeTextColorBevelButtonStickyInactive, 0 }, /* 156 */
  164.     { "NotificationText",     0, kThemeTextColorNotification, 0 }, /* 157 */
  165.     { "SystemDetailText",     0, kThemeTextColorSystemDetail, 0 }, /* 158 */
  166.     { "WhiteText",     0, kThemeTextColorWhite, 0 }, /* 159 */
  167.     { "TabPaneBackground",     0, 0, kThemeBackgroundTabPane }, /* 160 */
  168.     { "PlacardBackground",     0, 0, kThemeBackgroundPlacard }, /* 161 */
  169.     { "WindowHeaderBackground",     0, 0, kThemeBackgroundWindowHeader }, /* 162 */
  170.     { "ListViewWindowHeaderBackground",     0, 0, kThemeBackgroundListViewWindowHeader }, /* 163 */
  171.     { "SecondaryGroupBoxBackground",     0, 0, kThemeBackgroundSecondaryGroupBox }, /* 164 */
  172.     { "MetalBackground",     0, 0, kThemeBackgroundMetal }, /* 165 */
  173.     { NULL,     0, 0, 0 }
  174. };
  175. #define MAX_PIXELCODE 165
  176. /*
  177.  *----------------------------------------------------------------------
  178.  *
  179.  * GetThemeFromPixelCode --
  180.  *
  181.  * When given a pixel code corresponding to a theme system color,
  182.  * set one of brush, textColor or background to the corresponding
  183.  * Appearance Mgr theme constant.
  184.  *
  185.  * Results:
  186.  * Returns false if not a real pixel, true otherwise.
  187.  *
  188.  * Side effects:
  189.  * None.
  190.  *
  191.  *----------------------------------------------------------------------
  192.  */
  193. static int
  194. GetThemeFromPixelCode(
  195.     unsigned char code,
  196.     ThemeBrush *brush,
  197.     ThemeTextColor *textColor,
  198.     ThemeBackgroundKind *background)
  199. {
  200.     if (code >= MIN_PIXELCODE && code <= MAX_PIXELCODE && code != PIXEL_MAGIC) {
  201. *brush = systemColorMap[code - MIN_PIXELCODE].brush;
  202. *textColor = systemColorMap[code - MIN_PIXELCODE].textColor;
  203. *background = systemColorMap[code - MIN_PIXELCODE].background;
  204.     } else {
  205. *brush = 0;
  206. *textColor = 0;
  207. *background = 0;
  208.     }
  209.     if (!*brush && !*textColor && !*background && code != PIXEL_MAGIC) {
  210. return false;
  211.     } else {
  212. return true;
  213.     }
  214. }
  215. /*
  216.  *----------------------------------------------------------------------
  217.  *
  218.  * GetThemeColor --
  219.  *
  220.  * Get RGB color for a given system color or pixel value.
  221.  *
  222.  * Results:
  223.  * OSStatus
  224.  *
  225.  * Side effects:
  226.  * None.
  227.  *
  228.  *----------------------------------------------------------------------
  229.  */
  230. static OSStatus
  231. GetThemeColor(
  232.     unsigned long pixel,
  233.     ThemeBrush brush,
  234.     ThemeTextColor textColor,
  235.     ThemeBackgroundKind background,
  236.     RGBColor *c)
  237. {
  238.     OSStatus err = noErr;
  239.     if (brush) {
  240. err = ChkErr(GetThemeBrushAsColor,
  241. brush == kThemeBrushMenuBackgroundSelected ?
  242. kThemeBrushFocusHighlight : brush, 32, true, c);
  243.     } else if (textColor) {
  244. err = ChkErr(GetThemeTextColor, textColor, 32, true, c);
  245.     } else {
  246. c->red   = (pixel >> 16) & 0xff;
  247. c->green  = (pixel >>  8) & 0xff;
  248. c->blue   = (pixel ) & 0xff;
  249. c->red  |= c->red   << 8;
  250. c->green |= c->green << 8;
  251. c->blue  |= c->blue  << 8;
  252.     }
  253.     return err;
  254. }
  255. /*
  256.  *----------------------------------------------------------------------
  257.  *
  258.  * TkSetMacColor --
  259.  *
  260.  * Populates a Macintosh RGBColor structure from a X style
  261.  * pixel value.
  262.  *
  263.  * Results:
  264.  * Returns false if not a real pixel, true otherwise.
  265.  *
  266.  * Side effects:
  267.  * The variable macColor is updated to the pixels value.
  268.  *
  269.  *----------------------------------------------------------------------
  270.  */
  271. int
  272. TkSetMacColor(
  273.     unsigned long pixel, /* Pixel value to convert. */
  274.     RGBColor *macColor) /* Mac color struct to modify. */
  275. {
  276.     OSStatus err = -1;
  277.     ThemeBrush brush;
  278.     ThemeTextColor textColor;
  279.     ThemeBackgroundKind background;
  280.     if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor,
  281.     &background)) {
  282. err = ChkErr(GetThemeColor, pixel, brush, textColor, background,
  283. macColor);
  284.     }
  285.     return (err == noErr);
  286. }
  287. /*
  288.  *----------------------------------------------------------------------
  289.  *
  290.  * TkMacOSXSetColorInPort --
  291.  *
  292.  * Sets fore or back color in the given QD port from an X pixel
  293.  * value, and if the pixel code indicates a system color, sets
  294.  * the corresponding brush, textColor or background via
  295.  * Appearance mgr APIs.
  296.  *
  297.  * Results:
  298.  * None.
  299.  *
  300.  * Side effects:
  301.  * If penPat is non-NULL it is set to the forground color/pattern.
  302.  *
  303.  *----------------------------------------------------------------------
  304.  */
  305. void
  306. TkMacOSXSetColorInPort(
  307.     unsigned long pixel,
  308.     int fg,
  309.     PixPatHandle penPat,
  310.     CGrafPtr port)
  311. {
  312.     OSStatus err;
  313.     RGBColor c;
  314.     ThemeBrush brush;
  315.     ThemeTextColor textColor;
  316.     ThemeBackgroundKind background;
  317.     int setPenPat = 0;
  318.     if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor,
  319.     &background)) {
  320. CGrafPtr savePort;
  321. Boolean portChanged;
  322. portChanged = QDSwapPort(port, &savePort);
  323. err = ChkErr(GetThemeColor, pixel, brush, textColor, background, &c);
  324. if (err == noErr) {
  325.     if (fg) {
  326. RGBForeColor(&c);
  327. if (penPat) {
  328.     MakeRGBPat(penPat, &c);
  329.     setPenPat = 1;
  330. }
  331.     } else {
  332. RGBBackColor(&c);
  333.     }
  334. }
  335. err = -1;
  336. if (brush) {
  337.     err = ChkErr(SetThemeBackground,
  338.     brush == kThemeBrushMenuBackgroundSelected ?
  339.     kThemeBrushFocusHighlight : brush, 32, true);
  340. } else if (textColor && fg) {
  341.     err = ChkErr(SetThemeTextColor, textColor, 32, true);
  342. } else if (background) {
  343.     Rect bounds;
  344.     GetPortBounds(port, &bounds);
  345.     err = ChkErr(ApplyThemeBackground, background, &bounds,
  346.     kThemeStateActive, 32, true);
  347. }
  348. if (penPat && err == noErr && (brush || background)) {
  349.     GetPortBackPixPat(port, penPat);
  350.     setPenPat = 1;
  351. }
  352. if (portChanged) {
  353.     QDSwapPort(savePort, NULL);
  354. }
  355.     } else {
  356. TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
  357.     }
  358.     if (penPat && !setPenPat) {
  359. GetPortBackPixPat(port, penPat);
  360.     }
  361. }
  362. /*
  363.  *----------------------------------------------------------------------
  364.  *
  365.  * TkMacOSXSetColorInContext --
  366.  *
  367.  * Sets fill and stroke color in the given CG context from an X
  368.  * pixel value, or if the pixel code indicates a system color,
  369.  * sets the corresponding brush, textColor or background via
  370.  * HITheme APIs if available or Appearance mgr APIs.
  371.  *
  372.  * Results:
  373.  * None.
  374.  *
  375.  * Side effects:
  376.  * None.
  377.  *
  378.  *----------------------------------------------------------------------
  379.  */
  380. void
  381. TkMacOSXSetColorInContext(
  382.     unsigned long pixel,
  383.     CGContextRef context)
  384. {
  385.     OSStatus err = -1;
  386.     RGBColor c;
  387.     ThemeBrush brush;
  388.     ThemeTextColor textColor;
  389.     ThemeBackgroundKind background;
  390.     if (GetThemeFromPixelCode((pixel >> 24) & 0xff, &brush, &textColor,
  391.     &background)) {
  392. if (brush) {
  393.     TK_IF_MAC_OS_X_API (4, HIThemeSetFill,
  394. err = ChkErr(HIThemeSetFill, brush, NULL, context,
  395. kHIThemeOrientationNormal);
  396. TK_IF_MAC_OS_X_API_COND (4, HIThemeSetFill, err == noErr,
  397.     err = ChkErr(HIThemeSetStroke, brush, NULL, context,
  398.     kHIThemeOrientationNormal);
  399. ) TK_ENDIF
  400.     ) TK_ENDIF
  401. } else if (textColor) {
  402.     TK_IF_MAC_OS_X_API (4, HIThemeSetTextFill,
  403. err = ChkErr(HIThemeSetTextFill, textColor, NULL, context,
  404. kHIThemeOrientationNormal);
  405.     ) TK_ENDIF
  406. } else if (background) {
  407.     TK_IF_MAC_OS_X_API (3, CGContextGetClipBoundingBox,
  408. CGRect rect = CGContextGetClipBoundingBox(context);
  409. HIThemeBackgroundDrawInfo info = { 0, kThemeStateActive,
  410. background };
  411. TK_IF_MAC_OS_X_API (3, HIThemeApplyBackground,
  412.     TK_IF_HI_TOOLBOX (3, /* c.f. QA1377 */
  413. err = ChkErr(HIThemeApplyBackground, &rect, &info,
  414. context, kHIThemeOrientationNormal);
  415.     ) TK_ENDIF
  416. ) TK_ENDIF
  417.     ) TK_ENDIF
  418. }
  419. if (err == noErr) {
  420.     return;
  421. }
  422. #if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
  423. /*
  424.  * Convert Appearance theme pattern to CGPattern:
  425.  */
  426. if ((brush || background) && CGPatternCreateWithImage != NULL) {
  427.     static PixPatHandle pixpat = NULL;
  428.     static GWorldPtr patGWorld = NULL;
  429.     static uint32_t bitmapInfo = 0;
  430.     const short patDim = 16;
  431.     const Rect bounds = {0, 0, patDim, patDim};
  432.     CGrafPtr savePort;
  433.     Boolean portChanged;
  434.     PixMapHandle pixmap;
  435.     long rowbytes;
  436.     CGImageRef img;
  437.     CGColorSpaceRef rgbCspace;
  438.     CGDataProviderRef provider;
  439.     if (!pixpat) {
  440. pixpat = NewPixPat();
  441. err = ChkErr(NewGWorld, &patGWorld, 32, &bounds, NULL, NULL, 0
  442. #ifdef __LITTLE_ENDIAN__
  443. | kNativeEndianPixMap
  444. #endif
  445. );
  446. if (!pixpat || err != noErr || !patGWorld) {
  447.     Tcl_Panic("TkMacOSXSetColorInContext(): "
  448. "pattern initialization failed !");
  449. }
  450. TK_IF_HI_TOOLBOX (4,
  451.     bitmapInfo = kCGBitmapByteOrder32Host;
  452. ) TK_ENDIF
  453.     }
  454.     portChanged = QDSwapPort(patGWorld, &savePort);
  455.     TkMacOSXSetColorInPort(pixel, 1, pixpat, patGWorld);
  456. #ifdef TK_MAC_DEBUG
  457.     Rect patBounds;
  458.     GetPixBounds((**pixpat).patMap, &patBounds);
  459.     if (patBounds.right > patDim || patBounds.bottom > patDim) {
  460. Tcl_Panic("TkMacOSXSetColorInContext(): "
  461.     "pattern larger than expected !");
  462.     }
  463. #endif /* TK_MAC_DEBUG */
  464.     FillCRect(&bounds, pixpat);
  465.     if (portChanged) {
  466. QDSwapPort(savePort, NULL);
  467.     }
  468.     pixmap = GetPortPixMap(patGWorld);
  469.     rowbytes = GetPixRowBytes(pixmap);
  470.     provider = CGDataProviderCreateWithData(&patGWorld,
  471.     GetPixBaseAddr(pixmap), rowbytes * patDim, NULL);
  472.     rgbCspace = CGColorSpaceCreateDeviceRGB();
  473.     img = CGImageCreate(patDim, patDim, 8, 32,
  474.     rowbytes, rgbCspace, kCGImageAlphaFirst | bitmapInfo,
  475.     provider, NULL, 0, kCGRenderingIntentDefault);
  476.     CGColorSpaceRelease(rgbCspace);
  477.     CGDataProviderRelease(provider);
  478.     if (img) {
  479. CGPatternRef pat = CGPatternCreateWithImage(img, 2);
  480. CGColorSpaceRef patCSpace = CGColorSpaceCreatePattern(NULL);
  481. const float alpha = 1;
  482. CGContextSetFillColorSpace(context, patCSpace);
  483. CGContextSetFillPattern(context, pat, &alpha);
  484. CGContextSetStrokeColorSpace(context, patCSpace);
  485. CGContextSetStrokePattern(context, pat, &alpha);
  486. CGColorSpaceRelease(patCSpace);
  487. CGPatternRelease(pat);
  488. CGImageRelease(img);
  489. return;
  490.     }
  491. }
  492. #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1040 */
  493. err = ChkErr(GetThemeColor, pixel, brush, textColor, background, &c);
  494. if (err == noErr) {
  495.     double r = c.red   / 65535.0;
  496.     double g = c.green / 65535.0;
  497.     double b = c.blue  / 65535.0;
  498.     CGContextSetRGBFillColor(context, r, g, b, 1.0);
  499.     CGContextSetRGBStrokeColor(context, r, g, b, 1.0);
  500. }
  501.     } else if (((pixel >> 24) & 0xff) == TRANSPARENT_PIXEL) {
  502. CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.0);
  503. CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.0);
  504.     } else {
  505. TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
  506.     }
  507. }
  508. /*
  509.  *----------------------------------------------------------------------
  510.  *
  511.  * TkpGetColor --
  512.  *
  513.  * Allocate a new TkColor for the color with the given name.
  514.  *
  515.  * Results:
  516.  * Returns a newly allocated TkColor, or NULL on failure.
  517.  *
  518.  * Side effects:
  519.  * May invalidate the colormap cache associated with tkwin upon
  520.  * allocating a new colormap entry. Allocates a new TkColor
  521.  * structure.
  522.  *
  523.  *----------------------------------------------------------------------
  524.  */
  525. TkColor *
  526. TkpGetColor(
  527.     Tk_Window tkwin, /* Window in which color will be used. */
  528.     Tk_Uid name) /* Name of color to allocated (in form
  529.  * suitable for passing to XParseColor). */
  530. {
  531.     Display *display = Tk_Display(tkwin);
  532.     Colormap colormap = Tk_Colormap(tkwin);
  533.     TkColor *tkColPtr;
  534.     XColor color;
  535.     /*
  536.      * Check to see if this is a system color. Otherwise, XParseColor
  537.      * will do all the work.
  538.      */
  539.     if (strncasecmp(name, "system", 6) == 0) {
  540. Tcl_Obj *strPtr = Tcl_NewStringObj(name+6, -1);
  541. int idx, result;
  542. result = Tcl_GetIndexFromObjStruct(NULL, strPtr, systemColorMap,
  543.     sizeof(struct SystemColorMapEntry), NULL, TCL_EXACT, &idx);
  544. Tcl_DecrRefCount(strPtr);
  545. if (result == TCL_OK) {
  546.     OSStatus err;
  547.     RGBColor c;
  548.     unsigned char pixelCode = idx + MIN_PIXELCODE;
  549.     ThemeBrush brush = systemColorMap[idx].brush;
  550.     ThemeTextColor textColor = systemColorMap[idx].textColor;
  551.     ThemeBackgroundKind background = systemColorMap[idx].background;
  552.     err = ChkErr(GetThemeColor, 0, brush, textColor, background, &c);
  553.     if (err == noErr) {
  554. color.red   = c.red;
  555. color.green = c.green;
  556. color.blue  = c.blue;
  557. color.pixel = ((((((pixelCode << 8)
  558.     | ((color.red   >> 8) & 0xff)) << 8)
  559.     | ((color.green >> 8) & 0xff)) << 8)
  560.     | ((color.blue  >> 8) & 0xff));
  561. goto validXColor;
  562.     }
  563. }
  564.     }
  565.     if (XParseColor(display, colormap, name, &color) == 0) {
  566. return (TkColor *) NULL;
  567.     }
  568. validXColor:
  569.     tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
  570.     tkColPtr->color = color;
  571.     return tkColPtr;
  572. }
  573. /*
  574.  *----------------------------------------------------------------------
  575.  *
  576.  * TkpGetColorByValue --
  577.  *
  578.  * Given a desired set of red-green-blue intensities for a color,
  579.  * locate a pixel value to use to draw that color in a given
  580.  * window.
  581.  *
  582.  * Results:
  583.  * The return value is a pointer to an TkColor structure that
  584.  * indicates the closest red, blue, and green intensities available
  585.  * to those specified in colorPtr, and also specifies a pixel
  586.  * value to use to draw in that color.
  587.  *
  588.  * Side effects:
  589.  * May invalidate the colormap cache for the specified window.
  590.  * Allocates a new TkColor structure.
  591.  *
  592.  *----------------------------------------------------------------------
  593.  */
  594. TkColor *
  595. TkpGetColorByValue(
  596.     Tk_Window tkwin, /* Window in which color will be used. */
  597.     XColor *colorPtr) /* Red, green, and blue fields indicate
  598.  * desired color. */
  599. {
  600.     TkColor *tkColPtr = (TkColor *) ckalloc(sizeof(TkColor));
  601.     tkColPtr->color.red = colorPtr->red;
  602.     tkColPtr->color.green = colorPtr->green;
  603.     tkColPtr->color.blue = colorPtr->blue;
  604.     tkColPtr->color.pixel = TkpGetPixel(&tkColPtr->color);
  605.     return tkColPtr;
  606. }
  607. #if 0
  608. /*
  609.  *----------------------------------------------------------------------
  610.  *
  611.  * TkMacOSXCompareColors --
  612.  *
  613.  * On Mac, color codes may specify symbolic values like "highlight
  614.  * foreground", but we really need the actual values to compare.
  615.  * Maybe see also: "TIP #154: Add Named Colors to Tk".
  616.  *
  617.  * Results:
  618.  * Returns true if both colors are the same, false otherwise.
  619.  *
  620.  * Side effects:
  621.  * None.
  622.  *
  623.  *----------------------------------------------------------------------
  624.  */
  625. int
  626. TkMacOSXCompareColors(
  627.     unsigned long c1,
  628.     unsigned long c2)
  629. {
  630.     RGBColor col1, col2;
  631.     return  TkSetMacColor(c1,&col1) &&
  632.     TkSetMacColor(c1,&col2) &&
  633.     !memcmp(&col1,&col2,sizeof(col1));
  634. }
  635. #endif /* !TK_DRAW_IN_CONTEXT */
  636. /*
  637.  *----------------------------------------------------------------------
  638.  *
  639.  * Stub functions --
  640.  *
  641.  * These functions are just stubs for functions that either
  642.  * don't make sense on the Mac or have yet to be implemented.
  643.  *
  644.  * Results:
  645.  * None.
  646.  *
  647.  * Side effects:
  648.  * These calls do nothing - which may not be expected.
  649.  *
  650.  *----------------------------------------------------------------------
  651.  */
  652. Status
  653. XAllocColor(
  654.     Display *display, /* Display. */
  655.     Colormap map, /* Not used. */
  656.     XColor *colorPtr) /* XColor struct to modify. */
  657. {
  658.     display->request++;
  659.     colorPtr->pixel = TkpGetPixel(colorPtr);
  660.     return 1;
  661. }
  662. Colormap
  663. XCreateColormap(
  664.     Display *display, /* Display. */
  665.     Window window, /* X window. */
  666.     Visual *visual, /* Not used. */
  667.     int alloc) /* Not used. */
  668. {
  669.     static Colormap index = 1;
  670.     /*
  671.      * Just return a new value each time.
  672.      */
  673.     return index++;
  674. }
  675. void
  676. XFreeColormap(
  677.     Display* display, /* Display. */
  678.     Colormap colormap) /* Colormap. */
  679. {
  680. }
  681. void
  682. XFreeColors(
  683.     Display* display, /* Display. */
  684.     Colormap colormap, /* Colormap. */
  685.     unsigned long* pixels, /* Array of pixels. */
  686.     int npixels, /* Number of pixels. */
  687.     unsigned long planes) /* Number of pixel planes. */
  688. {
  689.     /*
  690.      * The Macintosh version of Tk uses TrueColor. Nothing
  691.      * needs to be done to release colors as there really is
  692.      * no colormap in the Tk sense.
  693.      */
  694. }