jdk/src/windows/native/sun/windows/awt_Toolkit.h
author dav
Tue, 16 Sep 2008 12:17:02 +0400
changeset 1962 6c293d33645b
parent 1954 b93b85df3211
child 2472 b7aba00cabb6
permissions -rw-r--r--
6315717: Support for mouse with multiple scroll wheels and 4 or more buttons Summary: implementation of the more mouse buttons support Reviewed-by: art, dcherepanov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
105
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
     2
 * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * The Toolkit class has two functions: it instantiates the AWT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * ToolkitPeer's native methods, and provides the DLL's core functions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * There are two ways this DLL can be used: either as a dynamically-
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * loaded Java native library from the interpreter, or by a Windows-
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * specific app.  The first manner requires that the Toolkit provide
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * all support needed so the app can function as a first-class Windows
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * app, while the second assumes that the app will provide that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * functionality.  Which mode this DLL functions in is determined by
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * which initialization paradigm is used. If the Toolkit is constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * normally, then the Toolkit will have its own pump. If it is explicitly
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * initialized for an embedded environment (via a static method on
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * sun.awt.windows.WToolkit), then it will rely on an external message
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * pump.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * The most basic functionality needed is a Windows message pump (also
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * known as a message loop).  When an Java app is started as a console
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * app by the interpreter, the Toolkit needs to provide that message
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * pump if the AWT is dynamically loaded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
#ifndef AWT_TOOLKIT_H
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
#define AWT_TOOLKIT_H
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
#include "awt.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
#include "awtmsg.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
#include "Trace.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
#include "sun_awt_windows_WToolkit.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
class AwtObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
class AwtDialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
class AwtDropTarget;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
typedef VOID (CALLBACK* IDLEPROC)(VOID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
typedef BOOL (CALLBACK* PEEKMESSAGEPROC)(MSG&);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * class JNILocalFrame
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * Push/PopLocalFrame helper
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
class JNILocalFrame {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
  public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    INLINE JNILocalFrame(JNIEnv *env, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        m_env = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        int result = m_env->PushLocalFrame(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        if (result < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            DASSERT(FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            JNU_ThrowOutOfMemoryError(m_env, "Can't allocate localRefs");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    INLINE ~JNILocalFrame() { m_env->PopLocalFrame(NULL); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
  private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    JNIEnv* m_env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * class CriticalSection
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * ~~~~~ ~~~~~~~~~~~~~~~~
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * Lightweight intra-process thread synchronization. Can only be used with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * other critical sections, and only within the same process.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
class CriticalSection {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
  public:
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
    91
    INLINE  CriticalSection() { ::InitializeCriticalSection(&rep); }
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
    92
    INLINE ~CriticalSection() { ::DeleteCriticalSection(&rep); }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    class Lock {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
      public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        INLINE Lock(const CriticalSection& cs) : critSec(cs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
            (const_cast<CriticalSection &>(critSec)).Enter();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        INLINE ~Lock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
            (const_cast<CriticalSection &>(critSec)).Leave();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
      private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        const CriticalSection& critSec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    friend Lock;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
  private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    CRITICAL_SECTION rep;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    CriticalSection(const CriticalSection&);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    const CriticalSection& operator =(const CriticalSection&);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
  public:
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
   114
    virtual void Enter() {
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
   115
        ::EnterCriticalSection(&rep);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    }
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
   117
    virtual BOOL TryEnter() {
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
   118
        return ::TryEnterCriticalSection(&rep);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
1954
b93b85df3211 6585765: RFE: Remove Unicows-related code from AWT
art
parents: 105
diff changeset
   120
    virtual void Leave() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        ::LeaveCriticalSection(&rep);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
// Macros for using CriticalSection objects that help trace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
// lock/unlock actions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
#define CRITICAL_SECTION_ENTER(cs) { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    J2dTraceLn4(J2D_TRACE_VERBOSE2, \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                "CS.Wait:  tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    (cs).Enter(); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    J2dTraceLn4(J2D_TRACE_VERBOSE2, \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                "CS.Enter: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
#define CRITICAL_SECTION_LEAVE(cs) { \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    J2dTraceLn4(J2D_TRACE_VERBOSE2, \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                "CS.Leave: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    (cs).Leave(); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    J2dTraceLn4(J2D_TRACE_VERBOSE2, \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                "CS.Left:  tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
/************************************************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 * AwtToolkit class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
class AwtToolkit {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    enum {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        KB_STATE_SIZE = 256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    /* java.awt.Toolkit method ids */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    static jmethodID getDefaultToolkitMID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    static jmethodID getFontMetricsMID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        static jmethodID insetsMID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    /* sun.awt.windows.WToolkit ids */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    static jmethodID windowsSettingChangeMID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    static jmethodID displayChangeMID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    BOOL m_isDynamicLayoutSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    AwtToolkit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    ~AwtToolkit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    BOOL Initialize(BOOL localPump);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    BOOL Dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    void SetDynamicLayout(BOOL dynamic);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    BOOL IsDynamicLayoutSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    BOOL IsDynamicLayoutSupported();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    BOOL IsDynamicLayoutActive();
1962
6c293d33645b 6315717: Support for mouse with multiple scroll wheels and 4 or more buttons
dav
parents: 1954
diff changeset
   178
    BOOL areExtraMouseButtonsEnabled();
6c293d33645b 6315717: Support for mouse with multiple scroll wheels and 4 or more buttons
dav
parents: 1954
diff changeset
   179
    void setExtraMouseButtonsEnabled(BOOL enable);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    INLINE BOOL localPump() { return m_localPump; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    INLINE HWND GetHWnd() { return m_toolkitHWnd; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    INLINE HMODULE GetModuleHandle() { return m_dllHandle; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    INLINE void SetModuleHandle(HMODULE h) { m_dllHandle = h; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    INLINE static DWORD MainThread() { return GetInstance().m_mainThreadId; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    INLINE void VerifyActive() throw (awt_toolkit_shutdown) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        if (!m_isActive && m_mainThreadId != ::GetCurrentThreadId()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            throw awt_toolkit_shutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    INLINE BOOL IsDisposed() { return m_isDisposed; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    static UINT GetMouseKeyState();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    static void GetKeyboardState(PBYTE keyboardState);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    static ATOM RegisterClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    static void UnregisterClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    INLINE LRESULT SendMessage(UINT msg, WPARAM wParam=0, LPARAM lParam=0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (!m_isDisposed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            return ::SendMessage(GetHWnd(), msg, wParam, lParam);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                                    LPARAM lParam);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    static LRESULT CALLBACK GetMessageFilter(int code, WPARAM wParam,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                                             LPARAM lParam);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    static LRESULT CALLBACK ForegroundIdleFilter(int code, WPARAM wParam,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                                                 LPARAM lParam);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    INLINE static AwtToolkit& GetInstance() { return theInstance; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    INLINE void SetPeer(JNIEnv *env, jobject wToolkit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        AwtToolkit &tk = AwtToolkit::GetInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        if (tk.m_peer != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            env->DeleteGlobalRef(tk.m_peer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        tk.m_peer = (wToolkit != NULL) ? env->NewGlobalRef(wToolkit) : NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    INLINE jobject GetPeer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        return m_peer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    // is this thread the main thread?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    INLINE static BOOL IsMainThread() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        return GetInstance().m_mainThreadId == ::GetCurrentThreadId();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    // post a message to the message pump thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    INLINE BOOL PostMessage(UINT msg, WPARAM wp=0, LPARAM lp=0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        return ::PostMessage(GetHWnd(), msg, wp, lp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    // cause the message pump thread to call the function synchronously now!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    INLINE void * InvokeFunction(void*(*ftn)(void)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        return (void *)SendMessage(WM_AWT_INVOKE_VOID_METHOD, (WPARAM)ftn, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    INLINE void InvokeFunction(void (*ftn)(void)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        InvokeFunction((void*(*)(void))ftn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    INLINE void * InvokeFunction(void*(*ftn)(void *), void* param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        return (void *)SendMessage(WM_AWT_INVOKE_METHOD, (WPARAM)ftn,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                                   (LPARAM)param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    INLINE void InvokeFunction(void (*ftn)(void *), void* param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        InvokeFunction((void*(*)(void*))ftn, param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    INLINE CriticalSection &GetSyncCS() { return m_Sync; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    void *SyncCall(void*(*ftn)(void *), void* param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    void SyncCall(void (*ftn)(void *), void *param);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    void *SyncCall(void *(*ftn)(void));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    void SyncCall(void (*ftn)(void));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    // cause the message pump thread to call the function later ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    INLINE void InvokeFunctionLater(void (*ftn)(void *), void* param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        if (!PostMessage(WM_AWT_INVOKE_METHOD, (WPARAM)ftn, (LPARAM)param)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
   // cause the message pump thread to synchronously synchronize on the handle
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    INLINE void WaitForSingleObject(HANDLE handle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        SendMessage(WM_AWT_WAIT_FOR_SINGLE_OBJECT, 0, (LPARAM)handle);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * Create an AwtXxxx C++ component using a given factory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    typedef void (*ComponentFactory)(void*, void*);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    static void CreateComponent(void* hComponent, void* hParent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                                ComponentFactory compFactory, BOOL isParentALocalReference=TRUE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    static void DestroyComponentHWND(HWND hwnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    // constants used to PostQuitMessage
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    static const int EXIT_ENCLOSING_LOOP;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    static const int EXIT_ALL_ENCLOSING_LOOPS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    // ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    void QuitMessageLoop(int status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    BOOL PreProcessMsg(MSG& msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    /* Create an ID which maps to an AwtObject pointer, such as a menu. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    UINT CreateCmdID(AwtObject* object);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    // removes cmd id mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    void RemoveCmdID(UINT id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    /* Return the AwtObject associated with its ID. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    AwtObject* LookupCmdID(UINT id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    /* Return the current application icon. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    HICON GetAwtIcon();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    HICON GetAwtIconSm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    /* Turns on/off dialog modality for the system. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    INLINE AwtDialog* SetModal(AwtDialog* frame) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        AwtDialog* previousDialog = m_pModalDialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        m_pModalDialog = frame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        return previousDialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    INLINE void ResetModal(AwtDialog* oldFrame) { m_pModalDialog = oldFrame; };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    INLINE BOOL IsModal() { return (m_pModalDialog != NULL); };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    INLINE AwtDialog* GetModalDialog(void) { return m_pModalDialog; };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    /* Stops the current message pump (normally a modal dialog pump) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    INLINE void StopMessagePump() { m_breakOnError = TRUE; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    /* Debug settings */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    INLINE void SetVerbose(long flag)   { m_verbose = (flag != 0); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    INLINE void SetVerify(long flag)    { m_verifyComponents = (flag != 0); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    INLINE void SetBreak(long flag)     { m_breakOnError = (flag != 0); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    INLINE void SetHeapCheck(long flag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    static void SetBusy(BOOL busy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    /* Set and get the default input method Window handler. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    INLINE void SetInputMethodWindow(HWND inputMethodHWnd) { m_inputMethodHWnd = inputMethodHWnd; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    INLINE HWND GetInputMethodWindow() { return m_inputMethodHWnd; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    static VOID CALLBACK PrimaryIdleFunc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    static VOID CALLBACK SecondaryIdleFunc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    static BOOL CALLBACK CommonPeekMessageFunc(MSG& msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    static BOOL activateKeyboardLayout(HKL hkl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    HANDLE m_waitEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    DWORD eventNumber;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    HWND CreateToolkitWnd(LPCTSTR name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    BOOL m_localPump;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    DWORD m_mainThreadId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    HWND m_toolkitHWnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    HWND m_inputMethodHWnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    BOOL m_verbose;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    BOOL m_isActive; // set to FALSE at beginning of Dispose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    BOOL m_isDisposed; // set to TRUE at end of Dispose
1962
6c293d33645b 6315717: Support for mouse with multiple scroll wheels and 4 or more buttons
dav
parents: 1954
diff changeset
   356
    BOOL m_areExtraMouseButtonsEnabled;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    BOOL m_vmSignalled; // set to TRUE if QUERYENDSESSION has successfully
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        // raised SIGTERM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
    BOOL m_verifyComponents;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    BOOL m_breakOnError;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    BOOL  m_breakMessageLoop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    UINT  m_messageLoopResult;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    class AwtComponent* m_lastMouseOver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    BOOL                m_mouseDown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    HHOOK m_hGetMessageHook;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    UINT_PTR  m_timer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    class AwtCmdIDList* m_cmdIDs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    BYTE                m_lastKeyboardState[KB_STATE_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    CriticalSection     m_lockKB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    static AwtToolkit theInstance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    /* The current modal dialog frame (normally NULL). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    AwtDialog* m_pModalDialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    /* The WToolkit peer instance */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    jobject m_peer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    HMODULE m_dllHandle;  /* The module handle. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    CriticalSection m_Sync;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
/* track display changes - used by palette-updating code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
   This is a workaround for a windows bug that prevents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
   WM_PALETTECHANGED event from occurring immediately after
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
   a WM_DISPLAYCHANGED event.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    BOOL m_displayChanged;  /* Tracks displayChanged events */
105
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   396
    // 0 means we are not embedded.
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   397
    DWORD m_embedderProcessID;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    BOOL HasDisplayChanged() { return m_displayChanged; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    void ResetDisplayChanged() { m_displayChanged = FALSE; }
105
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   402
    void RegisterEmbedderProcessId(HWND);
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   403
    BOOL IsEmbedderProcessId(const DWORD processID) const
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   404
    {
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   405
        return m_embedderProcessID && (processID == m_embedderProcessID);
e08ac2105adc 6595651: Focus transfers broken for applications embedding AWT across processes
son
parents: 2
diff changeset
   406
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
 private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    static JNIEnv *m_env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    static HANDLE m_thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
 public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    static void SetEnv(JNIEnv *env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    static JNIEnv* GetEnv();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
 * Class to encapsulate the extraction of the java string contents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
 * into a buffer and the cleanup of the buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
class JavaStringBuffer {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
  public:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    JavaStringBuffer(JNIEnv *env, jstring jstr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    INLINE ~JavaStringBuffer() { delete[] buffer; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    INLINE operator LPTSTR() { return buffer; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    INLINE operator LPARAM() { return (LPARAM)buffer; }  /* for SendMessage */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
  private:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    LPTSTR buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
/*  creates an instance of T and assigns it to the argument, but only if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    the argument is initially NULL. Supposed to be thread-safe.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    returns the new value of the argument. I'm not using volatile here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    as InterlockedCompareExchange ensures volatile semantics
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    and acquire/release.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    The function is useful when used with static POD NULL-initialized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    pointers, as they are guaranteed to be NULL before any dynamic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    initialization takes place. This function turns such a pointer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    into a thread-safe singleton, working regardless of dynamic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    initialization order. Destruction problem is not solved,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    we don't need it here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
template<typename T> inline T* SafeCreate(T* &pArg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    /*  this implementation has no locks, it just destroys the object if it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        fails to be the first to init. another way would be using a special
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        flag pointer value to mark the pointer as "being initialized". */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    T* pTemp = (T*)InterlockedCompareExchangePointer((void**)&pArg, NULL, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    if (pTemp != NULL) return pTemp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    T* pNew = new T;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    pTemp = (T*)InterlockedCompareExchangePointer((void**)&pArg, pNew, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    if (pTemp != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        // we failed it - another thread has already initialized pArg
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        delete pNew;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        return pTemp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        return pNew;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
#endif /* AWT_TOOLKIT_H */