1 /*
2  * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include "awt_Brush.h"
27 
28 GDIHashtable AwtBrush::cache("Brush cache", DeleteAwtBrush);
29 
AwtBrush(COLORREF color)30 AwtBrush::AwtBrush(COLORREF color) {
31     if (!EnsureGDIObjectAvailability()) {
32         // If we've run out of GDI objects, don't try to create
33         // a new one
34         return;
35     }
36     SetColor(color);
37     HBRUSH brush = ::CreateSolidBrush(color);
38     /*
39      * Fix for BugTraq ID 4191297.
40      * If GDI resource creation failed flush all GDIHashtables
41      * to destroy unreferenced GDI resources.
42      */
43     if (brush == NULL) {
44         cache.flushAll();
45         brush = ::CreateSolidBrush(color);
46     }
47     DASSERT(brush != NULL);
48     SetHandle(brush);
49     if (brush == NULL) {
50         // We've already incremented the counter: decrement if
51         // creation failed
52         Decrement();
53     }
54 }
55 
Get(COLORREF color)56 AwtBrush* AwtBrush::Get(COLORREF color) {
57 
58     CriticalSection::Lock l(cache.getManagerLock());
59 
60     AwtBrush* obj = static_cast<AwtBrush*>(cache.get(
61         reinterpret_cast<void*>(static_cast<INT_PTR>(color))));
62     if (obj == NULL) {
63         obj = new AwtBrush(color);
64         VERIFY(cache.put(reinterpret_cast<void*>(
65             static_cast<INT_PTR>(color)), obj) == NULL);
66     }
67     obj->IncrRefCount();
68     return obj;
69 }
70 
ReleaseInCache()71 void AwtBrush::ReleaseInCache() {
72 
73     CriticalSection::Lock l(cache.getManagerLock());
74 
75     if (DecrRefCount() == 0) {
76         cache.release(reinterpret_cast<void*>(
77             static_cast<INT_PTR>(GetColor())));
78     }
79 }
80 
DeleteAwtBrush(void * pBrush)81 void AwtBrush::DeleteAwtBrush(void* pBrush) {
82     delete (AwtBrush*)pBrush;
83 }
84