~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/windows/identity/ui/notifier.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-10-30 10:28:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20061030102853-x7v876vw4af46v0m
Tags: 1.4.4-3ubuntu1
* Merge with Debian; only Ubuntu change:
  - src/include/k5-thread.h: Define__USE_GNU when #include'ing pthread.h to
    fix FTBFS (from 1.4.3-9ubuntu1).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2004 Massachusetts Institute of Technology
 
2
 * Copyright (c) 2005 Massachusetts Institute of Technology
3
3
 *
4
4
 * Permission is hereby granted, free of charge, to any person
5
5
 * obtaining a copy of this software and associated documentation
37
37
/* notifier message for notification icon */
38
38
#define KHUI_WM_NOTIFIER            WM_COMMAND
39
39
 
 
40
#define KHUI_ALERT_QUEUE_MAX        64
 
41
 
40
42
/* window class registration atom for message only notifier window
41
43
   class */
42
44
ATOM atom_notifier = 0;
49
51
 
50
52
BOOL notifier_ready = FALSE;
51
53
 
 
54
khm_boolean notifier_modal_loop = FALSE;
 
55
 
52
56
khui_alert * current_alert = NULL;
53
57
 
 
58
khui_alert * alert_queue[KHUI_ALERT_QUEUE_MAX];
 
59
khm_int32    alert_queue_head = 0;
 
60
khm_int32    alert_queue_tail = 0;
 
61
 
 
62
int  iid_normal = IDI_NOTIFY_NONE;
 
63
 
 
64
#define is_alert_queue_empty() (alert_queue_head == alert_queue_tail)
 
65
#define is_alert_queue_full()  (((alert_queue_tail + 1) % KHUI_ALERT_QUEUE_MAX) == alert_queue_head)
 
66
 
 
67
static void 
 
68
add_to_alert_queue(khui_alert * a) {
 
69
    if (is_alert_queue_full()) return;
 
70
    alert_queue[alert_queue_tail++] = a;
 
71
    khui_alert_hold(a);
 
72
    alert_queue_tail %= KHUI_ALERT_QUEUE_MAX;
 
73
}
 
74
 
 
75
static khui_alert * 
 
76
del_from_alert_queue(void) {
 
77
    khui_alert * a;
 
78
 
 
79
    if (is_alert_queue_empty()) return NULL;
 
80
    a = alert_queue[alert_queue_head++];
 
81
    alert_queue_head %= KHUI_ALERT_QUEUE_MAX;
 
82
 
 
83
    return a;                   /* held */
 
84
}
 
85
 
 
86
static khui_alert * 
 
87
peek_alert_queue(void) {
 
88
    if (is_alert_queue_empty()) return NULL;
 
89
    return alert_queue[alert_queue_head];
 
90
}
 
91
 
 
92
static void
 
93
check_for_queued_alerts(void) {
 
94
    if (!is_alert_queue_empty()) {
 
95
        khui_alert * a;
 
96
 
 
97
        a = peek_alert_queue();
 
98
 
 
99
        if (a->title) {
 
100
            HICON hi;
 
101
            int res;
 
102
 
 
103
            if (a->severity == KHERR_ERROR)
 
104
                res = OIC_ERROR;
 
105
            else if (a->severity == KHERR_WARNING)
 
106
                res = OIC_WARNING;
 
107
            else
 
108
                res = OIC_INFORMATION;
 
109
 
 
110
            hi = LoadImage(0, MAKEINTRESOURCE(res),
 
111
                           IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
 
112
                           LR_SHARED);
 
113
 
 
114
            khm_statusbar_set_part(KHUI_SBPART_NOTICE,
 
115
                                   hi,
 
116
                                   a->title);
 
117
        }
 
118
    } else {
 
119
        khm_statusbar_set_part(KHUI_SBPART_NOTICE,
 
120
                               NULL, NULL);
 
121
    }
 
122
}
 
123
 
54
124
 
55
125
/* forward dcls */
56
126
static khm_int32 
62
132
static khm_int32
63
133
alert_show_normal(khui_alert * a);
64
134
 
 
135
static khm_int32
 
