~ubuntu-branches/ubuntu/gutsy/amsn/gutsy

« back to all changes in this revision

Viewing changes to utils/windows/winflash/flash.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Theodore Karkoulis
  • Date: 2006-01-04 15:26:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060104152602-ipe1yg00rl3nlklv
Tags: 0.95-1
New Upstream Release (closes: #345052, #278575).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
                File : flash.cpp
 
3
 
 
4
                Description :   Contains all functions for the Tk extension of flash windows
 
5
                                                This is an extension for Tk only for windows, it will make the window 
 
6
                                                flash in the taskbar until it gets focus.
 
7
 
 
8
                MAN :
 
9
 
 
10
                        NAME :
 
11
                                winflash - Flashes the window taskbar and caption of a toplevel widget
 
12
 
 
13
                        SYNOPSYS :
 
14
                                winflash window_name ?option value option value...?
 
15
 
 
16
                        DESCRIPTION :
 
17
                                This command will make the taskbar of a toplevel window and it's caption flash under windows,
 
18
                                the window_name argument must be the tk pathname of a toplevel widget (.window for example)
 
19
                                The options (abbrevations allowed) are as follow :
 
20
 
 
21
                                -state <boolean>
 
22
                                        The -state option sets is used to make the window flash or to make it stop flashing, a boolean 
 
23
                                        must follow the -state option, 0 to make it stop flashing, 1 to make it flash.
 
24
 
 
25
                                -count <int>
 
26
                                        The -count option specifies the number of time the window must flash before stoping and keeping the 
 
27
                                        orange color. Use -1 to make it flash continuously (you then MUST use a winflash -state 0 to make it 
 
28
                                        stop, it won't stop even if it gets the focus.
 
29
 
 
30
                                -interval <int>
 
31
                                        The -interval option specifies the interval in ms between each flash, use 0 to take the default 
 
32
                                        cursor timeout.
 
33
 
 
34
                                -tray <boolean>
 
35
                                        The -tray option can be used to specify that you only want the taskbar to flash.
 
36
                                        If not specified, the taskbar AND the title of the window will flash.
 
37
                                        if you want only the tray to flash, use -caption 0
 
38
 
 
39
                                -caption <boolean>
 
40
                                        The -caption option can be used to specify that you only want the title of the window to flash
 
41
                                        If you want only the title to flash, use -tray 0
 
42
 
 
43
                                -appfocus <boolean>
 
44
                                        This option is used to specify that the flashing should stop when any window of the application gets focus.
 
45
                                        If not specified, the flashing will stop only when focus is on the flashing window.
 
46
 
 
47
 
 
48
 
 
49
                Author : Youness El Alaoui (KaKaRoTo - kakaroto@users.sourceforge.net)
 
50
*/
 
51
 
 
52
 
 
53
// Include the header file
 
54
#include "flash.h"
 
55
 
 
56
 
 
57
/*
 
58
        Function : Tk_FlashWindow
 
59
 
 
60
        Description :   This is the function that does the whole job, it will flash the window as 
 
61
                                        given in it's argument
 
62
 
 
63
        Arguments   :   ClienData clientdata  : who knows what's that used for :P 
 
64
                                                                                        anways, it's set to NULL and it's not used
 
65
 
 
66
                                        Tcl_Interp *interp    : This is the interpreter that called this function
 
67
                                                                                        it will be used to get some info about the window used
 
68
 
 
69
                                        int objc                          :     This is the number of arguments given to the function
 
70
 
 
71
                                        Tcl_Obj *CONST objv[] : This is the array that contains all arguments given to
 
72
                                                                                        the function
 
73
 
 
74
        Return value : TCL_OK in case everything is ok, or TCL_ERROR in case there is an error
 
75
 
 
76
        Comments     : hummmm... not much, it's simple :)
 
77
 
 
78
*/
 
79
static int Tk_FlashWindow (ClientData clientData,
 
80
                                                                 Tcl_Interp *interp,
 
81
                                                                 int objc,
 
82
                                                                 Tcl_Obj *CONST objv[]) {
 
83
        
 
84
 
 
85
        // We declare our variables, we need one for every intermediate token we get,
 
86
        // so we can verify if one of the function calls returned NULL
 
87
 
 
88
        HWND hwnd;
 
89
        Tk_Window tkwin;
 
90
        Window window;
 
91
        char * win = NULL,
 
92
                * option = NULL,
 
93
                opt[10],
 
94
                opt1, opt2;
 
95
        int state = 1,
 
96
                count = 5,
 
97
                interval = 0,
 
98
                tray = 1,
 
99
                caption = 1,
 
100
                appfocus = 0,
 
101
                optlength,
 
102
                ret = TCL_OK;
 
103
    
 
104
 
 
105
        // We verify the arguments, we must have one arg, not more
 
106
        if( objc < 2) {
 
107
                Tcl_AppendResult (interp, "Wrong number of args.\nShould be \"winflash window_name \?option value option value...\?\"" , (char *) NULL);
 
108
                return TCL_ERROR;
 
109
        }
 
110
        
 
111
        
 
112
        // Get the first argument string (object name) and check it 
 
113
        win=Tcl_GetStringFromObj(objv[1], NULL);
 
114
 
 
115
        // We check if the pathname is valid, this means it must beguin with a "." 
 
116
        // the strncmp(win, ".", 1) is used to compare the first char of the pathname
 
117
 
 
118
        if (strncmp(win,".",1)) {
 
119
                Tcl_AppendResult (interp, "Bad window path name : ",
 
120
                        Tcl_GetStringFromObj(objv[1], NULL) , (char *) NULL);
 
121
                return TCL_ERROR;
 
122
        }
 
123
        
 
124
 
 
125
        // We then get each more arguments if they exist, and check their validity, and then change variables depending on options
 
126
        // We stop one arg before the last arg, because we parse 2 at a time, and we stop when the return value of Tcl_GetBooleanFromObj 
 
127
        // or Tcl_GetIntFromObj returns TCL_ERROR
 
128
        for (int i = 2; i < objc -1 && ret != TCL_ERROR; i++) {
 
129
                // We get the option and the first two chars to compare with (to allow abbrevations)
 
130
                option = Tcl_GetStringFromObj(objv[i], &optlength);
 
131
                if ( strncmp(option, "-", 1) ){
 
132
                        Tcl_AppendResult (interp, "Invalid option : ",
 
133
                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
134
                        return TCL_ERROR;
 
135
                }
 
136
                if ( optlength < 2 ) {
 
137
                        opt1 = '\0';
 
138
                        opt2 = '\0';
 
139
                }
 
140
                if ( optlength == 2 ){
 
141
                        opt1 = option[1];
 
142
                        opt2 = '\0';
 
143
                }
 
144
                if (optlength > 2) { 
 
145
                        opt1 = option[1];
 
146
            opt2 = option[2];
 
147
                } 
 
148
 
 
149
                // Switch, depending on first letter of the option (after the -)
 
150
                switch (opt1) {
 
151
                        // The state option
 
152
                        case 's':
 
153
                                // We compare each char of the option with "-state"
 
154
                                strcpy(opt,"-state");
 
155
                                // If option is longer than -state, then it's not valid (also avoids bug in the for statement below
 
156
                                if ( optlength > 6) {
 
157
                                        Tcl_AppendResult (interp, "Invalid option : ",
 
158
                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
159
                                        return TCL_ERROR;
 
160
                                }
 
161
                                // For each char of the option, compare it.
 
162
                                for ( int j = 2; j < optlength ; j++) {
 
163
                                        if ( option[j] != opt[j]) {
 
164
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
165
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
166
                                                return TCL_ERROR;
 
167
                                        }
 
168
                                }
 
169
                        
 
170
                                // Retreive the value
 
171
                                ret = Tcl_GetBooleanFromObj(interp, objv[++i],&state);
 
172
                                break;
 
173
                        case 'c':
 
174
                                // The -count and -caption options
 
175
                                if ( opt2 == 'o' ) {
 
176
                                        // The -count option
 
177
                                        strcpy(opt,"-count");
 
178
 
 
179
                                        // comments are the same as in the -state option
 
180
                                        if ( optlength > 6) {
 
181
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
182
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
183
                                                return TCL_ERROR;
 
184
                                        }
 
185
                                        for ( int j = 2; j < optlength ; j++) {
 
186
                                                if ( option[j] != opt[j]) {
 
187
                                                        Tcl_AppendResult (interp, "Invalid option : ",
 
188
                                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
189
                                                        return TCL_ERROR;
 
190
                                                }
 
191
                                        }
 
192
 
 
193
                                        ret = Tcl_GetIntFromObj(interp, objv[++i],&count);
 
194
                                } else if (opt2 == 'a' ) {
 
195
                                        // The -caption option
 
196
                                        strcpy(opt,"-caption");
 
197
                                        if ( optlength > 8) {
 
198
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
199
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
200
                                                return TCL_ERROR;
 
201
                                        }
 
202
                                        for ( int j = 2; j < optlength ; j++) {
 
203
                                                if ( option[j] != opt[j]) {
 
204
                                                        Tcl_AppendResult (interp, "Invalid option : ",
 
205
                                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
206
                                                        return TCL_ERROR;
 
207
                                                }
 
208
                                        }
 
209
 
 
210
                                        ret = Tcl_GetBooleanFromObj(interp, objv[++i],&caption);
 
211
                                } else {
 
212
                                        // If the second letter is not 'o' or 'a' (for count/caption), bring error
 
213
                                        Tcl_AppendResult (interp, "Invalid option : ",
 
214
                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
215
                                        return TCL_ERROR;
 
216
                                }
 
217
                                break;
 
218
                        case 'i':
 
219
                                // The -interval option
 
220
                                strcpy(opt,"-interval");
 
221
                                if ( optlength > 9) {
 
222
                                        Tcl_AppendResult (interp, "Invalid option : ",
 
223
                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
224
                                        return TCL_ERROR;
 
225
                                }
 
226
                                for ( int j = 2; j < optlength ; j++) {
 
227
                                        if ( option[j] != opt[j]) {
 
228
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
229
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
230
                                                return TCL_ERROR;
 
231
                                        }
 
232
                                }
 
233
 
 
234
                                ret = Tcl_GetIntFromObj(interp, objv[++i],&interval);
 
235
                                break;
 
236
                        case 't':
 
237
                                // The -trat option
 
238
                                strcpy(opt,"-tray");
 
239
                                if ( optlength > 5) {
 
240
                                        Tcl_AppendResult (interp, "Invalid option : ",
 
241
                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
242
                                        return TCL_ERROR;
 
243
                                }
 
244
                                for ( int j = 2; j < optlength ; j++) {
 
245
                                        if ( option[j] != opt[j]) {
 
246
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
247
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
248
                                                return TCL_ERROR;
 
249
                                        }
 
250
                                }
 
251
 
 
252
                                ret = Tcl_GetBooleanFromObj(interp, objv[++i],&tray);
 
253
                                break;
 
254
                        case 'a':
 
255
                                // The -appfocus option
 
256
                                strcpy(opt,"-appfocus");
 
257
                                if ( optlength > 9) {
 
258
                                        Tcl_AppendResult (interp, "Invalid option : ",
 
259
                                                Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
260
                                        return TCL_ERROR;
 
261
                                }
 
262
                                for ( int j = 2; j < optlength ; j++) {
 
263
                                        if ( option[j] != opt[j]) {
 
264
                                                Tcl_AppendResult (interp, "Invalid option : ",
 
265
                                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
266
                                                return TCL_ERROR;
 
267
                                        }
 
268
                                }
 
269
 
 
270
                                ret = Tcl_GetBooleanFromObj(interp, objv[++i],&appfocus);
 
271
                                break;
 
272
                        default:
 
273
                                // If no valid option, bring error
 
274
                                Tcl_AppendResult (interp, "Invalid option : ",
 
275
                                        Tcl_GetStringFromObj(objv[i], NULL), "\nMust be -state, -count, -interval, -tray, -caption or -appfocus", (char *) NULL);
 
276
                                return TCL_ERROR;
 
277
                }
 
278
 
 
279
        }
 
280
 
 
281
        // If one of the Tcl_Get*FromObj returned error, then bring error
 
282
        if ( ret == TCL_ERROR ) return TCL_ERROR;
 
283
 
 
284
        // If we stopped before the end, then there is an option without value, bring error.
 
285
        if ( i != objc) {
 
286
                Tcl_AppendResult (interp, "Option \"",
 
287
                        Tcl_GetStringFromObj(objv[i], NULL), "\" don't have any value", (char *) NULL);
 
288
                return TCL_ERROR;
 
289
        }
 
290
 
 
291
        // Here we ge the long pathname (tk window name), from the short pathname, using the MainWindow from the interpreter
 
292
        tkwin = Tk_NameToWindow(interp, win, Tk_MainWindow(interp));
 
293
 
 
294
        // Error check
 
295
        if ( tkwin == NULL) return TCL_ERROR;
 
296
 
 
297
        // We then get the windowId (the X token) of the window, from it's long pathname
 
298
        window = Tk_WindowId(tkwin);
 
299
 
 
300
        // Error check
 
301
        if ( window == NULL ) {
 
302
                Tcl_AppendResult (interp, "error while processing WindowId : Window probably not viewable", (char *) NULL);
 
303
                return TCL_ERROR;
 
304
        }
 
305
 
 
306
        // We then get the HWND (Window Handler) from the X token.
 
307
        hwnd = Tk_GetHWND(window);
 
308
 
 
309
        // Error check
 
310
        if ( hwnd == NULL ) {
 
311
                Tcl_AppendResult (interp, "error while processing GetHWND ", (char *) NULL);
 
312
                return TCL_ERROR;
 
313
        }
 
314
 
 
315
        // We get it's parent window handler. This is a bit tricky, in fact, in Tk, toplevel windows are 
 
316
        // just widgets embeded in a container, and we need to get that container's HWND to make it flash
 
317
        hwnd = GetParent(hwnd);
 
318
 
 
319
        if ( hwnd == NULL || ! IsWindow(hwnd)) {
 
320
                Tcl_AppendResult(interp, "Unknown error, pathname is not a valid toplevel window" , (char *) NULL);
 
321
                return TCL_ERROR;
 
322
        }
 
323
 
 
324
 
 
325
        // We set our structure and fill it properly
 
326
        FLASHWINFO fInfo;
 
327
        fInfo.hwnd = hwnd;
 
328
        fInfo.cbSize = sizeof(fInfo);
 
329
        fInfo.uCount = count;  // number of times to flash
 
330
        fInfo.dwTimeout = interval; //Time out between flashes, 0 means default
 
331
        
 
332
        // The FLASHW_STOP flag is equal to 0, so if state is set to false, the flag is FLASHW_STOP, else, it has one of the 
 
333
        // flafs from below
 
334
        fInfo.dwFlags = FLASHW_STOP;
 
335
 
 
336
 
 
337
        // depending on options, fill the flag variable
 
338
        if ( state) {
 
339
                if ( tray) {
 
340
                        fInfo.dwFlags |= FLASHW_TRAY;
 
341
                }
 
342
                if ( caption ) {
 
343
                        fInfo.dwFlags |= FLASHW_CAPTION;
 
344
                }
 
345
                if ( appfocus) {
 
346
                        fInfo.dwFlags |= FLASHW_TIMERNOFG;
 
347
                }
 
348
        } 
 
349
 
 
350
        // Finally call the Windows API, and it's done :D
 
351
        FlashWindowEx ( &fInfo);
 
352
 
 
353
        return TCL_OK;
 
354
}
 
355
 
 
356
 
 
357
 
 
358
/*
 
359
        Function : Flash_Init
 
360
 
 
361
        Description :   The Init function that will be called when the extension is loaded to your tk shell
 
362
 
 
363
        Arguments   :   Tcl_Interp *interp    : This is the interpreter from which the load was made and to 
 
364
                                                                                        which we'll add the new command
 
365
 
 
366
 
 
367
        Return value : TCL_OK in case everything is ok, or TCL_ERROR in case there is an error (Tk version < 8.3)
 
368
 
 
369
        Comments     : hummmm... not much, it's simple :)
 
370
 
 
371
*/
 
372
int Flash_Init (Tcl_Interp *interp ) {
 
373
        
 
374
        //Check TK version is 8.0 or higher
 
375
        if (Tk_InitStubs(interp, "8.3", 0) == NULL) {
 
376
                return TCL_ERROR;
 
377
        }
 
378
        
 
379
        
 
380
        // Create the new command "winflash" linked to the Tk_FlashWindow function with a NULL clientdata and no deleteproc
 
381
        Tcl_CreateObjCommand(interp, "winflash", Tk_FlashWindow,
 
382
                (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
 
383
        
 
384
        // end
 
385
        return TCL_OK;
 
386
}