00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00051 #include <config.h>
00052 #include "bell.h"
00053 #include "screen-private.h"
00054 #include "prefs.h"
00055
00074 static void
00075 bell_flash_screen (MetaDisplay *display,
00076 MetaScreen *screen)
00077 {
00078 Window root = screen->xroot;
00079 int width = screen->rect.width;
00080 int height = screen->rect.height;
00081
00082 if (screen->flash_window == None)
00083 {
00084 Visual *visual = (Visual *)CopyFromParent;
00085 XSetWindowAttributes xswa;
00086 int depth = CopyFromParent;
00087 xswa.save_under = True;
00088 xswa.override_redirect = True;
00089
00090
00091
00092
00093
00094
00095 screen->flash_window = XCreateWindow (display->xdisplay, root,
00096 0, 0, width, height,
00097 0, depth,
00098 InputOutput,
00099 visual,
00100
00101 CWSaveUnder | CWOverrideRedirect,
00102 &xswa);
00103 XSelectInput (display->xdisplay, screen->flash_window, ExposureMask);
00104 XMapWindow (display->xdisplay, screen->flash_window);
00105 XSync (display->xdisplay, False);
00106 XFlush (display->xdisplay);
00107 XUnmapWindow (display->xdisplay, screen->flash_window);
00108 }
00109 else
00110 {
00111
00112 GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL);
00113 XMapWindow (display->xdisplay, screen->flash_window);
00114 XSetForeground (display->xdisplay, gc,
00115 WhitePixel (display->xdisplay,
00116 XScreenNumberOfScreen (screen->xscreen)));
00117 XFillRectangle (display->xdisplay, screen->flash_window, gc,
00118 0, 0, width, height);
00119 XSetForeground (display->xdisplay, gc,
00120 BlackPixel (display->xdisplay,
00121 XScreenNumberOfScreen (screen->xscreen)));
00122 XFillRectangle (display->xdisplay, screen->flash_window, gc,
00123 0, 0, width, height);
00124 XFlush (display->xdisplay);
00125 XSync (display->xdisplay, False);
00126 XUnmapWindow (display->xdisplay, screen->flash_window);
00127 XFreeGC (display->xdisplay, gc);
00128 }
00129
00130 if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK &&
00131 !display->mouse_mode)
00132 meta_display_increment_focus_sentinel (display);
00133 XFlush (display->xdisplay);
00134 }
00135
00146 #ifdef HAVE_XKB
00147 static void
00148 bell_flash_fullscreen (MetaDisplay *display,
00149 XkbAnyEvent *xkb_ev)
00150 {
00151 XkbBellNotifyEvent *xkb_bell_ev = (XkbBellNotifyEvent *) xkb_ev;
00152 MetaScreen *screen;
00153
00154 g_assert (xkb_ev->xkb_type == XkbBellNotify);
00155 if (xkb_bell_ev->window != None)
00156 {
00157 screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window);
00158 if (screen)
00159 bell_flash_screen (display, screen);
00160 }
00161 else
00162 {
00163 GSList *screen_list = display->screens;
00164 while (screen_list)
00165 {
00166 screen = (MetaScreen *) screen_list->data;
00167 bell_flash_screen (display, screen);
00168 screen_list = screen_list->next;
00169 }
00170 }
00171 }
00172
00187 static gboolean
00188 bell_unflash_frame (gpointer data)
00189 {
00190 MetaFrame *frame = (MetaFrame *) data;
00191 frame->is_flashing = 0;
00192 meta_frame_queue_draw (frame);
00193 return FALSE;
00194 }
00195
00207 static void
00208 bell_flash_window_frame (MetaWindow *window)
00209 {
00210 g_assert (window->frame != NULL);
00211 window->frame->is_flashing = 1;
00212 meta_frame_queue_draw (window->frame);
00213 g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 100,
00214 bell_unflash_frame, window->frame, NULL);
00215 }
00216
00224 static void
00225 bell_flash_frame (MetaDisplay *display,
00226 XkbAnyEvent *xkb_ev)
00227 {
00228 XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
00229 MetaWindow *window;
00230
00231 g_assert (xkb_ev->xkb_type == XkbBellNotify);
00232 window = meta_display_lookup_x_window (display, xkb_bell_event->window);
00233 if (!window && (display->focus_window) && (display->focus_window->frame))
00234 {
00235 window = display->focus_window;
00236 }
00237 if (window)
00238 {
00239 bell_flash_window_frame (window);
00240 }
00241 else
00242 {
00243 bell_flash_fullscreen (display, xkb_ev);
00244 }
00245 }
00246
00258 static void
00259 bell_visual_notify (MetaDisplay *display,
00260 XkbAnyEvent *xkb_ev)
00261 {
00262 switch (meta_prefs_get_visual_bell_type ())
00263 {
00264 case META_VISUAL_BELL_FULLSCREEN_FLASH:
00265 bell_flash_fullscreen (display, xkb_ev);
00266 break;
00267 case META_VISUAL_BELL_FRAME_FLASH:
00268 bell_flash_frame (display, xkb_ev);
00269 break;
00270 case META_VISUAL_BELL_INVALID:
00271
00272 break;
00273 }
00274 }
00275
00276 void
00277 meta_bell_notify (MetaDisplay *display,
00278 XkbAnyEvent *xkb_ev)
00279 {
00280
00281 if (meta_prefs_get_visual_bell ())
00282 bell_visual_notify (display, xkb_ev);
00283 }
00284 #endif
00285
00286 void
00287 meta_bell_set_audible (MetaDisplay *display, gboolean audible)
00288 {
00289 #ifdef HAVE_XKB
00290 XkbChangeEnabledControls (display->xdisplay,
00291 XkbUseCoreKbd,
00292 XkbAudibleBellMask,
00293 audible ? XkbAudibleBellMask : 0);
00294 #endif
00295 }
00296
00297 gboolean
00298 meta_bell_init (MetaDisplay *display)
00299 {
00300 #ifdef HAVE_XKB
00301 int xkb_base_error_type, xkb_opcode;
00302
00303 if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
00304 &display->xkb_base_event_type,
00305 &xkb_base_error_type,
00306 NULL, NULL))
00307 {
00308 display->xkb_base_event_type = -1;
00309 g_message ("could not find XKB extension.");
00310 return FALSE;
00311 }
00312 else
00313 {
00314 unsigned int mask = XkbBellNotifyMask;
00315 gboolean visual_bell_auto_reset = FALSE;
00316
00317 XkbSelectEvents (display->xdisplay,
00318 XkbUseCoreKbd,
00319 XkbBellNotifyMask,
00320 XkbBellNotifyMask);
00321 XkbChangeEnabledControls (display->xdisplay,
00322 XkbUseCoreKbd,
00323 XkbAudibleBellMask,
00324 meta_prefs_bell_is_audible ()
00325 ? XkbAudibleBellMask : 0);
00326 if (visual_bell_auto_reset) {
00327 XkbSetAutoResetControls (display->xdisplay,
00328 XkbAudibleBellMask,
00329 &mask,
00330 &mask);
00331 }
00332 return TRUE;
00333 }
00334 #endif
00335 return FALSE;
00336 }
00337
00338 void
00339 meta_bell_shutdown (MetaDisplay *display)
00340 {
00341 #ifdef HAVE_XKB
00342
00343 XkbChangeEnabledControls (display->xdisplay,
00344 XkbUseCoreKbd,
00345 XkbAudibleBellMask,
00346 XkbAudibleBellMask);
00347 #endif
00348 }
00349
00358 void
00359 meta_bell_notify_frame_destroy (MetaFrame *frame)
00360 {
00361 if (frame->is_flashing)
00362 g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
00363 }