136
alert_enqueue(khui_alert * a);
 
137
 
 
138
/* These are defined for APPVER >= 0x501.  We are defining them here
 
139
   so that we can build with APPVER = 0x500 and use the same binaries
 
140
   with Win XP. */
 
141
 
 
142
#ifndef NIN_BALLOONSHOW
 
143
#define NIN_BALLOONSHOW (WM_USER + 2)
 
144
#endif
 
145
 
 
146
#ifndef NIN_BALLOONHIDE
 
147
#define NIN_BALLOONHIDE (WM_USER + 3)
 
148
#endif
 
149
 
 
150
#ifndef NIN_BALLOONTIMEOUT
 
151
#define NIN_BALLOONTIMEOUT (WM_USER + 4)
 
152
#endif
 
153
 
 
154
#ifndef NIN_BALLOONUSERCLICK
 
155
#define NIN_BALLOONUSERCLICK (WM_USER + 5)
 
156
#endif
 
157
 
 
158
 
65
159
/**********************************************************************
66
160
  Notifier
67
161
***********************************************************************
87
181
        if(m->type == KMSG_ALERT) {
88
182
            /* handle notifier messages */
89
183
            switch(m->subtype) {
90
 
                case KMSG_ALERT_SHOW:
91
 
                    rv = alert_show((khui_alert *) m->vparam);
92
 
                    khui_alert_release((khui_alert *) m->vparam);
93
 
                    break;
 
184
            case KMSG_ALERT_SHOW:
 
185
                rv = alert_show((khui_alert *) m->vparam);
 
186
                khui_alert_release((khui_alert *) m->vparam);
 
187
                break;
 
188
 
 
189
            case KMSG_ALERT_QUEUE:
 
190
                rv = alert_enqueue((khui_alert *) m->vparam);
 
191
                khui_alert_release((khui_alert *) m->vparam);
 
192
                break;
 
193
 
 
194
            case KMSG_ALERT_CHECK_QUEUE:
 
195
                check_for_queued_alerts();
 
196
                break;
 
197
 
 
198
            case KMSG_ALERT_SHOW_QUEUED:
 
199
                if (current_alert == NULL) {
 
200
                    khui_alert * a;
 
201
 
 
202
                    a = del_from_alert_queue();
 
203
                    if (a) {
 
204
                        rv = alert_show(a);
 
205
                        check_for_queued_alerts();
 
206
                        khui_alert_release(a);
 
207
                    }
 
208
                }
 
209
                break;
 
210
 
 
211
            case KMSG_ALERT_SHOW_MODAL:
 
212
                {
 
213
                    khui_alert * a;
 
214
 
 
215
                    a = (khui_alert *) m->vparam;
 
216
                    a->flags |= KHUI_ALERT_FLAG_MODAL;
 
217
                    rv = alert_show(a);
 
218
                    khui_alert_release(a);
 
219
 
 
220
                    if (KHM_SUCCEEDED(rv)) {
 
221
                        notifier_modal_loop = TRUE;
 
222
 
 
223
                        khm_message_loop_int(&notifier_modal_loop);
 
224
                    }
 
225
                }
 
226
                break;
94
227
            }
95
228
        } else if (m->type == KMSG_CRED &&
96
229
                   m->subtype == KMSG_CRED_ROOTDELTA) {
 
230
 
97
231
            KillTimer(hwnd, KHUI_REFRESH_TIMER_ID);
98
232
            SetTimer(hwnd, KHUI_REFRESH_TIMER_ID,
99
233
                     KHUI_REFRESH_TIMEOUT,
100
234
                     NULL);
 
235
 
101
236
        }
102
237
 
103
238
        return kmq_wm_end(m, rv);
134
269
 
135
270
        case WM_LBUTTONUP:
136
271
            /* fall through */
137
 
 
138
272
        case NIN_SELECT:
 
273
            /* fall through */
139
274
        case NIN_KEYSELECT:
140
275
            khm_show_main_window();
141
276
            break;
