--- rxvt-unicode/src/init.C 2010/08/29 15:05:08 1.279 +++ rxvt-unicode/src/init.C 2011/12/06 10:27:15 1.304 @@ -12,7 +12,7 @@ * Copyright (c) 1997,1998 Oezguer Kesim * Copyright (c) 1998-2001 Geoff Wing * - extensive modifications - * Copyright (c) 2003-2008 Marc Lehmann + * Copyright (c) 2003-2008 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,6 +57,11 @@ # include #endif +#ifdef HAVE_STARTUP_NOTIFICATION +# define SN_API_NOT_YET_FROZEN +# include +#endif + #ifdef DISPLAY_IS_IP /* On Solaris link with -lsocket and -lnsl */ #include @@ -145,7 +150,7 @@ } #endif -const char *const def_colorName[] = +static const char *const def_colorName[] = { COLOR_FOREGROUND, COLOR_BACKGROUND, @@ -565,7 +570,7 @@ rxvt_term::init_resources (int argc, const char *const *argv) { int i, r_argc; - const char **cmd_argv, **r_argv; + const char **cmd_argv; /* * Look for -e option. Find => split and make cmd_argv[] of command args @@ -588,13 +593,6 @@ cmd_argv[i] = NULL; } - r_argv = (const char **)rxvt_malloc (sizeof (char *) * (r_argc + 1)); - - for (i = 0; i < r_argc; i++) - r_argv[i] = (const char *)argv[i]; - - r_argv[i] = NULL; - rs[Rs_name] = rxvt_basename (argv[0]); /* @@ -604,13 +602,10 @@ if ((rs[Rs_display_name] = getenv ("DISPLAY")) == NULL) rs[Rs_display_name] = ":0"; - get_options (r_argc, r_argv); + get_options (r_argc, argv); if (!(display = displays.get (rs[Rs_display_name]))) - { - free (r_argv); - rxvt_fatal ("can't open display %s, aborting.\n", rs[Rs_display_name]); - } + rxvt_fatal ("can't open display %s, aborting.\n", rs[Rs_display_name]); // using a local pointer decreases code size a lot xa = display->xa; @@ -623,17 +618,10 @@ select_visual (strtol (rs[Rs_depth], 0, 0)); #endif - free (r_argv); - for (int i = NUM_RESOURCES; i--; ) if (rs [i] == resval_undef) rs [i] = 0; -#ifdef HAVE_AFTERIMAGE - set_application_name ((char *)rs[Rs_name]); - set_output_threshold (OUTPUT_LEVEL_WARNING); -#endif - #if ENABLE_PERL if (!rs[Rs_perl_ext_1]) rs[Rs_perl_ext_1] = "default"; @@ -647,6 +635,10 @@ } #endif + // must be called after initialising the perl interpreter as it + // may invoke the `on_register_command' hook + extract_keysym_resources (); + /* * set any defaults not already set */ @@ -791,10 +783,20 @@ } if (option (Opt_scrollBar)) - scrollBar.state = STATE_IDLE; /* set existence for size calculations */ + scrollBar.state = SB_STATE_IDLE; /* set existence for size calculations */ pty = ptytty::create (); +#ifdef HAVE_AFTERIMAGE + set_application_name ((char *)rs[Rs_name]); + set_output_threshold (OUTPUT_LEVEL_WARNING); +#endif + + // must be called before create_windows, because the latter may call set_icon +#ifdef HAVE_PIXBUF + g_type_init (); +#endif + create_windows (argc, argv); init_xlocale (); @@ -809,25 +811,23 @@ scrollBar.resize (); /* create and map scrollbar */ #ifdef HAVE_BG_PIXMAP { - bgPixmap.set_target (this); - bgPixmap.invalidate (); + bg_init (); #ifdef ENABLE_TRANSPARENCY if (option (Opt_transparent)) { - bgPixmap.set_transparent (); + bg_set_transparent (); -#ifdef HAVE_AFTERIMAGE if (rs [Rs_blurradius]) - bgPixmap.set_blur_radius (rs [Rs_blurradius]); -#endif + bg_set_blur (rs [Rs_blurradius]); + if (ISSET_PIXCOLOR (Color_tint)) - bgPixmap.set_tint (pix_colors_focused [Color_tint]); + bg_set_tint (pix_colors_focused [Color_tint]); if (rs [Rs_shade]) - bgPixmap.set_shade (rs [Rs_shade]); + bg_set_shade (rs [Rs_shade]); - bgPixmap.set_root_pixmap (); + bg_set_root_pixmap (); XSelectInput (dpy, display->root, PropertyChangeMask); rootwin_ev.start (display, display->root); } @@ -836,18 +836,8 @@ #ifdef BG_IMAGE_FROM_FILE if (rs[Rs_backgroundPixmap]) { - const char *p = rs[Rs_backgroundPixmap]; - - if ((p = strchr (p, ';')) != 0) - { - p++; - bgPixmap.set_geometry (p); - } - else - bgPixmap.set_defaultGeometry (); - - if (bgPixmap.set_file (rs[Rs_backgroundPixmap])) - if (!bgPixmap.window_position_sensitive ()) + if (bg_set_file (rs[Rs_backgroundPixmap])) + if (!bg_window_position_sensitive ()) update_background (); } #endif @@ -874,13 +864,37 @@ { long info[2] = { 0, XEMBED_MAPPED }; - XChangeProperty (dpy, parent[0], xa[XA_XEMBED_INFO], xa[XA_XEMBED_INFO], + XChangeProperty (dpy, parent, xa[XA_XEMBED_INFO], xa[XA_XEMBED_INFO], 32, PropModeReplace, (unsigned char *)&info, 2); } #endif +#if HAVE_STARTUP_NOTIFICATION + SnDisplay *snDisplay; + SnLauncheeContext *snContext; + + snDisplay = sn_display_new (dpy, NULL, NULL); + snContext = sn_launchee_context_new_from_environment (snDisplay, DefaultScreen (dpy)); + + /* Tell the window manager that this window is part of the startup context */ + if (snContext) + sn_launchee_context_setup_window (snContext, parent); +#endif + XMapWindow (dpy, vt); - XMapWindow (dpy, parent[0]); + XMapWindow (dpy, parent); + +#if HAVE_STARTUP_NOTIFICATION + if (snContext) + { + /* Mark the startup process as complete */ + sn_launchee_context_complete (snContext); + + sn_launchee_context_unref (snContext); + } + + sn_display_unref (snDisplay); +#endif refresh_check (); } @@ -889,7 +903,6 @@ void rxvt_term::init_env () { - int i; char *val; #ifdef DISPLAY_IS_IP @@ -913,12 +926,11 @@ if (rs[Rs_display_name] == NULL) rs[Rs_display_name] = val; /* use broken `:0' value */ - i = strlen (val); - env_display = (char *)rxvt_malloc (i + 9); + env_display = (char *)rxvt_malloc (strlen (val) + 9); sprintf (env_display, "DISPLAY=%s", val); - sprintf (env_windowid, "WINDOWID=%lu", (unsigned long)parent[0]); + sprintf (env_windowid, "WINDOWID=%lu", (unsigned long)parent); /* add entries to the environment: * @ DISPLAY: in case we started with -display @@ -1294,10 +1306,10 @@ return; } - int w = im->width; - int h = im->height; + unsigned int w = im->width; + unsigned int h = im->height; - if (!IN_RANGE_INC (w, 1, 32767) || !IN_RANGE_INC (h, 1, 32767)) + if (!IN_RANGE_INC (w, 1, 16383) || !IN_RANGE_INC (h, 1, 16383)) { rxvt_warn ("Icon image too big, continuing without.\n"); destroy_asimage (&im); @@ -1325,7 +1337,7 @@ for (unsigned int i = 0; i < w * h; ++i) buffer [i + 2] = asbuf [i]; - XChangeProperty (dpy, parent[0], xa[XA_NET_WM_ICON], XA_CARDINAL, 32, + XChangeProperty (dpy, parent, xa[XA_NET_WM_ICON], XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) buffer, 2 + w * h); free (buffer); } @@ -1334,10 +1346,67 @@ destroy_asimage (&result); #endif + +#ifdef HAVE_PIXBUF + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (file, NULL); + if (!pixbuf) + { + rxvt_warn ("Loading image icon failed, continuing without.\n"); + return; + } + + unsigned int w = gdk_pixbuf_get_width (pixbuf); + unsigned int h = gdk_pixbuf_get_height (pixbuf); + + if (!IN_RANGE_INC (w, 1, 16383) || !IN_RANGE_INC (h, 1, 16383)) + { + rxvt_warn ("Icon image too big, continuing without.\n"); + g_object_unref (pixbuf); + return; + } + + if (long *buffer = (long *)malloc ((2 + w * h) * sizeof (long))) + { + int rowstride = gdk_pixbuf_get_rowstride (pixbuf); + unsigned char *row = gdk_pixbuf_get_pixels (pixbuf); + int channels = gdk_pixbuf_get_n_channels (pixbuf); + + buffer [0] = w; + buffer [1] = h; + for (int i = 0; i < h; i++) + { + for (int j = 0; j < w; j++) + { + unsigned char *pixel = row + j * channels; + long value; + + if (channels == 4) + value = pixel[3]; + else + value = (unsigned char)0x00ff; + + value = (value << 8) + pixel[0]; + value = (value << 8) + pixel[1]; + value = (value << 8) + pixel[2]; + buffer[(i * w + j) + 2] = value; + } + + row += rowstride; + } + + XChangeProperty (dpy, parent, xa[XA_NET_WM_ICON], XA_CARDINAL, 32, + PropModeReplace, (const unsigned char *) buffer, 2 + w * h); + free (buffer); + } + else + rxvt_warn ("Memory allocation for icon hint failed, continuing without.\n"); + + g_object_unref (pixbuf); +#endif } /*----------------------------------------------------------------------*/ -/* rxvt_Create_Windows () - Open and map the window */ +/* Open and map the window */ void rxvt_term::create_windows (int argc, const char *const *argv) { @@ -1393,7 +1462,7 @@ window_calc (0, 0); - /* sub-window placement & size in rxvt_resize_subwindows () */ + /* sub-window placement & size in rxvt_term::resize_all_windows () */ attributes.background_pixel = pix_colors_focused [Color_border]; attributes.border_pixel = pix_colors_focused [Color_border]; attributes.colormap = cmap; @@ -1406,7 +1475,7 @@ CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &attributes); - this->parent[0] = top; + this->parent = top; old_width = szHint.width; old_height = szHint.height; @@ -1449,7 +1518,7 @@ #endif }; - XSetWMProtocols (dpy, top, protocols, sizeof (protocols) / sizeof (protocols[0])); + XSetWMProtocols (dpy, top, protocols, ecb_array_length (protocols)); #if ENABLE_FRILLS if (rs[Rs_transient_for])