OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [insight/] [tcl/] [win/] [tclWinNotify.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclWinNotify.c --
3
 *
4
 *      This file contains Windows-specific procedures for the notifier,
5
 *      which is the lowest-level part of the Tcl event loop.  This file
6
 *      works together with ../generic/tclNotify.c.
7
 *
8
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9
 *
10
 * See the file "license.terms" for information on usage and redistribution
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
 *
13
 * RCS: @(#) $Id: tclWinNotify.c,v 1.1.1.1 2002-01-16 10:25:38 markom Exp $
14
 */
15
 
16
#include "tclInt.h"
17
#include "tclPort.h"
18
#include <winsock.h>
19
 
20
/*
21
 * The follwing static indicates whether this module has been initialized.
22
 */
23
 
24
static int initialized = 0;
25
 
26
#define INTERVAL_TIMER 1                /* Handle of interval timer. */
27
 
28
/*
29
 * The following static structure contains the state information for the
30
 * Windows implementation of the Tcl notifier.
31
 */
32
 
33
static struct {
34
    HWND hwnd;                  /* Messaging window. */
35
    int timeout;                /* Current timeout value. */
36
    int timerActive;            /* 1 if interval timer is running. */
37
} notifier;
38
 
39
/*
40
 * Static routines defined in this file.
41
 */
42
 
43
static void             InitNotifier(void);
44
static void             NotifierExitHandler(ClientData clientData);
45
static LRESULT CALLBACK NotifierProc(HWND hwnd, UINT message,
46
                            WPARAM wParam, LPARAM lParam);
47
static void             UpdateTimer(int timeout);
48
 
49
/*
50
 *----------------------------------------------------------------------
51
 *
52
 * InitNotifier --
53
 *
54
 *      Initializes the notifier window.
55
 *
56
 * Results:
57
 *      None.
58
 *
59
 * Side effects:
60
 *      Creates a new notifier window and window class.
61
 *
62
 *----------------------------------------------------------------------
63
 */
64
 
65
static void
66
InitNotifier(void)
67
{
68
    WNDCLASS class;
69
 
70
    initialized = 1;
71
    notifier.timerActive = 0;
72
    class.style = 0;
73
    class.cbClsExtra = 0;
74
    class.cbWndExtra = 0;
75
    class.hInstance = TclWinGetTclInstance();
76
    class.hbrBackground = NULL;
77
    class.lpszMenuName = NULL;
78
    class.lpszClassName = "TclNotifier";
79
    class.lpfnWndProc = NotifierProc;
80
    class.hIcon = NULL;
81
    class.hCursor = NULL;
82
 
83
    if (!RegisterClass(&class)) {
84
        panic("Unable to register TclNotifier window class");
85
    }
86
    notifier.hwnd = CreateWindow("TclNotifier", "TclNotifier", WS_TILED,
87
            0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);
88
    Tcl_CreateExitHandler(NotifierExitHandler, NULL);
89
}
90
 
91
/*
92
 *----------------------------------------------------------------------
93
 *
94
 * NotifierExitHandler --
95
 *
96
 *      This function is called to cleanup the notifier state before
97
 *      Tcl is unloaded.
98
 *
99
 * Results:
100
 *      None.
101
 *
102
 * Side effects:
103
 *      Destroys the notifier window.
104
 *
105
 *----------------------------------------------------------------------
106
 */
107
 
108
static void
109
NotifierExitHandler(
110
    ClientData clientData)      /* Old window proc */
111
{
112
    initialized = 0;
113
    if (notifier.hwnd) {
114
        KillTimer(notifier.hwnd, INTERVAL_TIMER);
115
        DestroyWindow(notifier.hwnd);
116
        UnregisterClass("TclNotifier", TclWinGetTclInstance());
117
        notifier.hwnd = NULL;
118
    }
119
}
120
 
121
/*
122
 *----------------------------------------------------------------------
123
 *
124
 * UpdateTimer --
125
 *
126
 *      This function starts or stops the notifier interval timer.
127
 *
128
 * Results:
129
 *      None.
130
 *
131
 * Side effects:
132
 *      None.
133
 *
134
 *----------------------------------------------------------------------
135
 */
136
 
137
void
138
UpdateTimer(
139
    int timeout)                /* ms timeout, 0 means cancel timer */
140
{
141
    notifier.timeout = timeout;
142
    if (timeout != 0) {
143
        notifier.timerActive = 1;
144
        SetTimer(notifier.hwnd, INTERVAL_TIMER,
145
                    (unsigned long) notifier.timeout, NULL);
146
    } else {
147
        notifier.timerActive = 0;
148
        KillTimer(notifier.hwnd, INTERVAL_TIMER);
149
    }
150
}
151
 
152
/*
153
 *----------------------------------------------------------------------
154
 *
155
 * Tcl_SetTimer --
156
 *
157
 *      This procedure sets the current notifier timer value.  The
158
 *      notifier will ensure that Tcl_ServiceAll() is called after
159
 *      the specified interval, even if no events have occurred.
160
 *
161
 * Results:
162
 *      None.
163
 *
164
 * Side effects:
165
 *      Replaces any previous timer.
166
 *
167
 *----------------------------------------------------------------------
168
 */
169
 
170
void
171
Tcl_SetTimer(
172
    Tcl_Time *timePtr)          /* Maximum block time, or NULL. */
173
{
174
    UINT timeout;
175
 
176
    if (!initialized) {
177
        InitNotifier();
178
    }
179
 
180
    if (!timePtr) {
181
        timeout = 0;
182
    } else {
183
        /*
184
         * Make sure we pass a non-zero value into the timeout argument.
185
         * Windows seems to get confused by zero length timers.
186
         */
187
        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
188
        if (timeout == 0) {
189
            timeout = 1;
190
        }
191
    }
192
    UpdateTimer(timeout);
193
}
194
 
195
/*
196
 *----------------------------------------------------------------------
197
 *
198
 * NotifierProc --
199
 *
200
 *      This procedure is invoked by Windows to process the timer
201
 *      message whenever we are using an external dispatch loop.
202
 *
203
 * Results:
204
 *      A standard windows result.
205
 *
206
 * Side effects:
207
 *      Services any pending events.
208
 *
209
 *----------------------------------------------------------------------
210
 */
211
 
212
static LRESULT CALLBACK
213
NotifierProc(
214
    HWND hwnd,
215
    UINT message,
216
    WPARAM wParam,
217
    LPARAM lParam)
218
{
219
 
220
    if (message != WM_TIMER) {
221
        return DefWindowProc(hwnd, message, wParam, lParam);
222
    }
223
 
224
    /*
225
     * Process all of the runnable events.
226
     */
227
 
228
    Tcl_ServiceAll();
229
    return 0;
230
}
231
 
232
/*
233
 *----------------------------------------------------------------------
234
 *
235
 * Tcl_WaitForEvent --
236
 *
237
 *      This function is called by Tcl_DoOneEvent to wait for new
238
 *      events on the message queue.  If the block time is 0, then
239
 *      Tcl_WaitForEvent just polls the event queue without blocking.
240
 *
241
 * Results:
242
 *      Returns -1 if a WM_QUIT message is detected, returns 1 if
243
 *      a message was dispatched, otherwise returns 0.
244
 *
245
 * Side effects:
246
 *      Dispatches a message to a window procedure, which could do
247
 *      anything.
248
 *
249
 *----------------------------------------------------------------------
250
 */
251
 
252
int
253
Tcl_WaitForEvent(
254
    Tcl_Time *timePtr)          /* Maximum block time, or NULL. */
255
{
256
    MSG msg;
257
    int timeout;
258
 
259
    if (!initialized) {
260
        InitNotifier();
261
    }
262
 
263
    /*
264
     * Only use the interval timer for non-zero timeouts.  This avoids
265
     * generating useless messages when we really just want to poll.
266
     */
267
 
268
    if (timePtr) {
269
        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
270
    } else {
271
        timeout = 0;
272
    }
273
    UpdateTimer(timeout);
274
 
275
    if (!timePtr || (timeout != 0)
276
            || PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
277
        if (!GetMessage(&msg, NULL, 0, 0)) {
278
 
279
            /*
280
             * The application is exiting, so repost the quit message
281
             * and start unwinding.
282
             */
283
 
284
            PostQuitMessage(msg.wParam);
285
            return -1;
286
        }
287
 
288
        /*
289
         * Handle timer expiration as a special case so we don't
290
         * claim to be doing work when we aren't.
291
         */
292
 
293
        if (msg.message == WM_TIMER && msg.hwnd == notifier.hwnd) {
294
            return 0;
295
        }
296
 
297
        TranslateMessage(&msg);
298
        DispatchMessage(&msg);
299
        return 1;
300
    }
301
    return 0;
302
}
303
 
304
/*
305
 *----------------------------------------------------------------------
306
 *
307
 * Tcl_Sleep --
308
 *
309
 *      Delay execution for the specified number of milliseconds.
310
 *
311
 * Results:
312
 *      None.
313
 *
314
 * Side effects:
315
 *      Time passes.
316
 *
317
 *----------------------------------------------------------------------
318
 */
319
 
320
void
321
Tcl_Sleep(ms)
322
    int ms;                     /* Number of milliseconds to sleep. */
323
{
324
    Sleep(ms);
325
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.