145
280
                if ((current_alert->flags & KHUI_ALERT_FLAG_DEFACTION) &&
146
281
                    current_alert->n_alert_commands > 0) {
147
282
                    PostMessage(khm_hwnd_main, WM_COMMAND,
148
 
                                MAKEWPARAM(current_alert->alert_commands[0], 0),
 
283
                                MAKEWPARAM(current_alert->alert_commands[0], 
 
284
                                           0),
149
285
                                0);
150
 
                } else if (current_alert->flags & KHUI_ALERT_FLAG_REQUEST_WINDOW) {
 
286
                } else if (current_alert->flags & 
 
287
                           KHUI_ALERT_FLAG_REQUEST_WINDOW) {
151
288
                    khm_show_main_window();
152
289
                    alert_show_normal(current_alert);
153
290
                }
154
291
            }
155
292
            /* fallthrough */
 
293
        case NIN_BALLOONHIDE:
156
294
        case NIN_BALLOONTIMEOUT:
157
 
            khui_notify_icon_change(KHERR_NONE);
 
295
            khm_notify_icon_change(KHERR_NONE);
158
296
            if (current_alert) {
159
297
                khui_alert_release(current_alert);
160
298
                current_alert = NULL;
175
313
}
176
314
 
177
315
ATOM 
178
 
khui_register_notifier_wnd_class(void)
 
316
khm_register_notifier_wnd_class(void)
179
317
{
180
318
    WNDCLASSEX wcx;
181
319
 
315
453
 
316
454
    a->flags |= KHUI_ALERT_FLAG_DISPLAY_BALLOON;
317
455
 
 
456
#if (_WIN32_IE >= 0x0501)
318
457
    current_alert = a;
319
458
    khui_alert_hold(a);
 
459
#endif
320
460
 
321
 
    khui_notify_icon_balloon(a->severity,
 
461
    khm_notify_icon_balloon(a->severity,
322
462
                             tbuf,
323
463
                             mbuf,
324
464
                             NTF_TIMEOUT);
340
480
        title = a->title;
341
481
 
342
482
    /* if we don't have any commands, we just add a "close" button */
343
 
    if(a->n_alert_commands == 0) {
 
483
    if (a->n_alert_commands == 0) {
344
484
        khui_alert_add_command(a, KHUI_PACTION_CLOSE);
345
485
    }
346
486
 
 
487
    /* if there are other alerts queued up, we should add a 'Next
 
488
       alert...' button that when clicked, would show the next queued
 
489
       alert.  However, we only do this if the current alert doesn't
 
490
       actually require a command response.  Otherwise, clicking the
 
491
       'next' button will be the equivalent of cancelling out of the
 
492
       alert without selecting any of the commands. */
 
493
    if (!is_alert_queue_empty() &&
 
494
        a->n_alert_commands == 1 &&
 
495
        a->alert_commands[0] == KHUI_PACTION_CLOSE) {
 
496
 
 
497
        khui_alert_add_command(a, KHUI_PACTION_NEXT);
 
498
    }
 
499
 
347
500
    /* we don't need to keep track of the window handle
348
501
       because the window procedure adds it to the dialog
349
502
       list automatically */
352
505
        CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP,
353
506
                       MAKEINTATOM(atom_alerter),
354
507
                       title,
355
 
                       WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN |
356
 
                       WS_VISIBLE,
 
508
                       WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN,
357
509
                       0, 0, 300, 300, // bogus values
358
510
                       khm_hwnd_main,
359
511
                       (HMENU) NULL,
360
512
                       khm_hInstance,
361
513
                       (LPVOID) a);
362
514
 
 
515
    ShowWindow(hwa, SW_SHOW);
 
516
 
363
517
    return KHM_ERROR_SUCCESS;
364
518
}
365
519
 
366
520
static khm_int32 
367
521
alert_show(khui_alert * a) {
 
522
    /* is there an alert already?  If so, we just enqueue the message
 
523
       and let it sit. */
 
524
    if (current_alert) {
 
525
        return alert_enqueue(a);
 
526
    }
 
527
 
368
528
    /* the window has already been shown */
369
529
    if((a->flags & KHUI_ALERT_FLAG_DISPLAY_WINDOW) ||
370
530
        ((a->flags & KHUI_ALERT_FLAG_DISPLAY_BALLOON) &&
380
540
 
381
541
    /* depending on the state of the main window, we
382
542
       need to either show a window or a balloon */
383
 
    if(khm_is_main_window_active() &&
384
 
       !(a->flags & KHUI_ALERT_FLAG_REQUEST_BALLOON))
 
543
    if ((a->flags & KHUI_ALERT_FLAG_MODAL) ||
 
544
        (khm_is_main_window_active() &&
 
545
         !(a->flags & KHUI_ALERT_FLAG_REQUEST_BALLOON)))
385
546
        return alert_show_normal(a);
386
547
    else
387
548
        return alert_show_minimized(a);
388
549
}
389
550
 
 
551
static khm_int32
 
552
alert_enqueue(khui_alert * a) {
 
553
    if (is_alert_queue_full())
 
554
        return KHM_ERROR_NO_RESOURCES;
 
555
 
 
556
    add_to_alert_queue(a);
 
557
    check_for_queued_alerts();
 
558
 
 
559
    return KHM_ERROR_SUCCESS;
 
560
}
 
561
 
390
562
/* the alerter window is actually a dialog */
391
563
static LRESULT CALLBACK 
392
564
alerter_wnd_proc(HWND hwnd,
410
582
            a = (khui_alert *) lpcs->lpCreateParams;
411
583
            khui_alert_hold(a);
412
584
 
413
 
            d = malloc(sizeof(*d));
 
585
            d = PMALLOC(sizeof(*d));
414
586
            ZeroMemory(d, sizeof(*d));
415
587
 
416
588
            d->alert = a;
554
726
                        CreateWindowEx(0,
555
727
                                       L"BUTTON",
556
728
                                       caption,
557
 
                                       WS_VISIBLE | WS_CHILD,
 
729
                                       WS_VISIBLE | WS_CHILD |
 
730
                                       /* the first button is the default */
 
731
                                       ((i==0)? BS_DEFPUSHBUTTON: 0),
558
732
                                       x,y,width,height,
559
733
                                       hwnd,
560
734
                                       (HMENU)(INT_PTR) (action->cmd),
570
744
                }
571
745
            }
572
746
 
573
 
            khui_notify_icon_change(a->severity);
 
747
            khm_notify_icon_change(a->severity);
574
748
 
575
749
            khui_alert_unlock(a);
576
750
 
597
771
 
598
772
            khui_alert_lock(d->alert);
599
773
            d->alert->flags &= ~KHUI_ALERT_FLAG_DISPLAY_WINDOW;
 
774
            if (d->alert->flags & KHUI_ALERT_FLAG_MODAL)
 
775
                notifier_modal_loop = FALSE;
600
776
            khui_alert_unlock(d->alert);
601
777
 
602
778
            khui_alert_release(d->alert);
603
779
 
604
780
            DeleteObject(d->hfont);
605
781
 
606
 
            free(d);
 
782
            PFREE(d);
607
783
 
608
 
            khui_notify_icon_change(KHERR_NONE);
 
784
            khm_notify_icon_change(KHERR_NONE);
609
785
 
610
786
            return TRUE;
611
787
        }
659
835
                hicon = LoadImage(NULL, 
660
836
                                  MAKEINTRESOURCE(iid), 
661
837
                                  IMAGE_ICON,
662
 
                                  SM_CXICON, SM_CYICON,
 
838
                                  GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
663
839
                                  LR_SHARED);
664
840
 
665
841
                DrawIcon(hdc, x, y, hicon);
718
894
                CopyRect(&ro, &r);
719
895
 
720
896
                // adjust for icon and padding
721
 
                r.left += SM_CXICON + d->dx_suggest_pad * 2;
 
897
                r.left += GetSystemMetrics(SM_CXSMICON) + d->dx_suggest_pad * 2;
722
898
                r.top += d->dx_suggest_pad;
723
899
                r.right -= d->dx_suggest_pad;
724
900
                r.bottom -= d->dx_suggest_pad;
748
924
                        LoadImage(0,
749
925
                                  MAKEINTRESOURCE(OIC_INFORMATION),
750
926
                                  IMAGE_ICON,
751
 
                                  SM_CXICON, SM_CYICON,
 
927
                                  GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
752
928
                                  LR_SHARED);
753
929
 
754
930
                    assert(h_sug_ico != NULL);
757
933
                               ro.left + d->dx_suggest_pad, 
758
934
                               ro.top + d->dx_suggest_pad, 
759
935
                               h_sug_ico,
760
 
                               SM_CXICON, SM_CYICON,
 
936
                               GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
761
937
                               0, NULL,
762
938
                               DI_NORMAL);
763
939
 
813
989
                             SWP_NOMOVE | SWP_NOOWNERZORDER |
814
990
                             SWP_NOZORDER);
815
991
 
 
992
                InvalidateRect(hwnd, NULL, TRUE);
 
993
 
816
994
                x = d->x_message;
817
995
                y = d->dy_client - d->dy_bb;
818
996
                width = d->dx_button;
847
1025
                khm_leave_modal();
848
1026
 
849
1027
                DestroyWindow(hwnd);
 
1028
 
 
1029
                if (LOWORD(wParam) == KHUI_PACTION_NEXT)
 
1030
                    kmq_post_message(KMSG_ALERT, KMSG_ALERT_SHOW_QUEUED, 0, 0);
850
1031
                return 0;
851
1032
            }
852
1033
        }
857
1038
    //return DefWindowProc(hwnd, uMsg, wParam, lParam);
858
1039
}
859
1040
 
860
 
ATOM khui_register_alerter_wnd_class(void)
 
1041
ATOM khm_register_alerter_wnd_class(void)
861
1042
{
862
1043
    WNDCLASSEX wcx;
863
1044
 
864
1045
    ZeroMemory(&wcx, sizeof(wcx));
865
1046
 
866
1047
    wcx.cbSize = sizeof(wcx);
867
 
    wcx.style = CS_DROPSHADOW | CS_OWNDC;
 
1048
    wcx.style =
 
1049
        CS_OWNDC |
 
1050
#if(_WIN32_WINNT >= 0x0501)
 
1051
        ((IS_COMMCTL6())? CS_DROPSHADOW: 0) |
 
1052
#endif
 
1053
        0;
868
1054
    wcx.lpfnWndProc = alerter_wnd_proc;
869
1055
    wcx.cbClsExtra = 0;
870
1056
    wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR);
887
1073
 
888
1074
#define KHUI_NOTIFY_ICON_ID 0
889
1075
 
890
 
void khui_notify_icon_add(void) {
 
1076
void khm_notify_icon_add(void) {
891
1077
    NOTIFYICONDATA ni;
892
1078
    wchar_t buf[256];
893
1079
 
897
1083
    ni.hWnd = hwnd_notifier;
898
1084
    ni.uID = KHUI_NOTIFY_ICON_ID;
899
1085
    ni.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
900
 
    ni.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_NOTIFY_NONE));
 
1086
    ni.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(iid_normal));
901
1087
    ni.uCallbackMessage = KHUI_WM_NOTIFIER;
902
1088
    LoadString(khm_hInstance, IDS_NOTIFY_PREFIX, buf, ARRAYLENGTH(buf));
903
1089
    StringCbCopy(ni.szTip, sizeof(ni.szTip), buf);
914
1100
}
915
1101
 
916
1102
void 
917
 
khui_notify_icon_balloon(khm_int32 severity,
 
1103
khm_notify_icon_balloon(khm_int32 severity,
918
1104
                         wchar_t * title,
919
1105
                         wchar_t * msg,
920
1106
                         khm_int32 timeout) {
938
1124
        iid = IDI_NOTIFY_ERROR;
939
1125
    } else {
940
1126
        ni.dwInfoFlags = NIIF_NONE;
941
 
        iid = IDI_NOTIFY_NONE;
 
1127
        iid = iid_normal;
942
1128
    }
943
1129
 
944
1130
    ni.hWnd = hwnd_notifier;
970
1156
    DestroyIcon(ni.hIcon);
971
1157
}
972
1158
 
973
 
void khui_notify_icon_change(khm_int32 severity) {
 
1159
void khm_notify_icon_expstate(enum khm_notif_expstate expseverity) {
 
1160
    int new_iid;
 
1161
 
 
1162
    if (expseverity == KHM_NOTIF_OK)
 
1163
        new_iid = IDI_APPICON_OK;
 
1164
    else if (expseverity == KHM_NOTIF_WARN)
 
1165
        new_iid = IDI_APPICON_WARN;
 
1166
    else if (expseverity == KHM_NOTIF_EXP)
 
1167
        new_iid = IDI_APPICON_EXP;
 
1168
    else
 
1169
        new_iid = IDI_NOTIFY_NONE;
 
1170
 
 
1171
    if (iid_normal == new_iid)
 
1172
        return;
 
1173
 
 
1174
    iid_normal = new_iid;
 
1175
 
 
1176
    if (current_alert == NULL)
 
1177
        khm_notify_icon_change(KHERR_NONE);
 
1178
}
 
1179
 
 
1180
void khm_notify_icon_change(khm_int32 severity) {
974
1181
    NOTIFYICONDATA ni;
975
1182
    wchar_t buf[256];
976
1183
    int iid;
982
1189
    else if (severity == KHERR_ERROR)
983
1190
        iid = IDI_NOTIFY_ERROR;
984
1191
    else
985
 
        iid = IDI_NOTIFY_NONE;
 
1192
        iid = iid_normal;
986
1193
 
987
1194
    ZeroMemory(&ni, sizeof(ni));
988
1195
 
1004
1211
    DestroyIcon(ni.hIcon);
1005
1212
}
1006
1213
 
1007
 
void khui_notify_icon_remove(void) {
 
1214
void khm_notify_icon_remove(void) {
1008
1215
    NOTIFYICONDATA ni;
1009
1216
 
1010
1217
    ZeroMemory(&ni, sizeof(ni));
1020
1227
  Initialization
1021
1228
**********************************************************************/
1022
1229
 
1023
 
void khui_init_notifier(void)
 
1230
void khm_init_notifier(void)
1024
1231
{
1025
 
    if(!khui_register_notifier_wnd_class())
 
1232
    if(!khm_register_notifier_wnd_class())
1026
1233
        return;
1027
1234
 
1028
 
    if(!khui_register_alerter_wnd_class())
 
1235
    if(!khm_register_alerter_wnd_class())
1029
1236
        return;
1030
1237
 
1031
1238
    hwnd_notifier = CreateWindowEx(0,
1043
1250
        kmq_subscribe_hwnd(KMSG_CRED, hwnd_notifier);
1044
1251
        notifier_ready = TRUE;
1045
1252
 
1046
 
        khui_notify_icon_add();
 
1253
        khm_notify_icon_add();
1047
1254
    }
1048
1255
#ifdef DEBUG
1049
1256
    else {
1051
1258
    }
1052
1259
#endif
1053
1260
    khm_timer_init();
 
1261
 
 
1262
    khm_addr_change_notifier_init();
1054
1263
}
1055
1264
 
1056
 
void khui_exit_notifier(void)
 
1265
void khm_exit_notifier(void)
1057
1266
{
 
1267
    khm_addr_change_notifier_exit();
 
1268
 
1058
1269
    khm_timer_exit();
1059
1270
 
1060
1271
    if(hwnd_notifier != NULL) {
1061
 
        khui_notify_icon_remove();
 
1272
        khm_notify_icon_remove();
1062
1273
        kmq_unsubscribe_hwnd(KMSG_ALERT, hwnd_notifier);
1063
1274
        kmq_unsubscribe_hwnd(KMSG_CRED, hwnd_notifier);
1064
1275
        DestroyWindow(hwnd_notifier);