./0000755000004100000410000000000013570225707011253 5ustar www-datawww-data./NEWS0000644000004100000410000000216513570225707011756 0ustar www-datawww-dataNoteworthy changes since last release (0.9.30): * Mono-example don't compile (under Oneiric Ocelot) * ported to gtk+ 3.x * ported to libnotify 0.7.x * updated C- and Python-examples ---- This is the inital version of the new notification daemon "notify osd" developed by Canonical's dx- and design-teams. It follows the freedesktop notification specification and introduces some new policies for streamlining the user- experience by discouraging the use of actions and timeouts. C-, Python- and C#-examples demonstrating correct usage of notifications have been added. Have a look at the examples-directory. This accompanies the devel- oper guidelines availabled under: https://wiki.ubuntu.com/NotificationDevelopmentGuidelines Noteworthy changes since last release (0.9.22): * updating NEWS file now, fixes LP: #432486 * no long using hard-coded -Werror, fixes LP: #361788 * solved regression regarding throbbing-animation for value-indicator, fixes LP: #435116 * looking up gravity-gconf-key upon startup, fixes LP: #431200 * convert newline characters to spaces, fixes LP: #402247 ./README0000644000004100000410000000100413570225707012126 0ustar www-datawww-dataThe Desktop Notifications framework provides a standard way of doing passive pop-up notifications on the Linux desktop. These are designed to notify the user of something without interrupting their work with a dialog box that they must close. Passive popups can automatically disappear after a short period of time. The project homepage is located here: https://edge.launchpad.net/notify-osd This version of Notify OSD implements the specification defined here: https://wiki.ubuntu.com/NotifyOSD?rev=143 ./icons/0000755000004100000410000000000013570225707012366 5ustar www-datawww-data./icons/avatar.svg0000644000004100000410000000422313570225707014366 0ustar www-datawww-data image/svg+xml ./icons/wifi-100.svg0000644000004100000410000000703413570225707014347 0ustar www-datawww-data ./icons/wifi-75.svg0000644000004100000410000000714613570225707014306 0ustar www-datawww-data ./icons/chat.svg0000644000004100000410000000277313570225707014037 0ustar www-datawww-data ./icons/avatar.png0000644000004100000410000003626413570225707014365 0ustar www-datawww-dataPNG  IHDR>asRGBbKGD pHYs$$P$tIME 01 IDATx}Ys$uw2k߫5fIS(/'Y Wu<>%c78t`8<{3 R/lzq$ +'Xdd2Q{5=σrr(XZZMH&Hyh4d2roab8b<OExnd+++z"na"L`A~LmJl{} fvL$k(e|0$Br35q1:;T*9J%A\.L&qP(p,h4prYbD' 5ړ&Nv?P p @jqqѸUcg@Jz.8Fvj̧d2JjL&D"\.7%ݣFx\HRr' 1*y_A"@VC^s駟 O~[10 ]cD&X* F#b1y1nE @~w5H$P,rT*%.z٬J1h6<$f!3yl 7Zod\ױF!ē;5gc6(,UL&eQ|Y64ɞGRA"@2Dzb;8XX NGl yNNv{ N0 nP^x<3.9g 7YP@.t)aRp]W~An=jV_rBNnW oggDT .\h4yz8<4 `0@&A>p8dYrv-^6~n;xR)d2Z-)" nyf9iO;gLf\ L&}z= CلT*%&#cx7O-u5'}opZyh Ҟon) T* /` 'y{{zHJD,I&n1?'^wE AtT'x;jc4h~!S>FřLF<_z`< RFLK 0@:[s&0D"Ϧv>6QJi:WTg2 2ln<Lfrit2X,\.'$Aj(edZ-r9  ) 0+#8K AX9tu<K?L#|0 v-P%S@UȃڋΒ6_f́)@;Iϣ(n;k^Z-i&fXUd2A*B>GՒ0Z0[=(sY>m^'B$,$ah`4IHw" tӳkyтgqsFbZeݞJTF0 Q.y@Ǿ|1̔y?:@xxx<~/euH$du~|< 8CJg T*Pq~ t^#`} ^kh4AaXXX@|> lYȬaT2D.y7WqTnipwQM$J'4>^,RR^z b}zvwwQ,DZCAdYdYaii |^ID&P:pxxFx[nl ynn 5v]h˵wW͜r3y6S_["pfqUF^z X^^FA\HڵkGZEX<:Q0pbyY$2aR-LT*ի_V ᥗ^B,~3lmm{HHa7_}nx5!kO* X^^VVVPT!*jX\\ҥKIt<\ETBXD*77"sp &P(`www:^{5 TU?\~BFqBDT%Dy'&}y:vNuBa8zJ&u666pcV~~ F?=Bmh7.Y(ޙ~3m3\]]wy_W1uEaE TU+`*BXD. %dql!|##Ub}}X]]͛7m,..&>s3çM'&6ծ3xwyyT NG6}ee.\0 Q<& 6660 UWt 9]hZ>@mjP,ӟV rDT*XYYo lnn (4}9ǑlV (^uJ%QϤask.]&"ժtE:FT^;6JCWD}xݮf!kH$իrRn޼[nagg\V;Q/\+++xʼn[]]ƍ8<իWܫP(ѣG(A"W,h&Ѭ%!vp}!չ~uJp%d28 looÇz= )HiۈzCĥK} ޹hHGG+[O7 clFuϣŋG 7 Nc/_^#͢~P~}tZ*iBM`k##_"B\6ũB 2G^Sj< (%"0,qyb1ܸq.ug X\FZl8A"nߺ|!]eimx'$M)XIBNa/$.s}dY C=!* \d2f|>^t:\.'9:677jJ"ahzm^ 0 ŋF6ORI8LTe0;8F4ʊl?>=zNd"\6 N:}]>Mj.2͛X____?0777PT"M>Nc0drxWu϶P KP( H&$Ft:HRlq/X__Zk׮!NVRbggG0p0/RPb`{"6<Cu7MܻwHP2 Jy!,♚jEdS{_#ŨT*x嗑5p8DA,;͢V!ckk DV 8<;0`Ck׮X,JU@\.p]W:vA=V!aeejUu@^!0\Z@R#pa' 2 P%zܫT*I˨VVK6{FC==S800zjxJ& :2 >Cuz=L&$IZ$\h^ҲV%xB2DX&L hr2XY4zT`4X(w~wynݺ~xVA(-h! .Dm?/E@;E~ww ˡ!O?qt rT~xx>aJO"zl)J&X@dm5Os!cyo&*~W~o4R0"zY!=x0L• KȣGey `yyz]N#9ED"!.=wn4O@X8%|}F\N>`0H|_#, =_*h4yaA\xAQٿ' !tvx@9 Z Z  q-,,)/ S0TX ^C܋Ɠ|խnt$!m_VprG$ xyQs/׸`0ޝ4o%P(S(t: 7JlMJmìTИNL%qO$V-x,|xRRH~~ >Q['yB0ڥv4V0Q(:{.!=z$%8 0u 0qN6T9Feӧv, T*SEhEԧI OaߨQ$b_2DݻwaQ% 8rĜ+Ev Q 5uZa k DH`0Ǣ Gп@{]dz./^͝qyZ@' KuӜzۮB!MT H9G@ouSMQ/kgML,13Qs=a!ѣGE,C& >ә׌rғpCE:~OKy& gn+ӷ`cy1Bs$fzvN  ]O>n~;;;݅(JX\\bTXΟ聘z:F}!g.e#RòGΣ`8NuDב | c00 ` 5891l6n?>O8єe;-\?`kJ {* ^:T*uB1j۶4-H'g6 $9C&.q<:Q#'_G 80,BO%:>>Cz=át#GU@*5zB*K؂;7F#LGBFM i;#ElmmM5p{}Qk|L&_r34!JZ&dnD6J/å!"pJ]m0#KЖt7W^+I%xfst(D qBan<w20>~$QF:kXajI%I#LF`<Ox{j&I&((͛7o %dp4bg=X4e@2(Nυad2y>zhT/|2pppz.|:~IؼSqn\3Ǡcqܼyo">S<|ZM\.'tPO ?j eEajU?q>XDApnnjesl5 ҳ XlLTJjh&~!Q9v卮.Y?7| |2qvTS(7*_M)\xE >+7DPヒ>,2aï? vdd6S=g2i2)cޟv 5Zo"/?$I,S8JşfOKMBqm{b)yi.$h$œ7V< ~:^~ecR}Zg_.KXj=N\n$l|q+++(Rڦɝb#q>ꞅDUI~KR\i{wss3r5?dVVVg Ō?p8q:F.G7e naMlooc4!NiF"0F5,ej [У~>Du5m꼣;Υid2d2X[[Ly)%cm=I؄ CN6kt:hH*~moo#K:v"u]*ޟH!ScO:)ۓv,CRAP.aXu i + `0Vtdmx_ M"aJah"ԏ8@*P7*ޏJ G 'ɓvi'i^`/C:pRMtmoߖz1*eXH,& wFTZu{]䣊Rfx0p }t0ga< =sF@ӑ177'*ݻsZ677tc$l:b 5m>}Z677vίti4I}ϖC'{7LK7NQ* ښl lBOlm`VjdmRT!XNI CqLTͪ4JH48gTieHxe)rT*0sii oFٔ09R_?Aׂ-hݮ<:z й|M0фNm.1F&dRH/ib6)ػOXO+vyRt+aii :~ӟJ-Br]}f^ygJ|>/ :~յDb-}O?~.ãVE|^ںF<>jnDQۋfrzppbEk4W(Uk687jw{|P˜8IS} Cae<|p1#ȍci?(<=ժ^|7zߗI<ܜhH3}~\N込ړeYU>Dž p) څ)'tf )X,J*Y Q]7qD"B˗/cccCm4{VK$b :gΚgJP˥R)a04 M&9giIgNK'+*G&=@~.v󩨖4v,sZtnϴȱ/k i}]E. 5vg6\gNu>6Ԯ4PD;҈b )+?I3'j) F2" aUM!*?$"AY>6FFBmF`d0'5(Aj.Gg|zir X\\ܜ@=lDU{v'Ww86a<4٫O %k6UȱԌY~-ۡZ7IPWUlooKgYyx".^B ݦ慎ݎ] zCIa$ 5Z@DkF~} 2 NS*MfQ3N sf,ÍJNڵkX]]1맲n%yT*1Ngq4m5(044Q: d]E4tmon9K_x]Ѽ*^}H4 *14juF7f7nP('?вVq\"^gw-djj<$#}Y:h4Nvw j;ӽ5oO B4Oi:wj Fm,b%l%K/!G}$r dX#k8ܘ1/ J''$FGsSCPaBv50 4zMPDDav/4|VqYD" P*0??/-666p]ܽ{W]t kkkrt5}v l6.R*%s(QK]^٪T+Oy(=% miTS RT`3h6dH0o4akkKl&3xd\gsŘqQmS&T1>5t4U 4 6CWPpUݖpv0d̵iycG=c@S3}gsl`VYwTo#dZvZsbr(ooOBxmjTYA>—d|>?E2dB1驨ZV3 D) XSlTkdVϺlFczyR54knչu=B]fNlC?v-`ZS& 4c3+ AꫂeQZV6JHAoM%Ӭ{g%#@M \O8SWɤ%j!M(eHUJ}_0&D1>@L@0 |acJ-6'Qstj[w "I]׿uy]8C`8`c>V juJd/"&zޔ_j]8rEܻwoJD0 }ć1f8 00iAs)ID.%u\thlIwimBL&nOP!,̦qʦruɸ֩QVζv^H$pxx(#uΗΎZ*l6ELM&uoaӿsN(A{0=BW9DFt }l&|/dr}<zIp/Lĥc:FRۨjS]ENcΪ lb<cnnNhoDTwP1I($9T .{ҙf^'Ys*MZkz?0XvןƘƘa8^PatzW<^ƴ,\?rƍc YÎ{ Rj^ 9A\tZ{%Hwm6yP*P,Q(P(ҥKSq<`8@E&{ćx8EO9Ǫ? L&0 \y6|vTe???xA|s7abq$b8N j[x t,~:ƷAѭg`j3EOSR~y?c u]TUG?^ .$Kյ&h$Hȴ'81c7?6;@?aĜX* Co<ʭMzyS xH8CqL$1d{FD!5 .jGF>Gј*Hq q@4gJ͛wvvv5P(`ggr ;x5h<+ 00c:a#3_3!ÿ˿2  hؘGtR.ԑO5LHW)gjVeCtȥBP(t8 bדY,fwuhZR bnnnvjQ*s"oQ' Ya0[̺y0ZIENDB`./icons/wifi-lost.svg0000644000004100000410000000657013570225707015034 0ustar www-datawww-data ./src/0000755000004100000410000000000013570225713012037 5ustar www-datawww-data./src/raico-blur.h0000644000004100000410000000411413570225707014252 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // raico-blur.h - implements public API for blurring cairo image-surfaces // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef _RAICO_BLUR_H #define _RAICO_BLUR_H #include #include typedef enum _raico_blur_quality_t { RAICO_BLUR_QUALITY_LOW = 0, // low quality, but fast, maybe interactive RAICO_BLUR_QUALITY_MEDIUM, // compromise between speed and quality RAICO_BLUR_QUALITY_HIGH // quality before speed } raico_blur_quality_t; typedef struct _raico_blur_private_t raico_blur_private_t; typedef struct _raico_blur_t { raico_blur_private_t* priv; } raico_blur_t; raico_blur_t* raico_blur_create (raico_blur_quality_t quality); raico_blur_quality_t raico_blur_get_quality (raico_blur_t* blur); void raico_blur_set_quality (raico_blur_t* blur, raico_blur_quality_t quality); guint raico_blur_get_radius (raico_blur_t* blur); void raico_blur_set_radius (raico_blur_t* blur, guint radius); void raico_blur_apply (raico_blur_t* blur, cairo_surface_t* surface); void raico_blur_destroy (raico_blur_t* blur); #endif // _RAICO_BLUR_H ./src/util.h0000644000004100000410000000314613570225707013174 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** util.h - all sorts of helper functions ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Cody Russell ** Mirco "MacSlow" Mueller ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #define WM_NAME_COMPIZ "compiz" #define WM_NAME_METACITY "Metacity" #define WM_NAME_XFCE "Xfwm4" #define WM_NAME_KWIN "KWin" #define WM_NAME_XMONAD "xmonad" gchar* filter_text (const gchar* text); gchar* newline_to_space (const gchar* text); cairo_surface_t* copy_surface (cairo_surface_t* orig); gchar* get_wm_name (Display* dpy); GString* extract_font_face (const gchar* string); ./src/apport.h0000644000004100000410000000267113570225707013526 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** apport.h - apport hooks for triggering bug-reports on non-spec notifications ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ /* this module should send a report via apport when an application is trying to use elements of the spec we don't support anymore */ void apport_report (const gchar* app_name, const gchar* summary, gchar** actions, gint timeout); ./src/log.c0000644000004100000410000000706513570225707012777 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** log.h - log utils ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** Contributor(s): ** Sense "qense" Hofstede (fix LP: #465801, rev. 415) ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include "config.h" #include #include #include #include #include "bubble.h" static FILE *logfile = NULL; static void log_logger_null(const char *domain, GLogLevelFlags log_level, const char *message, gpointer user_data) { return; } void log_init (void) { if (! g_getenv ("LOG")) return; const char *homedir = g_getenv ("HOME"); if (!homedir) homedir = g_get_home_dir (); g_return_if_fail (homedir != NULL); // Make sure the cache directory is there, if at all possible const gchar *dirname = g_get_user_cache_dir (); g_mkdir_with_parents (dirname, 0700); char *filename = g_build_filename (dirname, "notify-osd.log", NULL); logfile = fopen (filename, "w"); if (logfile == NULL) g_warning ("could not open/append to %s; logging disabled", filename); g_free (filename); /* discard all debug messages unless DEBUG is set */ if (! g_getenv ("DEBUG")) g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_logger_null, NULL); g_message ("DEBUG mode enabled"); } char* log_create_timestamp (void) { struct timeval tv; struct tm *tm; /* FIXME: deal with tz offsets */ gettimeofday (&tv, NULL); tm = localtime (&tv.tv_sec); return g_strdup_printf ("%.4d-%.2d-%.2dT%.2d:%.2d:%.2d%.1s%.2d:%.2d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, "-", 0, 0); } void log_bubble (Bubble *bubble, const char *app_name, const char *option) { g_return_if_fail (IS_BUBBLE (bubble)); if (logfile == NULL) return; char *ts = log_create_timestamp (); if (option) fprintf (logfile, "[%s, %s %s] %s\n", ts, app_name, option, bubble_get_title (bubble)); else fprintf (logfile, "[%s, %s] %s\n", ts, app_name, bubble_get_title (bubble)); fprintf (logfile, "%s\n\n", bubble_get_message_body (bubble)); fflush (logfile); g_free (ts); } void log_bubble_debug (Bubble *bubble, const char *app_name, const char *icon) { g_return_if_fail (bubble != NULL && IS_BUBBLE (bubble)); char *ts = log_create_timestamp (); g_debug ("[%s, %s, id:%d, icon:%s%s] %s\n%s\n", ts, app_name, bubble_get_id (bubble), icon, bubble_is_synchronous (bubble) ? " (synchronous)" : "", bubble_get_title (bubble), bubble_get_message_body (bubble)); g_free (ts); } ./src/exponential-blur.c0000644000004100000410000001422713570225707015504 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // raico-blur // // exponential-blur.c - implements exponential-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // Jason Smith // // Notes: // based on exponential-blur algorithm by Jani Huhtanen // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// // FIXME: not working yet, unfinished #include #include "exponential-blur.h" static inline void _blurinner (guchar* pixel, gint *zR, gint *zG, gint *zB, gint *zA, gint alpha, gint aprec, gint zprec); static inline void _blurrow (guchar* pixels, gint width, gint height, gint channels, gint line, gint alpha, gint aprec, gint zprec); static inline void _blurcol (guchar* pixels, gint width, gint height, gint channels, gint col, gint alpha, gint aprec, gint zprec); void _expblur (guchar* pixels, gint width, gint height, gint channels, gint radius, gint aprec, gint zprec); void surface_exponential_blur (cairo_surface_t* surface, guint radius) { guchar* pixels; guint width; guint height; cairo_format_t format; // sanity checks are done in raico-blur.c // before we mess with the surface execute any pending drawing cairo_surface_flush (surface); pixels = cairo_image_surface_get_data (surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); format = cairo_image_surface_get_format (surface); switch (format) { case CAIRO_FORMAT_ARGB32: _expblur (pixels, width, height, 4, radius, 16, 7); break; case CAIRO_FORMAT_RGB24: _expblur (pixels, width, height, 3, radius, 16, 7); break; case CAIRO_FORMAT_A8: _expblur (pixels, width, height, 1, radius, 16, 7); break; default : // do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty (surface); } // // pixels image-data // width image-width // height image-height // channels image-channels // // in-place blur of image 'img' with kernel of approximate radius 'radius' // // blurs with two sided exponential impulse response // // aprec = precision of alpha parameter in fixed-point format 0.aprec // // zprec = precision of state parameters zR,zG,zB and zA in fp format 8.zprec // void _expblur (guchar* pixels, gint width, gint height, gint channels, gint radius, gint aprec, gint zprec) { gint alpha; gint row = 0; gint col = 0; if (radius < 1) return; // calculate the alpha such that 90% of // the kernel is within the radius. // (Kernel extends to infinity) alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); for (; row < height; row++) _blurrow (pixels, width, height, channels, row, alpha, aprec, zprec); for(; col < width; col++) _blurcol (pixels, width, height, channels, col, alpha, aprec, zprec); return; } static inline void _blurinner (guchar* pixel, gint *zR, gint *zG, gint *zB, gint *zA, gint alpha, gint aprec, gint zprec) { gint R; gint G; gint B; guchar A; R = *pixel; G = *(pixel + 1); B = *(pixel + 2); A = *(pixel + 3); *zR += (alpha * ((R << zprec) - *zR)) >> aprec; *zG += (alpha * ((G << zprec) - *zG)) >> aprec; *zB += (alpha * ((B << zprec) - *zB)) >> aprec; *zA += (alpha * ((A << zprec) - *zA)) >> aprec; *pixel = *zR >> zprec; *(pixel + 1) = *zG >> zprec; *(pixel + 2) = *zB >> zprec; *(pixel + 3) = *zA >> zprec; } static inline void _blurrow (guchar* pixels, gint width, gint height, gint channels, gint line, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* scanline; scanline = &(pixels[line * width * channels]); zR = *scanline << zprec; zG = *(scanline + 1) << zprec; zB = *(scanline + 2) << zprec; zA = *(scanline + 3) << zprec; for (index = 0; index < width; index ++) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = width - 2; index >= 0; index--) _blurinner (&scanline[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } static inline void _blurcol (guchar* pixels, gint width, gint height, gint channels, gint x, gint alpha, gint aprec, gint zprec) { gint zR; gint zG; gint zB; gint zA; gint index; guchar* ptr; ptr = pixels; ptr += x * channels; zR = *((guchar*) ptr ) << zprec; zG = *((guchar*) ptr + 1) << zprec; zB = *((guchar*) ptr + 2) << zprec; zA = *((guchar*) ptr + 3) << zprec; for (index = width; index < (height - 1) * width; index += width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); for (index = (height - 2) * width; index >= 0; index -= width) _blurinner ((guchar*) &ptr[index * channels], &zR, &zG, &zB, &zA, alpha, aprec, zprec); } ./src/bubble-window-accessible-factory.c0000644000004100000410000000472713570225707020520 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window-accessible-factory.c - implements an accessible object factory ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include "bubble-window-accessible-factory.h" #include "bubble-window-accessible.h" G_DEFINE_TYPE (BubbleWindowAccessibleFactory, bubble_window_accessible_factory, ATK_TYPE_OBJECT_FACTORY); static AtkObject* bubble_window_accessible_factory_create_accessible (GObject *obj); static GType bubble_window_accessible_factory_get_accessible_type (void); static void bubble_window_accessible_factory_init (BubbleWindowAccessibleFactory *object) { /* TODO: Add initialization code here */ } static void bubble_window_accessible_factory_class_init (BubbleWindowAccessibleFactoryClass *klass) { AtkObjectFactoryClass *class = ATK_OBJECT_FACTORY_CLASS (klass); class->create_accessible = bubble_window_accessible_factory_create_accessible; class->get_accessible_type = bubble_window_accessible_factory_get_accessible_type; } AtkObjectFactory* bubble_window_accessible_factory_new (void) { GObject *factory; factory = g_object_new (BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY, NULL); return ATK_OBJECT_FACTORY (factory); } static AtkObject* bubble_window_accessible_factory_create_accessible (GObject *obj) { GtkWidget *widget; g_return_val_if_fail (GTK_IS_WIDGET (obj), NULL); widget = GTK_WIDGET (obj); return bubble_window_accessible_new (widget); } static GType bubble_window_accessible_factory_get_accessible_type (void) { return BUBBLE_WINDOW_TYPE_ACCESSIBLE; } ./src/stack-blur.c0000644000004100000410000001551613570225707014265 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // raico-blur // // stack-blur.c - implements stack-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // based on stack-blur algorithm by Mario Klingemann // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// // FIXME: not working yet, unfinished #include #include #include "stack-blur.h" void surface_stack_blur (cairo_surface_t* surface, guint radius) { guchar* pixels; guint width; guint height; cairo_format_t format; // sanity checks are done in raico-blur.c // before we mess with the surface execute any pending drawing cairo_surface_flush (surface); pixels = cairo_image_surface_get_data (surface); width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); format = cairo_image_surface_get_format (surface); switch (format) { case CAIRO_FORMAT_ARGB32:{ gint w = width; gint h = height; gint wm = w - 1; gint hm = h - 1; gint wh = w * h; gint div = radius + radius + 1; if (radius < 1) break; gint* r = (gint*) g_malloc0 (wh); gint* g = (gint*) g_malloc0 (wh); gint* b = (gint*) g_malloc0 (wh); gint* a = (gint*) g_malloc0 (wh); gint rsum; gint gsum; gint bsum; gint asum; gint x; gint y; gint i; gint yp; gint yi; gint yw; gint* dv = NULL; gint* vmin = (gint*) g_malloc0 (MAX (w, h)); gint divsum = (div + 1) >> 1; divsum *= divsum; dv = (gint*) g_malloc0 (256 * divsum); g_assert (dv != NULL); for (i = 0; i < 256 * divsum; ++i) dv[i] = (i / divsum); yw = yi = 0; gint** stack = (gint**) g_malloc0 (div); for (i = 0; i < div; ++i) stack[i] = (gint*) g_malloc0 (4); gint stackpointer; gint stackstart; gint* sir; gint rbs; gint r1 = radius + 1; gint routsum; gint goutsum; gint boutsum; gint aoutsum; gint rinsum; gint ginsum; gint binsum; gint ainsum; for (y = 0; y < h; ++y) { rinsum = ginsum = binsum = ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0; for(i =- radius; i <= radius; ++i) { sir = stack[i + radius]; sir[0] = pixels[yi + MIN (wm, MAX (i, 0)) + 0]; sir[1] = pixels[yi + MIN (wm, MAX (i, 0)) + 1]; sir[2] = pixels[yi + MIN (wm, MAX (i, 0)) + 2]; sir[3] = pixels[yi + MIN (wm, MAX (i, 0)) + 3]; rbs = r1 - abs (i); rsum += sir[0] * rbs; gsum += sir[1] * rbs; bsum += sir[2] * rbs; asum += sir[3] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; } } stackpointer = radius; for (x = 0; x < w; ++x) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; a[yi] = dv[asum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; asum -= aoutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; aoutsum -= sir[3]; if (y == 0) vmin[x] = MIN (x + radius + 1, wm); sir[0] = pixels[yw + vmin[x] + 0]; sir[1] = pixels[yw + vmin[x] + 1]; sir[2] = pixels[yw + vmin[x] + 2]; sir[3] = pixels[yw + vmin[x] + 3]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; rsum += rinsum; gsum += ginsum; bsum += binsum; asum += ainsum; stackpointer = (stackpointer + 1) % div; sir = stack[(stackpointer) % div]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; ainsum -= sir[3]; ++yi; } yw += w; } for (x = 0; x < w; ++x) { rinsum = ginsum = binsum = ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0; yp =- radius * w; for (i =- radius; i <= radius; ++i) { yi = MAX (0, yp) + x; sir = stack[i + radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; sir[3] = a[yi]; rbs = r1 - abs (i); rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs; asum += a[yi] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; } if (i < hm) yp += w; } yi = x; stackpointer = radius; for (y = 0; y < h; ++y) { pixels[yi + 0] = dv[rsum]; pixels[yi + 1] = dv[gsum]; pixels[yi + 2] = dv[bsum]; pixels[yi + 3] = dv[asum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; asum -= aoutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; aoutsum -= sir[3]; if (x == 0) vmin[y] = MIN (y + r1, hm) * w; gint pixel = x + vmin[y]; sir[0] = r[pixel]; sir[1] = g[pixel]; sir[2] = b[pixel]; sir[3] = a[pixel]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; ainsum += sir[3]; rsum += rinsum; gsum += ginsum; bsum += binsum; asum += ainsum; stackpointer = (stackpointer + 1) % div; sir = stack[stackpointer]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; aoutsum += sir[3]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; ainsum -= sir[3]; yi += w; } } g_free ((gpointer) r); g_free ((gpointer) g); g_free ((gpointer) b); g_free ((gpointer) a); g_free ((gpointer) vmin); g_free ((gpointer) dv); for (i = 0; i < div; ++i) g_free ((gpointer) stack[i]); g_free ((gpointer) stack); } break; case CAIRO_FORMAT_RGB24: // do nothing, for the moment break; case CAIRO_FORMAT_A8: // do nothing, for the moment break; default : // really do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty (surface); } ./src/tile.c0000644000004100000410000001526113570225707013150 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // tile.c - implements public API surface/blur cache // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include "util.h" #include "tile.h" #include "raico-blur.h" struct _tile_private_t { cairo_surface_t* normal; cairo_surface_t* blurred; guint blur_radius; gboolean use_padding; guint pad_width; guint pad_height; }; tile_t* tile_new (cairo_surface_t* source, guint blur_radius) { tile_private_t* priv = NULL; tile_t* tile = NULL; raico_blur_t* blur = NULL; if (blur_radius < 1) return NULL; priv = g_new0 (tile_private_t, 1); if (!priv) return NULL; tile = g_new0 (tile_t, 1); if (!tile) return NULL; tile->priv = priv; tile->priv->normal = copy_surface (source); tile->priv->blurred = copy_surface (source); tile->priv->blur_radius = blur_radius; tile->priv->use_padding = FALSE; tile->priv->pad_width = 0; tile->priv->pad_height = 0; blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, blur_radius); raico_blur_apply (blur, tile->priv->blurred); raico_blur_destroy (blur); return tile; } tile_t* tile_new_for_padding (cairo_surface_t* normal, cairo_surface_t* blurred, gint width, gint height) { tile_private_t* priv = NULL; tile_t* tile = NULL; priv = g_new0 (tile_private_t, 1); if (!priv) return NULL; tile = g_new0 (tile_t, 1); if (!tile) return NULL; if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS || cairo_surface_status (blurred) != CAIRO_STATUS_SUCCESS) return NULL; tile->priv = priv; tile->priv->normal = copy_surface (normal); tile->priv->blurred = copy_surface (blurred); tile->priv->blur_radius = 0; tile->priv->use_padding = TRUE; tile->priv->pad_width = width; tile->priv->pad_height = height; return tile; } void tile_destroy (tile_t* tile) { if (!tile) return; //cairo_surface_write_to_png (tile->priv->normal, "./tile-normal.png"); //cairo_surface_write_to_png (tile->priv->blurred, "./tile-blurred.png"); cairo_surface_destroy (tile->priv->normal); cairo_surface_destroy (tile->priv->blurred); g_free ((gpointer) tile->priv); g_free ((gpointer) tile); } // assumes x and y to be actual pixel-measurement values void tile_paint (tile_t* tile, cairo_t* cr, gdouble x, gdouble y, gdouble normal_alpha, gdouble blurred_alpha) { if (!tile) return; if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) return; if (normal_alpha > 0.0f) { cairo_set_source_surface (cr, tile->priv->normal, x, y); cairo_paint_with_alpha (cr, normal_alpha); } if (blurred_alpha > 0.0f) { cairo_set_source_surface (cr, tile->priv->blurred, x, y); cairo_paint_with_alpha (cr, blurred_alpha); } } void _pad_paint (cairo_t* cr, cairo_pattern_t* pattern, guint x, guint y, guint width, guint height, guint pad_width, guint pad_height, gdouble alpha) { cairo_matrix_t matrix; // top left cairo_rectangle (cr, x, y, width - pad_width, height - pad_height); cairo_clip (cr); cairo_paint_with_alpha (cr, alpha); cairo_reset_clip (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -1.0f * width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - pad_width, y, pad_width, height - pad_height); cairo_clip (cr); cairo_paint_with_alpha (cr, alpha); cairo_reset_clip (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -1.0f * width, -1.0f * height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, pad_width, height - pad_height, width - pad_width, pad_height); cairo_clip (cr); cairo_paint_with_alpha (cr, alpha); cairo_reset_clip (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -1.0f * height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, x, height - pad_height, pad_width, pad_height); cairo_clip (cr); cairo_paint_with_alpha (cr, alpha); cairo_reset_clip (cr); } void tile_paint_with_padding (tile_t* tile, cairo_t* cr, gdouble x, gdouble y, gdouble width, gdouble height, gdouble normal_alpha, gdouble blurred_alpha) { cairo_pattern_t* pattern = NULL; guint pad_width = 0; guint pad_height = 0; if (!tile) return; if (!tile->priv->use_padding) return; if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) return; pad_width = tile->priv->pad_width; pad_height = tile->priv->pad_height; if (normal_alpha > 0.0f) { pattern = cairo_pattern_create_for_surface (tile->priv->normal); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { if (pattern) cairo_pattern_destroy (pattern); return; } cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); _pad_paint (cr, pattern, x, y, width, height, pad_width, pad_height, normal_alpha); cairo_pattern_destroy (pattern); } if (blurred_alpha > 0.0f) { pattern = cairo_pattern_create_for_surface (tile->priv->blurred); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { if (pattern) cairo_pattern_destroy (pattern); return; } cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); _pad_paint (cr, pattern, x, y, width, height, pad_width, pad_height, blurred_alpha); cairo_pattern_destroy (pattern); } } ./src/gaussian-blur.c0000644000004100000410000001064413570225707014767 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // raico-blur // // gaussian-blur.c - implements gaussian-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // based on filters in libpixman // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include #include "gaussian-blur.h" pixman_fixed_t* create_gaussian_blur_kernel (gint radius, gdouble sigma, gint* length) { const gdouble scale2 = 2.0f * sigma * sigma; const gdouble scale1 = 1.0f / (G_PI * scale2); const gint size = 2 * radius + 1; const gint n_params = size * size; pixman_fixed_t* params; gdouble* tmp; gdouble sum; gint x; gint y; gint i; tmp = g_newa (double, n_params); // caluclate gaussian kernel in floating point format for (i = 0, sum = 0, x = -radius; x <= radius; ++x) { for (y = -radius; y <= radius; ++y, ++i) { const gdouble u = x * x; const gdouble v = y * y; tmp[i] = scale1 * exp (-(u+v)/scale2); sum += tmp[i]; } } // normalize gaussian kernel and convert to fixed point format params = g_new (pixman_fixed_t, n_params + 2); params[0] = pixman_int_to_fixed (size); params[1] = pixman_int_to_fixed (size); for (i = 0; i < n_params; ++i) params[2 + i] = pixman_double_to_fixed (tmp[i] / sum); if (length) *length = n_params + 2; return params; } void _blur_image_surface (cairo_surface_t* surface, gint radius, gdouble sigma /* pass 0.0f for auto-calculation */) { pixman_fixed_t* params = NULL; gint n_params; pixman_image_t* src; gint w; gint h; gint s; gpointer p; gdouble radiusf; radiusf = fabs (radius) + 1.0f; if (sigma == 0.0f) sigma = sqrt (-(radiusf * radiusf) / (2.0f * log (1.0f / 255.0f))); w = cairo_image_surface_get_width (surface); h = cairo_image_surface_get_height (surface); s = cairo_image_surface_get_stride (surface); // create pixman image for cairo image surface p = cairo_image_surface_get_data (surface); src = pixman_image_create_bits (PIXMAN_a8r8g8b8, w, h, p, s); // attach gaussian kernel to pixman image params = create_gaussian_blur_kernel (radius, sigma, &n_params); pixman_image_set_filter (src, PIXMAN_FILTER_CONVOLUTION, params, n_params); g_free (params); // render blured image to new pixman image pixman_image_composite (PIXMAN_OP_SRC, src, NULL, src, 0, 0, 0, 0, 0, 0, w, h); pixman_image_unref (src); } void surface_gaussian_blur (cairo_surface_t* surface, guint radius) { cairo_format_t format; // sanity checks are done in raico-blur.c // before we mess with the surface execute any pending drawing cairo_surface_flush (surface); format = cairo_image_surface_get_format (surface); switch (format) { case CAIRO_FORMAT_ARGB32: _blur_image_surface (surface, radius, 0.0f); break; case CAIRO_FORMAT_RGB24: // do nothing, for now break; case CAIRO_FORMAT_A8: // do nothing, for now break; default : // do nothing break; } // inform cairo we altered the surfaces contents cairo_surface_mark_dirty (surface); } ./src/dialog.c0000644000004100000410000001716213570225707013454 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // dialog.c - fallback to display when a notification is not spec-compliant // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // David Barth // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include "dialog.h" #include #include "dbus.h" #include "util.h" typedef struct _DialogInfo DialogInfo; struct _DialogInfo { int id; gchar* sender; }; static void dialog_info_destroy (DialogInfo* dialog_info) { if (!dialog_info) return; g_free (dialog_info->sender); g_free (dialog_info); } static void handle_close (GtkWidget* dialog, guint response_id, gpointer user_data) { DialogInfo* dialog_info = g_object_get_data (G_OBJECT (dialog), "_dialog_info"); if (!dialog_info) { gtk_widget_destroy (GTK_WIDGET (dialog)); return; } dbus_send_close_signal (dialog_info->sender, dialog_info->id, 2); dialog_info_destroy (dialog_info); gtk_widget_destroy (GTK_WIDGET (dialog)); } static void handle_response (GtkWidget* button, GdkEventButton* event, GtkDialog* dialog) { gchar *action = g_object_get_data (G_OBJECT (button), "_libnotify_action"); DialogInfo *dialog_info = g_object_get_data (G_OBJECT (dialog), "_dialog_info"); if (!dialog_info || !action) { gtk_widget_destroy (GTK_WIDGET (dialog)); return; } // send a "click" signal... dbus_send_action_signal (dialog_info->sender, dialog_info->id, action); dbus_send_close_signal (dialog_info->sender, dialog_info->id, 3); gtk_widget_destroy (GTK_WIDGET (dialog)); } static void add_pathological_action_buttons (GtkWidget* dialog, gchar** actions) { int i; for (i = 0; actions[i] != NULL; i += 2) { gchar *label = actions[i + 1]; if (label == NULL) { g_warning ("missing label for action \"%s\"" "; discarding the action", actions[i]); break; } if (g_strcmp0 (actions[i], "default") == 0) continue; GtkWidget *button = gtk_dialog_add_button (GTK_DIALOG (dialog), label, i/2); g_object_set_data_full (G_OBJECT (button), "_libnotify_action", g_strdup (actions[i]), g_free); g_signal_connect (G_OBJECT (button), "button-release-event", G_CALLBACK (handle_response), dialog); } } void fallback_dialog_show (Defaults* d, const gchar* sender, const gchar* app_name, int id, const gchar* title_text, const gchar* _body_message, gchar** actions) { GtkWidget* dialog; GtkWidget* hbox; GtkWidget* vbox; GtkWidget* title; GtkWidget* body; GtkWidget* image; gchar* body_message = NULL; gchar* new_body_message = NULL; guint gap = EM2PIXELS (defaults_get_margin_size (d), d); gboolean success = FALSE; GError* error = NULL; if (!IS_DEFAULTS (d) || !sender || !app_name || !title_text || !_body_message || !actions) return; DialogInfo* dialog_info = g_new0 (DialogInfo, 1); if (!dialog_info) return; dialog_info->id = id; dialog_info->sender = g_strdup(sender); dialog = gtk_dialog_new (); hbox = g_object_new (GTK_TYPE_BOX, "orientation", GTK_ORIENTATION_HORIZONTAL, "spacing", gap, "border-width", 12, NULL); // We deliberately use the gtk-dialog-warning icon rather than // the specified one to discourage people from trying to use // the notification system as a way of showing custom alert // dialogs. image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); vbox = g_object_new (GTK_TYPE_BOX, "orientation", GTK_ORIENTATION_VERTICAL, NULL); title = gtk_label_new (NULL); gtk_label_set_text (GTK_LABEL (title), title_text); gtk_label_set_line_wrap (GTK_LABEL (title), TRUE); body = gtk_label_new (NULL); body_message = filter_text (_body_message); if (body_message) { success = pango_parse_markup (body_message, -1, 0, NULL, &new_body_message, NULL, &error); if (error && !success) { g_warning ("fallback_dialog_show(): Got error \"%s\"\n", error->message); g_error_free (error); error = NULL; } } if (new_body_message) { gtk_label_set_text (GTK_LABEL (body), new_body_message); g_free (new_body_message); } else gtk_label_set_text (GTK_LABEL (body), body_message); g_free (body_message); gtk_label_set_line_wrap (GTK_LABEL (body), TRUE); gtk_misc_set_alignment (GTK_MISC (title), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (vbox), title, TRUE, TRUE, 0); gtk_misc_set_alignment (GTK_MISC (body), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (vbox), body, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (hbox), vbox); gtk_container_add (GTK_CONTAINER ( gtk_dialog_get_content_area ( GTK_DIALOG (dialog))), hbox); gtk_container_set_border_width (GTK_CONTAINER (dialog), 2); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); gtk_window_set_default_size (GTK_WINDOW (dialog), EM2PIXELS (defaults_get_bubble_width (d) * 1.2f, d), -1); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); gtk_window_set_title (GTK_WINDOW (dialog), app_name); gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE); // is it a bad notification with actions? if (actions[0] != NULL) add_pathological_action_buttons (dialog, actions); GtkButton *cancel = GTK_BUTTON ( gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL)); g_signal_connect_swapped (G_OBJECT (cancel), "button-release-event", G_CALLBACK (handle_close), dialog); gtk_widget_set_can_default(GTK_WIDGET(cancel), FALSE); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (handle_close), dialog); GtkButton *ok = GTK_BUTTON ( gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK)); g_object_set_data_full (G_OBJECT (ok), "_libnotify_action", g_strdup ("default"), g_free); g_signal_connect (G_OBJECT (ok), "button-release-event", G_CALLBACK (handle_response), dialog); gtk_widget_set_can_default(GTK_WIDGET(ok), FALSE); g_object_set_data (G_OBJECT (dialog), "_dialog_info", dialog_info); g_signal_connect (G_OBJECT (dialog), "button-release-event", G_CALLBACK (handle_response), dialog); gtk_window_set_focus (GTK_WINDOW (dialog), NULL); gtk_window_set_default (GTK_WINDOW (dialog), NULL); gtk_widget_show_all (dialog); } ./src/display.c0000644000004100000410000002471313570225707013662 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** display.c - manages the display of notifications waiting in the stack/queue ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ /* This is actually part of stack.c, but moved here because it manages the display of notifications. This is also in preparation for some refactoring, where we'll create: * - a distinct (non-graphical) notification.c module * - a distinct display.c module that takes care of placing bubbles * on the screen */ static Bubble* stack_find_bubble_on_display (Stack *self) { GList* list = NULL; Bubble* bubble = NULL; g_assert (IS_STACK (self)); /* find the bubble on display */ for (list = g_list_first (self->list); list != NULL; list = g_list_next (list)) { bubble = (Bubble*) list->data; if (bubble_is_visible (bubble)) return bubble; } return NULL; } static gboolean stack_is_at_top_corner (Stack *self, Bubble *bubble) { GdkScreen* screen; gint x, y1, y2; g_assert (IS_STACK (self)); g_assert (IS_BUBBLE (bubble)); defaults_get_top_corner (self->defaults, &screen, &x, &y1); bubble_get_position (bubble, &x, &y2); return y1 == y2; } static void stack_display_position_sync_bubble (Stack *self, Bubble *bubble) { Defaults* d = self->defaults; GdkScreen* screen; gint y = 0; gint x = 0; defaults_get_top_corner (d, &screen, &x, &y); // TODO: with multi-head, in focus follow mode, there may be enough // space left on the top monitor switch (defaults_get_slot_allocation (d)) { case SLOT_ALLOCATION_FIXED: if (stack_is_slot_vacant (self, SLOT_TOP)) { stack_get_slot_position (self, SLOT_TOP, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No slot-coords!\n", G_STRFUNC); else stack_allocate_slot (self, bubble, SLOT_TOP); } else { g_warning ("%s(): Top slot taken!\n", G_STRFUNC); } break; case SLOT_ALLOCATION_DYNAMIC: // see if we're call at the wrong moment, when both // slots are occupied by bubbles if (!stack_is_slot_vacant (self, SLOT_TOP) && !stack_is_slot_vacant (self, SLOT_BOTTOM)) { g_warning ("%s(): Both slots taken!\n", G_STRFUNC); } else { // first check if we can place the sync. bubble // in the top slot and the bottom slot is still // vacant, this is to avoid the "gap" between // bottom slot and panel if (stack_is_slot_vacant (self, SLOT_TOP) && stack_is_slot_vacant (self, SLOT_BOTTOM)) { stack_get_slot_position (self, SLOT_TOP, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else stack_allocate_slot (self, bubble, SLOT_TOP); } // next check if top is occupied and bottom is // still vacant, then place sync. bubble in // bottom slot else if (!stack_is_slot_vacant (self, SLOT_TOP) && stack_is_slot_vacant (self, SLOT_BOTTOM)) { stack_get_slot_position (self, SLOT_BOTTOM, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else { stack_allocate_slot ( self, bubble, SLOT_BOTTOM); bubble_sync_with ( bubble, self->slots[SLOT_TOP]); } } // this case, top vacant, bottom occupied, // should never happen for the old placement, // we want to avoid the "gap" between the bottom // bubble and the panel else if (stack_is_slot_vacant (self, SLOT_TOP) && !stack_is_slot_vacant (self, SLOT_BOTTOM)) { g_warning ("%s(): Gap, gap, gap!!!\n", G_STRFUNC); } } break; default : g_warning ("Unhandled slot-allocation!\n"); break; } bubble_move (bubble, x, y); } static void stack_display_sync_bubble (Stack *self, Bubble *bubble) { g_return_if_fail (IS_STACK (self)); g_return_if_fail (IS_BUBBLE (bubble)); bubble_set_timeout (bubble, 2000); Bubble *other = stack_find_bubble_on_display (self); if (other != NULL) { /* synchronize the sync bubble with the timeout of the bubble at the bottom */ if (stack_is_at_top_corner (self, bubble)) bubble_sync_with (bubble, other); else bubble_sync_with (bubble, other); bubble_refresh (other); } /* is the notification reusing the current bubble? */ if (sync_bubble == bubble) { bubble_start_timer (bubble, TRUE); bubble_refresh (bubble); return; } stack_display_position_sync_bubble (self, bubble); bubble_fade_in (bubble, 100); sync_bubble = bubble; g_signal_connect (G_OBJECT (bubble), "timed-out", G_CALLBACK (close_handler), self); } static Bubble* stack_select_next_to_display (Stack *self) { Bubble* next_to_display = NULL; GList* list = NULL; Bubble* bubble = NULL; /* pickup the next bubble to display */ for (list = g_list_first (self->list); list != NULL; list = g_list_next (list)) { bubble = (Bubble*) list->data; /* sync. bubbles have already been taken care of */ if (bubble_is_synchronous (bubble)) { g_critical ("synchronous notifications are managed separately"); continue; } /* if there is already one bubble on display we don't have room for another one */ if (bubble_is_visible (bubble)) return NULL; if (bubble_is_urgent (bubble)) { /* pick-up the /first/ urgent bubble in the queue (FIFO) */ return bubble; } if (next_to_display == NULL) next_to_display = bubble; /* loop, in case there are urgent bubbles waiting higher up in the stack */ } return next_to_display; } /* Returns true if the next bubble is shown */ static gboolean stack_layout (Stack* self) { Bubble* bubble = NULL; Defaults* d; GdkScreen* screen; gint y = 0; gint x = 0; g_return_if_fail (self != NULL); bubble = stack_select_next_to_display (self); if (bubble == NULL) /* this actually happens when we're called for a synchronous bubble or after a bubble timed out, but there where no other notifications waiting in the queue */ return FALSE; if (dnd_dont_disturb_user () && (! bubble_is_urgent (bubble))) { guint id = bubble_get_id (bubble); /* find entry in list corresponding to id and remove it */ self->list = g_list_delete_link (self->list, find_entry_by_id (self, id)); g_object_unref (bubble); /* loop, in case there are other bubbles to discard */ stack_layout (self); return FALSE; } bubble_set_timeout (bubble, defaults_get_on_screen_timeout (self->defaults)); defaults_get_top_corner (self->defaults, &screen, &x, &y); d = self->defaults; switch (defaults_get_slot_allocation (d)) { case SLOT_ALLOCATION_FIXED: if (stack_is_slot_vacant (self, SLOT_TOP) && bubble_is_synchronous (bubble)) { stack_get_slot_position (self, SLOT_TOP, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else stack_allocate_slot (self, bubble, SLOT_TOP); } else if (stack_is_slot_vacant (self, SLOT_BOTTOM) && !bubble_is_synchronous (bubble)) { stack_get_slot_position (self, SLOT_BOTTOM, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else stack_allocate_slot (self, bubble, SLOT_BOTTOM); } else { g_warning ("%s(): Error while handling fixed " "slot-allocation!\n", G_STRFUNC); } break; case SLOT_ALLOCATION_DYNAMIC: if (stack_is_slot_vacant (self, SLOT_TOP) && stack_is_slot_vacant (self, SLOT_BOTTOM)) { stack_get_slot_position (self, SLOT_TOP, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else stack_allocate_slot (self, bubble, SLOT_TOP); } else if (!stack_is_slot_vacant (self, SLOT_TOP) && stack_is_slot_vacant (self, SLOT_BOTTOM)) { stack_get_slot_position (self, SLOT_BOTTOM, bubble_get_height (bubble), &x, &y); if (x == -1 || y == -1) g_warning ("%s(): No coords!\n", G_STRFUNC); else { stack_allocate_slot (self, bubble, SLOT_BOTTOM); if (sync_bubble != NULL && bubble_is_visible (sync_bubble)) { // synchronize the sync bubble with the timeout // of the bubble at the bottom bubble_sync_with (self->slots[SLOT_TOP], self->slots[SLOT_BOTTOM]); } } } else { g_warning ("%s(): Error while handling dynamic " "slot-allocation!\n", G_STRFUNC); } break; default : g_warning ("%s(): Unhandled slot-allocation scheme!\n", G_STRFUNC); break; } bubble_move (bubble, x, y); /* TODO: adjust timings for bubbles that appear in a serie of bubbles */ if (bubble_is_urgent (bubble)) bubble_fade_in (bubble, 100); else bubble_fade_in (bubble, 200); return TRUE; } ./src/dbus.h0000644000004100000410000000341313570225707013151 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** dbus.h - dbus boiler-plate code for talking with libnotify ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __NOTIFY_OSD_DBUS_H #define __NOTIFY_OSD_DBUS_H #include #include #include #ifndef DBUS_PATH #define DBUS_PATH "/org/freedesktop/Notifications" #endif #ifndef DBUS_NAME #define DBUS_NAME "org.freedesktop.Notifications" #endif DBusGConnection* dbus_create_service_instance (const char *service_name); DBusGConnection* dbus_get_connection (void); void dbus_send_close_signal (gchar *dest, guint id, guint reason); void dbus_send_action_signal (gchar *dest, guint id, const char *action_key); G_END_DECLS #endif /* __NOTIFY_OSD_DBUS_H */ ./src/bubble-window.c0000644000004100000410000000742613570225707014757 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window.c - implements bubble window ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include "bubble-window.h" #include "bubble.h" #include "bubble-window-accessible-factory.h" G_DEFINE_TYPE (BubbleWindow, bubble_window, GTK_TYPE_WINDOW); static AtkObject* bubble_window_get_accessible (GtkWidget *widget); static void bubble_window_init (BubbleWindow *object) { /* TODO: Add initialization code here */ } static void bubble_window_finalize (GObject *object) { /* TODO: Add deinitalization code here */ G_OBJECT_CLASS (bubble_window_parent_class)->finalize (object); } static void bubble_window_class_init (BubbleWindowClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); widget_class->get_accessible = bubble_window_get_accessible; object_class->finalize = bubble_window_finalize; } GtkWidget * bubble_window_new (void) { GtkWidget *bubble_window; bubble_window = g_object_new (BUBBLE_TYPE_WINDOW, "type", GTK_WINDOW_POPUP, NULL); return bubble_window; } static AtkObject * bubble_window_get_accessible (GtkWidget *widget) { static gboolean first_time = TRUE; static GQuark quark_accessible_object; if (first_time) { AtkObjectFactory *factory = NULL; AtkRegistry *registry = NULL; GType derived_type = NULL; GType derived_atk_type = NULL; /* * Figure out whether accessibility is enabled by looking at the * type of the accessible object which would be created for * the parent type WnckPager. */ derived_type = g_type_parent (BUBBLE_TYPE_WINDOW); registry = atk_get_default_registry (); factory = atk_registry_get_factory (registry, derived_type); derived_atk_type = atk_object_factory_get_accessible_type (factory); atk_registry_set_factory_type (registry, BUBBLE_TYPE_WINDOW, BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY); quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object"); first_time = FALSE; } AtkRegistry *default_registry = atk_get_default_registry (); AtkObjectFactory *factory = NULL; AtkObject *accessible = g_object_get_qdata (G_OBJECT (widget), quark_accessible_object); if (accessible) return accessible; factory = atk_registry_get_factory (default_registry, G_TYPE_FROM_INSTANCE (widget)); accessible = atk_object_factory_create_accessible (factory, G_OBJECT (widget)); g_object_set_qdata (G_OBJECT (widget), quark_accessible_object, accessible); return accessible; } ./src/notify-osd.xml0000644000004100000410000000325213570225707014661 0ustar www-datawww-data ./src/tile.h0000644000004100000410000000360213570225707013151 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // tile.h - implements public API surface/blur cache // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef _TILE_H #define _TILE_H #include #include typedef struct _tile_private_t tile_private_t; typedef struct _tile_t { tile_private_t* priv; } tile_t; tile_t* tile_new (cairo_surface_t* source, guint blur_radius); tile_t* tile_new_for_padding (cairo_surface_t* normal, cairo_surface_t* blurred, gint width, gint height); void tile_destroy (tile_t* tile); void tile_paint (tile_t* tile, cairo_t* cr, gdouble x, gdouble y, gdouble normal_alpha, gdouble blurred_alpha); void tile_paint_with_padding (tile_t* tile, cairo_t* cr, gdouble x, gdouble y, gdouble width, gdouble height, gdouble normal_alpha, gdouble blurred_alpha); #endif // _TILE_H ./src/bubble.h0000644000004100000410000001247713570225707013461 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // bubble.h - implements all the rendering of a notification bubble // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // David Barth // // Contributor(s): // Eitan Isaacson (ATK interface for a11y, rev. 351) // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef __BUBBLE_H #define __BUBBLE_H #include #include #include "defaults.h" typedef enum { LAYOUT_NONE = 0, LAYOUT_ICON_ONLY, LAYOUT_ICON_INDICATOR, LAYOUT_ICON_TITLE, LAYOUT_ICON_TITLE_BODY, LAYOUT_TITLE_BODY, LAYOUT_TITLE_ONLY } BubbleLayout; G_BEGIN_DECLS #define BUBBLE_TYPE (bubble_get_type ()) #define BUBBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUBBLE_TYPE, Bubble)) #define BUBBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BUBBLE_TYPE, BubbleClass)) #define IS_BUBBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUBBLE_TYPE)) #define IS_BUBBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BUBBLE_TYPE)) #define BUBBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BUBBLE_TYPE, BubbleClass)) typedef struct _Bubble Bubble; typedef struct _BubbleClass BubbleClass; typedef struct _BubblePrivate BubblePrivate; // instance structure struct _Bubble { GObject parent; Defaults* defaults; //< private > BubblePrivate *priv; }; // class structure struct _BubbleClass { GObjectClass parent; //< signals > void (*timed_out) (Bubble* bubble); void (*value_changed) (Bubble* bubble); void (*message_body_deleted) (Bubble* bubble); void (*message_body_inserted) (Bubble* bubble); }; GType bubble_get_type (void); Bubble* bubble_new (Defaults* defaults); gchar* bubble_get_synchronous (Bubble *self); gchar* bubble_get_sender (Bubble *self); void bubble_set_title (Bubble* self, const gchar* title); const gchar* bubble_get_title (Bubble* self); void bubble_set_message_body (Bubble* self, const gchar* body); const gchar* bubble_get_message_body (Bubble* self); void bubble_set_icon (Bubble* self, const gchar* name); void bubble_set_icon_from_pixbuf (Bubble* self, GdkPixbuf* pixbuf); GdkPixbuf* bubble_get_icon_pixbuf (Bubble *self); void bubble_set_value (Bubble* self, gint value); gint bubble_get_value (Bubble* self); void bubble_set_size (Bubble* self, gint width, gint height); void bubble_get_size (Bubble* self, gint* width, gint* height); void bubble_set_timeout (Bubble* self, guint timeout); guint bubble_get_timeout (Bubble* self); void bubble_set_timer_id (Bubble* self, guint timer_id); guint bubble_get_timer_id (Bubble* self); void bubble_set_mouse_over (Bubble* self, gboolean flag); gboolean bubble_is_mouse_over (Bubble* self); void bubble_move (Bubble* self, gint x, gint y); gboolean bubble_timed_out (Bubble* self); void bubble_show (Bubble* self); void bubble_refresh (Bubble* self); void bubble_hide (Bubble* self); void bubble_set_id (Bubble* self, guint id); guint bubble_get_id (Bubble* self); gboolean bubble_is_visible (Bubble* self); void bubble_start_timer (Bubble* self, gboolean trigger); void bubble_clear_timer (Bubble* self); void bubble_get_position (Bubble* self, gint* x, gint* y); gint bubble_get_height (Bubble *self); gint bubble_get_future_height (Bubble *self); void bubble_recalc_size (Bubble *self); gboolean bubble_is_synchronous (Bubble *self); void bubble_set_synchronous (Bubble *self, const gchar *sync); void bubble_set_sender (Bubble *self, const gchar *sender); gboolean bubble_is_urgent (Bubble *self); guint bubble_get_urgency (Bubble *self); void bubble_set_urgency (Bubble *self, guint urgency); void bubble_fade_out (Bubble *self, guint msecs); void bubble_fade_in (Bubble *self, guint msecs); void bubble_determine_layout (Bubble* self); BubbleLayout bubble_get_layout (Bubble* self); void bubble_set_icon_only (Bubble* self, gboolean allowed); void bubble_set_append (Bubble* self, gboolean allowed); gboolean bubble_is_append_allowed (Bubble* self); void bubble_append_message_body (Bubble* self, const gchar* append_body); void bubble_sync_with (Bubble *self, Bubble *other); GObject* bubble_show_dialog (Bubble *bubble, const char *process_name, gchar **actions); G_END_DECLS #endif // __BUBBLE_H ./src/exponential-blur.h0000644000004100000410000000261013570225707015502 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // raico-blur // // exponential-blur.h - implements exponential-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // based on exponential-blur algorithm by Jani Huhtanen // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef _EXPONENTIAL_BLUR_H #define _EXPONENTIAL_BLUR_H #include #include void surface_exponential_blur (cairo_surface_t* surface, guint radius); #endif // _EXPONENTIAL_BLUR_H ./src/defaults.h0000644000004100000410000001566213570225707014034 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** defaults.h - a singelton providing all default values for sizes, colors etc. ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __DEFAULTS_H #define __DEFAULTS_H #include #include #include G_BEGIN_DECLS #define DEFAULTS_TYPE (defaults_get_type ()) #define DEFAULTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEFAULTS_TYPE, Defaults)) #define DEFAULTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEFAULTS_TYPE, DefaultsClass)) #define IS_DEFAULTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEFAULTS_TYPE)) #define IS_DEFAULTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEFAULTS_TYPE)) #define DEFAULTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEFAULTS_TYPE, DefaultsClass)) /* FIXME: quick hack to get every measurement to use em instead of pixels, to * correctly use these two macros you'll need to pass it a valid Defaults class * object * * example use: * PIXEL2EM(42, defaults) - that will returns a gdouble * EM2PIXEL(0.375, defaults) - that will return a gint */ #define PIXELS2EM(pixel_value, d) ((gdouble) ((gdouble) pixel_value / defaults_get_pixel_per_em(d))) #define EM2PIXELS(em_value, d) ((gint) (em_value * defaults_get_pixel_per_em(d))) typedef struct _Defaults Defaults; typedef struct _DefaultsClass DefaultsClass; typedef enum { GRAVITY_NONE = 0, GRAVITY_NORTH_EAST, // top-right of screen GRAVITY_EAST // vertically centered at right of screen } Gravity; typedef enum { SLOT_ALLOCATION_NONE = 0, SLOT_ALLOCATION_FIXED, // async. always in top, sync. always in bottom SLOT_ALLOCATION_DYNAMIC // async. and sync can take top or bottom } SlotAllocation; /* instance structure */ struct _Defaults { GObject parent; /* private */ GSettings* nosd_settings; GSettings* gnome_settings; gint desktop_width; gint desktop_height; gdouble desktop_bottom_gap; gdouble stack_height; gdouble bubble_vert_gap; gdouble bubble_horz_gap; gdouble bubble_width; gdouble bubble_min_height; gdouble bubble_max_height; gdouble bubble_shadow_size; GString* bubble_shadow_color; GString* bubble_bg_color; GString* bubble_bg_opacity; GString* bubble_hover_opacity; gdouble bubble_corner_radius; gdouble content_shadow_size; GString* content_shadow_color; gdouble margin_size; gdouble icon_size; gdouble gauge_size; gdouble gauge_outline_width; gint fade_in_timeout; gint fade_out_timeout; gint on_screen_timeout; GString* text_font_face; GString* text_title_color; gint text_title_weight; gdouble text_title_size; GString* text_body_color; gint text_body_weight; gdouble text_body_size; gdouble pixels_per_em; gdouble system_font_size; gdouble screen_dpi; Gravity gravity; SlotAllocation slot_allocation; }; /* class structure */ struct _DefaultsClass { GObjectClass parent; /*< signals >*/ void (*value_changed) (Defaults* defaults); /* used to "inform" bubble ** about any changes in ** rendering and position */ void (*gravity_changed) (Defaults* defaults); // used to "inform" about // gravity/position change // for bubbles }; GType defaults_get_type (void); Defaults* defaults_new (void); gint defaults_get_desktop_width (Defaults* self); gint defaults_get_desktop_height (Defaults* self); gint defaults_get_desktop_top (Defaults* self); gint defaults_get_desktop_bottom (Defaults* self); gint defaults_get_desktop_left (Defaults* self); gint defaults_get_desktop_right (Defaults* self); gdouble defaults_get_desktop_bottom_gap (Defaults* self); gdouble defaults_get_stack_height (Defaults* self); gdouble defaults_get_bubble_width (Defaults* self); gdouble defaults_get_bubble_min_height (Defaults* self); gdouble defaults_get_bubble_max_height (Defaults* self); gdouble defaults_get_bubble_vert_gap (Defaults* self); gdouble defaults_get_bubble_horz_gap (Defaults* self); gdouble defaults_get_bubble_shadow_size (Defaults* self, gboolean is_composited); gchar* defaults_get_bubble_shadow_color (Defaults* self); gchar* defaults_get_bubble_bg_color (Defaults* self); gchar* defaults_get_bubble_bg_opacity (Defaults* self); gchar* defaults_get_bubble_hover_opacity (Defaults* self); gdouble defaults_get_bubble_corner_radius (Defaults* self, gboolean is_composited); gdouble defaults_get_content_shadow_size (Defaults* self); gchar* defaults_get_content_shadow_color (Defaults* self); gdouble defaults_get_margin_size (Defaults* self); gdouble defaults_get_icon_size (Defaults* self); gdouble defaults_get_gauge_size (Defaults* self); gdouble defaults_get_gauge_outline_width (Defaults* self); gint defaults_get_fade_in_timeout (Defaults* self); gint defaults_get_fade_out_timeout (Defaults* self); gint defaults_get_on_screen_timeout (Defaults* self); gchar* defaults_get_text_font_face (Defaults* self); gchar* defaults_get_text_title_color (Defaults* self); gint defaults_get_text_title_weight (Defaults* self); gdouble defaults_get_text_title_size (Defaults* self); gchar* defaults_get_text_body_color (Defaults* self); gint defaults_get_text_body_weight (Defaults* self); gdouble defaults_get_text_body_size (Defaults* self); gdouble defaults_get_pixel_per_em (Defaults* self); gdouble defaults_get_system_font_size (Defaults* self); gdouble defaults_get_screen_dpi (Defaults* self); void defaults_refresh_bg_property (Defaults *self); void defaults_refresh_screen_dimension_properties (Defaults *self); void defaults_get_top_corner (Defaults *self, GdkScreen **screen, gint *x, gint *y); Gravity defaults_get_gravity (Defaults *self); SlotAllocation defaults_get_slot_allocation (Defaults *self); G_END_DECLS #endif /* __DEFAULTS_H */ ./src/stack.h0000644000004100000410000000735113570225707013326 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** stack.h - implements singelton handling all the internal queue-logic ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __STACK_H #define __STACK_H #include #include #include #include "defaults.h" #include "bubble.h" #include "observer.h" G_BEGIN_DECLS #define STACK_TYPE (stack_get_type ()) #define STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STACK_TYPE, Stack)) #define STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STACK_TYPE, StackClass)) #define IS_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STACK_TYPE)) #define IS_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STACK_TYPE)) #define STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STACK_TYPE, StackClass)) #define MAX_STACK_SIZE 50 #define VACANT TRUE #define OCCUPIED FALSE typedef struct _Stack Stack; typedef struct _StackClass StackClass; typedef enum { SLOT_TOP = 0, SLOT_BOTTOM } Slot; /* instance structure */ struct _Stack { GObject parent; /* private */ Defaults* defaults; Observer* observer; GList* list; guint next_id; Bubble* slots[2]; // NULL: vacant, non-NULL: occupied }; /* class structure */ struct _StackClass { GObjectClass parent; }; GType stack_get_type (void); Stack* stack_new (Defaults* defaults, Observer* observer); void stack_del (Stack* self); guint stack_push_bubble (Stack* self, Bubble* bubble); void stack_pop_bubble_by_id (Stack* self, guint id); gboolean stack_notify_handler (Stack* self, const gchar* app_name, guint id, const gchar* icon, const gchar* summary, const gchar* body, gchar** actions, GHashTable* hints, gint timeout, DBusGMethodInvocation* context); gboolean stack_close_notification_handler (Stack* self, guint id, GError** error); gboolean stack_get_capabilities (Stack* self, gchar*** out_caps); gboolean stack_get_server_information (Stack* self, gchar** out_name, gchar** out_vendor, gchar** out_version, gchar** out_spec_ver); gboolean stack_is_slot_vacant (Stack* self, Slot slot); void stack_get_slot_position (Stack* self, Slot slot, gint bubble_height, gint* x, gint* y); gboolean stack_allocate_slot (Stack* self, Bubble* bubble, Slot slot); gboolean stack_free_slot (Stack* self, Bubble* bubble); G_END_DECLS #endif /* __STACK_H */ ./src/bubble-window-accessible.c0000644000004100000410000003026713570225707017051 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window-accessible.c - implements an accessible bubble window ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include "bubble-window-accessible.h" #include "bubble.h" #include static void bubble_window_accessible_init (BubbleWindowAccessible* object); static void bubble_window_accessible_finalize (GObject* object); static void bubble_window_accessible_class_init (BubbleWindowAccessibleClass* klass); static const char* bubble_window_accessible_get_name (AtkObject* obj); static const char* bubble_window_accessible_get_description (AtkObject* obj); static void bubble_window_real_initialize (AtkObject* obj, gpointer data); static void atk_value_interface_init (AtkValueIface* iface); static void atk_text_interface_init (AtkTextIface* iface); static void bubble_window_get_current_value (AtkValue* obj, GValue* value); static void bubble_window_get_maximum_value (AtkValue* obj, GValue* value); static void bubble_window_get_minimum_value (AtkValue* obj, GValue* value); static void bubble_value_changed_event (Bubble* bubble, gint value, AtkObject *obj); static void bubble_message_body_deleted_event (Bubble* bubble, const gchar* text, AtkObject* obj); static void bubble_message_body_inserted_event (Bubble* bubble, const gchar* text, AtkObject* obj); static gchar* bubble_window_get_text (AtkText *obj, gint start_offset, gint end_offset); static gint bubble_window_get_character_count (AtkText *obj); static gunichar bubble_window_get_character_at_offset (AtkText *obj, gint offset); static void* bubble_window_accessible_parent_class; G_DEFINE_TYPE_WITH_CODE (BubbleWindowAccessible, bubble_window_accessible, GTK_TYPE_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init) G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init)) static void atk_value_interface_init (AtkValueIface* iface) { g_return_if_fail (iface != NULL); iface->get_current_value = bubble_window_get_current_value; iface->get_maximum_value = bubble_window_get_maximum_value; iface->get_minimum_value = bubble_window_get_minimum_value; } static void atk_text_interface_init (AtkTextIface* iface) { g_return_if_fail (iface != NULL); iface->get_text = bubble_window_get_text; iface->get_character_count = bubble_window_get_character_count; iface->get_character_at_offset = bubble_window_get_character_at_offset; } static void bubble_window_accessible_init (BubbleWindowAccessible *object) { /* TODO: Add initialization code here */ } static void bubble_window_accessible_finalize (GObject *object) { /* TODO: Add deinitalization code here */ G_OBJECT_CLASS (bubble_window_accessible_parent_class)->finalize (object); } static void bubble_window_accessible_class_init (BubbleWindowAccessibleClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); AtkObjectClass* class = ATK_OBJECT_CLASS (klass); bubble_window_accessible_parent_class = g_type_class_peek_parent (klass); class->get_name = bubble_window_accessible_get_name; class->get_description = bubble_window_accessible_get_description; class->initialize = bubble_window_real_initialize; object_class->finalize = bubble_window_accessible_finalize; } static void bubble_window_real_initialize (AtkObject* obj, gpointer data) { GtkWidget* widget = GTK_WIDGET (data); Bubble* bubble; ATK_OBJECT_CLASS (bubble_window_accessible_parent_class)->initialize (obj, data); bubble = g_object_get_data (G_OBJECT(widget), "bubble"); g_signal_connect (bubble, "value-changed", G_CALLBACK (bubble_value_changed_event), obj); g_signal_connect (bubble, "message-body-deleted", G_CALLBACK (bubble_message_body_deleted_event), obj); g_signal_connect (bubble, "message-body-inserted", G_CALLBACK (bubble_message_body_inserted_event), obj); atk_object_set_role (obj, ATK_ROLE_NOTIFICATION); } AtkObject* bubble_window_accessible_new (GtkWidget *widget) { GObject *object; AtkObject *aobj; object = g_object_new (BUBBLE_WINDOW_TYPE_ACCESSIBLE, NULL); aobj = ATK_OBJECT (object); gtk_accessible_set_widget (GTK_ACCESSIBLE (aobj), widget); atk_object_initialize (aobj, widget); return aobj; } static const char* bubble_window_accessible_get_name (AtkObject* obj) { GtkWidget* widget; Bubble* bubble; const gchar* title; g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), ""); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return ""; bubble = g_object_get_data (G_OBJECT (widget), "bubble"); g_return_val_if_fail (IS_BUBBLE (bubble), ""); title = bubble_get_title(bubble); if (g_strcmp0(title, " ") == 0) { /* HACK: Titles should never be empty. This solution is extremely wrong. https://bugs.launchpad.net/notify-osd/+bug/334292 */ const gchar* synch_str; synch_str = bubble_get_synchronous(bubble); if (synch_str != NULL) return synch_str; else return ""; } return title; } static const char* bubble_window_accessible_get_description (AtkObject* obj) { GtkWidget *widget; Bubble *bubble; g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), ""); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return ""; bubble = g_object_get_data (G_OBJECT (widget), "bubble"); g_return_val_if_fail (IS_BUBBLE (bubble), ""); return bubble_get_message_body(bubble); } static void bubble_window_get_current_value (AtkValue* obj, GValue* value) { gdouble current_value; GtkWidget* widget; Bubble* bubble; g_return_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj)); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return; bubble = g_object_get_data (G_OBJECT (widget), "bubble"); current_value = (gdouble) bubble_get_value(bubble); memset (value, 0, sizeof (GValue)); g_value_init (value, G_TYPE_DOUBLE); g_value_set_double (value,current_value); } static void bubble_window_get_maximum_value (AtkValue* obj, GValue* value) { memset (value, 0, sizeof (GValue)); g_value_init (value, G_TYPE_DOUBLE); g_value_set_double (value, 100.0); } static void bubble_window_get_minimum_value (AtkValue* obj, GValue* value) { memset (value, 0, sizeof (GValue)); g_value_init (value, G_TYPE_DOUBLE); g_value_set_double (value, 0.0); } static void bubble_value_changed_event (Bubble* bubble, gint value, AtkObject* obj) { g_object_notify (G_OBJECT (obj), "accessible-value"); } static void bubble_message_body_deleted_event (Bubble* bubble, const gchar* text, AtkObject* obj) { /* Not getting very fancy here, delete is always complete */ g_signal_emit_by_name ( obj, "text_changed::delete", 0, g_utf8_strlen (text, -1)); } static void bubble_message_body_inserted_event (Bubble* bubble, const gchar* text, AtkObject* obj) { const gchar* message_body; message_body = bubble_get_message_body (bubble); g_signal_emit_by_name ( obj, "text_changed::insert", g_utf8_strlen (message_body, -1) - g_utf8_strlen (text, -1), g_utf8_strlen (message_body, -1)); } static gchar* bubble_window_get_text (AtkText *obj, gint start_offset, gint end_offset) { GtkWidget* widget; Bubble* bubble; const gchar* body_text; gsize char_length; glong body_strlen; g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), g_strdup("")); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); g_return_val_if_fail (GTK_IS_WINDOW (widget), g_strdup("")); bubble = g_object_get_data (G_OBJECT(widget), "bubble"); if (end_offset <= start_offset) return g_strdup(""); body_text = bubble_get_message_body (bubble); body_strlen = g_utf8_strlen(body_text, -1); if (start_offset > body_strlen) start_offset = body_strlen; if (end_offset > body_strlen || end_offset == -1) end_offset = body_strlen; char_length = g_utf8_offset_to_pointer (body_text, end_offset) - g_utf8_offset_to_pointer (body_text, start_offset); return g_strndup (g_utf8_offset_to_pointer(body_text, start_offset), char_length); } static gint bubble_window_get_character_count (AtkText *obj) { GtkWidget* widget; Bubble* bubble; g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return 0; bubble = g_object_get_data (G_OBJECT (widget), "bubble"); return g_utf8_strlen(bubble_get_message_body (bubble), -1); } static gunichar bubble_window_get_character_at_offset (AtkText *obj, gint offset) { GtkWidget* widget; Bubble* bubble; const gchar* body_text; g_return_val_if_fail (BUBBLE_WINDOW_IS_ACCESSIBLE (obj), 0); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); if (widget == NULL) return 0; bubble = g_object_get_data (G_OBJECT (widget), "bubble"); body_text = bubble_get_message_body (bubble); return g_utf8_get_char (g_utf8_offset_to_pointer (body_text, offset)); } ./src/raico-blur.c0000644000004100000410000001056413570225707014253 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // raico-blur.c - implements public API for blurring cairo image-surfaces // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include "raico-blur.h" #include "exponential-blur.h" #include "stack-blur.h" #include "gaussian-blur.h" struct _raico_blur_private_t { raico_blur_quality_t quality; // low, medium, high guint radius; // blur-radius }; raico_blur_t* raico_blur_create (raico_blur_quality_t quality) { raico_blur_t* blur = NULL; raico_blur_private_t* priv = NULL; blur = g_new0 (raico_blur_t, 1); if (!blur) { g_debug ("raico_blur_create(): could not allocate blur struct"); return NULL; } priv = g_new0 (raico_blur_private_t, 1); if (!priv) { g_debug ("raico_blur_create(): could not allocate priv struct"); g_free ((gpointer) blur); return NULL; } priv->quality = quality; priv->radius = 0; blur->priv = priv; return blur; } raico_blur_quality_t raico_blur_get_quality (raico_blur_t* blur) { g_assert (blur != NULL); return blur->priv->quality; } void raico_blur_set_quality (raico_blur_t* blur, raico_blur_quality_t quality) { if (!blur) { g_debug ("raico_blur_set_quality(): NULL blur-pointer passed"); return; } blur->priv->quality = quality; } guint raico_blur_get_radius (raico_blur_t* blur) { g_assert (blur != NULL); return blur->priv->radius; } void raico_blur_set_radius (raico_blur_t* blur, guint radius) { if (!blur) { g_debug ("raico_blur_set_radius(): NULL blur-pointer passed"); return; } blur->priv->radius = radius; } void raico_blur_apply (raico_blur_t* blur, cairo_surface_t* surface) { cairo_format_t format; double x_scale; double y_scale; guint radius; // sanity checks if (!blur) { g_debug ("raico_blur_apply(): NULL blur-pointer passed"); return; } if (!surface) { g_debug ("raico_blur_apply(): NULL surface-pointer passed"); return; } if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { g_debug ("raico_blur_apply(): invalid surface status"); return; } if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_IMAGE) { g_debug ("raico_blur_apply(): non-image surface passed"); return; } format = cairo_image_surface_get_format (surface); if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_RGB24 && format != CAIRO_FORMAT_ARGB32) { g_debug ("raico_blur_apply(): unsupported image-format"); return; } // stupid, but you never know if (blur->priv->radius == 0) return; /* adjust radius for device scale. We don't support blurring * different amounts in x and y, so just use the mean value * between cairo's respective device scales (in practice they * should always be the same). */ cairo_surface_get_device_scale (surface, &x_scale, &y_scale); radius = blur->priv->radius * 0.5 * (x_scale + y_scale); // now do the real work switch (blur->priv->quality) { case RAICO_BLUR_QUALITY_LOW: surface_exponential_blur (surface, radius); break; case RAICO_BLUR_QUALITY_MEDIUM: //surface_stack_blur (surface, blur->priv->radius); surface_gaussian_blur (surface, radius); break; case RAICO_BLUR_QUALITY_HIGH: surface_gaussian_blur (surface, radius); break; } } void raico_blur_destroy (raico_blur_t* blur) { if (!blur) { g_debug ("raico_blur_destroy(): invalid blur-pointer passed"); return; } g_free ((gpointer) blur->priv); g_free ((gpointer) blur); } ./src/gaussian-blur.h0000644000004100000410000000254313570225707014773 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // gaussian-blur.h - implements gaussian-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // based on filters in libpixman // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef _GAUSSIAN_BLUR_H #define _GAUSSIAN_BLUR_H #include #include void surface_gaussian_blur (cairo_surface_t* surface, guint radius); #endif // _GAUSSIAN_BLUR_H ./src/dbus.c0000644000004100000410000000761713570225707013156 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** dbus.c - dbus boiler-plate code for talking with libnotify ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #include #include #include "dbus.h" static DBusGConnection* connection = NULL; DBusGConnection* dbus_get_connection (void) { /* usefull mostly for unit tests */ if (connection == NULL) connection = dbus_create_service_instance (DBUS_NAME); return connection; } DBusGConnection* dbus_create_service_instance (const char *service_name) { DBusGProxy* proxy = NULL; guint request_name_result; GError* error = NULL; error = NULL; connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); if (error) { g_warning ("dbus_create_service_instance(): " "Got error \"%s\"\n", error->message); g_error_free (error); return NULL; } proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus"); error = NULL; if (!dbus_g_proxy_call (proxy, "RequestName", &error, G_TYPE_STRING, service_name, G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT, G_TYPE_INVALID, G_TYPE_UINT, &request_name_result, G_TYPE_INVALID)) { g_warning ("dbus_create_service_instance(): " "Got error \"%s\"\n", error->message); g_error_free (error); g_object_unref (proxy); return NULL; } g_object_unref (proxy); if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { g_warning ("Another instance has already registered %s", service_name); return NULL; } return connection; } void dbus_send_close_signal (gchar *dest, guint id, guint reason) { DBusMessage *msg; msg = dbus_message_new_signal ("/org/freedesktop/Notifications", "org.freedesktop.Notifications", "NotificationClosed"); dbus_message_set_destination (msg, dest); dbus_message_append_args (msg, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID); dbus_message_append_args (msg, DBUS_TYPE_UINT32, &reason, DBUS_TYPE_INVALID); dbus_connection_send (dbus_g_connection_get_connection (connection), msg, NULL); dbus_message_unref (msg); } void dbus_send_action_signal (gchar *dest, guint id, const char *action_key) { DBusMessage *msg; msg = dbus_message_new_signal ("/org/freedesktop/Notifications", "org.freedesktop.Notifications", "ActionInvoked"); dbus_message_set_destination (msg, dest); dbus_message_append_args (msg, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID); dbus_message_append_args (msg, DBUS_TYPE_STRING, &action_key, DBUS_TYPE_INVALID); dbus_connection_send (dbus_g_connection_get_connection (connection), msg, NULL); dbus_message_unref (msg); } ./src/stack.c0000644000004100000410000006220213570225713013312 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** stack.c - manages the stack/queue of incoming notifications ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** Contributor(s): ** Abhishek Mukherjee (append fixes, rev. 280) ** Aurélien Gâteau (0.10 spec, rev. 348) ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include "dbus.h" #include #include #include "stack.h" #include "bubble.h" #include "apport.h" #include "dialog.h" #include "dnd.h" #include "log.h" G_DEFINE_TYPE (Stack, stack, G_TYPE_OBJECT); #define FORCED_SHUTDOWN_THRESHOLD 500 /* fwd declaration */ void close_handler (GObject* n, Stack* stack); /*-- internal API ------------------------------------------------------------*/ static void stack_dispose (GObject* gobject) { /* chain up to the parent class */ G_OBJECT_CLASS (stack_parent_class)->dispose (gobject); } static void disconnect_bubble (gpointer data, gpointer user_data) { Bubble* bubble = BUBBLE(data); Stack* stack = STACK(user_data); g_signal_handlers_disconnect_by_func (G_OBJECT(bubble), G_CALLBACK (close_handler), stack); } static void stack_finalize (GObject* gobject) { if (STACK(gobject)->list != NULL) g_list_foreach (STACK(gobject)->list, disconnect_bubble, gobject); if (STACK(gobject)->defaults != NULL) g_object_unref (STACK(gobject)->defaults); if (STACK(gobject)->observer != NULL) g_object_unref (STACK(gobject)->observer); /* chain up to the parent class */ G_OBJECT_CLASS (stack_parent_class)->finalize (gobject); } static void stack_init (Stack* self) { /* If you need specific construction properties to complete ** initialization, delay initialization completion until the ** property is set. */ self->list = NULL; } static void stack_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { switch (prop) { default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } #include "stack-glue.h" static void stack_class_init (StackClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = stack_dispose; gobject_class->finalize = stack_finalize; gobject_class->get_property = stack_get_property; dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), &dbus_glib_stack_object_info); } gint compare_id (gconstpointer a, gconstpointer b) { gint result; guint id_1; guint id_2; if (!a || !b) return -1; if (!IS_BUBBLE (a)) return -1; id_1 = bubble_get_id ((Bubble*) a); id_2 = *((guint*) b); if (id_1 < id_2) result = -1; if (id_1 == id_2) result = 0; if (id_1 > id_2) result = 1; return result; } static gint compare_append (gconstpointer a, gconstpointer b) { const gchar* str_1; const gchar* str_2; gint cmp; if (!a || !b) return -1; if (!IS_BUBBLE (a)) return -1; if (!IS_BUBBLE (b)) return 1; if (!bubble_is_append_allowed((Bubble*) a)) return -1; if (!bubble_is_append_allowed((Bubble*) b)) return 1; str_1 = bubble_get_title ((Bubble*) a); str_2 = bubble_get_title ((Bubble*) b); cmp = g_strcmp0(str_1, str_2); if (cmp < 0) return -1; if (cmp > 0) return 1; str_1 = bubble_get_sender ((Bubble*) a); str_2 = bubble_get_sender ((Bubble*) b); return g_strcmp0(str_1, str_2); } GList* find_entry_by_id (Stack* self, guint id) { GList* entry; /* sanity check */ if (!self) return NULL; entry = g_list_find_custom (self->list, (gconstpointer) &id, compare_id); if (!entry) return NULL; return entry; } static Bubble* find_bubble_by_id (Stack* self, guint id) { GList* entry; /* sanity check */ if (!self) return NULL; entry = g_list_find_custom (self->list, (gconstpointer) &id, compare_id); if (!entry) return NULL; return (Bubble*) entry->data; } static Bubble* find_bubble_for_append(Stack* self, Bubble *bubble) { GList* entry; /* sanity check */ if (!self) return NULL; entry = g_list_find_custom(self->list, (gconstpointer) bubble, compare_append); if (!entry) return NULL; return (Bubble*) entry->data; } static void _weak_notify_cb (gpointer data, GObject* former_object) { Stack* stack = STACK (data); stack->list = g_list_remove (stack->list, former_object); } static void _trigger_bubble_redraw (gpointer data, gpointer user_data) { Bubble* bubble; if (!data) return; bubble = BUBBLE (data); if (!IS_BUBBLE (bubble)) return; bubble_recalc_size (bubble); bubble_refresh (bubble); } static Bubble *sync_bubble = NULL; static void value_changed_handler (Defaults* defaults, Stack* stack) { if (stack->list != NULL) g_list_foreach (stack->list, _trigger_bubble_redraw, NULL); if (sync_bubble != NULL) { bubble_recalc_size (sync_bubble); bubble_refresh (sync_bubble); } } #include "display.c" /*-- public API --------------------------------------------------------------*/ Stack* stack_new (Defaults* defaults, Observer* observer) { Stack* this; if (!defaults || !observer) return NULL; this = g_object_new (STACK_TYPE, NULL); if (!this) return NULL; this->defaults = defaults; this->observer = observer; this->list = NULL; this->next_id = 1; this->slots[SLOT_TOP] = NULL; this->slots[SLOT_BOTTOM] = NULL; /* hook up handler to act on changes of defaults/settings */ g_signal_connect (G_OBJECT (defaults), "value-changed", G_CALLBACK (value_changed_handler), this); return this; } void stack_del (Stack* self) { if (!self) return; g_object_unref (self); } void close_handler (GObject *n, Stack* stack) { /* TODO: use weak-refs to dispose the bubble. Meanwhile, do nothing here to avoid segfaults and rely on the stack_purge_old_bubbles() call later on in the thread. */ if (n != NULL) { if (IS_BUBBLE (n)) stack_free_slot (stack, BUBBLE (n)); if (IS_BUBBLE (n) && bubble_is_synchronous (BUBBLE (n))) { g_object_unref (n); sync_bubble = NULL; } if (IS_BUBBLE (n)) { stack_pop_bubble_by_id (stack, bubble_get_id ((Bubble*) n)); /* Fix for a tricky race condition where a bubble fades out in sync with a synchronous bubble: the symc. one is still considered visible while the normal one has triggered this signal. This ensures the display slot of the sync. bubble is recycled, and no gap is left on the screen */ sync_bubble = NULL; } else { /* Fix for a tricky race condition where a bubble fades out in sync with a synchronous bubble: the symc. one is still considered visible while the normal one has triggered this signal. This ensures the display slot of the sync. bubble is recycled, and no gap is left on the screen */ sync_bubble = NULL; } stack_layout (stack); } return; } /* since notification-ids are unsigned integers the first id index is 1, 0 is ** used to indicate an error */ guint stack_push_bubble (Stack* self, Bubble* bubble) { guint notification_id = -1; /* sanity check */ if (!self || !IS_BUBBLE (bubble)) return -1; notification_id = bubble_get_id (bubble); /* check if this is just an update */ if (find_bubble_by_id (self, notification_id)) { bubble_start_timer (bubble, TRUE); bubble_refresh (bubble); /* resync the synchronous bubble if it's at the top */ if (sync_bubble != NULL && bubble_is_visible (sync_bubble)) if (stack_is_at_top_corner (self, sync_bubble)) bubble_sync_with (sync_bubble, bubble); return notification_id; } /* add bubble/id to stack */ if (notification_id == 0) { do { notification_id = self->next_id++; } while (find_bubble_by_id (self, notification_id)); } // FIXME: migrate stack to use abstract notification object and don't // keep heavy bubble objects around, at anyone time at max. only two // bubble-objects will be in memory... this will also reduce leak- // potential bubble_set_id (bubble, notification_id); self->list = g_list_append (self->list, (gpointer) bubble); g_signal_connect (G_OBJECT (bubble), "timed-out", G_CALLBACK (close_handler), self); /* return current/new id to caller (usually our DBus-dispatcher) */ return notification_id; } void stack_pop_bubble_by_id (Stack* self, guint id) { Bubble* bubble; /* sanity check */ if (!self) return; /* find bubble corresponding to id */ bubble = find_bubble_by_id (self, id); if (!bubble) return; /* close/hide/fade-out bubble */ bubble_hide (bubble); /* find entry in list corresponding to id and remove it */ self->list = g_list_delete_link (self->list, find_entry_by_id (self, id)); g_object_unref (bubble); /* immediately refresh the layout of the stack */ stack_layout (self); } static GdkPixbuf* process_dbus_icon_data (GValue *data) { GType dbus_icon_t; GArray *pixels; int width, height, rowstride, bits_per_sample, n_channels, size; gboolean has_alpha; guchar *copy; GdkPixbuf *pixbuf = NULL; g_return_val_if_fail (data != NULL, NULL); dbus_icon_t = dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_INT, dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), G_TYPE_INVALID); if (G_VALUE_HOLDS (data, dbus_icon_t)) { dbus_g_type_struct_get (data, 0, &width, 1, &height, 2, &rowstride, 3, &has_alpha, 4, &bits_per_sample, 5, &n_channels, 6, &pixels, G_MAXUINT); size = (height - 1) * rowstride + width * ((n_channels * bits_per_sample + 7) / 8); copy = (guchar *) g_memdup (pixels->data, size); pixbuf = gdk_pixbuf_new_from_data(copy, GDK_COLORSPACE_RGB, has_alpha, bits_per_sample, width, height, rowstride, (GdkPixbufDestroyNotify)g_free, NULL); } return pixbuf; } // control if there are non-default actions requested with this notification static gboolean dialog_check_actions_and_timeout (gchar** actions, gint timeout) { int i = 0; gboolean turn_into_dialog = FALSE; if (actions != NULL) { for (i = 0; actions[i] != NULL; i += 2) { if (actions[i+1] == NULL) { g_debug ("incorrect action callback " "with no label"); break; } turn_into_dialog = TRUE; g_debug ("notification request turned into a dialog " "box, because it contains at least one action " "callback (%s: \"%s\")", actions[i], actions[i+1]); } if (timeout == 0) { turn_into_dialog = TRUE; g_debug ("notification request turned into a dialog " "box, because of its infinite timeout"); } } return turn_into_dialog; } // FIXME: a intnernal function used for the forcefully-shutdown work-around // regarding mem-leaks gboolean _arm_forced_quit (gpointer data) { Stack* stack = NULL; // sanity check, "disarming" this forced quit if (!data) return FALSE; stack = STACK (data); // only forcefully quit if the queue is empty if (g_list_length (stack->list) == 0) { gtk_main_quit (); // I don't think this is ever reached :) return FALSE; } return TRUE; } gboolean stack_notify_handler (Stack* self, const gchar* app_name, guint id, const gchar* icon, const gchar* summary, const gchar* body, gchar** actions, GHashTable* hints, gint timeout, DBusGMethodInvocation* context) { Bubble* bubble = NULL; Bubble* app_bubble = NULL; GValue* data = NULL; GValue* compat = NULL; GdkPixbuf* pixbuf = NULL; gboolean new_bubble = FALSE; gboolean turn_into_dialog; guint real_id; gchar *sender; // check max. allowed limit queue-size if (g_list_length (self->list) > MAX_STACK_SIZE) { GError* error = NULL; error = g_error_new (g_quark_from_string ("notify-osd"), 1, "Reached stack-limit of %d", MAX_STACK_SIZE); dbus_g_method_return_error (context, error); g_error_free (error); error = NULL; return TRUE; } // see if pathological actions or timeouts are used by an app issuing a // notification turn_into_dialog = dialog_check_actions_and_timeout (actions, timeout); if (turn_into_dialog) { // TODO: apport_report (app_name, summary, actions, timeout); gchar* sender = dbus_g_method_get_sender (context); fallback_dialog_show (self->defaults, sender, app_name, id, summary, body, actions); g_free (sender); dbus_g_method_return (context, id); return TRUE; } // check if a bubble exists with same id bubble = find_bubble_by_id (self, id); sender = dbus_g_method_get_sender (context); if (bubble) { if (g_strcmp0 (bubble_get_sender (bubble), sender) != 0) { // Another sender is trying to replace a notification, let's block it! id = 0; bubble = NULL; } } if (bubble == NULL) { new_bubble = TRUE; bubble = bubble_new (self->defaults); g_object_weak_ref (G_OBJECT (bubble), _weak_notify_cb, (gpointer) self); bubble_set_sender (bubble, sender); bubble_set_id (bubble, id); } g_free (sender); if (new_bubble && hints) { data = (GValue*) g_hash_table_lookup (hints, "x-canonical-append"); compat = (GValue*) g_hash_table_lookup (hints, "append"); if ((data && G_VALUE_HOLDS_STRING (data)) || (compat && G_VALUE_HOLDS_STRING (compat))) bubble_set_append (bubble, TRUE); else bubble_set_append (bubble, FALSE); } if (summary) bubble_set_title (bubble, summary); if (body) bubble_set_message_body (bubble, body); if (new_bubble && bubble_is_append_allowed(bubble)) { app_bubble = find_bubble_for_append(self, bubble); /* Appending to an old bubble */ if (app_bubble != NULL) { g_object_unref(bubble); bubble = app_bubble; if (body) { bubble_append_message_body (bubble, body); } } } real_id = bubble_get_id (bubble); if (hints) { data = (GValue*) g_hash_table_lookup (hints, "x-canonical-private-synchronous"); compat = (GValue*) g_hash_table_lookup (hints, "synchronous"); if ((data && G_VALUE_HOLDS_STRING (data)) || (compat && G_VALUE_HOLDS_STRING (compat))) { if (sync_bubble != NULL && IS_BUBBLE (sync_bubble)) { g_object_unref (bubble); bubble = sync_bubble; bubble_set_title (sync_bubble, summary ? summary : ""); bubble_set_message_body (sync_bubble, body ? body : ""); bubble_set_value (sync_bubble, -2); bubble_determine_layout (sync_bubble); } if (data && G_VALUE_HOLDS_STRING (data)) bubble_set_synchronous (bubble, g_value_get_string (data)); if (compat && G_VALUE_HOLDS_STRING (compat)) bubble_set_synchronous (bubble, g_value_get_string (compat)); } } if (hints) { data = (GValue*) g_hash_table_lookup (hints, "value"); if (data && G_VALUE_HOLDS_INT (data)) bubble_set_value (bubble, g_value_get_int (data)); } if (hints) { data = (GValue*) g_hash_table_lookup (hints, "urgency"); if (data && G_VALUE_HOLDS_UCHAR (data)) bubble_set_urgency (bubble, g_value_get_uchar (data)); /* Note: urgency was defined as an enum: LOW, NORMAL, CRITICAL So, 2 means CRITICAL */ } if (hints) { data = (GValue*) g_hash_table_lookup (hints, "x-canonical-private-icon-only"); compat = (GValue*) g_hash_table_lookup (hints, "icon-only"); if ((data && G_VALUE_HOLDS_STRING (data)) || (compat && G_VALUE_HOLDS_STRING (compat))) bubble_set_icon_only (bubble, TRUE); else bubble_set_icon_only (bubble, FALSE); } if (hints) { if ((data = (GValue*) g_hash_table_lookup (hints, "image_data"))) { g_debug("Using image_data hint\n"); pixbuf = process_dbus_icon_data (data); bubble_set_icon_from_pixbuf (bubble, pixbuf); } else if ((data = (GValue*) g_hash_table_lookup (hints, "image_path"))) { g_debug("Using image_path hint\n"); if ((data && G_VALUE_HOLDS_STRING (data))) bubble_set_icon (bubble, g_value_get_string(data)); else g_warning ("image_path hint is not a string\n"); } else if ((data = (GValue*) g_hash_table_lookup (hints, "image-path"))) { g_debug("Using image-path hint\n"); if ((data && G_VALUE_HOLDS_STRING (data))) bubble_set_icon (bubble, g_value_get_string(data)); else g_warning ("image-path hint is not a string\n"); } else if (icon && *icon != '\0') { g_debug("Using icon parameter\n"); bubble_set_icon (bubble, icon); } else if ((data = (GValue*) g_hash_table_lookup (hints, "icon_data"))) { g_debug("Using deprecated icon_data hint\n"); pixbuf = process_dbus_icon_data (data); bubble_set_icon_from_pixbuf (bubble, pixbuf); } } log_bubble_debug (bubble, app_name, (*icon == '\0' && data != NULL) ? "..." : icon); bubble_determine_layout (bubble); bubble_recalc_size (bubble); if (bubble_is_synchronous (bubble)) { stack_display_sync_bubble (self, bubble); } else { real_id = stack_push_bubble (self, bubble); if (! new_bubble && bubble_is_append_allowed (bubble)) log_bubble (bubble, app_name, "appended"); else if (! new_bubble) log_bubble (bubble, app_name, "replaced"); else log_bubble (bubble, app_name, ""); /* make sure the sync. bubble is positioned correctly even for the append case */ // no longer needed since we have the two-slots mechanism now //if (sync_bubble != NULL // && bubble_is_visible (sync_bubble)) // stack_display_position_sync_bubble (self, sync_bubble); /* update the layout of the stack; * this will also open the new bubble */ if (!stack_layout (self)) bubble = NULL; } dbus_g_method_return (context, real_id); // FIXME: this is a temporary work-around, I do not like at all, until // the heavy memory leakage of notify-osd is fully fixed... // after a threshold-value is reached, "arm" a forceful shutdown of // notify-osd (still allowing notifications in the queue, and coming in, // to be displayed), in order to get the leaked memory freed again, any // new notifications, coming in after the shutdown, will instruct the // session to restart notify-osd if (bubble_get_id (bubble) == FORCED_SHUTDOWN_THRESHOLD) g_timeout_add (defaults_get_on_screen_timeout (self->defaults), _arm_forced_quit, (gpointer) self); return TRUE; } gboolean stack_close_notification_handler (Stack* self, guint id, GError** error) { if (id == 0) g_warning ("%s(): notification id == 0, likely wrong\n", G_STRFUNC); Bubble* bubble = find_bubble_by_id (self, id); // exit but pretend it's ok, for applications // that call us after an action button was clicked if (bubble == NULL) return TRUE; dbus_send_close_signal (bubble_get_sender (bubble), bubble_get_id (bubble), 3); // do not trigger any closure of a notification-bubble here, as // this kind of control from outside (DBus) does not comply with // the notify-osd specification //bubble_hide (bubble); //g_object_unref (bubble); //stack_layout (self); return TRUE; } gboolean stack_get_capabilities (Stack* self, gchar*** out_caps) { *out_caps = g_malloc0 (13 * sizeof(char *)); (*out_caps)[0] = g_strdup ("body"); (*out_caps)[1] = g_strdup ("body-markup"); (*out_caps)[2] = g_strdup ("icon-static"); (*out_caps)[3] = g_strdup ("image/svg+xml"); (*out_caps)[4] = g_strdup ("x-canonical-private-synchronous"); (*out_caps)[5] = g_strdup ("x-canonical-append"); (*out_caps)[6] = g_strdup ("x-canonical-private-icon-only"); (*out_caps)[7] = g_strdup ("x-canonical-truncation"); /* a temp. compatibility-check for the transition time to allow apps a ** grace-period to catch up with the capability- and hint-name-changes ** introduced with notify-osd rev. 224 */ (*out_caps)[8] = g_strdup ("private-synchronous"); (*out_caps)[9] = g_strdup ("append"); (*out_caps)[10] = g_strdup ("private-icon-only"); (*out_caps)[11] = g_strdup ("truncation"); (*out_caps)[12] = NULL; return TRUE; } gboolean stack_get_server_information (Stack* self, gchar** out_name, gchar** out_vendor, gchar** out_version, gchar** out_spec_ver) { *out_name = g_strdup ("notify-osd"); *out_vendor = g_strdup ("Canonical Ltd"); *out_version = g_strdup ("1.0"); *out_spec_ver = g_strdup ("1.1"); return TRUE; } gboolean stack_is_slot_vacant (Stack* self, Slot slot) { // sanity checks if (!self || !IS_STACK (self)) return FALSE; if (slot != SLOT_TOP && slot != SLOT_BOTTOM) return FALSE; return self->slots[slot] == NULL ? VACANT : OCCUPIED; } // return values of -1 for x and y indicate an error by the caller void stack_get_slot_position (Stack* self, Slot slot, gint bubble_height, gint* x, gint* y) { GdkScreen* screen = NULL; gboolean is_composited = FALSE; // sanity checks if (!x && !y) return; if (!self || !IS_STACK (self)) { *x = -1; *y = -1; return; } if (slot != SLOT_TOP && slot != SLOT_BOTTOM) { *x = -1; *y = -1; return; } // initialize x and y defaults_get_top_corner (self->defaults, &screen, x, y); is_composited = gdk_screen_is_composited (screen); // differentiate returned top-left corner for top and bottom slot // depending on the placement switch (defaults_get_gravity (self->defaults)) { Defaults* d; case GRAVITY_EAST: d = self->defaults; // the position for the sync./feedback bubble if (slot == SLOT_TOP) *y += defaults_get_desktop_height (d) / 2 - EM2PIXELS (defaults_get_bubble_vert_gap (d) / 2.0f, d) - bubble_height + EM2PIXELS (defaults_get_bubble_shadow_size (d, is_composited), d); // the position for the async. bubble else if (slot == SLOT_BOTTOM) *y += defaults_get_desktop_height (d) / 2 + EM2PIXELS (defaults_get_bubble_vert_gap (d) / 2.0f, d) - EM2PIXELS (defaults_get_bubble_shadow_size (d, is_composited), d); break; case GRAVITY_NORTH_EAST: d = self->defaults; // there's nothing to do for slot == SLOT_TOP as we // already have correct x and y from the call to // defaults_get_top_corner() earlier // this needs to look at the height of the bubble in the // top slot if (slot == SLOT_BOTTOM) { switch (defaults_get_slot_allocation (d)) { case SLOT_ALLOCATION_FIXED: *y += EM2PIXELS (defaults_get_icon_size (d), d) + 2 * EM2PIXELS (defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_bubble_vert_gap (d), d); /* + 2 * EM2PIXELS (defaults_get_bubble_shadow_size (d, is_composited), d);*/ break; case SLOT_ALLOCATION_DYNAMIC: g_assert (stack_is_slot_vacant (self, SLOT_TOP) == OCCUPIED); *y += bubble_get_height (self->slots[SLOT_TOP]) + EM2PIXELS (defaults_get_bubble_vert_gap (d), d) - 2 * EM2PIXELS (defaults_get_bubble_shadow_size (d, is_composited), d); break; default: break; } } break; default: g_warning ("Unhandled placement!\n"); break; } } // call this _before_ the fade-in animation of the bubble starts gboolean stack_allocate_slot (Stack* self, Bubble* bubble, Slot slot) { // sanity checks if (!self || !IS_STACK (self)) return FALSE; if (!bubble || !IS_BUBBLE (bubble)) return FALSE; if (slot != SLOT_TOP && slot != SLOT_BOTTOM) return FALSE; if (stack_is_slot_vacant (self, slot)) self->slots[slot] = BUBBLE (g_object_ref ((gpointer) bubble)); else return FALSE; return TRUE; } // call this _after_ the fade-out animation of the bubble is finished gboolean stack_free_slot (Stack* self, Bubble* bubble) { // sanity checks if (!self || !IS_STACK (self)) return FALSE; if (!bubble || !IS_BUBBLE (bubble)) return FALSE; // check top and bottom slots for bubble pointer equality if (bubble == self->slots[SLOT_TOP]) { g_object_unref (self->slots[SLOT_TOP]); self->slots[SLOT_TOP] = NULL; } else if (bubble == self->slots[SLOT_BOTTOM]) { g_object_unref (self->slots[SLOT_BOTTOM]); self->slots[SLOT_BOTTOM] = NULL; } else return FALSE; return TRUE; } ./src/bubble-window-accessible.h0000644000004100000410000000467013570225707017055 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window-accessible.h - implements an accessible bubble window ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef _BUBBLE_WINDOW_ACCESSIBLE_H_ #define _BUBBLE_WINDOW_ACCESSIBLE_H_ #include #include #include "bubble-window.h" G_BEGIN_DECLS #define BUBBLE_WINDOW_TYPE_ACCESSIBLE (bubble_window_accessible_get_type ()) #define BUBBLE_WINDOW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE, BubbleWindowAccessible)) #define BUBBLE_WINDOW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BUBBLE_WINDOW_TYPE_ACCESSIBLE, BubbleWindowAccessibleClass)) #define BUBBLE_WINDOW_IS_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE)) #define BUBBLE_WINDOW_IS_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BUBBLE_WINDOW_TYPE_ACCESSIBLE)) #define BUBBLE_WINDOW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE, BubbleWindowAccessibleClass)) typedef struct _BubbleWindowAccessibleClass BubbleWindowAccessibleClass; typedef struct _BubbleWindowAccessible BubbleWindowAccessible; struct _BubbleWindowAccessibleClass { GtkAccessibleClass parent_class; }; struct _BubbleWindowAccessible { GtkAccessible parent_instance; }; GType bubble_window_accessible_get_type (void); AtkObject* bubble_window_accessible_new (GtkWidget *widget); G_END_DECLS #endif /* _BUBBLE_WINDOW_ACCESSIBLE_H_ */ ./src/notification.h0000644000004100000410000001016013570225707014677 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // notification.h - notification object storing attributes like title- and body- // text, value, icon, id, sender-pid etc. // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef __NOTIFICATION_H #define __NOTIFICATION_H #include #include G_BEGIN_DECLS #define NOTIFICATION_TYPE (notification_get_type ()) #define NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NOTIFICATION_TYPE, Notification)) #define NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NOTIFICATION_TYPE, NotificationClass)) #define IS_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NOTIFICATION_TYPE)) #define IS_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NOTIFICATION_TYPE)) #define NOTIFICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NOTIFICATION_TYPE, NotificationClass)) #define NOTIFICATION_VALUE_MIN_ALLOWED -1 #define NOTIFICATION_VALUE_MAX_ALLOWED 101 typedef struct _Notification Notification; typedef struct _NotificationClass NotificationClass; typedef struct _NotificationPrivate NotificationPrivate; typedef enum { URGENCY_LOW = 0, URGENCY_NORMAL, URGENCY_HIGH, URGENCY_NONE } Urgency; // instance structure struct _Notification { GObject parent; //< private > NotificationPrivate* priv; }; // class structure struct _NotificationClass { GObjectClass parent; //< signals > }; GType Notification_get_type (void); Notification* notification_new (); gint notification_get_id (Notification* n); void notification_set_id (Notification* n, const gint id); gchar* notification_get_title (Notification* n); void notification_set_title (Notification* n, const gchar* title); gchar* notification_get_body (Notification* n); void notification_set_body (Notification* n, const gchar* body); gint notification_get_value (Notification* n); void notification_set_value (Notification* n, const gint value); gchar* notification_get_icon_themename (Notification* n); void notification_set_icon_themename (Notification* n, const gchar* icon_themename); gchar* notification_get_icon_filename (Notification* n); void notification_set_icon_filename (Notification* n, const gchar* icon_filename); GdkPixbuf* notification_get_icon_pixbuf (Notification* n); void notification_set_icon_pixbuf (Notification* n, const GdkPixbuf* icon_pixbuf); gint notification_get_onscreen_time (Notification* n); void notification_set_onscreen_time (Notification* n, const gint onscreen_time); gchar* notification_get_sender_name (Notification* n); void notification_set_sender_name (Notification* n, const gchar* sender_name); gint notification_get_sender_pid (Notification* n); void notification_set_sender_pid (Notification* n, const gint sender_pid); GTimeVal* notification_get_timestamp (Notification* n); void notification_set_timestamp (Notification* n, const GTimeVal* timestamp); gint notification_get_urgency (Notification* n); void notification_set_urgency (Notification* n, const Urgency urgency); G_END_DECLS #endif // __NOTIFICATION_H ./src/observer.c0000644000004100000410000001070213570225707014035 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** observer.c - meant to be a singelton watching for mouse-over-bubble cases ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include "observer.h" G_DEFINE_TYPE (Observer, observer, G_TYPE_OBJECT); enum { PROP_DUMMY = 0, PROP_X, PROP_Y }; /*-- internal API ------------------------------------------------------------*/ static void observer_dispose (GObject* gobject) { /* chain up to the parent class */ G_OBJECT_CLASS (observer_parent_class)->dispose (gobject); } static void observer_finalize (GObject* gobject) { /* chain up to the parent class */ G_OBJECT_CLASS (observer_parent_class)->finalize (gobject); } static void observer_init (Observer* self) { /* this should not be here, but I don't know yet how do deal with ** the distinction between class-members and instance-members ** also I do not know if an instance can have properties too or ** only a class */ self->window = NULL; self->timeout_frequency = 0; self->timeout_id = 0; self->pointer_x = 0; self->pointer_y = 0; /* If you need specific construction properties to complete ** initialization, delay initialization completion until the ** property is set. */ } static void observer_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { Observer* observer; observer = OBSERVER (gobject); switch (prop) { case PROP_X: g_value_set_int (value, observer->pointer_x); break; case PROP_Y: g_value_set_int (value, observer->pointer_y); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void observer_set_property (GObject* gobject, guint prop, const GValue* value, GParamSpec* spec) { Observer* observer; observer = OBSERVER (gobject); switch (prop) { case PROP_X: observer->pointer_x = g_value_get_int (value); break; case PROP_Y: observer->pointer_y = g_value_get_int (value); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void observer_class_init (ObserverClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); GParamSpec* property_x; GParamSpec* property_y; gobject_class->dispose = observer_dispose; gobject_class->finalize = observer_finalize; gobject_class->get_property = observer_get_property; gobject_class->set_property = observer_set_property; property_x = g_param_spec_int ( "pointer-x", "pointer-x", "X-coord. of mouse pointer", 0, 4096, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_X, property_x); property_y = g_param_spec_int ( "pointer-y", "pointer-y", "Y-coord. of mouse pointer", 0, 4096, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_Y, property_y); } /*-- public API --------------------------------------------------------------*/ Observer* observer_new (void) { Observer* this = g_object_new (OBSERVER_TYPE, NULL); return this; } void observer_del (Observer* self) { g_object_unref (self); } gint observer_get_x (Observer* self) { gint x; g_object_get (self, "pointer-x", &x, NULL); return x; } gint observer_get_y (Observer* self) { gint y; g_object_get (self, "pointer-y", &y, NULL); return y; } ./src/stack-blur.h0000644000004100000410000000257113570225707014267 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // stack-blur.h - implements stack-blur function // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // based on stack-blur algorithm by Mario Klingemann // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef _STACK_BLUR_H #define _STACK_BLUR_H #include #include void surface_stack_blur (cairo_surface_t* surface, guint radius); #endif // _STACK_BLUR_H ./src/send-test-notification.sh0000755000004100000410000000442113570225707016774 0ustar www-datawww-data#!/bin/sh notify-send "Take note" "The next example will test the icon-only layout-case" -i dialog-info sleep 2 notify-send "Eject" -i notification-device-eject -h string:x-canonical-private-icon-only: sleep 2 notify-send "WiFi signal found" -i notification-network-wireless-medium sleep 2 notify-send "WiFi signal lost" -i notification-network-wireless-disconnected sleep 2 notify-send "Volume" -i notification-audio-volume-medium -h int:value:75 -h string:x-canonical-private-synchronous: sleep 2 notify-send "Volume" -i notification-audio-volume-low -h int:value:30 -h string:x-canonical-private-synchronous: sleep 2 notify-send "Brightness" -i notification-display-brightness-high -h int:value:101 -h string:x-canonical-private-synchronous: sleep 2 notify-send "Brightness" -i notification-keyboard-brightness-medium -h int:value:45 -h string:x-canonical-private-synchronous: sleep 2 notify-send "Testing markup" "Some bold, underlined, italic text. Note, you should not see any marked up text." sleep 2 notify-send "Jamshed Kakar" "Hey, what about this restaurant? http://www.blafasel.org Would you go from your place by train or should I pick you up from work? What do you think?" sleep 2 notify-send "English bubble" "The quick brown fox jumps over the lazy dog." -i network sleep 2 notify-send "Bubble from Germany" "Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark." -i gnome-system sleep 2 notify-send "Very russian" "Съешь ещё этих мягких французских булок, да выпей чаю." -i dialog-info sleep 2 notify-send "More from Germany" "Oje, Qualm verwölkt Dix zig Farbtriptychons." -i gnome-globe sleep 2 notify-send "Filter the world 1/3" "Ubuntu Don't rock the boat Kick him while he's down \"Film spectators are quiet vampires.\" Peace & Love War & Peace Law & Order Love & War 7 > 3 7 > 3" sleep 2 notify-send "Filter the world 2/3" "7 > 3 7 > 3 14 < 42 14 < 42 14 < 42 14 < 42 >< <> < this is not a tag > Not italic" sleep 2 notify-send "Filter the world 3/3" "So broken Nothing to see Test Bold Span E-flat Sandwich Fry Testing tag" ./src/dialog.h0000644000004100000410000000312313570225707013451 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // dialog.h - fallback to display when a notification is not spec-compliant // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // David Barth // // Contributor(s): // Abhishek Mukherjee (append fixes, rev. 280) // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef __DIALOG_H #define __DIALOG_H #include #include "defaults.h" void fallback_dialog_show (Defaults* defaults, const gchar* sender, const gchar* app_name, int id, const gchar* summary, const gchar* body, gchar** actions); #endif // __DIALOG_H ./src/timings.h0000644000004100000410000000466313570225707013676 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // timings.h - timings object handling duration and max. on-screen time // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #ifndef __TIMINGS_H #define __TIMINGS_H #include G_BEGIN_DECLS #define TIMINGS_TYPE (timings_get_type ()) #define TIMINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIMINGS_TYPE, Timings)) #define TIMINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIMINGS_TYPE, TimingsClass)) #define IS_TIMINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIMINGS_TYPE)) #define IS_TIMINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIMINGS_TYPE)) #define TIMINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIMINGS_TYPE, TimingsClass)) typedef struct _Timings Timings; typedef struct _TimingsClass TimingsClass; typedef struct _TimingsPrivate TimingsPrivate; // instance structure struct _Timings { GObject parent; //< private > TimingsPrivate* priv; }; // class structure struct _TimingsClass { GObjectClass parent; //< signals > void (*completed) (Timings* timings); void (*limit_reached) (Timings* timings); }; GType timings_get_type (void); Timings* timings_new (guint scheduled_duration, guint max_duration); gboolean timings_start (Timings* t); gboolean timings_stop (Timings* t); gboolean timings_pause (Timings* t); gboolean timings_continue (Timings* t); gboolean timings_extend (Timings* t, guint extension); G_END_DECLS #endif // __TIMINGS_H ./src/main.c0000644000004100000410000000510413570225707013132 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** main.c - pulling it all together ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #include "defaults.h" #include "stack.h" #include "observer.h" #include "dbus.h" #include "log.h" #define ICONS_DIR (DATADIR G_DIR_SEPARATOR_S "notify-osd" G_DIR_SEPARATOR_S "icons") int main (int argc, char** argv) { Defaults* defaults = NULL; Stack* stack = NULL; Observer* observer = NULL; DBusGConnection* connection = NULL; dbus_g_thread_init (); log_init (); gtk_init (&argc, &argv); /* Init some theme/icon stuff */ gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), ICONS_DIR); defaults = defaults_new (); observer = observer_new (); stack = stack_new (defaults, observer); connection = dbus_create_service_instance (DBUS_NAME); if (connection == NULL) { g_warning ("Could not register instance"); stack_del (stack); return 0; } DBusGProxy* proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus"); dbus_g_proxy_add_signal (proxy, "NameLost", G_TYPE_STRING, G_TYPE_INVALID); dbus_g_proxy_connect_signal (proxy, "NameLost", gtk_main_quit, NULL, NULL); dbus_g_connection_register_g_object (connection, DBUS_PATH, G_OBJECT (stack)); gtk_main (); stack_del (stack); g_object_unref (proxy); return 0; } ./src/bubble.c0000644000004100000410000027424213570225707013454 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // bubble.c - implements all the rendering of a notification bubble // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // David Barth // // Contributor(s): // Frederic "fredp" Peters (icon-only fix, rev. 204) // Eitan Isaacson (ATK interface for a11y, rev. 351) // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include //#include #include #include #include #include #include "bubble.h" #include "defaults.h" #include "stack.h" #include "dbus.h" #include "util.h" #include "bubble-window.h" #include "raico-blur.h" #include "tile.h" struct _BubblePrivate { BubbleLayout layout; GtkWidget* widget; gboolean visible; guint timer_id; gboolean mouse_over; gfloat distance; gchar* synchronous; gboolean composited; EggAlpha* alpha; EggTimeline* timeline; guint draw_handler_id; guint pointer_update_id; tile_t* tile_background_part; tile_t* tile_background; tile_t* tile_icon; tile_t* tile_title; tile_t* tile_body; tile_t* tile_indicator; gint title_width; gint title_height; gint body_width; gint body_height; gboolean append; gboolean icon_only; gint future_height; gboolean prevent_fade; // these will be replaced by class Notification later on GString* title; GString* message_body; gboolean title_needs_refresh; gboolean message_body_needs_refresh; guint id; GdkPixbuf* icon_pixbuf; gint value; // "empty": -2, valid range: -1..101, -1/101 trigger "over/undershoot"-effect gchar* sender; guint timeout; guint urgency; //notification_t* notification; // used to prevent unneeded updates of the tile-cache, for append-, // update or replace-cases, needs to move into class Notification gchar * old_icon_filename; }; G_DEFINE_TYPE_WITH_PRIVATE (Bubble, bubble, G_TYPE_OBJECT); enum { TIMED_OUT, VALUE_CHANGED, MESSAGE_BODY_DELETED, MESSAGE_BODY_INSERTED, LAST_SIGNAL }; enum { R = 0, G, B, A }; typedef struct _NotifyHSVColor NotifyHSVColor; struct _NotifyHSVColor { gdouble hue; gdouble saturation; gdouble value; }; // FIXME: this is in class Defaults already, but not yet hooked up so for the // moment we use the macros here, these values reflect the visual-guideline // for jaunty notifications #define TEXT_TITLE_COLOR_R 1.0f #define TEXT_TITLE_COLOR_G 1.0f #define TEXT_TITLE_COLOR_B 1.0f #define TEXT_TITLE_COLOR_A 1.0f #define TEXT_BODY_COLOR_R 0.91f #define TEXT_BODY_COLOR_G 0.91f #define TEXT_BODY_COLOR_B 0.91f #define TEXT_BODY_COLOR_A 1.0f #define TEXT_SHADOW_COLOR_R 0.0f #define TEXT_SHADOW_COLOR_G 0.0f #define TEXT_SHADOW_COLOR_B 0.0f #define TEXT_SHADOW_COLOR_A 1.0f #define BUBBLE_BG_COLOR_R 0.15f #define BUBBLE_BG_COLOR_G 0.15f #define BUBBLE_BG_COLOR_B 0.15f #define BUBBLE_BG_COLOR_A 0.9f #define INDICATOR_UNLIT_R 1.0f #define INDICATOR_UNLIT_G 1.0f #define INDICATOR_UNLIT_B 1.0f #define INDICATOR_UNLIT_A 0.3f #define INDICATOR_LIT_R 1.0f #define INDICATOR_LIT_G 1.0f #define INDICATOR_LIT_B 1.0f #define INDICATOR_LIT_A 1.0f #define FPS 60 #define PROXIMITY_THRESHOLD 40 #define WINDOW_MIN_OPACITY 0.4f #define WINDOW_MAX_OPACITY 1.0f // text drop-shadow should _never_ be bigger than content blur-radius!!! #define BUBBLE_CONTENT_BLUR_RADIUS 4 #define TEXT_DROP_SHADOW_SIZE 2 //-- private functions --------------------------------------------------------- static guint g_bubble_signals[LAST_SIGNAL] = { 0 }; gint g_pointer[2]; static cairo_surface_t * bubble_create_image_surface (Bubble* self, cairo_format_t format, gint width, gint height) { cairo_surface_t *surface; gint scale; scale = gtk_widget_get_scale_factor (self->priv->widget); surface = cairo_image_surface_create (format, scale * width, scale * height); cairo_surface_set_device_scale (surface, scale, scale); return surface; } static void draw_round_rect (cairo_t* cr, gdouble aspect, // aspect-ratio gdouble x, // top-left corner gdouble y, // top-left corner gdouble corner_radius, // "size" of the corners gdouble width, // width of the rectangle gdouble height) // height of the rectangle { gdouble radius = corner_radius / aspect; // top-left, right of the corner cairo_move_to (cr, x + radius, y); // top-right, left of the corner cairo_line_to (cr, x + width - radius, y); // top-right, below the corner cairo_arc (cr, x + width - radius, y + radius, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); // bottom-right, above the corner cairo_line_to (cr, x + width, y + height - radius); // bottom-right, left of the corner cairo_arc (cr, x + width - radius, y + height - radius, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); // bottom-left, right of the corner cairo_line_to (cr, x + radius, y + height); // bottom-left, above the corner cairo_arc (cr, x + radius, y + height - radius, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); // top-left, below the corner cairo_line_to (cr, x, y + radius); // top-left, right of the corner cairo_arc (cr, x + radius, y + radius, radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); } // color-, alpha-, radius-, width-, height- and gradient-values were determined // by very close obvervation of a SVG-mockup from the design-team static void _draw_value_indicator (cairo_t* cr, gint value, // value to render: 0 - 100 gint start_x, // top of surrounding rect gint start_y, // left of surrounding rect gint width, // width of surrounding rect gint height, // height of surrounding rect gint outline_thickness) // outline-thickness { gdouble outline_radius; gdouble outline_width; gdouble outline_height; gdouble bar_radius; gdouble bar_width; //gdouble bar_height; cairo_pattern_t* gradient; outline_radius = outline_thickness; outline_width = width; outline_height = height; // draw bar-background cairo_set_line_width (cr, outline_thickness); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.5f); draw_round_rect (cr, 1.0f, start_x, start_y, outline_radius, outline_width, outline_height); cairo_fill (cr); gradient = cairo_pattern_create_linear (0.0f, start_y + outline_thickness, 0.0f, start_y + outline_height - 2 * outline_thickness); cairo_pattern_add_color_stop_rgba (gradient, 0.0f, 0.866f, 0.866f, 0.866f, 0.3f); cairo_pattern_add_color_stop_rgba (gradient, 0.2f, 0.827f, 0.827f, 0.827f, 0.3f); cairo_pattern_add_color_stop_rgba (gradient, 0.3f, 0.772f, 0.772f, 0.772f, 0.3f); cairo_pattern_add_color_stop_rgba (gradient, 1.0f, 0.623f, 0.623f, 0.623f, 0.3f); cairo_set_source (cr, gradient); draw_round_rect (cr, 1.0f, start_x + outline_thickness, start_y + outline_thickness, outline_radius, outline_width - 2 * outline_thickness, outline_height - 2 * outline_thickness); cairo_fill (cr); cairo_pattern_destroy (gradient); bar_radius = outline_radius; bar_width = outline_width - 2 * outline_radius; //bar_height = outline_height - outline_radius; // draw value-bar if (value > 0) { gint corrected_value = value; if (corrected_value > 100) corrected_value = 100; draw_round_rect (cr, 1.0f, start_x + outline_thickness, start_y + outline_thickness, bar_radius, bar_width / 100.0f * (gdouble) corrected_value, outline_height - 2 * outline_thickness); gradient = cairo_pattern_create_linear (0.0f, start_y + outline_thickness, 0.0f, start_y + outline_height - 2 * outline_thickness); cairo_pattern_add_color_stop_rgba (gradient, 0.0f, 0.9f, 0.9f, 0.9f, 1.0f); cairo_pattern_add_color_stop_rgba (gradient, 0.75f, 0.5f, 0.5f, 0.5f, 1.0f); cairo_pattern_add_color_stop_rgba (gradient, 1.0f, 0.4f, 0.4f, 0.4f, 1.0f); cairo_set_source (cr, gradient); cairo_fill (cr); cairo_pattern_destroy (gradient); } } void _draw_shadow (Bubble* self, cairo_t* cr, gdouble width, gdouble height, gint shadow_radius, gint corner_radius) { cairo_surface_t* tmp_surface = NULL; cairo_surface_t* new_surface = NULL; cairo_pattern_t* pattern = NULL; cairo_t* cr_surf = NULL; cairo_matrix_t matrix; raico_blur_t* blur = NULL; double x_scale; double y_scale; tmp_surface = bubble_create_image_surface (self, CAIRO_FORMAT_ARGB32, 4 * shadow_radius, 4 * shadow_radius); if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS) { if (tmp_surface) cairo_surface_destroy (tmp_surface); return; } cr_surf = cairo_create (tmp_surface); if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); if (cr_surf) cairo_destroy (cr_surf); return; } cairo_scale (cr_surf, 1.0f, 1.0f); cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR); cairo_paint (cr_surf); cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 1.0f); cairo_arc (cr_surf, 2 * shadow_radius, 2 * shadow_radius, 1.75f * corner_radius, 0.0f, 360.0f * (G_PI / 180.f)); cairo_fill (cr_surf); cairo_destroy (cr_surf); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_HIGH); raico_blur_set_radius (blur, shadow_radius); // now blur it raico_blur_apply (blur, tmp_surface); // blur no longer needed raico_blur_destroy (blur); new_surface = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (tmp_surface), cairo_image_surface_get_format (tmp_surface), cairo_image_surface_get_width (tmp_surface) / 2, cairo_image_surface_get_height (tmp_surface) / 2, cairo_image_surface_get_stride (tmp_surface)); cairo_surface_get_device_scale (tmp_surface, &x_scale, &y_scale); cairo_surface_set_device_scale (new_surface, x_scale, y_scale); pattern = cairo_pattern_create_for_surface (new_surface); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); if (pattern) cairo_pattern_destroy (pattern); return; } // top left cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0.0f, 0.0f, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0.0f, 2 * shadow_radius, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - 2 * shadow_radius, 0.0f, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -width, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 2 * shadow_radius, height - 2 * shadow_radius, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // clean up cairo_pattern_destroy (pattern); cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); } static gdouble get_shadow_size (Bubble *bubble) { BubblePrivate* priv = bubble->priv; Defaults* d = bubble->defaults; return defaults_get_bubble_shadow_size (d, priv->composited); } static gdouble get_corner_radius (Bubble *bubble) { BubblePrivate* priv = bubble->priv; Defaults* d = bubble->defaults; return defaults_get_bubble_corner_radius (d, priv->composited); } static void _draw_layout_grid (cairo_t* cr, Bubble* bubble) { Defaults* d = bubble->defaults; if (!cr) return; cairo_set_line_width (cr, 1.0f); cairo_set_source_rgba (cr, 1.0f, 0.5f, 0.25f, 1.0f); // all vertical grid lines cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (2 * defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (2 * defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d) - EM2PIXELS (defaults_get_margin_size (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d) - EM2PIXELS (defaults_get_margin_size (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); // all horizontal grid lines cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_margin_size (d), d) + EM2PIXELS (defaults_get_icon_size (d), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d) - EM2PIXELS (defaults_get_margin_size (d), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d) - EM2PIXELS (defaults_get_margin_size (d), d)); cairo_move_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_line_to (cr, 0.5f + EM2PIXELS (get_shadow_size (bubble), d) + EM2PIXELS (defaults_get_bubble_width (d), d), 0.5f + (gdouble) bubble_get_height (bubble) - EM2PIXELS (get_shadow_size (bubble), d)); cairo_stroke (cr); } void _refresh_background (Bubble* self) { BubblePrivate* priv = self->priv; Defaults* d = self->defaults; cairo_t* cr = NULL; cairo_surface_t* scratch = NULL; cairo_surface_t* clone = NULL; cairo_surface_t* normal = NULL; cairo_surface_t* blurred = NULL; raico_blur_t* blur = NULL; gint width; gint height; gint scratch_shadow_size; bubble_get_size (self, &width, &height); // create temp. scratch surface for top-left shadow/background part if (priv->composited) { scratch_shadow_size = EM2PIXELS (get_shadow_size (self), d); scratch = bubble_create_image_surface ( self, CAIRO_FORMAT_ARGB32, 3 * scratch_shadow_size, 3 * scratch_shadow_size); } else { // We must have at least some width to this scratch surface. scratch_shadow_size = 1; scratch = bubble_create_image_surface ( self, CAIRO_FORMAT_RGB24, 3 * scratch_shadow_size, 3 * scratch_shadow_size); } g_return_if_fail (scratch); if (cairo_surface_status (scratch) != CAIRO_STATUS_SUCCESS) { if (scratch) cairo_surface_destroy (scratch); return; } // create drawing context for that temp. scratch surface cr = cairo_create (scratch); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (scratch); if (cr) cairo_destroy (cr); return; } // clear, render top-left part of shadow/background in scratch-surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); GdkRGBA color; gchar* color_string = NULL; color_string = defaults_get_bubble_bg_color (d); gdk_rgba_parse (&color, color_string); g_free (color_string); // Apply color tweaks NotifyHSVColor hsv_color; gtk_rgb_to_hsv (color.red, color.green, color.blue, &hsv_color.hue, &hsv_color.saturation, &hsv_color.value); hsv_color.saturation *= (2.0f - hsv_color.saturation); hsv_color.value = MIN (hsv_color.value, 0.4f); gtk_hsv_to_rgb (hsv_color.hue, hsv_color.saturation, hsv_color.value, &color.red, &color.green, &color.blue); if (priv->composited) { _draw_shadow ( self, cr, width, height, EM2PIXELS (get_shadow_size (self), d), EM2PIXELS (get_corner_radius (self), d)); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); draw_round_rect ( cr, 1.0f, EM2PIXELS (get_shadow_size (self), d), EM2PIXELS (get_shadow_size (self), d), EM2PIXELS (get_corner_radius (self), d), EM2PIXELS (defaults_get_bubble_width (d), d), (gdouble) bubble_get_height (self) - 2.0f * EM2PIXELS (get_shadow_size (self), d)); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, color.red, color.green, color.blue, BUBBLE_BG_COLOR_A); } else cairo_set_source_rgb (cr, color.red, color.green, color.blue); draw_round_rect ( cr, 1.0f, EM2PIXELS (get_shadow_size (self), d), EM2PIXELS (get_shadow_size (self), d), EM2PIXELS (get_corner_radius (self), d), EM2PIXELS (defaults_get_bubble_width (d), d), (gdouble) bubble_get_height (self) - 2.0f * EM2PIXELS (get_shadow_size (self), d)); cairo_fill (cr); cairo_destroy (cr); // create temp. clone of scratch surface clone = copy_surface (scratch); // create normal surface from that surface-clone normal = copy_surface (clone); // now blur the surface-clone blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, BUBBLE_CONTENT_BLUR_RADIUS); raico_blur_apply (blur, clone); raico_blur_destroy (blur); // create blurred version from that blurred surface-clone blurred = copy_surface (clone); cairo_surface_destroy (clone); // finally create tile with top-left shadow/background part if (priv->tile_background_part) tile_destroy (priv->tile_background_part); priv->tile_background_part = tile_new_for_padding (normal, blurred, 3 * scratch_shadow_size, 3 * scratch_shadow_size); cairo_surface_destroy (normal); cairo_surface_destroy (blurred); // create surface(s) for full shadow/background tile if (priv->composited) { // we need two RGBA-surfaces normal = bubble_create_image_surface (self, CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (scratch); if (normal) cairo_surface_destroy (normal); return; } blurred = bubble_create_image_surface (self, CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (blurred) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); cairo_surface_destroy (scratch); if (blurred) cairo_surface_destroy (blurred); return; } } else { // we need only one RGB-surface normal = bubble_create_image_surface (self, CAIRO_FORMAT_RGB24, width, height); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (scratch); if (normal) cairo_surface_destroy (normal); return; } } // use tile for top-left background-part to fill the full bg-surface if (priv->composited) { // create context for blurred surface cr = cairo_create (blurred); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); cairo_surface_destroy (blurred); cairo_surface_destroy (scratch); if (cr) cairo_destroy (cr); return; } // clear blurred surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // fill with blurred state of background-part tile tile_paint_with_padding (priv->tile_background_part, cr, 0.0f, 0.0f, width, height, 0.0f, 1.0f); // get rid of context for blurred surface cairo_destroy (cr); } // create context for normal surface cr = cairo_create (normal); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); cairo_surface_destroy (scratch); if (priv->composited) cairo_surface_destroy (blurred); return; } // clear normal surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // fill with normal state of background-part tile tile_paint_with_padding (priv->tile_background_part, cr, 0.0f, 0.0f, width, height, 1.0f, 0.0f); // get rid of context for normal surface cairo_destroy (cr); // finally create tile for full background if (priv->tile_background) tile_destroy (priv->tile_background); if (priv->composited) priv->tile_background = tile_new_for_padding (normal, blurred, width, height); else priv->tile_background = tile_new_for_padding (normal, normal, width, height); // clean up if (priv->composited) cairo_surface_destroy (blurred); cairo_surface_destroy (normal); cairo_surface_destroy (scratch); } void _refresh_icon (Bubble* self) { BubblePrivate* priv = self->priv; Defaults* d = self->defaults; cairo_surface_t* normal = NULL; cairo_surface_t* icon_surface = NULL; cairo_t* cr = NULL; if (!priv->icon_pixbuf) return; // create temp. scratch surface normal = bubble_create_image_surface ( self, CAIRO_FORMAT_ARGB32, EM2PIXELS (defaults_get_icon_size (d), d) + 2 * BUBBLE_CONTENT_BLUR_RADIUS, EM2PIXELS (defaults_get_icon_size (d), d) + 2 * BUBBLE_CONTENT_BLUR_RADIUS); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) return; // create context for normal surface cr = cairo_create (normal); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); return; } // clear normal surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // render icon into normal surface icon_surface = gdk_cairo_surface_create_from_pixbuf (priv->icon_pixbuf, 0, gtk_widget_get_window (priv->widget)); cairo_set_source_surface (cr, icon_surface, BUBBLE_CONTENT_BLUR_RADIUS, BUBBLE_CONTENT_BLUR_RADIUS); cairo_paint (cr); // create the surface/blur-cache from the normal surface if (priv->tile_icon) tile_destroy (priv->tile_icon); priv->tile_icon = tile_new (normal, BUBBLE_CONTENT_BLUR_RADIUS/2); // clean up cairo_destroy (cr); cairo_surface_destroy (icon_surface); cairo_surface_destroy (normal); } void _refresh_title (Bubble* self) { BubblePrivate* priv = self->priv; Defaults* d = self->defaults; cairo_surface_t* normal = NULL; cairo_t* cr = NULL; PangoFontDescription* desc = NULL; PangoLayout* layout = NULL; raico_blur_t* blur = NULL; gchar* text_font_face = NULL; // create temp. scratch surface normal = bubble_create_image_surface ( self, CAIRO_FORMAT_ARGB32, priv->title_width + 2 * BUBBLE_CONTENT_BLUR_RADIUS, priv->title_height + 2 * BUBBLE_CONTENT_BLUR_RADIUS); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) return; // create context for normal surface cr = cairo_create (normal); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); return; } // clear normal surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // create pango desc/layout layout = pango_cairo_create_layout (cr); text_font_face = defaults_get_text_font_face (d); desc = pango_font_description_from_string (text_font_face); g_free ((gpointer) text_font_face); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_title_size (d) * PANGO_SCALE); pango_font_description_set_weight (desc, defaults_get_text_title_weight (d)); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_width (layout, priv->title_width * PANGO_SCALE); pango_layout_set_height (layout, priv->title_height * PANGO_SCALE); // print and layout string (pango-wise) pango_layout_set_text (layout, priv->title->str, priv->title->len); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options ( pango_layout_get_context (layout), gdk_screen_get_font_options ( gtk_widget_get_screen (priv->widget))); pango_cairo_context_set_resolution (pango_layout_get_context (layout), defaults_get_screen_dpi (d)); pango_layout_context_changed (layout); // draw text for drop-shadow and ... cairo_move_to (cr, BUBBLE_CONTENT_BLUR_RADIUS, BUBBLE_CONTENT_BLUR_RADIUS); cairo_set_source_rgba (cr, TEXT_SHADOW_COLOR_R, TEXT_SHADOW_COLOR_G, TEXT_SHADOW_COLOR_B, TEXT_SHADOW_COLOR_A); pango_cairo_show_layout (cr, layout); // ... blur it blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, TEXT_DROP_SHADOW_SIZE); raico_blur_apply (blur, normal); raico_blur_destroy (blur); // now draw normal (non-blurred) text over drop-shadow cairo_set_source_rgba (cr, TEXT_TITLE_COLOR_R, TEXT_TITLE_COLOR_G, TEXT_TITLE_COLOR_B, TEXT_TITLE_COLOR_A); pango_cairo_show_layout (cr, layout); g_object_unref (layout); // create the surface/blur-cache from the normal surface if (priv->tile_title) tile_destroy (priv->tile_title); priv->tile_title = tile_new (normal, BUBBLE_CONTENT_BLUR_RADIUS); // clean up cairo_destroy (cr); cairo_surface_destroy (normal); // reset refresh-flag priv->title_needs_refresh = FALSE; } void _refresh_body (Bubble* self) { BubblePrivate* priv = self->priv; Defaults* d = self->defaults; cairo_surface_t* normal = NULL; cairo_t* cr = NULL; PangoFontDescription* desc = NULL; PangoLayout* layout = NULL; raico_blur_t* blur = NULL; gchar* text_font_face = NULL; // create temp. scratch surface normal = bubble_create_image_surface ( self, CAIRO_FORMAT_ARGB32, priv->body_width + 2 * BUBBLE_CONTENT_BLUR_RADIUS, priv->body_height + 2 * BUBBLE_CONTENT_BLUR_RADIUS); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) return; // create context for normal surface cr = cairo_create (normal); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); return; } // clear normal surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); // create pango desc/layout layout = pango_cairo_create_layout (cr); text_font_face = defaults_get_text_font_face (d); desc = pango_font_description_from_string (text_font_face); g_free ((gpointer) text_font_face); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_body_size (d) * PANGO_SCALE); pango_font_description_set_weight (desc, defaults_get_text_body_weight (d)); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_width (layout, priv->body_width * PANGO_SCALE); pango_layout_set_height (layout, priv->body_height * PANGO_SCALE); // print and layout string (pango-wise) pango_layout_set_text (layout, priv->message_body->str, priv->message_body->len); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options ( pango_layout_get_context (layout), gdk_screen_get_font_options ( gtk_widget_get_screen (priv->widget))); pango_cairo_context_set_resolution (pango_layout_get_context (layout), defaults_get_screen_dpi (d)); pango_layout_context_changed (layout); // draw text for drop-shadow and ... cairo_move_to (cr, BUBBLE_CONTENT_BLUR_RADIUS, BUBBLE_CONTENT_BLUR_RADIUS); cairo_set_source_rgba (cr, TEXT_SHADOW_COLOR_R, TEXT_SHADOW_COLOR_G, TEXT_SHADOW_COLOR_B, TEXT_SHADOW_COLOR_A); pango_cairo_show_layout (cr, layout); // ... blur it blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, TEXT_DROP_SHADOW_SIZE); raico_blur_apply (blur, normal); raico_blur_destroy (blur); // now draw normal (non-blurred) text over drop-shadow cairo_set_source_rgba (cr, TEXT_BODY_COLOR_R, TEXT_BODY_COLOR_G, TEXT_BODY_COLOR_B, TEXT_BODY_COLOR_A); pango_cairo_show_layout (cr, layout); g_object_unref (layout); // create the surface/blur-cache from the normal surface if (priv->tile_body) tile_destroy (priv->tile_body); priv->tile_body = tile_new (normal, BUBBLE_CONTENT_BLUR_RADIUS); // clean up cairo_destroy (cr); cairo_surface_destroy (normal); // reset refresh-flag priv->message_body_needs_refresh = FALSE; } void _refresh_indicator (Bubble* self) { BubblePrivate* priv = self->priv; Defaults* d = self->defaults; cairo_surface_t* normal = NULL; cairo_t* cr = NULL; // create temp. scratch surface normal = bubble_create_image_surface ( self, CAIRO_FORMAT_ARGB32, EM2PIXELS (defaults_get_bubble_width (d), d) - 3 * EM2PIXELS (defaults_get_margin_size (d), d) - EM2PIXELS (defaults_get_icon_size (d), d) + 2 * BUBBLE_CONTENT_BLUR_RADIUS, EM2PIXELS (defaults_get_icon_size (d), d) / 5.0f + 2 * BUBBLE_CONTENT_BLUR_RADIUS); if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) return; // create context for normal surface cr = cairo_create (normal); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (normal); return; } // clear normal surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); _draw_value_indicator ( cr, priv->value, BUBBLE_CONTENT_BLUR_RADIUS, BUBBLE_CONTENT_BLUR_RADIUS, EM2PIXELS (defaults_get_bubble_width (d), d) - 3 * EM2PIXELS (defaults_get_margin_size (d), d) - EM2PIXELS (defaults_get_icon_size (d), d), EM2PIXELS (defaults_get_gauge_size (d), d), EM2PIXELS (defaults_get_gauge_outline_width (d), d)); // create the surface/blur-cache from the normal surface if (priv->tile_indicator) tile_destroy (priv->tile_indicator); priv->tile_indicator = tile_new (normal, BUBBLE_CONTENT_BLUR_RADIUS/2); // clean up cairo_destroy (cr); cairo_surface_destroy (normal); } void _render_background (Bubble* self, cairo_t* cr, gdouble alpha_normal, gdouble alpha_blur) { Defaults* d = self->defaults; tile_paint (self->priv->tile_background, cr, 0.0f, 0.0f, alpha_normal, alpha_blur); // layout-grid and urgency-indication bar if (g_getenv ("DEBUG")) { // for debugging layout and positioning issues _draw_layout_grid (cr, self); switch (bubble_get_urgency (self)) { // low urgency-bar is painted blue case 0: cairo_set_source_rgb (cr, 0.25f, 0.5f, 1.0f); break; // normal urgency-bar is painted green case 1: cairo_set_source_rgb (cr, 0.0f, 1.0f, 0.0f); break; // urgent urgency-bar is painted red case 2: cairo_set_source_rgb (cr, 1.0f, 0.0f, 0.0f); break; default: break; } draw_round_rect ( cr, 1.0f, EM2PIXELS (get_shadow_size (self), d) + 2.0f, EM2PIXELS (get_shadow_size (self), d) + 2.0f, EM2PIXELS (get_corner_radius (self), d) - 2.0f, EM2PIXELS (defaults_get_bubble_width (d), d) - 4.0f, 2.0f * EM2PIXELS (get_shadow_size (self), d) - 2.0f); cairo_fill (cr); cairo_set_source_rgb (cr, 0.0f, 0.0f, 0.0f); cairo_set_font_size ( cr, EM2PIXELS (defaults_get_text_body_size (d), d)); cairo_move_to ( cr, EM2PIXELS (defaults_get_text_body_size (d), d) + EM2PIXELS (get_shadow_size (self), d) + 2.0f, EM2PIXELS (defaults_get_text_body_size (d), d) + EM2PIXELS (get_shadow_size (self), d) + 2.0f + ((2.0f * EM2PIXELS (get_shadow_size (self), d) - 2.0f) - EM2PIXELS (defaults_get_text_body_size (d), d)) / 2); switch (bubble_get_urgency (self)) { case 0: cairo_show_text ( cr, "low - report incorrect urgency?"); break; case 1: cairo_show_text ( cr, "normal - report incorrect urgency?"); break; case 2: cairo_show_text ( cr, "urgent - report incorrect urgency?"); break; default: break; } } } void _render_icon (Bubble* self, cairo_t* cr, gint x, gint y, gdouble alpha_normal, gdouble alpha_blur) { BubblePrivate* priv = self->priv; cairo_pattern_t* pattern; tile_paint (priv->tile_icon, cr, x, y, alpha_normal, alpha_blur); if (priv->alpha) { cairo_push_group (cr); tile_paint (priv->tile_icon, cr, x, y, 0.0f, (gfloat) egg_alpha_get_alpha (priv->alpha) / (gfloat) EGG_ALPHA_MAX_ALPHA); pattern = cairo_pop_group (cr); if (priv->value == -1) cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); if (priv->value == 101) cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); } } void _render_title (Bubble* self, cairo_t* cr, gint x, gint y, gdouble alpha_normal, gdouble alpha_blur) { tile_paint (self->priv->tile_title, cr, x, y, alpha_normal, alpha_blur); } void _render_body (Bubble* self, cairo_t* cr, gint x, gint y, gdouble alpha_normal, gdouble alpha_blur) { tile_paint (self->priv->tile_body, cr, x, y, alpha_normal, alpha_blur); } void _render_indicator (Bubble* self, cairo_t* cr, gint x, gint y, gdouble alpha_normal, gdouble alpha_blur) { BubblePrivate* priv = self->priv; cairo_pattern_t* pattern; tile_paint (priv->tile_indicator, cr, x, y, alpha_normal, alpha_blur); if (priv->alpha) { cairo_push_group (cr); tile_paint (priv->tile_indicator, cr, x, y, 0.0f, (gfloat) egg_alpha_get_alpha (priv->alpha) / (gfloat) EGG_ALPHA_MAX_ALPHA); pattern = cairo_pop_group (cr); if (priv->value == -1) cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); if (priv->value == 101) cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); } } void _render_layout (Bubble* self, cairo_t* cr, gdouble alpha_normal, gdouble alpha_blur) { Defaults* d = self->defaults; gint shadow = EM2PIXELS (get_shadow_size (self), d); gint icon_half = EM2PIXELS (defaults_get_icon_size (d), d) / 2; gint width_half = EM2PIXELS (defaults_get_bubble_width (d), d) / 2; gint height_half = EM2PIXELS (defaults_get_bubble_min_height (d), d) / 2; gint gauge_half = EM2PIXELS (defaults_get_gauge_size (d), d) / 2; gint margin = EM2PIXELS (defaults_get_margin_size (d), d); switch (bubble_get_layout (self)) { case LAYOUT_ICON_ONLY: _render_icon (self, cr, shadow + width_half - icon_half - BUBBLE_CONTENT_BLUR_RADIUS, shadow + height_half - icon_half - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_ICON_INDICATOR: _render_icon (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); _render_indicator (self, cr, shadow + 2 * margin + 2 * icon_half - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin + icon_half - gauge_half - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_ICON_TITLE: _render_icon (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); _render_title (self, cr, shadow + 2 * margin + 2 * icon_half - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin + icon_half - self->priv->title_height / 2 - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_ICON_TITLE_BODY: _render_icon (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); _render_title (self, cr, shadow + 2 * margin + 2 * icon_half - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); _render_body (self, cr, shadow + 2 * margin + 2 * icon_half - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin + self->priv->title_height - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_TITLE_BODY: _render_title (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); _render_body (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin + self->priv->title_height - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_TITLE_ONLY: _render_title (self, cr, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, shadow + margin - BUBBLE_CONTENT_BLUR_RADIUS, alpha_normal, alpha_blur); break; case LAYOUT_NONE: // should be intercepted by stack_notify_handler() g_warning ("WARNING: No layout defined!!!\n"); break; } } // the behind-bubble blur only works with the enabled/working compiz-plugin blur // by setting the hint _COMPIZ_WM_WINDOW_BLUR on the bubble-window void _set_bg_blur (GtkWidget* window, gboolean set_blur, gint shadow_size) { glong data[8]; GtkAllocation a; GdkWindow *gdkwindow; // sanity check if (!window) return; gtk_widget_get_allocation (window, &a); gdkwindow = gtk_widget_get_window (window); // this is meant to tell the blur-plugin what and how to blur, somehow // the y-coords are interpreted as being CenterGravity, I wonder why data[0] = 2; // threshold data[1] = 0; // filter data[2] = NorthWestGravity; // gravity of top-left data[3] = shadow_size; // x-coord of top-left data[4] = (-a.height / 2) + shadow_size; // y-coord of top-left data[5] = NorthWestGravity; // gravity of bottom-right data[6] = a.width - shadow_size; // bottom-right x-coord data[7] = (a.height / 2) - shadow_size; // bottom-right y-coord if (set_blur) { XChangeProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom (GDK_WINDOW_XDISPLAY (gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE), XA_INTEGER, 32, PropModeReplace, (guchar *) data, 8); } else { XDeleteProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom (GDK_WINDOW_XDISPLAY (gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE)); } } static void screen_changed_handler (GtkWindow* window, GdkScreen* old_screen, gpointer data) { GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (window)); GdkVisual* visual; if (!gdk_screen_is_composited (screen)) return; visual = gdk_screen_get_rgba_visual (screen); if (!visual) visual = gdk_screen_get_system_visual (screen); gtk_widget_set_visual (GTK_WIDGET (window), visual); } static void update_input_shape (GtkWidget* window) { cairo_region_t* region = NULL; const cairo_rectangle_int_t rect = {0, 0, 1, 1}; // sanity check if (!window) return; // set an 1x1 input-region to allow click-through region = cairo_region_create_rectangle (&rect); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_input_shape_combine_region (window, NULL); gtk_widget_input_shape_combine_region (window, region); } cairo_region_destroy (region); } static void update_shape (Bubble* self) { gint width; gint height; BubblePrivate* priv; // sanity test if (!self || !IS_BUBBLE (self)) return; priv = self->priv; // do we actually need a shape-mask at all? if (priv->composited) { gtk_widget_shape_combine_region (priv->widget, NULL); return; } // we're not-composited, so deal with mouse-over differently if (bubble_is_mouse_over (self)) { cairo_region_t* region = NULL; region = cairo_region_create (); gdk_window_shape_combine_region (gtk_widget_get_window (priv->widget), region, 0, 0); cairo_region_destroy (region); } else { gtk_widget_get_size_request (priv->widget, &width, &height); const cairo_rectangle_int_t rects[] = {{2, 0, width - 4, height}, {1, 1, width - 2, height - 2}, {0, 2, width, height - 4}}; cairo_region_t* region = NULL; region = cairo_region_create_rectangles (rects, 3); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_shape_combine_region (priv->widget, NULL); gtk_widget_shape_combine_region (priv->widget, region); } } } static void composited_changed_handler (GtkWidget* window, gpointer data) { Bubble* bubble; BubblePrivate* priv; bubble = BUBBLE (data); priv = bubble->priv; priv->composited = gdk_screen_is_composited (gtk_widget_get_screen (window)); update_shape (bubble); } static gboolean bubble_draw (GtkWidget* widget, cairo_t* cr, gpointer data) { Bubble* bubble; Defaults* d; BubblePrivate* priv; bubble = (Bubble*) G_OBJECT (data); d = bubble->defaults; priv = bubble->priv; // clear bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (priv->prevent_fade || !priv->composited) { // render drop-shadow and bubble-background _render_background (bubble, cr, 1.0f, 0.0f); // render content of bubble depending on layout _render_layout (bubble, cr, 1.0f, 0.0f); } else { // render drop-shadow and bubble-background _render_background (bubble, cr, priv->distance, 1.0f - priv->distance); // render content of bubble depending on layout _render_layout (bubble, cr, priv->distance, 1.0f - priv->distance); } _set_bg_blur (widget, TRUE, EM2PIXELS (get_shadow_size (bubble), d)); return TRUE; } static gboolean redraw_handler (Bubble* bubble) { GtkWindow* window; BubblePrivate* priv; if (!bubble) return FALSE; if (!bubble_is_visible (bubble)) return FALSE; priv = bubble->priv; if (!priv->composited) return TRUE; window = GTK_WINDOW (priv->widget); if (!GTK_IS_WINDOW (window)) return FALSE; if (priv->alpha == NULL) { if (priv->distance < 1.0f && !priv->prevent_fade) { gtk_widget_set_opacity (priv->widget, WINDOW_MIN_OPACITY + priv->distance * (WINDOW_MAX_OPACITY - WINDOW_MIN_OPACITY)); bubble_refresh (bubble); } else gtk_widget_set_opacity (priv->widget, WINDOW_MAX_OPACITY); } return TRUE; } static gboolean pointer_update (Bubble* bubble) { gint pointer_rel_x; gint pointer_rel_y; gint pointer_abs_x; gint pointer_abs_y; gint win_x; gint win_y; gint width; gint height; GtkWidget* window; BubblePrivate* priv; if (!bubble) return FALSE; if (!bubble_is_visible (bubble)) return FALSE; priv = bubble->priv; window = priv->widget; if (!GTK_IS_WINDOW (window)) return FALSE; if (gtk_widget_get_realized (window)) { GdkDeviceManager *device_manager; GdkDevice *device; gint distance_x; gint distance_y; device_manager = gdk_display_get_device_manager (gtk_widget_get_display (window)); device = gdk_device_manager_get_client_pointer (device_manager); gdk_window_get_device_position (gtk_widget_get_window (window), device, &pointer_rel_x, &pointer_rel_y, NULL); gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y); pointer_abs_x = win_x + pointer_rel_x; pointer_abs_y = win_y + pointer_rel_y; gtk_window_get_size (GTK_WINDOW (window), &width, &height); if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width && pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) { bubble_set_mouse_over (bubble, TRUE); } else { bubble_set_mouse_over (bubble, FALSE); } if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width) distance_x = 0; else { if (pointer_abs_x < win_x) distance_x = abs (pointer_rel_x); if (pointer_abs_x > win_x + width) distance_x = abs (pointer_rel_x - width); } if (pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) distance_y = 0; else { if (pointer_abs_y < win_y) distance_y = abs (pointer_rel_y); if (pointer_abs_y > win_y + height) distance_y = abs (pointer_rel_y - height); } priv->distance = sqrt (distance_x * distance_x + distance_y * distance_y) / (double) PROXIMITY_THRESHOLD; // mark mouse-pointer having left bubble and proximity-area // after inital show-up of bubble if (priv->prevent_fade && priv->distance > 1.0f) priv->prevent_fade = FALSE; } return TRUE; } //-- internal API -------------------------------------------------------------- static void bubble_dispose (GObject* gobject) { Bubble* bubble; BubblePrivate* priv; if (!gobject || !IS_BUBBLE (gobject)) return; bubble = BUBBLE (gobject); priv = bubble->priv; if (GTK_IS_WIDGET (priv->widget)) { gtk_widget_destroy (GTK_WIDGET (priv->widget)); priv->widget = NULL; } if (priv->title) { g_string_free ((gpointer) priv->title, TRUE); priv->title = NULL; } if (priv->message_body) { g_string_free ((gpointer) priv->message_body, TRUE); priv->message_body = NULL; } if (priv->synchronous) { g_free ((gpointer) priv->synchronous); priv->synchronous = NULL; } if (priv->sender) { g_free ((gpointer) priv->sender); priv->sender = NULL; } if (priv->icon_pixbuf) { g_object_unref (priv->icon_pixbuf); priv->icon_pixbuf = NULL; } if (priv->alpha) { g_object_unref (priv->alpha); priv->alpha = NULL; } if (priv->timeline) { g_object_unref (priv->timeline); priv->timeline = NULL; } if (priv->pointer_update_id) { g_source_remove (priv->pointer_update_id); priv->pointer_update_id = 0; } if (priv->draw_handler_id) { g_source_remove (priv->draw_handler_id); priv->draw_handler_id = 0; } if (priv->timer_id) { g_source_remove (priv->timer_id); priv->timer_id = 0; } if (priv->tile_background_part) { tile_destroy (priv->tile_background_part); priv->tile_background_part = NULL; } if (priv->tile_background) { tile_destroy (priv->tile_background); priv->tile_background = NULL; } if (priv->tile_icon) { tile_destroy (priv->tile_icon); priv->tile_icon = NULL; } if (priv->tile_title) { tile_destroy (priv->tile_title); priv->tile_title = NULL; } if (priv->tile_body) { tile_destroy (priv->tile_body); priv->tile_body = NULL; } if (priv->tile_indicator) { tile_destroy (priv->tile_indicator); priv->tile_indicator = NULL; } g_clear_pointer (&priv->old_icon_filename, g_free); // chain up to the parent class G_OBJECT_CLASS (bubble_parent_class)->dispose (gobject); } static void bubble_finalize (GObject* gobject) { // chain up to the parent class G_OBJECT_CLASS (bubble_parent_class)->finalize (gobject); } static void bubble_init (Bubble* self) { // If you need specific construction properties to complete // initialization, delay initialization completion until the // property is set. BubblePrivate *priv; self->priv = priv = bubble_get_instance_private (self); priv->layout = LAYOUT_NONE; priv->title = NULL; priv->message_body = NULL; priv->title_needs_refresh = FALSE; priv->message_body_needs_refresh = FALSE; priv->visible = FALSE; priv->icon_pixbuf = NULL; priv->value = -2; priv->synchronous = NULL; priv->sender = NULL; priv->draw_handler_id = 0; priv->pointer_update_id = 0; } static void bubble_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { switch (prop) { default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void bubble_class_init (BubbleClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = bubble_dispose; gobject_class->finalize = bubble_finalize; gobject_class->get_property = bubble_get_property; g_bubble_signals[TIMED_OUT] = g_signal_new ( "timed-out", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (BubbleClass, timed_out), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_bubble_signals[VALUE_CHANGED] = g_signal_new ( "value-changed", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (BubbleClass, value_changed), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); g_bubble_signals[MESSAGE_BODY_DELETED] = g_signal_new ( "message-body-deleted", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (BubbleClass, message_body_deleted), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); g_bubble_signals[MESSAGE_BODY_INSERTED] = g_signal_new ( "message-body-inserted", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (BubbleClass, message_body_inserted), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); } //-- public API ---------------------------------------------------------------- Bubble* bubble_new (Defaults* defaults) { Bubble* this = NULL; GtkWidget* window = NULL; BubblePrivate* priv; GdkRGBA transparent = {0.0, 0.0, 0.0, 0.0}; this = g_object_new (BUBBLE_TYPE, NULL); if (!this) return NULL; this->defaults = defaults; priv = this->priv; priv->widget = bubble_window_new(); window = priv->widget; if (!window) return NULL; g_object_set_data (G_OBJECT(window), "bubble", (gpointer) this); gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_NOTIFICATION); gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE); gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE); gtk_window_stick (GTK_WINDOW (window)); gtk_widget_add_events (window, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); // hook up input/event handlers to window g_signal_connect (G_OBJECT (window), "screen-changed", G_CALLBACK (screen_changed_handler), NULL); g_signal_connect (G_OBJECT (window), "composited-changed", G_CALLBACK (composited_changed_handler), this); gtk_window_move (GTK_WINDOW (window), 0, 0); // make sure the window opens with a RGBA-visual screen_changed_handler (GTK_WINDOW (window), NULL, NULL); gtk_widget_realize (window); gdk_window_set_background_rgba (gtk_widget_get_window (window), &transparent); // hook up window-event handlers to window g_signal_connect (window, "draw", G_CALLBACK (bubble_draw), this); // "clear" input-mask, set title/icon/attributes gtk_widget_set_app_paintable (window, TRUE); gtk_window_set_title (GTK_WINDOW (window), "notify-osd"); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_window_set_focus_on_map (GTK_WINDOW (window), FALSE); gtk_window_set_accept_focus (GTK_WINDOW (window), FALSE); gtk_widget_set_opacity (window, 0.0f); // TODO: fold some of that back into bubble_init this->priv = this->priv; this->priv->layout = LAYOUT_NONE; this->priv->widget = window; this->priv->title = g_string_new (""); this->priv->message_body = g_string_new (""); this->priv->title_needs_refresh = FALSE; this->priv->message_body_needs_refresh = FALSE; this->priv->icon_pixbuf = NULL; this->priv->value = -2; this->priv->visible = FALSE; this->priv->timeout = 5000; this->priv->mouse_over = FALSE; this->priv->distance = 1.0f; this->priv->composited = gdk_screen_is_composited ( gtk_widget_get_screen (window)); this->priv->alpha = NULL; this->priv->timeline = NULL; this->priv->title_width = 0; this->priv->title_height = 0; this->priv->body_width = 0; this->priv->body_height = 0; this->priv->append = FALSE; this->priv->icon_only = FALSE; this->priv->tile_background_part = NULL; this->priv->tile_background = NULL; this->priv->tile_icon = NULL; this->priv->tile_title = NULL; this->priv->tile_body = NULL; this->priv->tile_indicator = NULL; this->priv->prevent_fade = FALSE; update_input_shape (window); return this; } gchar* bubble_get_synchronous (Bubble* self) { g_return_val_if_fail (IS_BUBBLE (self), NULL); return self->priv->synchronous; } gchar* bubble_get_sender (Bubble* self) { g_return_val_if_fail (IS_BUBBLE (self), NULL); return self->priv->sender; } void bubble_set_title (Bubble* self, const gchar* title) { gchar* text; BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; // convert any newline to space text = newline_to_space (title); if (priv->title) { if (g_strcmp0 (priv->title->str, text)) priv->title_needs_refresh = TRUE; g_string_free (priv->title, TRUE); } priv->title = g_string_new (text); g_object_notify ( G_OBJECT (gtk_widget_get_accessible (self->priv->widget)), "accessible-name"); g_free (text); } const gchar* bubble_get_title (Bubble* self) { if (!self || !IS_BUBBLE (self)) return NULL; return self->priv->title->str; } void bubble_set_message_body (Bubble* self, const gchar* body) { gchar* text; BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; // filter out any HTML/markup if possible text = filter_text (body); g_strstrip (text); if (priv->message_body) if (g_strcmp0 (priv->message_body->str, text)) priv->message_body_needs_refresh = TRUE; if (priv->message_body && priv->message_body->len != 0) { g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_DELETED], 0, priv->message_body->str); g_string_free (priv->message_body, TRUE); } priv->message_body = g_string_new (text); g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text); g_object_notify (G_OBJECT (gtk_widget_get_accessible (priv->widget)), "accessible-description"); g_free (text); } const gchar* bubble_get_message_body (Bubble* self) { if (!self || !IS_BUBBLE (self)) return NULL; return self->priv->message_body->str; } void bubble_set_icon (Bubble* self, const gchar* name) { BubblePrivate *priv; gint scale; gint icon_size; g_return_if_fail (self != NULL); g_return_if_fail (name != NULL); priv = self->priv; scale = gtk_widget_get_scale_factor (priv->widget); icon_size = EM2PIXELS (defaults_get_icon_size (self->defaults), self->defaults); // check if an app tries to set the same file as icon again, this check // avoids superfluous regeneration of the tile/blur-cache for the icon, // thus it improves performance in update- and append-cases if (!g_strcmp0 (priv->old_icon_filename, name)) return; g_clear_object (&priv->icon_pixbuf); g_clear_pointer (&priv->old_icon_filename, g_free); if (g_str_has_prefix (name, "file://")) { gchar *filename; GError *error = NULL; filename = g_filename_from_uri (name, NULL, &error); if (filename == NULL) { g_warning ("%s is not a valid file uri: %s", name, error->message); g_error_free (error); return; } priv->icon_pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, scale * icon_size, scale * icon_size, TRUE, NULL); g_free (filename); } /* According to the spec, only file:// uris are allowed in the * name field. However, many applications send raw paths. * Support those as well, but only if they're absolute. */ else if (name[0] == '/') { priv->icon_pixbuf = gdk_pixbuf_new_from_file_at_scale (name, scale * icon_size, scale * icon_size, TRUE, NULL); } else { GError *error = NULL; GdkPixbuf *buffer; GtkIconTheme *theme; GtkIconLookupFlags flags; gchar *fallback_name; theme = gtk_icon_theme_get_default (); flags = GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_FORCE_SIZE; fallback_name = g_strconcat ("notification-", name, NULL); buffer = gtk_icon_theme_load_icon_for_scale (theme, fallback_name, icon_size, scale, flags, &error); g_free (fallback_name); if (buffer == NULL && g_error_matches (error, GTK_ICON_THEME_ERROR, GTK_ICON_THEME_NOT_FOUND)) { g_clear_error (&error); buffer = gtk_icon_theme_load_icon_for_scale (theme, name, icon_size, scale, flags, &error); } if (buffer == NULL) { g_warning ("Unable to load icon '%s': %s", name, error->message); g_error_free (error); return; } /* copy and unref buffer so on an icon-theme change old ** icons are not kept in memory due to dangling ** references, this also makes sure we do not need to ** connect to GtkWidget::style-set signal for the ** GdkPixbuf we get from gtk_icon_theme_load_icon() */ priv->icon_pixbuf = gdk_pixbuf_copy (buffer); g_object_unref (buffer); } // store the new icon-basename priv->old_icon_filename = g_strdup (name); _refresh_icon (self); } static GdkPixbuf * scale_pixbuf (const GdkPixbuf *pixbuf, gint size) { GdkPixbuf *scaled_icon; GdkPixbuf *new_icon; gint w, h, dest_x, dest_y, new_width, new_height, max_edge; dest_x = dest_y = 0; w = gdk_pixbuf_get_width (pixbuf); h = gdk_pixbuf_get_height (pixbuf); max_edge = MAX (w, h); // temporarily cast to float so we don't end up missing fractional parts // from the division, especially nasty for 0.something :) // e.g.: 99 / 100 = 0 but 99.0 / 100.0 = 0.99 new_width = size * ((gfloat) w / (gfloat) max_edge); new_height = size * ((gfloat) h / (gfloat) max_edge); /* Scale the pixbuf down, preserving the aspect ratio */ scaled_icon = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, GDK_INTERP_BILINEAR); if (w == h) return scaled_icon; /* Create a square pixbuf with an alpha channel */ new_icon = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (scaled_icon), TRUE, gdk_pixbuf_get_bits_per_sample (scaled_icon), size, size); /* Clear the pixbuf so it is transparent */ gdk_pixbuf_fill (new_icon, 0x00000000); /* Center the rectangular pixbuf inside the transparent square */ if (new_width > new_height) dest_y = (new_width - new_height) / 2; else dest_x = (new_height - new_width) / 2; /* Copy the rectangular pixbuf into the new pixbuf at a centered position */ gdk_pixbuf_copy_area (scaled_icon, 0, 0, gdk_pixbuf_get_width (scaled_icon), gdk_pixbuf_get_height (scaled_icon), new_icon, dest_x, dest_y); g_object_unref (scaled_icon); return new_icon; } void bubble_set_icon_from_pixbuf (Bubble* self, GdkPixbuf* pixbuf) { GdkPixbuf* scaled; gint height; gint width; Defaults* d; BubblePrivate* priv; if (!self || !IS_BUBBLE (self) || !pixbuf) return; priv = self->priv; // "reset" the stored the icon-filename, fixes LP: #451086 g_clear_pointer (&priv->old_icon_filename, g_free); if (priv->icon_pixbuf) { g_object_unref (priv->icon_pixbuf); priv->icon_pixbuf = NULL; } height = gdk_pixbuf_get_height (pixbuf); width = gdk_pixbuf_get_width (pixbuf); d = self->defaults; if (width != defaults_get_icon_size (d) || height != defaults_get_icon_size (d)) { scaled = scale_pixbuf (pixbuf, EM2PIXELS (defaults_get_icon_size (d), d)); g_object_unref (pixbuf); pixbuf = scaled; } priv->icon_pixbuf = pixbuf; _refresh_icon (self); } GdkPixbuf* bubble_get_icon_pixbuf (Bubble *self) { g_return_val_if_fail (IS_BUBBLE (self), NULL); return self->priv->icon_pixbuf; } void bubble_set_value (Bubble* self, gint value) { BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; // only really cause a refresh (blur, recreating tile-/blur-cache) if // a different value has been set, this helps improve performance when // a user e.g. presses and holds down keys for Volume-Up/Down or // Brightness-Up/Down and apps like gnome-settings-daemon or // gnome-power-daemon fire continues notification-updates due to the // key-repeat events if (priv->value != value) { priv->value = value; g_signal_emit (self, g_bubble_signals[VALUE_CHANGED], 0, value); _refresh_indicator (self); } } gint bubble_get_value (Bubble* self) { if (!self || !IS_BUBBLE (self)) return -2; return self->priv->value; } void bubble_set_size (Bubble* self, gint width, gint height) { if (!self || !IS_BUBBLE (self)) return; gtk_widget_set_size_request (self->priv->widget, width, height); } void bubble_get_size (Bubble* self, gint* width, gint* height) { if (!self || !IS_BUBBLE (self)) return; gtk_widget_get_size_request (self->priv->widget, width, height); } void bubble_set_timeout (Bubble* self, guint timeout) { if (!self || !IS_BUBBLE (self)) return; self->priv->timeout = timeout; } /* a timeout of 0 doesn't make much sense now does it, thus 0 indicates an ** error */ guint bubble_get_timeout (Bubble* self) { if (!self || !IS_BUBBLE (self)) return 0; return self->priv->timeout; } void bubble_set_timer_id (Bubble* self, guint timer_id) { if (!self || !IS_BUBBLE (self)) return; self->priv->timer_id = timer_id; } /* a valid GLib timer-id is always > 0, thus 0 indicates an error */ guint bubble_get_timer_id (Bubble* self) { if (!self || !IS_BUBBLE (self)) return 0; return self->priv->timer_id; } void bubble_set_mouse_over (Bubble* self, gboolean flag) { BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; /* did anything change? */ if (priv->mouse_over != flag) { priv->mouse_over = flag; update_shape (self); if (flag) { g_debug("mouse entered bubble, supressing timeout"); bubble_clear_timer(self); } else { g_debug("mouse left bubble, continuing timeout"); bubble_set_timeout(self, 3000); bubble_start_timer(self, TRUE); } } } gboolean bubble_is_mouse_over (Bubble* self) { BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return FALSE; priv = self->priv; if (priv->prevent_fade) return FALSE; return priv->mouse_over; } void bubble_move (Bubble* self, gint x, gint y) { if (!self || !IS_BUBBLE (self)) return; gtk_window_move (GTK_WINDOW (self->priv->widget), x, y); } static void glow_completed_cb (EggTimeline *timeline, Bubble *bubble) { BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (bubble)); priv = bubble->priv; /* get rid of the alpha, so that the mouse-over algorithm notices */ if (priv->alpha) { g_object_unref (priv->alpha); priv->alpha = NULL; } if (priv->timeline) { g_object_unref (priv->timeline); priv->timeline = NULL; } } static void glow_cb (EggTimeline *timeline, gint frame_no, Bubble *bubble) { g_return_if_fail (IS_BUBBLE (bubble)); bubble_refresh (bubble); } static void bubble_start_glow_effect (Bubble *self, guint msecs) { EggTimeline* timeline; BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (self)); priv = self->priv; timeline = egg_timeline_new_for_duration (msecs); egg_timeline_set_speed (timeline, FPS); priv->timeline = timeline; if (priv->alpha != NULL) { g_object_unref (priv->alpha); priv->alpha = NULL; } priv->alpha = egg_alpha_new_full (timeline, EGG_ALPHA_RAMP_DEC, NULL, NULL); g_signal_connect (G_OBJECT (timeline), "completed", G_CALLBACK (glow_completed_cb), self); g_signal_connect (G_OBJECT (timeline), "new-frame", G_CALLBACK (glow_cb), self); egg_timeline_start (timeline); } void bubble_show (Bubble* self) { BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; priv->visible = TRUE; gtk_widget_show_all (priv->widget); // check if mouse-pointer is over bubble (and proximity-area) initially pointer_update (self); if (priv->distance <= 1.0f) priv->prevent_fade = TRUE; else priv->prevent_fade = FALSE; // FIXME: do nasty busy-polling rendering in the drawing-area priv->draw_handler_id = g_timeout_add (1000/FPS, (GSourceFunc) redraw_handler, self); // FIXME: read out current mouse-pointer position every 1/25 second priv->pointer_update_id = g_timeout_add (1000/FPS, (GSourceFunc) pointer_update, self); } /* mostly called when we change the content of the bubble and need to force a redraw */ void bubble_refresh (Bubble* self) { if (!self || !IS_BUBBLE (self)) return; /* force a redraw */ gtk_widget_queue_draw (self->priv->widget); } static inline gboolean bubble_is_composited (Bubble *bubble) { /* no g_return_if_fail(), the caller should have already checked that */ return gtk_widget_is_composited (bubble->priv->widget); } static inline GtkWindow* bubble_get_window (Bubble *bubble) { return GTK_WINDOW (bubble->priv->widget); } static void fade_cb (EggTimeline *timeline, gint frame_no, Bubble *bubble) { float opacity; g_return_if_fail (IS_BUBBLE (bubble)); opacity = (float)egg_alpha_get_alpha (bubble->priv->alpha) / (float)EGG_ALPHA_MAX_ALPHA * WINDOW_MAX_OPACITY; if (bubble_is_mouse_over (bubble)) gtk_widget_set_opacity (bubble->priv->widget, WINDOW_MIN_OPACITY); else gtk_widget_set_opacity (bubble->priv->widget, opacity); } static void fade_out_completed_cb (EggTimeline *timeline, Bubble *bubble) { g_return_if_fail (IS_BUBBLE (bubble)); bubble_hide (bubble); dbus_send_close_signal (bubble_get_sender (bubble), bubble_get_id (bubble), 1); g_signal_emit (bubble, g_bubble_signals[TIMED_OUT], 0); } static void fade_in_completed_cb (EggTimeline* timeline, Bubble* bubble) { BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (bubble)); priv = bubble->priv; /* get rid of the alpha, so that the mouse-over algorithm notices */ if (priv->alpha) { g_object_unref (priv->alpha); priv->alpha = NULL; } if (priv->timeline) { g_object_unref (priv->timeline); priv->timeline = NULL; } if (bubble_is_mouse_over (bubble)) gtk_widget_set_opacity (bubble->priv->widget, WINDOW_MIN_OPACITY); else gtk_widget_set_opacity (bubble->priv->widget, WINDOW_MAX_OPACITY); bubble_start_timer (bubble, TRUE); } void bubble_fade_in (Bubble* self, guint msecs) { EggTimeline* timeline; BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (self)); priv = self->priv; if (!bubble_is_composited (self) || msecs == 0) { bubble_show (self); bubble_start_timer (self, TRUE); return; } timeline = egg_timeline_new_for_duration (msecs); egg_timeline_set_speed (timeline, FPS); if (priv->alpha != NULL) { g_object_unref (priv->alpha); priv->alpha = NULL; } priv->alpha = egg_alpha_new_full (timeline, EGG_ALPHA_RAMP_INC, NULL, NULL); g_signal_connect (G_OBJECT (timeline), "completed", G_CALLBACK (fade_in_completed_cb), self); g_signal_connect (G_OBJECT (timeline), "new-frame", G_CALLBACK (fade_cb), self); egg_timeline_start (timeline); gtk_widget_set_opacity (self->priv->widget, 0.0f); bubble_show (self); } void bubble_fade_out (Bubble* self, guint msecs) { EggTimeline* timeline; BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (self)); priv = self->priv; timeline = egg_timeline_new_for_duration (msecs); egg_timeline_set_speed (timeline, FPS); priv->timeline = timeline; if (priv->alpha != NULL) { g_object_unref (priv->alpha); priv->alpha = NULL; } priv->alpha = egg_alpha_new_full (timeline, EGG_ALPHA_RAMP_DEC, NULL, NULL); g_signal_connect (G_OBJECT (timeline), "completed", G_CALLBACK (fade_out_completed_cb), self); g_signal_connect (G_OBJECT (timeline), "new-frame", G_CALLBACK (fade_cb), self); egg_timeline_start (timeline); } gboolean bubble_timed_out (Bubble* self) { g_return_val_if_fail (IS_BUBBLE (self), FALSE); /* This function always returns FALSE, which removes the timer * source. Unset priv->timer_id so that we don't call * g_source_remove() on it later. */ bubble_set_timer_id (self, 0); if (self->priv->composited) { bubble_fade_out (self, 300); return FALSE; } bubble_hide (self); dbus_send_close_signal (bubble_get_sender (self), bubble_get_id (self), 1); g_signal_emit (self, g_bubble_signals[TIMED_OUT], 0); return FALSE; } void bubble_hide (Bubble* self) { BubblePrivate* priv; if (!self || !IS_BUBBLE (self) || !bubble_is_visible (self)) return; priv = self->priv; priv->visible = FALSE; gtk_widget_hide (priv->widget); priv->timeout = 0; if (priv->timeline) { egg_timeline_stop (priv->timeline); g_object_unref (priv->timeline); priv->timeline = NULL; } if (priv->alpha) { g_object_unref (priv->alpha); priv->alpha = NULL; } } void bubble_set_id (Bubble* self, guint id) { if (!self || !IS_BUBBLE (self)) return; self->priv->id = id; } guint bubble_get_id (Bubble* self) { if (!self || !IS_BUBBLE (self)) return 0; return self->priv->id; } gboolean bubble_is_visible (Bubble* self) { if (!self || !IS_BUBBLE (self)) return FALSE; return self->priv->visible; } void bubble_start_timer (Bubble* self, gboolean trigger) { guint timer_id; BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; priv = self->priv; timer_id = bubble_get_timer_id (self); if (timer_id > 0) g_source_remove (timer_id); /* and now let the timer tick... we use g_timeout_add_seconds() here ** because for the bubble timeouts microsecond-precise resolution is not ** needed, furthermore this also allows glib more room for optimizations ** and improve system-power-usage to be more efficient */ bubble_set_timer_id ( self, g_timeout_add_seconds (bubble_get_timeout (self) / 1000, (GSourceFunc) bubble_timed_out, self)); /* if the bubble is displaying a value that is out of bounds trigger a dim/glow animation */ if (trigger) if (priv->value == -1 || priv->value == 101) bubble_start_glow_effect (self, 500); } void bubble_clear_timer (Bubble* self) { guint timer_id; if (!self || !IS_BUBBLE (self)) return; timer_id = self->priv->timer_id; if (timer_id > 0) { g_source_remove (timer_id); bubble_set_timer_id(self, 0); } } void bubble_get_position (Bubble* self, gint* x, gint* y) { if (!self || !IS_BUBBLE (self)) return; gtk_window_get_position (GTK_WINDOW (self->priv->widget), x, y); } gint bubble_get_height (Bubble *self) { gint width; gint height; if (!self || !IS_BUBBLE (self)) return 0; gtk_window_get_size (GTK_WINDOW (self->priv->widget), &width, &height); return height; } gint bubble_get_future_height (Bubble *self) { if (!self || !IS_BUBBLE (self)) return 0; return self->priv->future_height; } gint _calc_title_height (Bubble* self, gint title_width /* requested text-width in pixels */) { Defaults* d; cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc = NULL; PangoLayout* layout = NULL; PangoRectangle log_rect = {0, 0, 0, 0}; gint title_height; BubblePrivate* priv; gchar* text_font_face = NULL; if (!self || !IS_BUBBLE (self)) return 0; d = self->defaults; priv = self->priv; surface = bubble_create_image_surface (self, CAIRO_FORMAT_A1, 1, 1); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { if (surface) cairo_surface_destroy (surface); return 0; } cr = cairo_create (surface); cairo_surface_destroy (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { if (cr) cairo_destroy (cr); return 0; } layout = pango_cairo_create_layout (cr); text_font_face = defaults_get_text_font_face (d); desc = pango_font_description_from_string (text_font_face); g_free ((gpointer) text_font_face); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options ( pango_layout_get_context (layout), gdk_screen_get_font_options ( gtk_widget_get_screen (priv->widget))); pango_cairo_context_set_resolution (pango_layout_get_context (layout), defaults_get_screen_dpi (d)); pango_layout_context_changed (layout); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_title_size (d) * PANGO_SCALE); pango_font_description_set_weight ( desc, defaults_get_text_title_weight (d)); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_width (layout, title_width * PANGO_SCALE); pango_layout_set_height (layout, -3); pango_layout_set_text (layout, priv->title->str, priv->title->len); pango_layout_get_extents (layout, NULL, &log_rect); title_height = PANGO_PIXELS (log_rect.height); g_object_unref (layout); cairo_destroy (cr); return title_height; } gint _calc_body_height (Bubble* self, gint body_width /* requested text-width in pixels */) { Defaults* d; cairo_t* cr; PangoFontDescription* desc = NULL; PangoLayout* layout = NULL; PangoRectangle log_rect; gint body_height; BubblePrivate* priv; gchar* text_font_face = NULL; if (!self || !IS_BUBBLE (self)) return 0; d = self->defaults; priv = self->priv; cr = gdk_cairo_create (gtk_widget_get_window (priv->widget)); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { if (cr) cairo_destroy (cr); return 0; } layout = pango_cairo_create_layout (cr); text_font_face = defaults_get_text_font_face (d); desc = pango_font_description_from_string (text_font_face); g_free ((gpointer) text_font_face); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options ( pango_layout_get_context (layout), gdk_screen_get_font_options ( gtk_widget_get_screen (priv->widget))); pango_cairo_context_set_resolution (pango_layout_get_context (layout), defaults_get_screen_dpi (d)); pango_layout_context_changed (layout); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_body_size (d) * PANGO_SCALE); pango_font_description_set_weight ( desc, defaults_get_text_body_weight (d)); pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE); pango_layout_set_width (layout, body_width * PANGO_SCALE); pango_layout_set_height (layout, -10); pango_layout_set_text (layout, priv->message_body->str, priv->message_body->len); /* enforce the 10 line-limit, usually only triggered by appended ** body-message text due to the newline-characters added with each ** append */ if (pango_layout_get_line_count (layout) > 10) { /* get it down to 9 lines, because we add our own ...-line */ while (pango_layout_get_line_count (layout) > 9) { GString* string = NULL; /* cut leading chunk of text up to the first newline */ string = g_string_new (g_strstr_len (priv->message_body->str, priv->message_body->len, "\n")); /* also cut the first newline itself */ string = g_string_erase (string, 0, 1); /* copy that stripped text back to the body-message */ g_string_assign (priv->message_body, string->str); /* set the new body-message text to the pango-layout */ pango_layout_set_text (layout, priv->message_body->str, priv->message_body->len); /* clean up */ g_string_free (string, TRUE); } /* add our own ellipsize-line */ g_string_prepend (priv->message_body, "...\n"); /* set final body-message text to the pango-layout again */ pango_layout_set_text (layout, priv->message_body->str, priv->message_body->len); } pango_layout_get_extents (layout, NULL, &log_rect); body_height = PANGO_PIXELS (log_rect.height); pango_font_description_free (desc); g_object_unref (layout); cairo_destroy (cr); return body_height; } void bubble_recalc_size (Bubble *self) { gint old_bubble_width = 0; gint old_bubble_height = 0; gint new_bubble_width = 0; gint new_bubble_height = 0; Defaults* d; BubblePrivate* priv; if (!self || !IS_BUBBLE (self)) return; d = self->defaults; priv = self->priv; /* FIXME: a quick fix to rescale an icon (e.g. user changed font-size or ** DPI while a bubble is displayed, thus bubble is re-rendered and the ** icon needs to adapt to the new size) */ if (priv->icon_pixbuf) { GdkPixbuf *pixbuf; pixbuf = gdk_pixbuf_scale_simple ( priv->icon_pixbuf, EM2PIXELS (defaults_get_icon_size (d), d), EM2PIXELS (defaults_get_icon_size (d), d), GDK_INTERP_BILINEAR); g_object_unref (priv->icon_pixbuf); priv->icon_pixbuf = pixbuf; } bubble_determine_layout (self); new_bubble_width = EM2PIXELS (defaults_get_bubble_width (d), d) + 2 * EM2PIXELS (get_shadow_size (self), d); switch (priv->layout) { case LAYOUT_ICON_ONLY: case LAYOUT_ICON_INDICATOR: case LAYOUT_ICON_TITLE: priv->title_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 3 * EM2PIXELS (defaults_get_margin_size (d), d) - EM2PIXELS (defaults_get_icon_size (d), d); priv->title_height = _calc_title_height ( self, self->priv->title_width); new_bubble_height = EM2PIXELS (defaults_get_bubble_min_height (d), d) + 2.0f * EM2PIXELS (get_shadow_size (self), d); break; case LAYOUT_ICON_TITLE_BODY: { gdouble available_height = 0.0f; gdouble bubble_height = 0.0f; priv->title_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 3 * EM2PIXELS (defaults_get_margin_size (d), d) - EM2PIXELS (defaults_get_icon_size (d), d); priv->title_height = _calc_title_height ( self, self->priv->title_width); priv->body_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 3 * EM2PIXELS (defaults_get_margin_size (d), d) - EM2PIXELS (defaults_get_icon_size (d), d); priv->body_height = _calc_body_height ( self, priv->body_width); available_height = PIXELS2EM (defaults_get_desktop_height (d), d) - defaults_get_desktop_bottom_gap (d) - defaults_get_bubble_min_height (d) - 2.0f * defaults_get_bubble_vert_gap (d); bubble_height = PIXELS2EM (priv->title_height, d) + PIXELS2EM (priv->body_height, d) + 2.0f * defaults_get_margin_size (d); if (bubble_height >= available_height) { new_bubble_height = EM2PIXELS (available_height, d); } else { if (priv->body_height + priv->title_height < EM2PIXELS (defaults_get_icon_size (d), d)) { new_bubble_height = EM2PIXELS (defaults_get_icon_size (d), d) + 2.0f * EM2PIXELS (defaults_get_margin_size (d), d) + 2.0f * EM2PIXELS (get_shadow_size (self), d); } else { new_bubble_height = priv->body_height + priv->title_height + 2.0f * EM2PIXELS (defaults_get_margin_size (d), d) + 2.0f * EM2PIXELS (get_shadow_size (self), d); } } } break; case LAYOUT_TITLE_BODY: { gdouble available_height = 0.0f; gdouble bubble_height = 0.0f; priv->title_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 2 * EM2PIXELS (defaults_get_margin_size (d), d); priv->title_height = _calc_title_height ( self, priv->title_width); priv->body_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 2 * EM2PIXELS (defaults_get_margin_size (d), d); priv->body_height = _calc_body_height ( self, priv->body_width); available_height = PIXELS2EM (defaults_get_desktop_height (d), d) - defaults_get_desktop_bottom_gap (d) - defaults_get_bubble_min_height (d) - 2.0f * defaults_get_bubble_vert_gap (d); bubble_height = PIXELS2EM (priv->title_height, d) + PIXELS2EM (priv->body_height, d) + 2.0f * defaults_get_margin_size (d); if (bubble_height >= available_height) { new_bubble_height = EM2PIXELS (available_height, d); } else { new_bubble_height = priv->body_height + priv->title_height + 2.0f * EM2PIXELS (defaults_get_margin_size (d), d) + 2.0f * EM2PIXELS (get_shadow_size (self), d); } } break; case LAYOUT_TITLE_ONLY: { priv->title_width = EM2PIXELS (defaults_get_bubble_width (d), d) - 2 * EM2PIXELS (defaults_get_margin_size (d), d); priv->title_height = _calc_title_height ( self, priv->title_width); new_bubble_height = priv->title_height + 2.0f * EM2PIXELS (defaults_get_margin_size (d), d) + 2.0f * EM2PIXELS (get_shadow_size (self), d); } break; case LAYOUT_NONE: g_warning ("bubble_recalc_size(): WARNING, no layout!!!\n"); break; } priv->future_height = new_bubble_height; bubble_get_size (self, &old_bubble_width, &old_bubble_height); bubble_set_size (self, new_bubble_width, new_bubble_height); // don't refresh tile/blur-caches for background, title or body if the // size or contents have not changed, this improves performance for the // update- and replace-cases if (old_bubble_width != new_bubble_width || old_bubble_height != new_bubble_height) _refresh_background (self); if (priv->title_needs_refresh) _refresh_title (self); if (priv->message_body_needs_refresh) _refresh_body (self); update_shape (self); } void bubble_set_synchronous (Bubble *self, const gchar *sync) { BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (self)); priv = self->priv; if (priv->synchronous != NULL) g_free (priv->synchronous); priv->synchronous = g_strdup (sync); } void bubble_set_sender (Bubble *self, const gchar *sender) { BubblePrivate* priv; g_return_if_fail (IS_BUBBLE (self)); priv = self->priv; if (priv->sender != NULL) g_free (priv->sender); priv->sender = g_strdup (sender); } gboolean bubble_is_synchronous (Bubble *self) { if (!self || !IS_BUBBLE (self)) return FALSE; return (self->priv->synchronous != NULL); } gboolean bubble_is_urgent (Bubble *self) { g_return_val_if_fail (IS_BUBBLE (self), FALSE); return (self->priv->urgency == 2); } guint bubble_get_urgency (Bubble *self) { g_return_val_if_fail (IS_BUBBLE (self), 0); return self->priv->urgency; } void bubble_set_urgency (Bubble *self, guint urgency) { g_return_if_fail (IS_BUBBLE (self)); self->priv->urgency = urgency; } void bubble_determine_layout (Bubble* self) { BubblePrivate* priv; /* sanity test */ if (!self || !IS_BUBBLE (self)) return; priv = self->priv; /* set a sane default */ priv->layout = LAYOUT_NONE; /* icon-only layout-case, e.g. eject */ if (priv->icon_only && priv->icon_pixbuf != NULL) { priv->layout = LAYOUT_ICON_ONLY; return; } /* icon + indicator layout-case, e.g. volume */ if ((priv->icon_pixbuf != NULL) && (priv->title->len != 0) && (priv->value >= -1)) { priv->layout = LAYOUT_ICON_INDICATOR; return; } /* icon + title layout-case, e.g. "Wifi signal lost" */ if ((priv->icon_pixbuf != NULL) && (priv->title->len != 0) && (priv->message_body->len == 0) && (priv->value == -2)) { priv->layout = LAYOUT_ICON_TITLE; return; } /* icon/avatar + title + body/message layout-case, e.g. IM-message */ if ((priv->icon_pixbuf != NULL) && (priv->title->len != 0) && (priv->message_body->len != 0) && (priv->value == -2)) { priv->layout = LAYOUT_ICON_TITLE_BODY; return; } /* title + body/message layout-case, e.g. IM-message without avatar */ if ((priv->icon_pixbuf == NULL) && (priv->title->len != 0) && (priv->message_body->len != 0) && (priv->value == -2)) { priv->layout = LAYOUT_TITLE_BODY; return; } /* title-only layout-case, use discouraged but needs to be supported */ if ((priv->icon_pixbuf == NULL) && (priv->title->len != 0) && (priv->message_body->len == 0) && (priv->value == -2)) { priv->layout = LAYOUT_TITLE_ONLY; return; } return; } BubbleLayout bubble_get_layout (Bubble* self) { if (!self || !IS_BUBBLE (self)) return LAYOUT_NONE; return self->priv->layout; } void bubble_set_icon_only (Bubble* self, gboolean allowed) { if (!self || !IS_BUBBLE (self)) return; self->priv->icon_only = allowed; } void bubble_set_append (Bubble* self, gboolean allowed) { if (!self || !IS_BUBBLE (self)) return; self->priv->append = allowed; } gboolean bubble_is_append_allowed (Bubble* self) { if (!self || !IS_BUBBLE (self)) return FALSE; return self->priv->append; } void bubble_append_message_body (Bubble* self, const gchar* append_body) { gboolean result = FALSE; gchar* text = NULL; GError* error = NULL; BubblePrivate* priv = NULL; if (!self || !IS_BUBBLE (self) || !append_body) return; priv = self->priv; // filter out any HTML/markup if possible result = pango_parse_markup (append_body, -1, 0, // no accel-marker needed NULL, // no PangoAttr needed &text, NULL, // no accel-marker-return needed &error); if (error && !result) { g_warning ("%s(): Got error \"%s\"\n", G_STRFUNC, error->message); g_error_free (error); error = NULL; if (text) g_free (text); } if (text) { g_strstrip (text); if (text[0] == '\0') { if (priv->message_body->len > 0 && priv->message_body->str[priv->message_body->len-1] != '\n') { // This is a special combination, that allows us to remember that a // new empty body line has been requested, but we won't show this till // something visible will be appended. g_string_append_c (priv->message_body, '\0'); g_string_append_c (priv->message_body, '\n'); } g_free (text); return; } if (priv->message_body->len > 1) { if (priv->message_body->str[priv->message_body->len-1] == '\n' && priv->message_body->str[priv->message_body->len-2] == '\0') { // A new message has been appended, let's remove the \0 we put before. g_string_erase (priv->message_body, priv->message_body->len-2, 1); } } // append text to current message-body g_string_append_c (priv->message_body, '\n'); g_string_append (priv->message_body, text); priv->message_body_needs_refresh = TRUE; g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text); g_object_notify ( G_OBJECT (gtk_widget_get_accessible (priv->widget)), "accessible-description"); g_free (text); } } void bubble_sync_with (Bubble *self, Bubble *other) { g_return_if_fail (IS_BUBBLE (self) && IS_BUBBLE (other)); bubble_set_timeout (self, bubble_get_timeout (other)); bubble_start_timer (self, FALSE); bubble_start_timer (other, FALSE); } ./src/log.h0000644000004100000410000000267313570225707013004 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** log.h - log utils ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __NOTIFY_OSD_LOG_H #define __NOTIFY_OSD_LOG_H G_BEGIN_DECLS void log_init (void); void log_bubble (Bubble *bubble, const char *app_name, const char *option); char* log_create_timestamp (void); void log_bubble_debug (Bubble *bubble, const char *app_name, const char *icon); G_END_DECLS #endif /* __NOTIFY_OSD_LOG_H */ ./src/util.c0000644000004100000410000001532313570225707013167 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** util.c - all sorts of helper functions ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Cody Russell ** Mirco "MacSlow" Mueller ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #include #include #define CHARACTER_LT_REGEX "&(lt;|#60;|#x3c;)" #define CHARACTER_GT_REGEX "&(gt;|#62;|#x3e;)" #define CHARACTER_AMP_REGEX "&(amp;|#38;|#x26;)" #define CHARACTER_APOS_REGEX "'" #define CHARACTER_QUOT_REGEX """ #define CHARACTER_NEWLINE_REGEX " *((]*/?>|\r|\n)+ *)+" #define TAG_MATCH_REGEX "<(b|i|u|big|a|img|span|s|sub|small|tt|html|qt)\\b[^>]*>(.*?)|<(img|span|a)[^>]/>|<(img)[^>]*>" #define TAG_REPLACE_REGEX "<(b|i|u|big|a|img|span|s|sub|small|tt|html|qt)\\b[^>]*>|" struct _ReplaceMarkupData { gchar* regex; gchar* replacement; }; typedef struct _ReplaceMarkupData ReplaceMarkupData; static gchar* strip_html (const gchar *text, const gchar *match_regex, const gchar* replace_regex) { GRegex *regex; gchar *ret; gboolean match = FALSE; GMatchInfo *info = NULL; regex = g_regex_new (match_regex, G_REGEX_DOTALL | G_REGEX_OPTIMIZE, 0, NULL); match = g_regex_match (regex, text, 0, &info); g_regex_unref (regex); if (match) { regex = g_regex_new (replace_regex, G_REGEX_DOTALL | G_REGEX_OPTIMIZE, 0, NULL); ret = g_regex_replace (regex, text, -1, 0, "", 0, NULL); g_regex_unref (regex); } else { ret = g_strdup (text); } if (info) g_match_info_free (info); return ret; } static gchar* replace_markup (const gchar *text, const gchar *match_regex, const gchar *replace_text) { GRegex *regex; gchar *ret; regex = g_regex_new (match_regex, G_REGEX_DOTALL | G_REGEX_OPTIMIZE, 0, NULL); ret = g_regex_replace (regex, text, -1, 0, replace_text, 0, NULL); g_regex_unref (regex); return ret; } gchar* filter_text (const gchar *text) { gchar *text1; text1 = strip_html (text, TAG_MATCH_REGEX, TAG_REPLACE_REGEX); static ReplaceMarkupData data[] = { { CHARACTER_AMP_REGEX, "&" }, { CHARACTER_LT_REGEX, "<" }, { CHARACTER_GT_REGEX, ">" }, { CHARACTER_APOS_REGEX, "'" }, { CHARACTER_QUOT_REGEX, "\"" }, { CHARACTER_NEWLINE_REGEX, "\n" } }; ReplaceMarkupData* ptr = data; ReplaceMarkupData* end = data + sizeof(data) / sizeof(ReplaceMarkupData); for (; ptr != end; ++ptr) { gchar* tmp = replace_markup (text1, ptr->regex, ptr->replacement); g_free (text1); text1 = tmp; } return text1; } gchar* newline_to_space (const gchar *text) { gchar *text1; text1 = strip_html (text, TAG_MATCH_REGEX, TAG_REPLACE_REGEX); static ReplaceMarkupData data[] = { { CHARACTER_NEWLINE_REGEX, " " } }; ReplaceMarkupData* ptr = data; ReplaceMarkupData* end = data + sizeof(data) / sizeof(ReplaceMarkupData); for (; ptr != end; ++ptr) { gchar* tmp = replace_markup (text1, ptr->regex, ptr->replacement); g_free (text1); text1 = tmp; } return text1; } cairo_surface_t* copy_surface (cairo_surface_t* orig) { cairo_surface_t* copy = NULL; cairo_format_t format; gint width; gint height; cairo_t* cr; double x_scale; double y_scale; width = cairo_image_surface_get_width (orig); height = cairo_image_surface_get_height (orig); format = cairo_image_surface_get_format (orig); cairo_surface_get_device_scale (orig, &x_scale, &y_scale); copy = cairo_surface_create_similar_image (orig, format, width, height); cairo_surface_set_device_scale (copy, x_scale, y_scale); cr = cairo_create (copy); cairo_set_source_surface (cr, orig, 0, 0); cairo_paint (cr); cairo_destroy (cr); return copy; } // code of get_wm_name() based in large chunks on www.amsn-project.net gchar* get_wm_name (Display* dpy) { int screen; Atom type; int format; unsigned long bytes_returned; unsigned long n_returned; unsigned char* buffer; Window* child; Window root; Atom supwmcheck; Atom wmname; if (!dpy) return NULL; screen = DefaultScreen (dpy); root = RootWindow (dpy, screen); supwmcheck = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False); wmname = XInternAtom (dpy, "_NET_WM_NAME", False); XGetWindowProperty (dpy, root, supwmcheck, 0, 8, False, AnyPropertyType, &type, &format, &n_returned, &bytes_returned, &buffer); child = (Window*) buffer; if (n_returned != 1) return NULL; XGetWindowProperty (dpy, *child, wmname, 0, 128, False, AnyPropertyType, &type, &format, &n_returned, &bytes_returned, &buffer); if (n_returned == 0) return NULL; XFree (child); // example wm-names as reported by get_wm_name() // // compiz // Metacity // Xfwm4 // KWin // xmonad return (gchar*) buffer; } GString* extract_font_face (const gchar* string) { GRegex* regex = NULL; GMatchInfo* match_info = NULL; GString* font_face = NULL; // sanity check if (!string) return NULL; // extract font-face-name/style font_face = g_string_new (""); if (!font_face) return NULL; // setup regular expression to extract leading text before trailing int regex = g_regex_new ("([A-Z a-z])+", 0, 0, NULL); // walk the string g_regex_match (regex, string, 0, &match_info); while (g_match_info_matches (match_info)) { gchar* word = NULL; word = g_match_info_fetch (match_info, 0); if (word) { g_string_append (font_face, word); g_free (word); } g_match_info_next (match_info, NULL); } // clean up g_match_info_free (match_info); g_regex_unref (regex); return font_face; } ./src/apport.c0000644000004100000410000000264513570225707013522 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** apport.c - apport hooks for triggering bug-reports on non-spec notifications ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include void apport_report (const gchar* app_name, const gchar* summary, gchar** actions, gint timeout) { /* call /usr/share/apport/notification_hook passing all the arguments in the request */ } ./src/dnd.h0000644000004100000410000000303413570225707012760 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** dnd.h - implements the "do not disturb"-mode, e.g. screensaver, presentations ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __DND_H #define __DNS_H G_BEGIN_DECLS /* Tries to determine whether the user is in "do not disturb" mode */ gboolean dnd_dont_disturb_user (void); gboolean dnd_is_xscreensaver_active (void); gboolean dnd_is_idle_inhibited (void); gboolean dnd_is_screensaver_active (void); gboolean dnd_has_one_fullscreen_window (void); G_END_DECLS #endif /* __DND_H */ ./src/timings.c0000644000004100000410000002645513570225707013674 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // timings.c - timings object handling duration and max. on-screen time // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include "timings.h" G_DEFINE_TYPE (Timings, timings, G_TYPE_OBJECT); #define GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), TIMINGS_TYPE, TimingsPrivate)) struct _TimingsPrivate { GTimer* on_screen_timer; GTimer* duration_timer; GTimer* paused_timer; guint timeout_id; guint max_timeout_id; guint scheduled_duration; // value interpreted as milliseconds guint max_duration; // value interpreted as milliseconds gboolean is_started; gboolean is_paused; }; enum { COMPLETED, LIMIT_REACHED, LAST_SIGNAL }; //-- private functions --------------------------------------------------------- static guint g_timings_signals[LAST_SIGNAL] = { 0 }; guint _ms_elapsed (GTimer* timer) { gulong microseconds; gulong milliseconds; gdouble duration; gdouble seconds; // sanity check g_assert (timer != NULL); // get elapsed time duration = g_timer_elapsed (timer, µseconds); // convert result to milliseconds ... milliseconds = microseconds / 1000; modf (duration, &seconds); // ... and return it return seconds * 1000 + milliseconds; } gboolean _emit_completed (gpointer data) { Timings* t; if (!data) return TRUE; t = (Timings*) data; if (!t || !IS_TIMINGS (t)) return TRUE; g_signal_emit (t, g_timings_signals[COMPLETED], 0); return FALSE; } gboolean _emit_limit_reached (gpointer data) { Timings* t; if (!data) return TRUE; t = (Timings*) data; if (!t || !IS_TIMINGS (t)) return TRUE; g_signal_emit (t, g_timings_signals[LIMIT_REACHED], 0); return FALSE; } void _debug_output (TimingsPrivate* priv) { if (g_getenv ("DEBUG")) { g_print ("\non-screen time: %d seconds, %d ms.\n", _ms_elapsed (priv->on_screen_timer) / 1000, _ms_elapsed (priv->on_screen_timer) % 1000); g_print ("paused time : %d seconds, %d ms.\n", _ms_elapsed (priv->paused_timer) / 1000, _ms_elapsed (priv->paused_timer) % 1000); g_print ("unpaused time : %d seconds, %d ms.\n", _ms_elapsed (priv->duration_timer) / 1000, _ms_elapsed (priv->duration_timer) % 1000); g_print ("scheduled time: %d seconds, %d ms.\n", priv->scheduled_duration / 1000, priv->scheduled_duration % 1000); } } //-- internal functions -------------------------------------------------------- // this is what gets called if one does g_object_unref(bla) static void timings_dispose (GObject* gobject) { Timings* t; TimingsPrivate* priv; // sanity checks g_assert (gobject); t = TIMINGS (gobject); g_assert (t); g_assert (IS_TIMINGS (t)); priv = GET_PRIVATE (t); g_assert (priv); // free any allocated resources if (priv->on_screen_timer) { g_timer_destroy (priv->on_screen_timer); priv->on_screen_timer = NULL; } if (priv->duration_timer) { g_timer_destroy (priv->duration_timer); priv->duration_timer = NULL; } if (priv->paused_timer) { g_timer_destroy (priv->paused_timer); priv->paused_timer = NULL; } if (priv->timeout_id != 0) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } if (priv->max_timeout_id != 0) { g_source_remove (priv->max_timeout_id); priv->max_timeout_id = 0; } // chain up to the parent class G_OBJECT_CLASS (timings_parent_class)->dispose (gobject); } static void timings_finalize (GObject* gobject) { // chain up to the parent class G_OBJECT_CLASS (timings_parent_class)->finalize (gobject); } static void timings_init (Timings* self) { // If you need specific construction properties to complete // initialization, delay initialization completion until the // property is set. } static void timings_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { switch (prop) { default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void timings_class_init (TimingsClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (TimingsPrivate)); gobject_class->dispose = timings_dispose; gobject_class->finalize = timings_finalize; gobject_class->get_property = timings_get_property; g_timings_signals[COMPLETED] = g_signal_new ( "completed", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (TimingsClass, completed), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); g_timings_signals[LIMIT_REACHED] = g_signal_new ( "limit-reached", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (TimingsClass, limit_reached), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } //-- public functions ---------------------------------------------------------- Timings* timings_new (guint scheduled_duration, guint max_duration) { Timings* this; TimingsPrivate* priv; // verify the caller is not stupid if (scheduled_duration > max_duration) return NULL; this = g_object_new (TIMINGS_TYPE, NULL); if (!this) return NULL; priv = GET_PRIVATE (this); priv->on_screen_timer = g_timer_new (); g_timer_stop (priv->on_screen_timer); priv->duration_timer = g_timer_new (); g_timer_stop (priv->duration_timer); priv->paused_timer = g_timer_new (); g_timer_stop (priv->paused_timer); priv->scheduled_duration = scheduled_duration; priv->max_duration = max_duration; priv->is_started = FALSE; priv->is_paused = FALSE; return this; } gboolean timings_start (Timings* t) { TimingsPrivate* priv; // sanity checks if (!t) return FALSE; priv = GET_PRIVATE (t); if (!priv) return FALSE; // if we have been started already return early if (priv->is_started) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Already started!\n"); return FALSE; } // install and start the two timeout-handlers priv->timeout_id = g_timeout_add (priv->scheduled_duration, _emit_completed, (gpointer) t); priv->max_timeout_id = g_timeout_add (priv->max_duration, _emit_limit_reached, (gpointer) t); // let the on-screen- and duration-timers tick g_timer_continue (priv->on_screen_timer); g_timer_continue (priv->duration_timer); // indicate that we started priv->is_started = TRUE; return TRUE; } gboolean timings_stop (Timings* t) { TimingsPrivate* priv; // sanity checks if (!t) return FALSE; priv = GET_PRIVATE (t); if (!priv) return FALSE; // if we have not been started, return early if (!priv->is_started) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Can't stop something, which " "is not started yet!\n"); return FALSE; } // get rid of timeouts if (!priv->is_paused) { // remove timeout for normal scheduled duration g_source_remove (priv->timeout_id); priv->timeout_id = 0; } // remove timeout enforcing max. time-limit g_source_remove (priv->max_timeout_id); priv->max_timeout_id = 0; // halt all timers if (priv->is_paused) g_timer_stop (priv->paused_timer); else { g_timer_stop (priv->on_screen_timer); g_timer_stop (priv->duration_timer); } // indicate that we stopped (means also not paused) priv->is_started = FALSE; priv->is_paused = FALSE; // spit out some debugging information _debug_output (priv); return TRUE; } gboolean timings_pause (Timings* t) { TimingsPrivate* priv; // sanity checks if (!t) return FALSE; priv = GET_PRIVATE (t); if (!priv) return FALSE; // only if we have been started it makes sense pause if (!priv->is_started) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Can't pause something, which " " is not started yet!\n"); return FALSE; } // don't halt if we are already paused if (priv->is_paused) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Already paused!\n"); return FALSE; } // make paused-timer tick again, hold duration-timer and update flag g_timer_continue (priv->paused_timer); g_timer_stop (priv->duration_timer); priv->is_paused = TRUE; // get rid of old timeout g_source_remove (priv->timeout_id); priv->timeout_id = 0; return TRUE; } gboolean timings_continue (Timings* t) { TimingsPrivate* priv; guint extension; // sanity checks if (!t) return FALSE; priv = GET_PRIVATE (t); if (!priv) return FALSE; // only if we have been started it makes sense to move on if (!priv->is_started) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Can't continue something, " "which is not started yet!\n"); return FALSE; } // don't continue if we are not paused if (!priv->is_paused) { if (g_getenv ("DEBUG")) g_print ("\n*** WARNING: Already running!\n"); return FALSE; } // make duration-timer tick again, hold paused-timer and update flag g_timer_continue (priv->duration_timer); g_timer_stop (priv->paused_timer); priv->is_paused = FALSE; // put new timeout in place extension = priv->scheduled_duration - _ms_elapsed (priv->duration_timer); priv->timeout_id = g_timeout_add (extension, _emit_completed, (gpointer) t); g_assert (priv->timeout_id != 0); return TRUE; } gboolean timings_extend (Timings* t, guint extension) { TimingsPrivate* priv; guint on_screen_time; // value interpreted as milliseconds // sanity checks if (!t) return FALSE; priv = GET_PRIVATE (t); if (!priv) return FALSE; // you never know how stupid the caller may be if (extension == 0) return FALSE; // only if we have been started we can extend if (!priv->is_started) return FALSE; // if paused only update scheduled duration and return if (priv->is_paused) { if (priv->scheduled_duration + extension > priv->max_duration) priv->scheduled_duration = priv->max_duration; else priv->scheduled_duration += extension; return TRUE; } // get rid of old timeout g_source_remove (priv->timeout_id); // ensure we don't overshoot limit with the on-screen time on_screen_time = _ms_elapsed (priv->duration_timer); if (priv->scheduled_duration + extension > priv->max_duration) { extension = priv->max_duration - on_screen_time; priv->scheduled_duration = priv->max_duration; } else { priv->scheduled_duration += extension; extension = priv->scheduled_duration - on_screen_time; } // add new timeout priv->timeout_id = g_timeout_add (extension, _emit_completed, (gpointer) t); return TRUE; } ./src/notification.c0000644000004100000410000004274513570225707014710 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // notification.c - notification object storing attributes like title- and body- // text, value, icon, id, sender-pid etc. // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include "notification.h" G_DEFINE_TYPE (Notification, notification, G_TYPE_OBJECT); enum { PROP_DUMMY = 0, PROP_ID, PROP_TITLE, PROP_BODY, PROP_VALUE, PROP_ICON_THEMENAME, PROP_ICON_FILENAME, PROP_ICON_PIXBUF, PROP_ONSCREEN_TIME, PROP_SENDER_NAME, PROP_SENDER_PID, PROP_TIMESTAMP, PROP_URGENCY }; #define GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), NOTIFICATION_TYPE, NotificationPrivate)) struct _NotificationPrivate { gint id; // unique notification-id GString* title; // summary-text strdup'ed from setter GString* body; // body-text strdup'ed from setter gint value; // range: 0..100, special: -1, 101 GString* icon_themename; // e.g. "notification-message-email" GString* icon_filename; // e.g. "/usr/share/icons/icon.png" GdkPixbuf* icon_pixbuf; // from setter memcpy'ed pixbuf gint onscreen_time; // time on-screen in ms GString* sender_name; // app-name, strdup'ed from setter gint sender_pid; // pid of sending application GTimeVal timestamp; // timestamp of reception Urgency urgency; // urgency-level: low, normal, high }; #define RETURN_GCHAR(n, string)\ NotificationPrivate* priv;\ g_return_val_if_fail (IS_NOTIFICATION (n), NULL);\ priv = GET_PRIVATE (n);\ if (!priv->string)\ return NULL;\ return GET_PRIVATE (n)->string->str; #define SET_GCHAR(n, string)\ NotificationPrivate* priv;\ g_assert (IS_NOTIFICATION (n));\ if (!string)\ return;\ priv = GET_PRIVATE (n);\ if (priv->string)\ {\ g_string_free (priv->string, TRUE);\ priv->string = NULL;\ }\ priv->string = g_string_new (string); //-- private functions --------------------------------------------------------- //-- internal functions -------------------------------------------------------- // this is what gets called if one does g_object_unref(bla) static void notification_dispose (GObject* gobject) { Notification* n; NotificationPrivate* priv; // sanity checks g_assert (gobject); n = NOTIFICATION (gobject); g_assert (n); g_assert (IS_NOTIFICATION (n)); priv = GET_PRIVATE (n); g_assert (priv); // free any allocated resources if (priv->title) { g_string_free (priv->title, TRUE); priv->title = NULL; } if (priv->body) { g_string_free (priv->body, TRUE); priv->body = NULL; } if (priv->icon_themename) { g_string_free (priv->icon_themename, TRUE); priv->icon_themename = NULL; } if (priv->icon_filename) { g_string_free (priv->icon_filename, TRUE); priv->icon_filename = NULL; } if (priv->icon_pixbuf) { g_object_unref (priv->icon_pixbuf); } if (priv->sender_name) { g_string_free (priv->sender_name, TRUE); priv->sender_name = NULL; } // chain up to the parent class G_OBJECT_CLASS (notification_parent_class)->dispose (gobject); } static void notification_finalize (GObject* gobject) { // chain up to the parent class G_OBJECT_CLASS (notification_parent_class)->finalize (gobject); } static void notification_init (Notification* n) { // nothing to be done here for now } static void notification_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { Notification* n = NOTIFICATION (gobject); // sanity checks are done in public getters switch (prop) { case PROP_ID: g_value_set_int (value, notification_get_id (n)); break; case PROP_TITLE: g_value_set_string (value, notification_get_title (n)); break; case PROP_BODY: g_value_set_string (value, notification_get_body (n)); break; case PROP_VALUE: g_value_set_int (value, notification_get_value (n)); break; case PROP_ICON_THEMENAME: g_value_set_string (value, notification_get_icon_themename (n)); break; case PROP_ICON_FILENAME: g_value_set_string (value, notification_get_icon_filename (n)); break; case PROP_ICON_PIXBUF: g_value_set_pointer (value, notification_get_icon_pixbuf (n)); break; case PROP_ONSCREEN_TIME: g_value_set_int (value, notification_get_onscreen_time (n)); break; case PROP_SENDER_NAME: g_value_set_string (value, notification_get_sender_name (n)); break; case PROP_SENDER_PID: g_value_set_int (value, notification_get_sender_pid (n)); break; case PROP_TIMESTAMP: g_value_set_pointer (value, notification_get_timestamp (n)); break; case PROP_URGENCY: g_value_set_int (value, notification_get_urgency (n)); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void notification_set_property (GObject* gobject, guint prop, const GValue* value, GParamSpec* spec) { Notification* n = NOTIFICATION (gobject); // sanity checks are done in the public setters switch (prop) { case PROP_ID: notification_set_id (n, g_value_get_int (value)); break; case PROP_TITLE: notification_set_title (n, g_value_get_string (value)); break; case PROP_BODY: notification_set_body (n, g_value_get_string (value)); break; case PROP_VALUE: notification_set_value (n, g_value_get_int (value)); break; case PROP_ICON_THEMENAME: notification_set_icon_themename ( n, g_value_get_string (value)); break; case PROP_ICON_FILENAME: notification_set_icon_filename ( n, g_value_get_string (value)); break; case PROP_ICON_PIXBUF: notification_set_icon_pixbuf ( n, g_value_get_pointer (value)); break; case PROP_ONSCREEN_TIME: notification_set_onscreen_time ( n, g_value_get_int (value)); break; case PROP_SENDER_NAME: notification_set_sender_name ( n, g_value_get_string (value)); break; case PROP_SENDER_PID: notification_set_sender_pid ( n, g_value_get_int (value)); break; case PROP_TIMESTAMP: notification_set_timestamp ( n, g_value_get_pointer (value)); break; case PROP_URGENCY: notification_set_urgency ( n, g_value_get_int (value)); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void notification_class_init (NotificationClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); GParamSpec* property_id; GParamSpec* property_title; GParamSpec* property_body; GParamSpec* property_value; GParamSpec* property_icon_themename; GParamSpec* property_icon_filename; GParamSpec* property_icon_pixbuf; GParamSpec* property_onscreen_time; GParamSpec* property_sender_name; GParamSpec* property_sender_pid; GParamSpec* property_timestamp; GParamSpec* property_urgency; g_type_class_add_private (klass, sizeof (NotificationPrivate)); gobject_class->dispose = notification_dispose; gobject_class->finalize = notification_finalize; gobject_class->get_property = notification_get_property; gobject_class->set_property = notification_set_property; property_id = g_param_spec_int ("id", "id", "unique notification id", -1, G_MAXINT, -1, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_ID, property_id); property_title = g_param_spec_string ("title", "title", "title-text of a notification", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_TITLE, property_title); property_body = g_param_spec_string ("body", "body", "body-text of a notification", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_BODY, property_body); property_value = g_param_spec_int ("value", "value", "value between -1..101 to render", -2, 101, -2, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_VALUE, property_value); property_icon_themename = g_param_spec_string ( "icon-themename", "icon-themename", "theme-name of icon to use", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_ICON_THEMENAME, property_icon_themename); property_icon_filename = g_param_spec_string ( "icon-filename", "icon-filename", "file-name of icon to use", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_ICON_FILENAME, property_icon_filename); property_icon_pixbuf = g_param_spec_pointer ("icon-pixbuf", "icon-pixbuf", "pixbuf of icon to use", G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_ICON_PIXBUF, property_icon_pixbuf); property_onscreen_time = g_param_spec_int ("onscreen-time", "onscreen-time", "time on screen sofar", 0, G_MAXINT, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_ONSCREEN_TIME, property_onscreen_time); property_sender_name = g_param_spec_string ( "sender-name", "sender-name", "name of sending application", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_SENDER_NAME, property_sender_name); property_sender_pid = g_param_spec_int ( "sender-pid", "sender-pid", "process ID of sending application", 0, G_MAXSHORT, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_SENDER_PID, property_sender_pid); property_timestamp = g_param_spec_pointer ("timestamp", "timestamp", "timestamp of reception", G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_TIMESTAMP, property_timestamp); property_urgency = g_param_spec_int ("urgency", "urgency", "urgency-level of notification", URGENCY_LOW, URGENCY_NONE, URGENCY_NONE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_URGENCY, property_urgency); } //-- public functions ---------------------------------------------------------- Notification* notification_new () { const GTimeVal timestamp = {0}; return g_object_new (NOTIFICATION_TYPE, "timestamp", ×tamp, NULL); } gint notification_get_id (Notification* n) { g_return_val_if_fail (IS_NOTIFICATION (n), -1); return GET_PRIVATE (n)->id; } // -1 is meant to "unset" the id, 0 is the smallest possible PID, but very // unlikely to ever be passed around void notification_set_id (Notification* n, gint id) { g_assert (IS_NOTIFICATION (n)); // IDs can't be negative, except for -1 to indicate it's "unset" if (id < -1) return; GET_PRIVATE (n)->id = id; } gchar* notification_get_title (Notification* n) { RETURN_GCHAR (n, title) } void notification_set_title (Notification* n, const gchar* title) { SET_GCHAR (n, title) } gchar* notification_get_body (Notification* n) { RETURN_GCHAR (n, body) } void notification_set_body (Notification* n, const gchar* body) { SET_GCHAR (n, body) } // the allowed range for stored values is -1..101, thus a return-value of -2 // indicates an error on behalf of the caller gint notification_get_value (Notification* n) { g_return_val_if_fail (IS_NOTIFICATION (n), -2); return GET_PRIVATE (n)->value; } // valid range is -1..101, -2 is used to indicate it's "unset" void notification_set_value (Notification* n, gint value) { NotificationPrivate* priv; g_assert (IS_NOTIFICATION (n)); priv = GET_PRIVATE (n); // this is used to indicate the "unset" state if (value == -2) { priv->value = value; return; } // don't store any values outside of allowed range -1..101 if (value <= NOTIFICATION_VALUE_MIN_ALLOWED) { priv->value = NOTIFICATION_VALUE_MIN_ALLOWED; return; } if (value >= NOTIFICATION_VALUE_MAX_ALLOWED) { priv->value = NOTIFICATION_VALUE_MAX_ALLOWED; return; } priv->value = value; } gchar* notification_get_icon_themename (Notification* n) { RETURN_GCHAR (n, icon_themename) } void notification_set_icon_themename (Notification* n, const gchar* icon_themename) { SET_GCHAR (n, icon_themename) } gchar* notification_get_icon_filename (Notification* n) { RETURN_GCHAR (n, icon_filename) } void notification_set_icon_filename (Notification* n, const gchar* icon_filename) { SET_GCHAR (n, icon_filename) } GdkPixbuf* notification_get_icon_pixbuf (Notification* n) { NotificationPrivate* priv; g_return_val_if_fail (IS_NOTIFICATION (n), NULL); priv = GET_PRIVATE (n); if (!priv->icon_pixbuf) return NULL; return GET_PRIVATE (n)->icon_pixbuf; } void notification_set_icon_pixbuf (Notification* n, const GdkPixbuf* icon_pixbuf) { NotificationPrivate* priv; // sanity checks g_assert (IS_NOTIFICATION (n)); if (!icon_pixbuf) return; priv = GET_PRIVATE (n); // free any previous stored pixbuf if (priv->icon_pixbuf) { g_object_unref (priv->icon_pixbuf); priv->icon_pixbuf = NULL; } // create a new/private copy of the supplied pixbuf priv->icon_pixbuf = gdk_pixbuf_copy (icon_pixbuf); } // a return-value of -1 indicates an error on behalf of the caller, a // return-value of 0 would indicate that a notification has not been displayed // yet gint notification_get_onscreen_time (Notification* n) { g_return_val_if_fail (IS_NOTIFICATION (n), -1); return GET_PRIVATE (n)->onscreen_time; } // only onscreen_time values <= 0 are considered valid void notification_set_onscreen_time (Notification* n, gint onscreen_time) { NotificationPrivate* priv; g_assert (IS_NOTIFICATION (n)); priv = GET_PRIVATE (n); // avoid storing negative values if (onscreen_time < 0) return; // onscreen-time can only increase not decrease if (priv->onscreen_time > onscreen_time) return; // you made it upto here, congratulations... let's store the new value priv->onscreen_time = onscreen_time; } gchar* notification_get_sender_name (Notification* n) { RETURN_GCHAR (n, sender_name) } void notification_set_sender_name (Notification* n, const gchar* sender_name) { SET_GCHAR (n, sender_name) } // a return-value of 0 indicates an error on behalf of the caller, PIDs are // never negative gint notification_get_sender_pid (Notification* n) { g_return_val_if_fail (IS_NOTIFICATION (n), 0); return GET_PRIVATE (n)->sender_pid; } void notification_set_sender_pid (Notification* n, const gint sender_pid) { g_assert (IS_NOTIFICATION (n)); // it's hardly possible we'll get a notification from init, but anyway if (sender_pid <= 0) return; GET_PRIVATE (n)->sender_pid = sender_pid; } GTimeVal* notification_get_timestamp (Notification* n) { NotificationPrivate* priv; g_return_val_if_fail (IS_NOTIFICATION (n), NULL); priv = GET_PRIVATE (n); return &priv->timestamp; } void notification_set_timestamp (Notification* n, const GTimeVal* timestamp) { NotificationPrivate* priv; // sanity checks g_assert (IS_NOTIFICATION (n)); if (!timestamp) return; priv = GET_PRIVATE (n); // don't store older timestamp over newer one if (priv->timestamp.tv_sec > timestamp->tv_sec) return; if (priv->timestamp.tv_sec == timestamp->tv_sec) if (priv->timestamp.tv_usec > timestamp->tv_usec) return; // new timestamp certainly more current that stored one priv->timestamp.tv_sec = timestamp->tv_sec; priv->timestamp.tv_usec = timestamp->tv_usec; } gint notification_get_urgency (Notification* n) { g_return_val_if_fail (IS_NOTIFICATION (n), URGENCY_NONE); return GET_PRIVATE (n)->urgency; } void notification_set_urgency (Notification* n, Urgency urgency) { NotificationPrivate* priv; g_assert (IS_NOTIFICATION (n)); priv = GET_PRIVATE (n); // URGENCY_NONE is meant to indicate the "unset" state if (urgency == URGENCY_NONE) { priv->urgency = URGENCY_NONE; return; } // don't store any values outside of allowed range LOW..HIGH if (urgency != URGENCY_LOW && urgency != URGENCY_NORMAL && urgency != URGENCY_HIGH) return; GET_PRIVATE (n)->urgency = urgency; } ./src/dnd.c0000644000004100000410000001270313570225707012756 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** dnd.c - implements the "do not disturb"-mode, e.g. gsmgr, presentations ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "dbus.h" static DBusGProxy *gsmgr = NULL; static DBusGProxy *gscrsvr = NULL; gboolean dnd_is_xscreensaver_active () { GdkDisplay *display = gdk_display_get_default (); Atom XA_BLANK = gdk_x11_get_xatom_by_name_for_display(display, "BLANK"); Atom XA_LOCK = gdk_x11_get_xatom_by_name_for_display(display, "BLANK"); Atom XA_SCREENSAVER_STATUS = gdk_x11_get_xatom_by_name_for_display(display, "_SCREENSAVER_STATUS"); gboolean active = FALSE; Atom type; int format; int status; unsigned long nitems, bytesafter; unsigned char* data = NULL; Display *dpy = gdk_x11_get_default_xdisplay (); Window win = gdk_x11_get_default_root_xwindow (); gdk_error_trap_push (); status = XGetWindowProperty (dpy, win, XA_SCREENSAVER_STATUS, 0, 999, False, XA_INTEGER, &type, &format, &nitems, &bytesafter, (unsigned char **) &data); gdk_flush (); gdk_error_trap_pop_ignored (); if (status == Success && type == XA_INTEGER && nitems >= 3 && data != NULL) { CARD32* tmp_data = (CARD32*) data; active = (tmp_data[0] == XA_BLANK || tmp_data[0] == XA_LOCK) && ((time_t)tmp_data[1] > (time_t)666000000L); g_debug ("Screensaver is currently active"); } if (data != NULL) free (data); return active; } static DBusGProxy* get_gnomesession_proxy (void) { if (gsmgr == NULL) { DBusGConnection *connection = dbus_get_connection (); gsmgr = dbus_g_proxy_new_for_name (connection, "org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager"); } return gsmgr; } gboolean dnd_is_idle_inhibited () { GError *error = NULL; gboolean inhibited = FALSE; guint idle = 8; // 8: Inhibit the session being marked as idle if (! get_gnomesession_proxy ()) return FALSE; dbus_g_proxy_call_with_timeout ( gsmgr, "IsInhibited", 2000, &error, G_TYPE_UINT, idle, G_TYPE_INVALID, G_TYPE_BOOLEAN, &inhibited, G_TYPE_INVALID); if (error) { g_warning ("dnd_is_idle_inhibited(): " "got error \"%s\"\n", error->message); g_error_free (error); error = NULL; } if (inhibited) g_debug ("Session idleness has been inhibited"); return inhibited; } static DBusGProxy* get_screensaver_proxy (void) { if (gscrsvr == NULL) { DBusGConnection *connection = dbus_get_connection (); gscrsvr = dbus_g_proxy_new_for_name (connection, "org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver"); } return gscrsvr; } gboolean dnd_is_screensaver_active () { GError *error = NULL; gboolean active = FALSE;; if (! get_screensaver_proxy ()) return FALSE; dbus_g_proxy_call_with_timeout ( gscrsvr, "GetActive", 2000, &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &active, G_TYPE_INVALID); if (error) { g_warning ("dnd_is_screensaver_active(): Got error \"%s\"\n", error->message); g_error_free (error); error = NULL; } if (active) g_debug ("Gnome screensaver is active"); return active; } static gboolean dnd_is_online_presence_dnd () { /* TODO: ask FUSA if we're in DND mode */ return FALSE; } static int is_fullscreen_cb (WnckWindow *window, WnckWorkspace *workspace) { if (wnck_window_is_visible_on_workspace (window, workspace) && wnck_window_is_fullscreen (window)) { return 0; } else { return 1; } } gboolean dnd_has_one_fullscreen_window (void) { gboolean result; WnckScreen *screen = wnck_screen_get_default (); wnck_screen_force_update (screen); WnckWorkspace *workspace = wnck_screen_get_active_workspace (screen); GList *list = wnck_screen_get_windows (screen); GList *item = g_list_find_custom (list, workspace, (GCompareFunc) is_fullscreen_cb); result = item != NULL; #ifdef HAVE_WNCK_SHUTDOWN wnck_shutdown (); #endif return result; } /* Tries to determine whether the user is in "do not disturb" mode */ gboolean dnd_dont_disturb_user (void) { return (dnd_is_online_presence_dnd() || dnd_is_xscreensaver_active() || dnd_is_screensaver_active() || dnd_is_idle_inhibited() || dnd_has_one_fullscreen_window() ); } ./src/Makefile.am0000644000004100000410000000460313570225707014101 0ustar www-datawww-dataNULL = transform = s/_/-/g INCLUDES = \ -I. \ -I$(srcdir) \ -I$(top_srcdir) \ $(NULL) notify_osddir = $(libexecdir) notify_osd_PROGRAMS = \ notify-osd \ $(NULL) notify_osd_sources = \ bubble.c \ defaults.c \ dialog.c \ notification.c \ main.c \ observer.c \ stack.c \ dbus.c \ dnd.c \ apport.c \ log.c \ util.c \ timings.c \ stack-blur.c \ exponential-blur.c \ gaussian-blur.c \ raico-blur.c \ tile.c \ bubble-window.c \ bubble-window-accessible.c \ bubble-window-accessible-factory.c \ $(top_srcdir)/egg/egg-fixed.c \ $(top_srcdir)/egg/egg-units.c \ $(top_srcdir)/egg/egg-timeline.c \ $(top_srcdir)/egg/egg-timeout-pool.c \ $(top_srcdir)/egg/egg-alpha.c \ $(top_srcdir)/egg/egg-hack.c \ $(NULL) notify_osd_headers = \ bubble.h \ defaults.h \ dialog.h \ notification.h \ observer.h \ stack.h \ stack-glue.h \ dbus.h \ dnd.h \ log.h \ apport.h \ util.h \ timings.h \ stack-blur.h \ exponential-blur.h \ gaussian-blur.h \ raico-blur.h \ tile.h \ bubble-window.h \ bubble-window-accessible.h \ bubble-window-accessible-factory.h \ $(top_srcdir)/egg/egg-fixed.h \ $(top_srcdir)/egg/egg-units.h \ $(top_srcdir)/egg/egg-timeline.h \ $(top_srcdir)/egg/egg-timeout-pool.h \ $(top_srcdir)/egg/egg-alpha.h \ $(top_srcdir)/egg/egg-debug.h \ $(top_srcdir)/egg/egg-hack.h \ $(NULL) notify_osd_SOURCES = \ $(notify_osd_sources) \ $(notify_osd_headers) \ $(NULL) notify_osd_LDADD = \ $(LIBM) \ $(X_LIBS) \ $(GLIB_LIBS) \ $(GTK_LIBS) \ $(NOTIFY_OSD_LIBS) \ $(DBUS_LIBS) \ $(WNCK_LIBS) \ -lm \ $(NULL) notify_osd_CFLAGS = \ -DDATADIR=\""$(datadir)"\" \ $(GTK_CFLAGS) \ $(NOTIFY_OSD_CFLAGS) \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ -DWNCK_I_KNOW_THIS_IS_UNSTABLE \ $(WNCK_CFLAGS) \ $(INCLUDES) \ $(NULL) notify_osd_LDFLAGS = \ -Xlinker -lm -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions \ $(NULL) # this comes from distutils.sysconfig.get_config_var('LINKFORSHARED') stack-glue.h: notify-osd.xml Makefile $(LIBTOOL) --mode=execute $(DBUS_GLIB_BIN)/dbus-binding-tool --prefix=stack --mode=glib-server --output=$@ $< BUILT_SOURCES = \ stack-glue.h EXTRA_DIST = \ notify-osd.xml \ dialog.c \ display.c \ $(NULL) dist-hook: cd $(distdir) ; rm -f $(CLEANFILES) DISTCLEANFILES = $(BUILT_SOURCES) ./src/defaults.c0000644000004100000410000013656313570225707014033 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** defaults.c - a singelton providing all default values for sizes, colors etc. ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** Contributor(s): ** Chow Loong Jin (fix for LP: #401809, rev. 349) ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #include #include #include "defaults.h" #include "util.h" G_DEFINE_TYPE (Defaults, defaults, G_TYPE_OBJECT); enum { PROP_DUMMY = 0, PROP_DESKTOP_BOTTOM_GAP, PROP_STACK_HEIGHT, PROP_BUBBLE_VERT_GAP, PROP_BUBBLE_HORZ_GAP, PROP_BUBBLE_WIDTH, PROP_BUBBLE_MIN_HEIGHT, PROP_BUBBLE_MAX_HEIGHT, PROP_BUBBLE_SHADOW_SIZE, PROP_BUBBLE_SHADOW_COLOR, PROP_BUBBLE_BG_COLOR, PROP_BUBBLE_BG_OPACITY, PROP_BUBBLE_HOVER_OPACITY, PROP_BUBBLE_CORNER_RADIUS, PROP_CONTENT_SHADOW_SIZE, PROP_CONTENT_SHADOW_COLOR, PROP_MARGIN_SIZE, PROP_ICON_SIZE, PROP_GAUGE_SIZE, PROP_GAUGE_OUTLINE_WIDTH, PROP_FADE_IN_TIMEOUT, PROP_FADE_OUT_TIMEOUT, PROP_ON_SCREEN_TIMEOUT, PROP_TEXT_FONT_FACE, PROP_TEXT_TITLE_COLOR, PROP_TEXT_TITLE_WEIGHT, PROP_TEXT_TITLE_SIZE, PROP_TEXT_BODY_COLOR, PROP_TEXT_BODY_WEIGHT, PROP_TEXT_BODY_SIZE, PROP_PIXELS_PER_EM, PROP_SYSTEM_FONT_SIZE, PROP_SCREEN_DPI, PROP_GRAVITY }; enum { VALUE_CHANGED, GRAVITY_CHANGED, LAST_SIGNAL }; enum { R = 0, G, B }; /* taking hints from Pango here, Qt looks a bit different*/ enum { TEXT_WEIGHT_LIGHT = 300, /* QFont::Light 25 */ TEXT_WEIGHT_NORMAL = 400, /* QFont::Normal 50 */ TEXT_WEIGHT_BOLD = 700 /* QFont::Bold 75 */ }; /* these values are interpreted as em-measurements and do comply to the * visual guide for jaunty-notifications */ #define DEFAULT_DESKTOP_BOTTOM_GAP 6.0f #define DEFAULT_BUBBLE_WIDTH 24.0f #define DEFAULT_BUBBLE_MIN_HEIGHT 5.0f #define DEFAULT_BUBBLE_MAX_HEIGHT 12.2f #define DEFAULT_BUBBLE_VERT_GAP 0.5f #define DEFAULT_BUBBLE_HORZ_GAP 0.5f #define DEFAULT_BUBBLE_SHADOW_SIZE 0.7f #define DEFAULT_BUBBLE_SHADOW_COLOR "#000000" #define DEFAULT_BUBBLE_BG_COLOR "#131313" #define DEFAULT_BUBBLE_BG_OPACITY "#cc" #define DEFAULT_BUBBLE_HOVER_OPACITY "#66" #define DEFAULT_BUBBLE_CORNER_RADIUS 0.375f #define DEFAULT_CONTENT_SHADOW_SIZE 0.125f #define DEFAULT_CONTENT_SHADOW_COLOR "#000000" #define DEFAULT_MARGIN_SIZE 1.0f #define DEFAULT_ICON_SIZE 3.0f #define DEFAULT_GAUGE_SIZE 0.625f #define DEFAULT_GAUGE_OUTLINE_WIDTH 0.125f #define DEFAULT_TEXT_FONT_FACE "Sans" #define DEFAULT_TEXT_TITLE_COLOR "#ffffff" #define DEFAULT_TEXT_TITLE_WEIGHT TEXT_WEIGHT_BOLD #define DEFAULT_TEXT_TITLE_SIZE 1.0f #define DEFAULT_TEXT_BODY_COLOR "#eaeaea" #define DEFAULT_TEXT_BODY_WEIGHT TEXT_WEIGHT_NORMAL #define DEFAULT_TEXT_BODY_SIZE 0.9f #define DEFAULT_PIXELS_PER_EM 10.0f #define DEFAULT_SYSTEM_FONT_SIZE 10.0f #define DEFAULT_SCREEN_DPI 96.0f #define DEFAULT_GRAVITY GRAVITY_NORTH_EAST /* these values are interpreted as milliseconds-measurements and do comply to * the visual guide for jaunty-notifications */ #define DEFAULT_FADE_IN_TIMEOUT 250 #define DEFAULT_FADE_OUT_TIMEOUT 1000 #define DEFAULT_ON_SCREEN_TIMEOUT 10000 /* notify-osd settings */ #define NOTIFY_OSD_SCHEMA "com.canonical.notify-osd" #define GSETTINGS_GRAVITY_KEY "gravity" #define GSETTINGS_MULTIHEAD_MODE_KEY "multihead-mode" /* gnome settings */ #define GNOME_DESKTOP_SCHEMA "org.gnome.desktop.interface" #define GSETTINGS_FONT_KEY "font-name" /* unity settings */ #define UNITY_SCHEMA "com.canonical.Unity" #define GSETTINGS_AVG_BG_COL_KEY "average-bg-color" static guint g_defaults_signals[LAST_SIGNAL] = { 0 }; /*-- internal API ------------------------------------------------------------*/ static void _get_font_size_dpi (Defaults* self) { GString* string = NULL; gdouble points = 0.0f; GString* font_face = NULL; gdouble dpi = 0.0f; gdouble pixels_per_em = 0; gchar* font_name = NULL; PangoFontDescription* desc = NULL; GtkSettings* gtk_settings = NULL; gint value = 0; if (!IS_DEFAULTS (self)) return; /* determine current system font-name/size */ font_name = g_settings_get_string (self->gnome_settings, GSETTINGS_FONT_KEY); string = g_string_new (font_name); // extract text point-size desc = pango_font_description_from_string (font_name); if (pango_font_description_get_size_is_absolute (desc)) points = (gdouble) pango_font_description_get_size (desc); else points = (gdouble) pango_font_description_get_size (desc) / (gdouble) PANGO_SCALE; pango_font_description_free (desc); g_free ((gpointer) font_name); // extract font-face-name/style font_face = extract_font_face (string->str); if (string != NULL) g_string_free (string, TRUE); /* update stored font-face name and clean up */ if (font_face != NULL) { g_object_set (self, "text-font-face", font_face->str, NULL); g_string_free (font_face, TRUE); } /* update stored system-font size (in pt!) */ g_object_set (self, "system-font-size", (gdouble) points, NULL); /* determine current system DPI-setting */ gtk_settings = gtk_settings_get_default (); // not ref'ed g_object_get (gtk_settings, "gtk-xft-dpi", &value, NULL); dpi = (float) value / (float) 1024; /* update stored DPI-value */ pixels_per_em = points * dpi / 72.0f; g_object_set (self, "pixels-per-em", pixels_per_em, NULL); g_object_set (self, "screen-dpi", dpi, NULL); if (g_getenv ("DEBUG")) g_print ("font-size: %fpt\ndpi: %3.1f\npixels/EM: %2.2f\nwidth: %d px\ntitle-height: %2.2f pt\nbody-height: %2.2f pt\n\n", points, defaults_get_screen_dpi (self), pixels_per_em, (gint) (pixels_per_em * DEFAULT_BUBBLE_WIDTH), defaults_get_system_font_size (self) * defaults_get_text_title_size (self), defaults_get_system_font_size (self) * defaults_get_text_body_size (self)); } static void _get_gravity (Defaults* self) { Gravity gravity = DEFAULT_GRAVITY; if (!IS_DEFAULTS (self)) return; // grab current gravity-setting for notify-osd from GSettings gravity = g_settings_get_int (self->nosd_settings, GSETTINGS_GRAVITY_KEY); // protect against out-of-bounds values for gravity if (gravity != GRAVITY_EAST && gravity != GRAVITY_NORTH_EAST) gravity = DEFAULT_GRAVITY; // update stored DPI-value g_object_set (self, "gravity", gravity, NULL); } static void _font_changed (GSettings* settings, gchar* key, gpointer data) { Defaults* defaults; if (!data) return; defaults = (Defaults*) data; if (!IS_DEFAULTS (defaults)) return; /* grab system-wide font-face/size and DPI */ _get_font_size_dpi (defaults); g_signal_emit (defaults, g_defaults_signals[VALUE_CHANGED], 0); } static void _gravity_changed (GSettings* settings, gchar* key, gpointer data) { Defaults* defaults; if (!data) return; defaults = (Defaults*) data; if (!IS_DEFAULTS (defaults)) return; // grab gravity setting for notify-osd from gconf _get_gravity (defaults); g_signal_emit (defaults, g_defaults_signals[GRAVITY_CHANGED], 0); } void defaults_refresh_bg_color_property (Defaults *self) { Atom real_type; gint result; gint real_format; gulong items_read; gulong items_left; gchar* colors; Atom representative_colors_atom; Display* display; g_return_if_fail ((self != NULL) && IS_DEFAULTS (self)); representative_colors_atom = gdk_x11_get_xatom_by_name ("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"); display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); gdk_error_trap_push (); result = XGetWindowProperty (display, GDK_ROOT_WINDOW (), representative_colors_atom, 0L, G_MAXLONG, False, XA_STRING, &real_type, &real_format, &items_read, &items_left, (guchar **) &colors); gdk_flush (); gdk_error_trap_pop_ignored (); if (result == Success && items_read) { /* by treating the result as a nul-terminated string, we * select the first colour in the list. */ g_object_set (self, "bubble-bg-color", colors, NULL); XFree (colors); } } static void defaults_constructed (GObject* gobject) { Defaults* self; gdouble margin_size; gdouble icon_size; gdouble bubble_height; gdouble new_bubble_height; GdkScreen* screen; gint x; gint y; self = DEFAULTS (gobject); defaults_get_top_corner (self, &screen, &x, &y); defaults_refresh_bg_color_property (self); /* grab system-wide font-face/size and DPI */ _get_font_size_dpi (self); _get_gravity (self); /* correct the default min. bubble-height, according to the icon-size */ g_object_get (self, "margin-size", &margin_size, NULL); g_object_get (self, "icon-size", &icon_size, NULL); g_object_get (self, "bubble-min-height", &bubble_height, NULL); #if 0 /* try to register the non-standard size for the gtk_icon_theme_lookup calls to work */ gtk_icon_size_register ("52x52", pixels_per_em * icon_size, pixels_per_em * icon_size); #endif new_bubble_height = 2.0f * margin_size + icon_size; if (new_bubble_height > bubble_height) { g_object_set (self, "bubble-min-height", new_bubble_height, NULL); } /* FIXME: calling this here causes a segfault */ /* chain up to the parent class */ /*G_OBJECT_CLASS (defaults_parent_class)->constructed (gobject);*/ } static void defaults_dispose (GObject* gobject) { Defaults* defaults; defaults = DEFAULTS (gobject); g_object_unref (defaults->nosd_settings); g_object_unref (defaults->gnome_settings); if (defaults->bubble_shadow_color) { g_string_free (defaults->bubble_shadow_color, TRUE); defaults->bubble_shadow_color = NULL; } if (defaults->bubble_bg_color) { g_string_free (defaults->bubble_bg_color, TRUE); defaults->bubble_bg_color = NULL; } if (defaults->bubble_bg_opacity) { g_string_free (defaults->bubble_bg_opacity, TRUE); defaults->bubble_bg_opacity = NULL; } if (defaults->bubble_hover_opacity) { g_string_free (defaults->bubble_hover_opacity, TRUE); defaults->bubble_hover_opacity = NULL; } if (defaults->content_shadow_color) { g_string_free (defaults->content_shadow_color, TRUE); defaults->content_shadow_color = NULL; } if (defaults->text_font_face) { g_string_free (defaults->text_font_face, TRUE); defaults->text_font_face = NULL; } if (defaults->text_title_color) { g_string_free (defaults->text_title_color, TRUE); defaults->text_title_color = NULL; } if (defaults->text_body_color) { g_string_free (defaults->text_body_color, TRUE); defaults->text_body_color = NULL; } // chain up to the parent class G_OBJECT_CLASS (defaults_parent_class)->dispose (gobject); } static void defaults_finalize (GObject* gobject) { // chain up to the parent class G_OBJECT_CLASS (defaults_parent_class)->finalize (gobject); } static void defaults_init (Defaults* self) { /* "connect" to the required GSettings schemas */ self->nosd_settings = g_settings_new (NOTIFY_OSD_SCHEMA); self->gnome_settings = g_settings_new (GNOME_DESKTOP_SCHEMA); g_signal_connect (self->gnome_settings, "changed", G_CALLBACK (_font_changed), self); g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi", G_CALLBACK (_font_changed), self); g_signal_connect (self->nosd_settings, "changed", G_CALLBACK (_gravity_changed), self); // use fixed slot-allocation for async. and sync. bubbles self->slot_allocation = SLOT_ALLOCATION_FIXED; } static void defaults_get_property (GObject* gobject, guint prop, GValue* value, GParamSpec* spec) { Defaults* defaults; defaults = DEFAULTS (gobject); switch (prop) { case PROP_DESKTOP_BOTTOM_GAP: g_value_set_double (value, defaults->desktop_bottom_gap); break; case PROP_STACK_HEIGHT: g_value_set_double (value, defaults->stack_height); break; case PROP_BUBBLE_VERT_GAP: g_value_set_double (value, defaults->bubble_vert_gap); break; case PROP_BUBBLE_HORZ_GAP: g_value_set_double (value, defaults->bubble_horz_gap); break; case PROP_BUBBLE_WIDTH: g_value_set_double (value, defaults->bubble_width); break; case PROP_BUBBLE_MIN_HEIGHT: g_value_set_double (value, defaults->bubble_min_height); break; case PROP_BUBBLE_MAX_HEIGHT: g_value_set_double (value, defaults->bubble_max_height); break; case PROP_BUBBLE_SHADOW_SIZE: g_value_set_double (value, defaults->bubble_shadow_size); break; case PROP_BUBBLE_SHADOW_COLOR: g_value_set_string (value, defaults->bubble_shadow_color->str); break; case PROP_BUBBLE_BG_COLOR: g_value_set_string (value, defaults->bubble_bg_color->str); break; case PROP_BUBBLE_BG_OPACITY: g_value_set_string (value, defaults->bubble_bg_opacity->str); break; case PROP_BUBBLE_HOVER_OPACITY: g_value_set_string (value, defaults->bubble_hover_opacity->str); break; case PROP_BUBBLE_CORNER_RADIUS: g_value_set_double (value, defaults->bubble_corner_radius); break; case PROP_CONTENT_SHADOW_SIZE: g_value_set_double (value, defaults->content_shadow_size); break; case PROP_CONTENT_SHADOW_COLOR: g_value_set_string (value, defaults->content_shadow_color->str); break; case PROP_MARGIN_SIZE: g_value_set_double (value, defaults->margin_size); break; case PROP_ICON_SIZE: g_value_set_double (value, defaults->icon_size); break; case PROP_GAUGE_SIZE: g_value_set_double (value, defaults->gauge_size); break; case PROP_GAUGE_OUTLINE_WIDTH: g_value_set_double (value, defaults->gauge_outline_width); break; case PROP_FADE_IN_TIMEOUT: g_value_set_int (value, defaults->fade_in_timeout); break; case PROP_FADE_OUT_TIMEOUT: g_value_set_int (value, defaults->fade_out_timeout); break; case PROP_ON_SCREEN_TIMEOUT: g_value_set_int (value, defaults->on_screen_timeout); break; case PROP_TEXT_FONT_FACE: g_value_set_string (value, defaults->text_font_face->str); break; case PROP_TEXT_TITLE_COLOR: g_value_set_string (value, defaults->text_title_color->str); break; case PROP_TEXT_TITLE_WEIGHT: g_value_set_int (value, defaults->text_title_weight); break; case PROP_TEXT_TITLE_SIZE: g_value_set_double (value, defaults->text_title_size); break; case PROP_TEXT_BODY_COLOR: g_value_set_string (value, defaults->text_body_color->str); break; case PROP_TEXT_BODY_WEIGHT: g_value_set_int (value, defaults->text_body_weight); break; case PROP_TEXT_BODY_SIZE: g_value_set_double (value, defaults->text_body_size); break; case PROP_PIXELS_PER_EM: g_value_set_double (value, defaults->pixels_per_em); break; case PROP_SYSTEM_FONT_SIZE: g_value_set_double (value, defaults->system_font_size); break; case PROP_SCREEN_DPI: g_value_set_double (value, defaults->screen_dpi); break; case PROP_GRAVITY: g_value_set_int (value, defaults->gravity); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void defaults_set_property (GObject* gobject, guint prop, const GValue* value, GParamSpec* spec) { Defaults* defaults; defaults = DEFAULTS (gobject); switch (prop) { case PROP_DESKTOP_BOTTOM_GAP: defaults->desktop_bottom_gap = g_value_get_double (value); break; case PROP_STACK_HEIGHT: defaults->stack_height = g_value_get_double (value); break; case PROP_BUBBLE_WIDTH: defaults->bubble_width = g_value_get_double (value); break; case PROP_BUBBLE_VERT_GAP: defaults->bubble_vert_gap = g_value_get_double (value); break; case PROP_BUBBLE_HORZ_GAP: defaults->bubble_horz_gap = g_value_get_double (value); break; case PROP_BUBBLE_MIN_HEIGHT: defaults->bubble_min_height = g_value_get_double (value); break; case PROP_BUBBLE_MAX_HEIGHT: defaults->bubble_max_height = g_value_get_double (value); break; case PROP_BUBBLE_SHADOW_SIZE: defaults->bubble_shadow_size = g_value_get_double (value); break; case PROP_BUBBLE_SHADOW_COLOR: if (defaults->bubble_shadow_color != NULL) { g_string_free (defaults->bubble_shadow_color, TRUE); } defaults->bubble_shadow_color = g_string_new ( g_value_get_string (value)); break; case PROP_BUBBLE_BG_COLOR: if (defaults->bubble_bg_color != NULL) { g_string_free (defaults->bubble_bg_color, TRUE); } defaults->bubble_bg_color = g_string_new ( g_value_get_string (value)); break; case PROP_BUBBLE_BG_OPACITY: if (defaults->bubble_bg_opacity != NULL) { g_string_free (defaults->bubble_bg_opacity, TRUE); } defaults->bubble_bg_opacity = g_string_new ( g_value_get_string (value)); break; case PROP_BUBBLE_HOVER_OPACITY: if (defaults->bubble_hover_opacity != NULL) { g_string_free (defaults->bubble_hover_opacity, TRUE); } defaults->bubble_hover_opacity = g_string_new ( g_value_get_string (value)); break; case PROP_BUBBLE_CORNER_RADIUS: defaults->bubble_corner_radius = g_value_get_double (value); break; case PROP_CONTENT_SHADOW_SIZE: defaults->content_shadow_size = g_value_get_double (value); break; case PROP_CONTENT_SHADOW_COLOR: if (defaults->content_shadow_color != NULL) { g_string_free (defaults->content_shadow_color, TRUE); } defaults->content_shadow_color = g_string_new ( g_value_get_string (value)); break; case PROP_MARGIN_SIZE: defaults->margin_size = g_value_get_double (value); break; case PROP_ICON_SIZE: defaults->icon_size = g_value_get_double (value); break; case PROP_GAUGE_SIZE: defaults->gauge_size = g_value_get_double (value); break; case PROP_GAUGE_OUTLINE_WIDTH: defaults->gauge_outline_width = g_value_get_double (value); break; case PROP_FADE_IN_TIMEOUT: defaults->fade_in_timeout = g_value_get_int (value); break; case PROP_FADE_OUT_TIMEOUT: defaults->fade_out_timeout = g_value_get_int (value); break; case PROP_ON_SCREEN_TIMEOUT: defaults->on_screen_timeout = g_value_get_int (value); break; case PROP_TEXT_FONT_FACE: if (defaults->text_font_face != NULL) { g_string_free (defaults->text_font_face, TRUE); } defaults->text_font_face = g_string_new ( g_value_get_string (value)); break; case PROP_TEXT_TITLE_COLOR: if (defaults->text_title_color != NULL) { g_string_free (defaults->text_title_color, TRUE); } defaults->text_title_color = g_string_new ( g_value_get_string (value)); break; case PROP_TEXT_TITLE_WEIGHT: defaults->text_title_weight = g_value_get_int (value); break; case PROP_TEXT_TITLE_SIZE: defaults->text_title_size = g_value_get_double (value); break; case PROP_TEXT_BODY_COLOR: if (defaults->text_body_color != NULL) { g_string_free (defaults->text_body_color, TRUE); } defaults->text_body_color = g_string_new ( g_value_get_string (value)); break; case PROP_TEXT_BODY_WEIGHT: defaults->text_body_weight = g_value_get_int (value); break; case PROP_TEXT_BODY_SIZE: defaults->text_body_size = g_value_get_double (value); break; case PROP_PIXELS_PER_EM: defaults->pixels_per_em = g_value_get_double (value); break; case PROP_SYSTEM_FONT_SIZE: defaults->system_font_size = g_value_get_double (value); break; case PROP_SCREEN_DPI: defaults->screen_dpi = g_value_get_double (value); break; case PROP_GRAVITY: defaults->gravity = g_value_get_int (value); break; default : G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop, spec); break; } } static void defaults_class_init (DefaultsClass* klass) { GObjectClass* gobject_class = G_OBJECT_CLASS (klass); GParamSpec* property_desktop_bottom_gap; GParamSpec* property_stack_height; GParamSpec* property_bubble_vert_gap; GParamSpec* property_bubble_horz_gap; GParamSpec* property_bubble_width; GParamSpec* property_bubble_min_height; GParamSpec* property_bubble_max_height; GParamSpec* property_bubble_shadow_size; GParamSpec* property_bubble_shadow_color; GParamSpec* property_bubble_bg_color; GParamSpec* property_bubble_bg_opacity; GParamSpec* property_bubble_hover_opacity; GParamSpec* property_bubble_corner_radius; GParamSpec* property_content_shadow_size; GParamSpec* property_content_shadow_color; GParamSpec* property_margin_size; GParamSpec* property_icon_size; GParamSpec* property_gauge_size; GParamSpec* property_gauge_outline_width; GParamSpec* property_fade_in_timeout; GParamSpec* property_fade_out_timeout; GParamSpec* property_on_screen_timeout; GParamSpec* property_text_font_face; GParamSpec* property_text_title_color; GParamSpec* property_text_title_weight; GParamSpec* property_text_title_size; GParamSpec* property_text_body_color; GParamSpec* property_text_body_weight; GParamSpec* property_text_body_size; GParamSpec* property_pixels_per_em; GParamSpec* property_system_font_size; GParamSpec* property_screen_dpi; GParamSpec* property_gravity; gobject_class->constructed = defaults_constructed; gobject_class->dispose = defaults_dispose; gobject_class->finalize = defaults_finalize; gobject_class->get_property = defaults_get_property; gobject_class->set_property = defaults_set_property; g_defaults_signals[VALUE_CHANGED] = g_signal_new ( "value-changed", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DefaultsClass, value_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_defaults_signals[GRAVITY_CHANGED] = g_signal_new ( "gravity-changed", G_OBJECT_CLASS_TYPE (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DefaultsClass, gravity_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); property_desktop_bottom_gap = g_param_spec_double ( "desktop-bottom-gap", "desktop-bottom-gap", "Bottom gap on the desktop in em", 0.0f, 16.0f, DEFAULT_DESKTOP_BOTTOM_GAP, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_DESKTOP_BOTTOM_GAP, property_desktop_bottom_gap); property_stack_height = g_param_spec_double ( "stack-height", "stack-height", "Maximum allowed height of stack (in em)", 0.0f, 256.0f, 50.0f, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_STACK_HEIGHT, property_stack_height); property_bubble_vert_gap = g_param_spec_double ( "bubble-vert-gap", "bubble-vert-gap", "Vert. gap between bubble and workarea edge (in em)", 0.0f, 10.0f, DEFAULT_BUBBLE_VERT_GAP, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_VERT_GAP, property_bubble_vert_gap); property_bubble_horz_gap = g_param_spec_double ( "bubble-horz-gap", "bubble-horz-gap", "Horz. gap between bubble and workarea edge (in em)", 0.0f, 10.0f, DEFAULT_BUBBLE_HORZ_GAP, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_HORZ_GAP, property_bubble_horz_gap); property_bubble_width = g_param_spec_double ( "bubble-width", "bubble-width", "Width of bubble (in em)", 0.0f, 256.0f, DEFAULT_BUBBLE_WIDTH, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_WIDTH, property_bubble_width); property_bubble_min_height = g_param_spec_double ( "bubble-min-height", "bubble-min-height", "Min. height of bubble (in em)", 0.0f, 256.0f, DEFAULT_BUBBLE_MIN_HEIGHT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_MIN_HEIGHT, property_bubble_min_height); property_bubble_max_height = g_param_spec_double ( "bubble-max-height", "bubble-max-height", "Max. height of bubble (in em)", 0.0f, 256.0f, DEFAULT_BUBBLE_MAX_HEIGHT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_MAX_HEIGHT, property_bubble_max_height); property_bubble_shadow_size = g_param_spec_double ( "bubble-shadow-size", "bubble-shadow-size", "Size (in em) of bubble drop-shadow", 0.0f, 32.0f, DEFAULT_BUBBLE_SHADOW_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_SHADOW_SIZE, property_bubble_shadow_size); property_bubble_shadow_color = g_param_spec_string ( "bubble-shadow-color", "bubble-shadow-color", "Color of bubble drop-shadow", DEFAULT_BUBBLE_SHADOW_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_SHADOW_COLOR, property_bubble_shadow_color); property_bubble_bg_color = g_param_spec_string ( "bubble-bg-color", "bubble-bg-color", "Color of bubble-background", DEFAULT_BUBBLE_BG_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_BG_COLOR, property_bubble_bg_color); property_bubble_bg_opacity = g_param_spec_string ( "bubble-bg-opacity", "bubble-bg-opacity", "Opacity of bubble-background", DEFAULT_BUBBLE_BG_OPACITY, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_BG_OPACITY, property_bubble_bg_opacity); property_bubble_hover_opacity = g_param_spec_string ( "bubble-hover-opacity", "bubble-hover-opacity", "Opacity of bubble in mouse-over case", DEFAULT_BUBBLE_HOVER_OPACITY, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_HOVER_OPACITY, property_bubble_hover_opacity); property_bubble_corner_radius = g_param_spec_double ( "bubble-corner-radius", "bubble-corner-radius", "Corner-radius of bubble (in em)", 0.0f, 16.0f, DEFAULT_BUBBLE_CORNER_RADIUS, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_BUBBLE_CORNER_RADIUS, property_bubble_corner_radius); property_content_shadow_size = g_param_spec_double ( "content-shadow-size", "content-shadow-size", "Size (in em) of icon/text drop-shadow", 0.0f, 8.0f, DEFAULT_CONTENT_SHADOW_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_CONTENT_SHADOW_SIZE, property_content_shadow_size); property_content_shadow_color = g_param_spec_string ( "content-shadow-color", "content-shadow-color", "Color of icon/text drop-shadow", DEFAULT_CONTENT_SHADOW_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_CONTENT_SHADOW_COLOR, property_content_shadow_color); property_margin_size = g_param_spec_double ( "margin-size", "margin-size", "Size (in em) of margin", 0.0f, 32.0f, DEFAULT_MARGIN_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_MARGIN_SIZE, property_margin_size); property_icon_size = g_param_spec_double ( "icon-size", "icon-size", "Size (in em) of icon/avatar", 0.0f, 64.0f, DEFAULT_ICON_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_ICON_SIZE, property_icon_size); property_gauge_size = g_param_spec_double ( "gauge-size", "gauge-size", "Size/height (in em) of gauge/indicator", 0.5f, 1.0f, DEFAULT_GAUGE_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_GAUGE_SIZE, property_gauge_size); property_gauge_outline_width = g_param_spec_double ( "gauge-outline-width", "gauge-outline-width", "Width/thickness (in em) of gauge-outline", 0.1f, 0.2f, DEFAULT_GAUGE_OUTLINE_WIDTH, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_GAUGE_OUTLINE_WIDTH, property_gauge_outline_width); property_fade_in_timeout = g_param_spec_int ( "fade-in-timeout", "fade-in-timeout", "Timeout for bubble fade-in in milliseconds", 0, 10000, DEFAULT_FADE_IN_TIMEOUT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_FADE_IN_TIMEOUT, property_fade_in_timeout); property_fade_out_timeout = g_param_spec_int ( "fade-out-timeout", "fade-out-timeout", "Timeout for bubble fade-out in milliseconds", 0, 10000, DEFAULT_FADE_OUT_TIMEOUT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_FADE_OUT_TIMEOUT, property_fade_out_timeout); property_on_screen_timeout = g_param_spec_int ( "on-screen-timeout", "on-screen-timeout", "Timeout for bubble on screen in milliseconds", 0, 10000, DEFAULT_ON_SCREEN_TIMEOUT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_ON_SCREEN_TIMEOUT, property_on_screen_timeout); property_text_font_face = g_param_spec_string ( "text-font-face", "text-font-face", "Font-face to use of any rendered text", DEFAULT_TEXT_FONT_FACE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_FONT_FACE, property_text_font_face); property_text_title_color = g_param_spec_string ( "text-title-color", "text-title-color", "Color to use for content title-text", DEFAULT_TEXT_TITLE_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_TITLE_COLOR, property_text_title_color); property_text_title_weight = g_param_spec_int ( "text-title-weight", "text-title-weight", "Weight to use for content title-text", 0, 1000, DEFAULT_TEXT_TITLE_WEIGHT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_TITLE_WEIGHT, property_text_title_weight); property_text_title_size = g_param_spec_double ( "text-title-size", "text-title-size", "Size (in em) of font to use for content title-text", 0.0f, 32.0f, DEFAULT_TEXT_TITLE_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_TITLE_SIZE, property_text_title_size); property_text_body_color = g_param_spec_string ( "text-body-color", "text-body-color", "Color to use for content body-text", DEFAULT_TEXT_BODY_COLOR, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_BODY_COLOR, property_text_body_color); property_text_body_weight = g_param_spec_int ( "text-body-weight", "text-body-weight", "Weight to use for content body-text", 0, 1000, DEFAULT_TEXT_BODY_WEIGHT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_BODY_WEIGHT, property_text_body_weight); property_text_body_size = g_param_spec_double ( "text-body-size", "text-body-size", "Size (in em) of font to use for content body-text", 0.0f, 32.0f, DEFAULT_TEXT_BODY_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_TEXT_BODY_SIZE, property_text_body_size); property_pixels_per_em = g_param_spec_double ( "pixels-per-em", "pixels-per-em", "Number of pixels for one em-unit", 1.0f, 100.0f, DEFAULT_PIXELS_PER_EM, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_PIXELS_PER_EM, property_pixels_per_em); property_system_font_size = g_param_spec_double ( "system-font-size", "system-font-size", "System font-size in pt", 1.0f, 100.0f, DEFAULT_SYSTEM_FONT_SIZE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_SYSTEM_FONT_SIZE, property_system_font_size); property_screen_dpi = g_param_spec_double ( "screen-dpi", "screen-dpi", "Screen DPI value", 10.0f, 600.0f, DEFAULT_SCREEN_DPI, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_SCREEN_DPI, property_screen_dpi); property_gravity = g_param_spec_int ( "gravity", "gravity", "Positional hint for placing bubbles", 0, 2, DEFAULT_GRAVITY, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (gobject_class, PROP_GRAVITY, property_gravity); } /*-- public API --------------------------------------------------------------*/ Defaults* defaults_new (void) { Defaults* this = g_object_new (DEFAULTS_TYPE, NULL); return this; } gint defaults_get_desktop_width (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return 0; return self->desktop_width; } gint defaults_get_desktop_height (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return 0; return self->desktop_height; } gdouble defaults_get_desktop_bottom_gap (Defaults* self) { gdouble bottom_gap; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "desktop-bottom-gap", &bottom_gap, NULL); return bottom_gap; } gdouble defaults_get_stack_height (Defaults* self) { gdouble stack_height; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "stack-height", &stack_height, NULL); return stack_height; } gdouble defaults_get_bubble_gap (Defaults* self) { gdouble gap; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-gap", &gap, NULL); return gap; } gdouble defaults_get_bubble_width (Defaults* self) { gdouble width; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-width", &width, NULL); return width; } gdouble defaults_get_bubble_min_height (Defaults* self) { gdouble bubble_min_height; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-min-height", &bubble_min_height, NULL); return bubble_min_height; } gdouble defaults_get_bubble_max_height (Defaults* self) { gdouble bubble_max_height; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-max-height", &bubble_max_height, NULL); return bubble_max_height; } gdouble defaults_get_bubble_vert_gap (Defaults* self) { gdouble bubble_vert_gap; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-vert-gap", &bubble_vert_gap, NULL); return bubble_vert_gap; } gdouble defaults_get_bubble_horz_gap (Defaults* self) { gdouble bubble_horz_gap; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-horz-gap", &bubble_horz_gap, NULL); return bubble_horz_gap; } gdouble defaults_get_bubble_height (Defaults* self) { gdouble height; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "bubble-height", &height, NULL); return height; } gdouble defaults_get_bubble_shadow_size (Defaults* self, gboolean is_composited) { gdouble bubble_shadow_size; if (!self || !IS_DEFAULTS (self) || !is_composited) return 0.0f; g_object_get (self, "bubble-shadow-size", &bubble_shadow_size, NULL); return bubble_shadow_size; } gchar* defaults_get_bubble_shadow_color (Defaults* self) { gchar* bubble_shadow_color = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "bubble-shadow-color", &bubble_shadow_color, NULL); return bubble_shadow_color; } gchar* defaults_get_bubble_bg_color (Defaults* self) { gchar* bubble_bg_color = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; defaults_refresh_bg_color_property (self); g_object_get (self, "bubble-bg-color", &bubble_bg_color, NULL); return bubble_bg_color; } gchar* defaults_get_bubble_bg_opacity (Defaults* self) { gchar* bubble_bg_opacity = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "bubble-bg-opacity", &bubble_bg_opacity, NULL); return bubble_bg_opacity; } gchar* defaults_get_bubble_hover_opacity (Defaults* self) { gchar* bubble_hover_opacity = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "bubble-hover-opacity", &bubble_hover_opacity, NULL); return bubble_hover_opacity; } gdouble defaults_get_bubble_corner_radius (Defaults* self, gboolean is_composited) { gdouble bubble_corner_radius; if (!self || !IS_DEFAULTS (self) || !is_composited) return 0.0f; g_object_get (self, "bubble-corner-radius", &bubble_corner_radius, NULL); return bubble_corner_radius; } gdouble defaults_get_content_shadow_size (Defaults* self) { gdouble content_shadow_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "content-shadow-size", &content_shadow_size, NULL); return content_shadow_size; } gchar* defaults_get_content_shadow_color (Defaults* self) { gchar* content_shadow_color = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "content-shadow-color", &content_shadow_color, NULL); return content_shadow_color; } gdouble defaults_get_margin_size (Defaults* self) { gdouble margin_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "margin-size", &margin_size, NULL); return margin_size; } gdouble defaults_get_icon_size (Defaults* self) { gdouble icon_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "icon-size", &icon_size, NULL); return icon_size; } gdouble defaults_get_gauge_size (Defaults* self) { gdouble gauge_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "gauge-size", &gauge_size, NULL); return gauge_size; } gdouble defaults_get_gauge_outline_width (Defaults* self) { gdouble gauge_outline_width; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "gauge-outline-width", &gauge_outline_width, NULL); return gauge_outline_width; } gint defaults_get_fade_in_timeout (Defaults* self) { gint fade_in_timeout; if (!self || !IS_DEFAULTS (self)) return 0; g_object_get (self, "fade-in-timeout", &fade_in_timeout, NULL); return fade_in_timeout; } gint defaults_get_fade_out_timeout (Defaults* self) { gint fade_out_timeout; if (!self || !IS_DEFAULTS (self)) return 0; g_object_get (self, "fade-out-timeout", &fade_out_timeout, NULL); return fade_out_timeout; } gint defaults_get_on_screen_timeout (Defaults* self) { gint on_screen_timeout; if (!self || !IS_DEFAULTS (self)) return 0; g_object_get (self, "on-screen-timeout", &on_screen_timeout, NULL); return on_screen_timeout; } gchar* defaults_get_text_font_face (Defaults* self) { gchar* text_font_face = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "text-font-face", &text_font_face, NULL); return text_font_face; } gchar* defaults_get_text_title_color (Defaults* self) { gchar* text_title_color = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "text-title-color", &text_title_color, NULL); return text_title_color; } gint defaults_get_text_title_weight (Defaults* self) { gint text_title_weight; if (!self || !IS_DEFAULTS (self)) return 0; g_object_get (self, "text-title-weight", &text_title_weight, NULL); return text_title_weight; } gdouble defaults_get_text_title_size (Defaults* self) { gdouble text_title_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "text-title-size", &text_title_size, NULL); return text_title_size; } gchar* defaults_get_text_body_color (Defaults* self) { gchar* text_body_color = NULL; if (!self || !IS_DEFAULTS (self)) return NULL; g_object_get (self, "text-body-color", &text_body_color, NULL); return text_body_color; } gint defaults_get_text_body_weight (Defaults* self) { gint text_body_weight; if (!self || !IS_DEFAULTS (self)) return 0; g_object_get (self, "text-body-weight", &text_body_weight, NULL); return text_body_weight; } gdouble defaults_get_text_body_size (Defaults* self) { gdouble text_body_size; if (!self || !IS_DEFAULTS (self)) return 0.0f; g_object_get (self, "text-body-size", &text_body_size, NULL); return text_body_size; } /* we use the normal font-height in pixels ("pixels-per-em") as the measurement * for 1 em, thus it should _not_ be called before defaults_constructed() */ gdouble defaults_get_pixel_per_em (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return 0.0f; gdouble pixels_per_em; g_object_get (self, "pixels-per-em", &pixels_per_em, NULL); return pixels_per_em; } gdouble defaults_get_system_font_size (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return 0.0f; gdouble system_font_size; g_object_get (self, "system-font-size", &system_font_size, NULL); return system_font_size; } gdouble defaults_get_screen_dpi (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return 0.0f; gdouble screen_dpi; g_object_get (self, "screen-dpi", &screen_dpi, NULL); return screen_dpi; } static gboolean defaults_multihead_does_focus_follow (Defaults *self) { gboolean mode = FALSE; g_return_val_if_fail (self != NULL && IS_DEFAULTS (self), FALSE); gchar* mode_str = g_settings_get_string (self->nosd_settings, GSETTINGS_MULTIHEAD_MODE_KEY); if (mode_str != NULL) { if (! g_strcmp0 (mode_str, "focus-follow")) mode = TRUE; g_free ((gpointer) mode_str); } return mode; } void defaults_get_top_corner (Defaults *self, GdkScreen **screen, gint *x, gint *y) { GdkRectangle rect; GdkWindow* active_window = NULL; GdkDeviceManager* device_manager; GdkDevice* device; gint mx; gint my; gint monitor = 0; gint aw_monitor; gboolean follow_focus = defaults_multihead_does_focus_follow (self); gboolean is_composited = FALSE; gint primary_monitor; g_return_if_fail (self != NULL && IS_DEFAULTS (self)); device_manager = gdk_display_get_device_manager (gdk_display_get_default ()); device = gdk_device_manager_get_client_pointer (device_manager); gdk_device_get_position (device, screen, &mx, &my); is_composited = gdk_screen_is_composited (*screen); if (follow_focus) { g_debug ("multi_head_focus_follow mode"); monitor = gdk_screen_get_monitor_at_point (*screen, mx, my); active_window = gdk_screen_get_active_window (*screen); if (active_window != NULL) { aw_monitor = gdk_screen_get_monitor_at_window ( *screen, active_window); if (monitor != aw_monitor) { g_debug ("choosing the monitor with the active" " window, not the one with the mouse" " cursor"); } monitor = aw_monitor; g_object_unref (active_window); } } /* _NET_WORKAREA is always a rectangle spanning all monitors of * a screen. As such, it can't properly deal with monitor setups * that aren't aligned or have different resolutions. * gdk_screen_get_monitor_workarea() works around this by only * returning the workarea for the primary screen and the full * geometry for all other monitors. * * This leads to the sync bubbles sometimes overlapping the * panel on secondary monitors. To work around this, we get the * panel's height on the primary monitor and use that for all * other monitors as well. */ primary_monitor = gdk_screen_get_primary_monitor (*screen); if (monitor == primary_monitor) { gdk_screen_get_monitor_workarea (*screen, primary_monitor, &rect); } else { GdkRectangle workarea; GdkRectangle primary_geom; gint panel_height; gdk_screen_get_monitor_workarea (*screen, primary_monitor, &workarea); gdk_screen_get_monitor_geometry (*screen, primary_monitor, &primary_geom); panel_height = workarea.y - primary_geom.y; gdk_screen_get_monitor_geometry (*screen, monitor, &rect); rect.y += panel_height; rect.height -= panel_height; } g_debug ("selecting monitor %d at (%d,%d) - %dx%d", monitor, rect.x, rect.y, rect.width, rect.height); self->desktop_width = rect.width; self->desktop_height = rect.height; *y = rect.y; *y += EM2PIXELS (defaults_get_bubble_vert_gap (self), self) - EM2PIXELS (defaults_get_bubble_shadow_size (self, is_composited), self); if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR) { *x = rect.x + rect.width; *x -= EM2PIXELS (defaults_get_bubble_shadow_size (self, is_composited), self) + EM2PIXELS (defaults_get_bubble_horz_gap (self), self) + EM2PIXELS (defaults_get_bubble_width (self), self); } else { *x = rect.x - EM2PIXELS (defaults_get_bubble_shadow_size (self, is_composited), self) + EM2PIXELS (defaults_get_bubble_horz_gap (self), self); } g_debug ("top corner at: %d, %d", *x, *y); } Gravity defaults_get_gravity (Defaults* self) { if (!self || !IS_DEFAULTS (self)) return GRAVITY_NONE; Gravity gravity; g_object_get (self, "gravity", &gravity, NULL); return gravity; } SlotAllocation defaults_get_slot_allocation (Defaults *self) { if (!self || !IS_DEFAULTS (self)) return SLOT_ALLOCATION_NONE; return self->slot_allocation; } ./src/bubble-window.h0000644000004100000410000000421013570225707014750 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window.h - implements bubble window ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef _BUBBLE_WINDOW_H_ #define _BUBBLE_WINDOW_H_ #include //#include #include G_BEGIN_DECLS #define BUBBLE_TYPE_WINDOW (bubble_window_get_type ()) #define BUBBLE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUBBLE_TYPE_WINDOW, BubbleWindow)) #define BUBBLE_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BUBBLE_TYPE_WINDOW, BubbleWindowClass)) #define BUBBLE_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUBBLE_TYPE_WINDOW)) #define BUBBLE_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BUBBLE_TYPE_WINDOW)) #define BUBBLE_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BUBBLE_TYPE_WINDOW, BubbleWindowClass)) typedef struct _BubbleWindowClass BubbleWindowClass; typedef struct _BubbleWindow BubbleWindow; struct _BubbleWindowClass { GtkWindowClass parent_class; }; struct _BubbleWindow { GtkWindow parent_instance; }; GType bubble_window_get_type (void) G_GNUC_CONST; GtkWidget *bubble_window_new (void); G_END_DECLS #endif /* _BUBBLE_WINDOW_H_ */ ./src/bubble-window-accessible-factory.h0000644000004100000410000000516213570225707020517 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** bubble-window-accessible-factory.h - implements an accessible object factory ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Eitan Isaacson ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef _BUBBLE_WINDOW_ACCESSIBLE_FACTORY_H_ #define _BUBBLE_WINDOW_ACCESSIBLE_FACTORY_H_ #include G_BEGIN_DECLS #define BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY (bubble_window_accessible_factory_get_type ()) #define BUBBLE_WINDOW_ACCESSIBLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY, BubbleWindowAccessibleFactory)) #define BUBBLE_WINDOW_ACCESSIBLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY, BubbleWindowAccessibleFactoryClass)) #define BUBBLE_WINDOW_IS_ACCESSIBLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY)) #define BUBBLE_WINDOW_IS_ACCESSIBLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY)) #define BUBBLE_WINDOW_ACCESSIBLE_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BUBBLE_WINDOW_TYPE_ACCESSIBLE_FACTORY, BubbleWindowAccessibleFactoryClass)) typedef struct _BubbleWindowAccessibleFactoryClass BubbleWindowAccessibleFactoryClass; typedef struct _BubbleWindowAccessibleFactory BubbleWindowAccessibleFactory; struct _BubbleWindowAccessibleFactoryClass { AtkObjectFactoryClass parent_class; }; struct _BubbleWindowAccessibleFactory { AtkObjectFactory parent_instance; }; GType bubble_window_accessible_factory_get_type (void) G_GNUC_CONST; AtkObjectFactory* bubble_window_accessible_factory_new (void); G_END_DECLS #endif /* _BUBBLE_WINDOW_ACCESSIBLE_FACTORY_H_ */ ./src/observer.h0000644000004100000410000000454013570225707014045 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** observer.h - meant to be a singelton watching for mouse-over-bubble cases ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #ifndef __OBSERVER_H #define __OBSERVER_H #include #include G_BEGIN_DECLS #define OBSERVER_TYPE (observer_get_type ()) #define OBSERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OBSERVER_TYPE, Observer)) #define OBSERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OBSERVER_TYPE, ObserverClass)) #define IS_OBSERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OBSERVER_TYPE)) #define IS_OBSERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OBSERVER_TYPE)) #define OBSERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OBSERVER_TYPE, ObserverClass)) typedef struct _Observer Observer; typedef struct _ObserverClass ObserverClass; /* instance structure */ struct _Observer { GObject parent; /* private */ GtkWidget* window; gint timeout_frequency; guint timeout_id; gint pointer_x; gint pointer_y; }; /* class structure */ struct _ObserverClass { GObjectClass parent; }; GType Observer_get_type (void); Observer* observer_new (void); void observer_del (Observer* self); gint observer_get_x (Observer* self); gint observer_get_y (Observer* self); G_END_DECLS #endif /* __OBSERVER_H */ ./autogen.sh0000755000004100000410000000117613570225707013261 0ustar www-datawww-data#!/bin/sh # Run this to generate all the initial makefiles, etc. srcdir=`dirname $0` test -z "$srcdir" && srcdir=. PKG_NAME="notify-osd" REQUIRED_AUTOCONF_VERSION=2.59 REQUIRED_AUTOMAKE_VERSION=1.8 REQUIRED_MACROS="python.m4" ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4" (test -f $srcdir/configure.in) || { echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" echo " top-level $PKG_NAME directory" exit 1 } which gnome-autogen.sh || { echo "You need to install the gnome-common module and make" echo "sure the gnome-autogen.sh script is in your \$PATH." exit 1 } USE_GNOME2_MACROS=1 . gnome-autogen.sh ./egg/0000755000004100000410000000000013570225707012015 5ustar www-datawww-data./egg/egg-timeout-pool.h0000644000004100000410000000356513570225707015374 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * * Copyright (C) 2006 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * EggTimeoutPool: pool of timeout functions using the same slice of * the GLib main loop * * Author: Emmanuele Bassi * * Based on similar code by Tristan van Berkom */ #ifndef __EGG_TIMEOUT_POOL_H__ #define __EGG_TIMEOUT_POOL_H__ #include G_BEGIN_DECLS typedef struct _EggTimeoutPool EggTimeoutPool; EggTimeoutPool *egg_timeout_pool_new (gint priority); guint egg_timeout_pool_add (EggTimeoutPool *pool, guint interval, GSourceFunc func, gpointer data, GDestroyNotify notify); void egg_timeout_pool_remove (EggTimeoutPool *pool, guint id); G_END_DECLS #endif /* __EGG_TIMEOUT_POOL_H__ */ ./egg/test-timeline-dup-frames.c0000644000004100000410000000410613570225707017006 0ustar www-datawww-data#include #include #include /* We use a nice slow timeline for this test since we * dont want the timeouts to interpolate the timeline * forward multiple frames */ #define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FRAME_COUNT 20 typedef struct _TestState { EggTimeline *timeline; gint prev_frame; gint completion_count; gint passed; }TestState; static void new_frame_cb (EggTimeline *timeline, gint frame_num, TestState *state) { gint current_frame = egg_timeline_get_current_frame (state->timeline); if (state->prev_frame != egg_timeline_get_current_frame (state->timeline)) { g_print("timeline previous frame=%-4i actual frame=%-4i (OK)\n", state->prev_frame, current_frame); } else { g_print("timeline previous frame=%-4i actual frame=%-4i (FAILED)\n", state->prev_frame, current_frame); state->passed = FALSE; } state->prev_frame = current_frame; } static void completed_cb (EggTimeline *timeline, TestState *state) { state->completion_count++; if (state->completion_count == 2) { if (state->passed) { g_print("Passed\n"); exit(EXIT_SUCCESS); } else { g_print("Failed\n"); exit(EXIT_FAILURE); } } } int main(int argc, char **argv) { TestState state; state.timeline = egg_timeline_new (TEST_TIMELINE_FRAME_COUNT, TEST_TIMELINE_FPS); egg_timeline_set_loop (state.timeline, TRUE); g_signal_connect (G_OBJECT(state.timeline), "new-frame", G_CALLBACK(new_frame_cb), &state); g_signal_connect (G_OBJECT(state.timeline), "completed", G_CALLBACK(completed_cb), &state); state.prev_frame = -1; state.completion_count = 0; state.passed = TRUE; egg_timeline_start (state.timeline); egg_main(); return EXIT_FAILURE; } ./egg/egg-hack.h0000644000004100000410000000506213570225707013637 0ustar www-datawww-data#ifndef __EGG_HACK_H__ #define __EGG_HACK_H__ #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include // #include "egg-backend.h" // #include "egg-event.h" // #include "egg-feature.h" // #include "egg-id-pool.h" // #include "egg-stage-manager.h" // #include "egg-stage-window.h" // #include "egg-stage.h" // #include "pango/pangoegg.h" #include "egg-debug.h" #include "egg-fixed.h" #include "egg-units.h" #include "egg-timeline.h" #include "egg-timeout-pool.h" #define I_(str) (g_intern_static_string ((str))) #define EGG_PRIORITY_TIMELINE (G_PRIORITY_DEFAULT + 30) #include G_BEGIN_DECLS #define EGG_PARAM_READABLE \ G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB #define EGG_PARAM_WRITABLE \ G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB #define EGG_PARAM_READWRITE \ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |G_PARAM_STATIC_BLURB guint egg_get_default_frame_rate (void); void egg_threads_enter (void); void egg_threads_leave (void); void egg_main (void); /* enumerations from "./egg-timeline.h" */ GType egg_timeline_direction_get_type (void) G_GNUC_CONST; #define EGG_TYPE_TIMELINE_DIRECTION (egg_timeline_direction_get_type()) /* VOID:STRING,INT (./egg-marshal.list:12) */ extern void egg_marshal_VOID__STRING_INT (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); /* VOID:VOID (./egg-marshal.list:13) */ #define egg_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID /* VOID:INT (./egg-marshal.list:4) */ #define egg_marshal_VOID__INT g_cclosure_marshal_VOID__INT /* UINT:VOID (./egg-marshal.list:2) */ extern void egg_marshal_UINT__VOID (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); G_END_DECLS #endif /* !__EGG_HACK_H__ */ ./egg/egg-timeout-pool.c0000644000004100000410000003445513570225707015371 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * * Copyright (C) 2006 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * EggTimeoutPool: pool of timeout functions using the same slice of * the GLib main loop * * Author: Emmanuele Bassi * * Based on similar code by Tristan van Berkom */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "egg-debug.h" #include "egg-timeout-pool.h" typedef struct _EggTimeout EggTimeout; typedef enum { EGG_TIMEOUT_NONE = 0, EGG_TIMEOUT_READY = 1 << 1 } EggTimeoutFlags; struct _EggTimeout { guint id; EggTimeoutFlags flags; gint refcount; guint interval; guint last_time; GSourceFunc func; gpointer data; GDestroyNotify notify; }; struct _EggTimeoutPool { GSource source; guint next_id; GTimeVal start_time; GList *timeouts, *dispatched_timeouts; gint ready; guint id; }; #define TIMEOUT_READY(timeout) (timeout->flags & EGG_TIMEOUT_READY) static gboolean egg_timeout_pool_prepare (GSource *source, gint *next_timeout); static gboolean egg_timeout_pool_check (GSource *source); static gboolean egg_timeout_pool_dispatch (GSource *source, GSourceFunc callback, gpointer data); static void egg_timeout_pool_finalize (GSource *source); static GSourceFuncs egg_timeout_pool_funcs = { egg_timeout_pool_prepare, egg_timeout_pool_check, egg_timeout_pool_dispatch, egg_timeout_pool_finalize }; static gint egg_timeout_sort (gconstpointer a, gconstpointer b) { const EggTimeout *t_a = a; const EggTimeout *t_b = b; gint comparison; /* Keep 'ready' timeouts at the front */ if (TIMEOUT_READY (t_a)) return -1; if (TIMEOUT_READY (t_b)) return 1; /* Otherwise sort by expiration time */ comparison = (t_a->last_time + t_a->interval) - (t_b->last_time + t_b->interval); if (comparison < 0) return -1; if (comparison > 0) return 1; return 0; } static gint egg_timeout_find_by_id (gconstpointer a, gconstpointer b) { const EggTimeout *t_a = a; return t_a->id == GPOINTER_TO_UINT (b) ? 0 : 1; } static guint egg_timeout_pool_get_ticks (EggTimeoutPool *pool) { GTimeVal time_now; g_source_get_current_time ((GSource *) pool, &time_now); return (time_now.tv_sec - pool->start_time.tv_sec) * 1000 + (time_now.tv_usec - pool->start_time.tv_usec) / 1000; } static gboolean egg_timeout_prepare (EggTimeoutPool *pool, EggTimeout *timeout, gint *next_timeout) { guint now = egg_timeout_pool_get_ticks (pool); /* If time has gone backwards or the time since the last frame is greater than the two frames worth then reset the time and do a frame now */ if (timeout->last_time > now || now - timeout->last_time > timeout->interval * 2) { timeout->last_time = now - timeout->interval; if (next_timeout) *next_timeout = 0; return TRUE; } else if (now - timeout->last_time >= timeout->interval) { if (next_timeout) *next_timeout = 0; return TRUE; } else { if (next_timeout) *next_timeout = timeout->interval + timeout->last_time - now; return FALSE; } } static gboolean egg_timeout_dispatch (GSource *source, EggTimeout *timeout) { gboolean retval = FALSE; if (G_UNLIKELY (!timeout->func)) { g_warning ("Timeout dispatched without a callback."); return FALSE; } if (timeout->func (timeout->data)) { timeout->last_time += timeout->interval; retval = TRUE; } return retval; } static EggTimeout * egg_timeout_new (guint interval) { EggTimeout *timeout; timeout = g_slice_new0 (EggTimeout); timeout->interval = interval; timeout->flags = EGG_TIMEOUT_NONE; timeout->refcount = 1; return timeout; } /* ref and unref are always called under the main Egg lock, so there * is not need for us to use g_atomic_int_* API. */ static EggTimeout * egg_timeout_ref (EggTimeout *timeout) { g_return_val_if_fail (timeout != NULL, timeout); g_return_val_if_fail (timeout->refcount > 0, timeout); timeout->refcount += 1; return timeout; } static void egg_timeout_unref (EggTimeout *timeout) { g_return_if_fail (timeout != NULL); g_return_if_fail (timeout->refcount > 0); timeout->refcount -= 1; if (timeout->refcount == 0) { if (timeout->notify) timeout->notify (timeout->data); g_slice_free (EggTimeout, timeout); } } static void egg_timeout_free (EggTimeout *timeout) { if (G_LIKELY (timeout)) { if (timeout->notify) timeout->notify (timeout->data); g_slice_free (EggTimeout, timeout); } } static gboolean egg_timeout_pool_prepare (GSource *source, gint *next_timeout) { EggTimeoutPool *pool = (EggTimeoutPool *) source; GList *l = pool->timeouts; /* the pool is ready if the first timeout is ready */ if (l && l->data) { EggTimeout *timeout = l->data; return egg_timeout_prepare (pool, timeout, next_timeout); } else { *next_timeout = -1; return FALSE; } } static gboolean egg_timeout_pool_check (GSource *source) { EggTimeoutPool *pool = (EggTimeoutPool *) source; GList *l = pool->timeouts; egg_threads_enter (); for (l = pool->timeouts; l; l = l->next) { EggTimeout *timeout = l->data; /* since the timeouts are sorted by expiration, as soon * as we get a check returning FALSE we know that the * following timeouts are not expiring, so we break as * soon as possible */ if (egg_timeout_prepare (pool, timeout, NULL)) { timeout->flags |= EGG_TIMEOUT_READY; pool->ready += 1; } else break; } egg_threads_leave (); return (pool->ready > 0); } static gboolean egg_timeout_pool_dispatch (GSource *source, GSourceFunc func, gpointer data) { EggTimeoutPool *pool = (EggTimeoutPool *) source; GList *dispatched_timeouts; /* the main loop might have predicted this, so we repeat the * check for ready timeouts. */ if (!pool->ready) egg_timeout_pool_check (source); egg_threads_enter (); /* Iterate by moving the actual start of the list along so that it * can cope with adds and removes while a timeout is being dispatched */ while (pool->timeouts && pool->timeouts->data && pool->ready-- > 0) { EggTimeout *timeout = pool->timeouts->data; GList *l; /* One of the ready timeouts may have been removed during dispatch, * in which case pool->ready will be wrong, but the ready timeouts * are always kept at the start of the list so we can stop once * we've reached the first non-ready timeout */ if (!(TIMEOUT_READY (timeout))) break; /* Add a reference to the timeout so it can't disappear * while it's being dispatched */ egg_timeout_ref (timeout); timeout->flags &= ~EGG_TIMEOUT_READY; /* Move the list node to a list of dispatched timeouts */ l = pool->timeouts; if (l->next) l->next->prev = NULL; pool->timeouts = l->next; if (pool->dispatched_timeouts) pool->dispatched_timeouts->prev = l; l->prev = NULL; l->next = pool->dispatched_timeouts; pool->dispatched_timeouts = l; if (!egg_timeout_dispatch (source, timeout)) { /* The timeout may have already been removed, but nothing * can be added to the dispatched_timeout list except in this * function so it will always either be at the head of the * dispatched list or have been removed */ if (pool->dispatched_timeouts && pool->dispatched_timeouts->data == timeout) { pool->dispatched_timeouts = g_list_delete_link (pool->dispatched_timeouts, pool->dispatched_timeouts); /* Remove the reference that was held by it being in the list */ egg_timeout_unref (timeout); } } egg_timeout_unref (timeout); } /* Re-insert the dispatched timeouts in sorted order */ dispatched_timeouts = pool->dispatched_timeouts; while (dispatched_timeouts) { EggTimeout *timeout = dispatched_timeouts->data; GList *next = dispatched_timeouts->next; if (timeout) pool->timeouts = g_list_insert_sorted (pool->timeouts, timeout, egg_timeout_sort); dispatched_timeouts = next; } g_list_free (pool->dispatched_timeouts); pool->dispatched_timeouts = NULL; pool->ready = 0; egg_threads_leave (); return TRUE; } static void egg_timeout_pool_finalize (GSource *source) { EggTimeoutPool *pool = (EggTimeoutPool *) source; /* force destruction */ g_list_foreach (pool->timeouts, (GFunc) egg_timeout_free, NULL); g_list_free (pool->timeouts); } /** * egg_timeout_pool_new: * @priority: the priority of the timeout pool. Typically this will * be #G_PRIORITY_DEFAULT * * Creates a new timeout pool source. A timeout pool should be used when * multiple timeout functions, running at the same priority, are needed and * the g_timeout_add() API might lead to starvation of the time slice of * the main loop. A timeout pool allocates a single time slice of the main * loop and runs every timeout function inside it. The timeout pool is * always sorted, so that the extraction of the next timeout function is * a constant time operation. * * Inside Egg, every #EggTimeline share the same timeout pool, unless * the EGG_TIMELINE=no-pool environment variable is set. * * #EggTimeoutPool is part of the #EggTimeline implementation * and should not be used by application developers. * * Return value: the newly created #EggTimeoutPool. The created pool * is owned by the GLib default context and will be automatically * destroyed when the context is destroyed. It is possible to force * the destruction of the timeout pool using g_source_destroy() * * Since: 0.4 */ EggTimeoutPool * egg_timeout_pool_new (gint priority) { EggTimeoutPool *pool; GSource *source; source = g_source_new (&egg_timeout_pool_funcs, sizeof (EggTimeoutPool)); if (!source) return NULL; if (priority != G_PRIORITY_DEFAULT) g_source_set_priority (source, priority); pool = (EggTimeoutPool *) source; g_get_current_time (&pool->start_time); pool->next_id = 1; pool->id = g_source_attach (source, NULL); /* let the default GLib context manage the pool */ g_source_unref (source); return pool; } /** * egg_timeout_pool_add: * @pool: a #EggTimeoutPool * @interval: the time between calls to the function, in milliseconds * @func: function to call * @data: data to pass to the function, or %NULL * @notify: function to call when the timeout is removed, or %NULL * * Sets a function to be called at regular intervals, and puts it inside * the @pool. The function is repeatedly called until it returns %FALSE, * at which point the timeout is automatically destroyed and the function * won't be called again. If @notify is not %NULL, the @notify function * will be called. The first call to @func will be at the end of @interval. * * Since version 0.8 this will try to compensate for delays. For * example, if @func takes half the interval time to execute then the * function will be called again half the interval time after it * finished. Before version 0.8 it would not fire until a full * interval after the function completes so the delay between calls * would be @interval * 1.5. This function does not however try to * invoke the function multiple times to catch up missing frames if * @func takes more than @interval ms to execute. * * Return value: the ID (greater than 0) of the timeout inside the pool. * Use egg_timeout_pool_remove() to stop the timeout. * * Since: 0.4 */ guint egg_timeout_pool_add (EggTimeoutPool *pool, guint interval, GSourceFunc func, gpointer data, GDestroyNotify notify) { EggTimeout *timeout; guint retval = 0; timeout = egg_timeout_new (interval); retval = timeout->id = pool->next_id++; timeout->last_time = egg_timeout_pool_get_ticks (pool); timeout->func = func; timeout->data = data; timeout->notify = notify; pool->timeouts = g_list_insert_sorted (pool->timeouts, timeout, egg_timeout_sort); return retval; } /** * egg_timeout_pool_remove: * @pool: a #EggTimeoutPool * @id: the id of the timeout to remove * * Removes a timeout function with @id from the timeout pool. The id * is the same returned when adding a function to the timeout pool with * egg_timeout_pool_add(). * * Since: 0.4 */ void egg_timeout_pool_remove (EggTimeoutPool *pool, guint id) { GList *l; if ((l = g_list_find_custom (pool->timeouts, GUINT_TO_POINTER (id), egg_timeout_find_by_id))) { egg_timeout_unref (l->data); pool->timeouts = g_list_delete_link (pool->timeouts, l); } else if ((l = g_list_find_custom (pool->dispatched_timeouts, GUINT_TO_POINTER (id), egg_timeout_find_by_id))) { egg_timeout_unref (l->data); pool->dispatched_timeouts = g_list_delete_link (pool->dispatched_timeouts, l); } } ./egg/egg-hack.c0000644000004100000410000001504113570225707013630 0ustar www-datawww-data#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "egg-hack.h" static guint egg_default_fps = 60; guint egg_get_default_frame_rate (void) { return egg_default_fps; } guint egg_debug_flags = 0; /* global egg debug flag */ #ifdef EGG_ENABLE_DEBUG static const GDebugKey egg_debug_keys[] = { { "misc", EGG_DEBUG_MISC }, { "actor", EGG_DEBUG_ACTOR }, { "texture", EGG_DEBUG_TEXTURE }, { "event", EGG_DEBUG_EVENT }, { "paint", EGG_DEBUG_PAINT }, { "gl", EGG_DEBUG_GL }, { "alpha", EGG_DEBUG_ALPHA }, { "behaviour", EGG_DEBUG_BEHAVIOUR }, { "pango", EGG_DEBUG_PANGO }, { "backend", EGG_DEBUG_BACKEND }, { "scheduler", EGG_DEBUG_SCHEDULER }, { "script", EGG_DEBUG_SCRIPT }, { "shader", EGG_DEBUG_SHADER }, { "multistage", EGG_DEBUG_MULTISTAGE }, }; #endif /* EGG_ENABLE_DEBUG */ gboolean egg_get_debug_enabled (void) { #ifdef EGG_ENABLE_DEBUG return egg_debug_flags != 0; #else return FALSE; #endif } void egg_threads_enter (void) { return; } void egg_threads_leave (void) { return; } static guint egg_main_loop_level = 0; static GSList *main_loops = NULL; /** * egg_main: * * Starts the Egg mainloop. */ void egg_main (void) { GMainLoop *loop; #if 0 /* Make sure there is a context */ EGG_CONTEXT (); #endif EGG_MARK (); egg_main_loop_level++; loop = g_main_loop_new (NULL, TRUE); main_loops = g_slist_prepend (main_loops, loop); #ifdef HAVE_EGG_FRUITY /* egg fruity creates an application that forwards events and manually * spins the mainloop */ egg_fruity_main (); #else if (g_main_loop_is_running (main_loops->data)) { egg_threads_leave (); g_main_loop_run (loop); egg_threads_enter (); } #endif main_loops = g_slist_remove (main_loops, loop); g_main_loop_unref (loop); egg_main_loop_level--; EGG_MARK (); } /* -------------------------------------------------------------------------- */ /* auto-generated code taken from egg-enum-types.c */ /* enumerations from "./egg-timeline.h" */ #include "./egg-timeline.h" GType egg_timeline_direction_get_type(void) { static GType etype = 0; if (G_UNLIKELY (!etype)) { static const GEnumValue values[] = { { EGG_TIMELINE_FORWARD, "EGG_TIMELINE_FORWARD", "forward" }, { EGG_TIMELINE_BACKWARD, "EGG_TIMELINE_BACKWARD", "backward" }, { 0, NULL, NULL } }; etype = g_enum_register_static (g_intern_static_string ("EggTimelineDirection"), values); } return etype; } /* auto-generated code taken from egg-marshal.c */ #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_int(v) (v)->data[0].v_int /* VOID:STRING,INT (./egg-marshal.list:12) */ void egg_marshal_VOID__STRING_INT (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer data1, gpointer arg_1, gint arg_2, gpointer data2); register GMarshalFunc_VOID__STRING_INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__STRING_INT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_string (param_values + 1), g_marshal_value_peek_int (param_values + 2), data2); } /* VOID:INT,INT (./egg-marshal.list:6) */ void egg_marshal_VOID__INT_INT (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, gint arg_1, gint arg_2, gpointer data2); register GMarshalFunc_VOID__INT_INT callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_int (param_values + 2), data2); } /* UINT:VOID (./egg-marshal.list:2) */ void egg_marshal_UINT__VOID (GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) { typedef guint (*GMarshalFunc_UINT__VOID) (gpointer data1, gpointer data2); register GMarshalFunc_UINT__VOID callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; guint v_return; g_return_if_fail (return_value != NULL); g_return_if_fail (n_param_values == 1); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_UINT__VOID) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, data2); g_value_set_uint (return_value, v_return); } ./egg/egg-timeline.h0000644000004100000410000001554413570225707014545 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * * Copyright (C) 2006 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _HAVE_EGG_TIMELINE_H #define _HAVE_EGG_TIMELINE_H #include #include G_BEGIN_DECLS #define EGG_TYPE_TIMELINE (egg_timeline_get_type ()) #define EGG_TIMELINE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ EGG_TYPE_TIMELINE, EggTimeline)) #define EGG_TIMELINE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ EGG_TYPE_TIMELINE, EggTimelineClass)) #define EGG_IS_TIMELINE(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ EGG_TYPE_TIMELINE)) #define EGG_IS_TIMELINE_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ EGG_TYPE_TIMELINE)) #define EGG_TIMELINE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ EGG_TYPE_TIMELINE, EggTimelineClass)) /** * EggTimelineDirection: * @EGG_TIMELINE_FORWARD: forward direction for a timeline * @EGG_TIMELINE_BACKWARD: backward direction for a timeline * * The direction of a #EggTimeline * * Since: 0.6 */ typedef enum { EGG_TIMELINE_FORWARD, EGG_TIMELINE_BACKWARD } EggTimelineDirection; typedef struct _EggTimeline EggTimeline; typedef struct _EggTimelineClass EggTimelineClass; typedef struct _EggTimelinePrivate EggTimelinePrivate; struct _EggTimeline { /*< private >*/ GObject parent; EggTimelinePrivate *priv; }; struct _EggTimelineClass { /*< private >*/ GObjectClass parent_class; /*< public >*/ void (*started) (EggTimeline *timeline); void (*completed) (EggTimeline *timeline); void (*paused) (EggTimeline *timeline); void (*new_frame) (EggTimeline *timeline, gint frame_num); void (*marker_reached) (EggTimeline *timeline, const gchar *marker_name, gint frame_num); /*< private >*/ void (*_egg_timeline_1) (void); void (*_egg_timeline_2) (void); void (*_egg_timeline_3) (void); void (*_egg_timeline_4) (void); void (*_egg_timeline_5) (void); }; GType egg_timeline_get_type (void) G_GNUC_CONST; EggTimeline *egg_timeline_new (guint n_frames, guint fps); EggTimeline *egg_timeline_new_for_duration (guint msecs); EggTimeline *egg_timeline_clone (EggTimeline *timeline); guint egg_timeline_get_duration (EggTimeline *timeline); void egg_timeline_set_duration (EggTimeline *timeline, guint msecs); guint egg_timeline_get_speed (EggTimeline *timeline); void egg_timeline_set_speed (EggTimeline *timeline, guint fps); EggTimelineDirection egg_timeline_get_direction (EggTimeline *timeline); void egg_timeline_set_direction (EggTimeline *timeline, EggTimelineDirection direction); void egg_timeline_start (EggTimeline *timeline); void egg_timeline_pause (EggTimeline *timeline); void egg_timeline_stop (EggTimeline *timeline); void egg_timeline_set_loop (EggTimeline *timeline, gboolean loop); gboolean egg_timeline_get_loop (EggTimeline *timeline); void egg_timeline_rewind (EggTimeline *timeline); void egg_timeline_skip (EggTimeline *timeline, guint n_frames); void egg_timeline_advance (EggTimeline *timeline, guint frame_num); gint egg_timeline_get_current_frame (EggTimeline *timeline); gdouble egg_timeline_get_progress (EggTimeline *timeline); EggFixed egg_timeline_get_progressx (EggTimeline *timeline); void egg_timeline_set_n_frames (EggTimeline *timeline, guint n_frames); guint egg_timeline_get_n_frames (EggTimeline *timeline); gboolean egg_timeline_is_playing (EggTimeline *timeline); void egg_timeline_set_delay (EggTimeline *timeline, guint msecs); guint egg_timeline_get_delay (EggTimeline *timeline); guint egg_timeline_get_delta (EggTimeline *timeline, guint *msecs); void egg_timeline_add_marker_at_frame (EggTimeline *timeline, const gchar *marker_name, guint frame_num); void egg_timeline_add_marker_at_time (EggTimeline *timeline, const gchar *marker_name, guint msecs); void egg_timeline_remove_marker (EggTimeline *timeline, const gchar *marker_name); gchar ** egg_timeline_list_markers (EggTimeline *timeline, gint frame_num, gsize *n_markers) G_GNUC_MALLOC; gboolean egg_timeline_has_marker (EggTimeline *timeline, const gchar *marker_name); void egg_timeline_advance_to_marker (EggTimeline *timeline, const gchar *marker_name); G_END_DECLS #endif /* _HAVE_EGG_TIMELINE_H */ ./egg/test-timeline-rewind.c0000644000004100000410000000404513570225707016235 0ustar www-datawww-data#include #include #include #define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FRAME_COUNT 5 #define TEST_WATCHDOG_KICK_IN_SECONDS 10 typedef struct _TestState { EggTimeline *timeline; gint rewind_count; }TestState; static gboolean watchdog_timeout (TestState *state) { g_print ("Watchdog timer kicking in\n"); g_print ("rewind_count=%i\n", state->rewind_count); if (state->rewind_count <= 3) { /* The test has hung */ g_print ("Failed (This test shouldn't have hung!)\n"); exit (EXIT_FAILURE); } else { g_print ("Passed\n"); exit (EXIT_SUCCESS); } return FALSE; } static void new_frame_cb (EggTimeline *timeline, gint frame_num, TestState *state) { gint current_frame = egg_timeline_get_current_frame (timeline); if (current_frame == TEST_TIMELINE_FRAME_COUNT) { g_print ("new-frame signal recieved (end of timeline)\n"); g_print ("Rewinding timeline\n"); egg_timeline_rewind (timeline); state->rewind_count++; } else { if (current_frame == 0) { g_print ("new-frame signal recieved (start of timeline)\n"); } else { g_print ("new-frame signal recieved (mid frame)\n"); } if (state->rewind_count >= 2) { g_print ("Sleeping for 1 second\n"); g_usleep (1000000); } } } int main (int argc, char **argv) { TestState state; state.timeline = egg_timeline_new (TEST_TIMELINE_FRAME_COUNT, TEST_TIMELINE_FPS); g_signal_connect (G_OBJECT(state.timeline), "new-frame", G_CALLBACK(new_frame_cb), &state); g_print ("Installing a watchdog timeout to determin if this test hangs\n"); g_timeout_add (TEST_WATCHDOG_KICK_IN_SECONDS*1000, (GSourceFunc)watchdog_timeout, &state); state.rewind_count = 0; egg_timeline_start (state.timeline); egg_main(); return EXIT_FAILURE; } ./egg/test-timeline.c0000644000004100000410000000747613570225707014762 0ustar www-datawww-data#include #include #include #include static void timeline_1_complete (EggTimeline *timeline) { g_debug ("1: Completed"); } static void timeline_2_complete (EggTimeline *timeline) { g_debug ("2: Completed"); } static void timeline_3_complete (EggTimeline *timeline) { g_debug ("3: Completed"); } static void timeline_1_new_frame_cb (EggTimeline *timeline, gint frame_no) { g_debug ("1: Doing frame %d.", frame_no); } static void timeline_2_new_frame_cb (EggTimeline *timeline, gint frame_no) { g_debug ("2: Doing frame %d.", frame_no); } static void timeline_3_new_frame_cb (EggTimeline *timeline, gint frame_no) { g_debug ("3: Doing frame %d.", frame_no); } static void timeline_1_marker_reached (EggTimeline *timeline, const gchar *marker_name, guint frame_num) { g_print ("1: Marker `%s' (%d) reached\n", marker_name, frame_num); } static void timeline_2_marker_reached (EggTimeline *timeline, const gchar *marker_name, guint frame_num) { g_print ("2: Marker `%s' (%d) reached\n", marker_name, frame_num); } static void timeline_3_marker_reached (EggTimeline *timeline, const gchar *marker_name, guint frame_num) { g_print ("3: Marker `%s' (%d) reached\n", marker_name, frame_num); } int main (int argc, char **argv) { EggTimeline *timeline_1; EggTimeline *timeline_2; EggTimeline *timeline_3; gchar **markers; gsize n_markers; timeline_1 = egg_timeline_new (10, 120); egg_timeline_add_marker_at_frame (timeline_1, "foo", 5); egg_timeline_add_marker_at_frame (timeline_1, "bar", 5); egg_timeline_add_marker_at_frame (timeline_1, "baz", 5); markers = egg_timeline_list_markers (timeline_1, 5, &n_markers); g_assert (markers != NULL); g_assert (n_markers == 3); g_strfreev (markers); timeline_2 = egg_timeline_clone (timeline_1); egg_timeline_add_marker_at_frame (timeline_2, "bar", 2); markers = egg_timeline_list_markers (timeline_2, -1, &n_markers); g_assert (markers != NULL); g_assert (n_markers == 1); g_assert (strcmp (markers[0], "bar") == 0); g_strfreev (markers); timeline_3 = egg_timeline_clone (timeline_1); egg_timeline_set_direction (timeline_3, EGG_TIMELINE_BACKWARD); egg_timeline_add_marker_at_frame (timeline_3, "baz", 8); g_signal_connect (timeline_1, "marker-reached", G_CALLBACK (timeline_1_marker_reached), NULL); g_signal_connect (timeline_1, "new-frame", G_CALLBACK (timeline_1_new_frame_cb), NULL); g_signal_connect (timeline_1, "completed", G_CALLBACK (timeline_1_complete), NULL); g_signal_connect (timeline_2, "marker-reached::bar", G_CALLBACK (timeline_2_marker_reached), NULL); g_signal_connect (timeline_2, "new-frame", G_CALLBACK (timeline_2_new_frame_cb), NULL); g_signal_connect (timeline_2, "completed", G_CALLBACK (timeline_2_complete), NULL); g_signal_connect (timeline_3, "marker-reached", G_CALLBACK (timeline_3_marker_reached), NULL); g_signal_connect (timeline_3, "new-frame", G_CALLBACK (timeline_3_new_frame_cb), NULL); g_signal_connect (timeline_3, "completed", G_CALLBACK (timeline_3_complete), NULL); egg_timeline_start (timeline_1); egg_timeline_start (timeline_2); egg_timeline_start (timeline_3); egg_main (); g_object_unref (timeline_1); g_object_unref (timeline_2); g_object_unref (timeline_3); return EXIT_SUCCESS; } ./egg/egg-fixed.c0000644000004100000410000011431013570225707014020 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Tomas Frydrych * * Copyright (C) 2006, 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #define G_IMPLEMENT_INLINES #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "egg-fixed.h" // #include "egg-private.h" #include "egg-hack.h" /** * SECTION:egg-fixed * @short_description: Fixed Point API * * Egg has a fixed point API targeted at platforms without a * floating point unit, such as embedded devices. On such platforms * this API should be preferred to the floating point one as it does * not trigger the slow path of software emulation, relying on integer * math for fixed-to-floating and floating-to-fixed conversion. * * It is no recommened for use on platforms with a floating point unit * (eg desktop systems) nor for use in bindings. * * Basic rules of Fixed Point arithmethic: * * * * Two fixed point numbers can be directly added, * subtracted and have their modulus taken. * * * To add other numerical type to a fixed point number it has to * be first converted to fixed point. * * * A fixed point number can be directly multiplied or divided by * an integer. * * * Two fixed point numbers can only be multiplied and divided by the * provided #EGG_FIXED_MUL and #EGG_FIXED_DIV macros. * * */ /* pre-computed sin table for 1st quadrant * * Currently contains 257 entries. * * The current error (compared to system sin) is about * 0.5% for values near the start of the table where the * curve is steep, but improving rapidly. If this precission * is not enough, we can increase the size of the table */ static EggFixed sin_tbl [] = { 0x00000000L, 0x00000192L, 0x00000324L, 0x000004B6L, 0x00000648L, 0x000007DAL, 0x0000096CL, 0x00000AFEL, 0x00000C90L, 0x00000E21L, 0x00000FB3L, 0x00001144L, 0x000012D5L, 0x00001466L, 0x000015F7L, 0x00001787L, 0x00001918L, 0x00001AA8L, 0x00001C38L, 0x00001DC7L, 0x00001F56L, 0x000020E5L, 0x00002274L, 0x00002402L, 0x00002590L, 0x0000271EL, 0x000028ABL, 0x00002A38L, 0x00002BC4L, 0x00002D50L, 0x00002EDCL, 0x00003067L, 0x000031F1L, 0x0000337CL, 0x00003505L, 0x0000368EL, 0x00003817L, 0x0000399FL, 0x00003B27L, 0x00003CAEL, 0x00003E34L, 0x00003FBAL, 0x0000413FL, 0x000042C3L, 0x00004447L, 0x000045CBL, 0x0000474DL, 0x000048CFL, 0x00004A50L, 0x00004BD1L, 0x00004D50L, 0x00004ECFL, 0x0000504DL, 0x000051CBL, 0x00005348L, 0x000054C3L, 0x0000563EL, 0x000057B9L, 0x00005932L, 0x00005AAAL, 0x00005C22L, 0x00005D99L, 0x00005F0FL, 0x00006084L, 0x000061F8L, 0x0000636BL, 0x000064DDL, 0x0000664EL, 0x000067BEL, 0x0000692DL, 0x00006A9BL, 0x00006C08L, 0x00006D74L, 0x00006EDFL, 0x00007049L, 0x000071B2L, 0x0000731AL, 0x00007480L, 0x000075E6L, 0x0000774AL, 0x000078ADL, 0x00007A10L, 0x00007B70L, 0x00007CD0L, 0x00007E2FL, 0x00007F8CL, 0x000080E8L, 0x00008243L, 0x0000839CL, 0x000084F5L, 0x0000864CL, 0x000087A1L, 0x000088F6L, 0x00008A49L, 0x00008B9AL, 0x00008CEBL, 0x00008E3AL, 0x00008F88L, 0x000090D4L, 0x0000921FL, 0x00009368L, 0x000094B0L, 0x000095F7L, 0x0000973CL, 0x00009880L, 0x000099C2L, 0x00009B03L, 0x00009C42L, 0x00009D80L, 0x00009EBCL, 0x00009FF7L, 0x0000A130L, 0x0000A268L, 0x0000A39EL, 0x0000A4D2L, 0x0000A605L, 0x0000A736L, 0x0000A866L, 0x0000A994L, 0x0000AAC1L, 0x0000ABEBL, 0x0000AD14L, 0x0000AE3CL, 0x0000AF62L, 0x0000B086L, 0x0000B1A8L, 0x0000B2C9L, 0x0000B3E8L, 0x0000B505L, 0x0000B620L, 0x0000B73AL, 0x0000B852L, 0x0000B968L, 0x0000BA7DL, 0x0000BB8FL, 0x0000BCA0L, 0x0000BDAFL, 0x0000BEBCL, 0x0000BFC7L, 0x0000C0D1L, 0x0000C1D8L, 0x0000C2DEL, 0x0000C3E2L, 0x0000C4E4L, 0x0000C5E4L, 0x0000C6E2L, 0x0000C7DEL, 0x0000C8D9L, 0x0000C9D1L, 0x0000CAC7L, 0x0000CBBCL, 0x0000CCAEL, 0x0000CD9FL, 0x0000CE8EL, 0x0000CF7AL, 0x0000D065L, 0x0000D14DL, 0x0000D234L, 0x0000D318L, 0x0000D3FBL, 0x0000D4DBL, 0x0000D5BAL, 0x0000D696L, 0x0000D770L, 0x0000D848L, 0x0000D91EL, 0x0000D9F2L, 0x0000DAC4L, 0x0000DB94L, 0x0000DC62L, 0x0000DD2DL, 0x0000DDF7L, 0x0000DEBEL, 0x0000DF83L, 0x0000E046L, 0x0000E107L, 0x0000E1C6L, 0x0000E282L, 0x0000E33CL, 0x0000E3F4L, 0x0000E4AAL, 0x0000E55EL, 0x0000E610L, 0x0000E6BFL, 0x0000E76CL, 0x0000E817L, 0x0000E8BFL, 0x0000E966L, 0x0000EA0AL, 0x0000EAABL, 0x0000EB4BL, 0x0000EBE8L, 0x0000EC83L, 0x0000ED1CL, 0x0000EDB3L, 0x0000EE47L, 0x0000EED9L, 0x0000EF68L, 0x0000EFF5L, 0x0000F080L, 0x0000F109L, 0x0000F18FL, 0x0000F213L, 0x0000F295L, 0x0000F314L, 0x0000F391L, 0x0000F40CL, 0x0000F484L, 0x0000F4FAL, 0x0000F56EL, 0x0000F5DFL, 0x0000F64EL, 0x0000F6BAL, 0x0000F724L, 0x0000F78CL, 0x0000F7F1L, 0x0000F854L, 0x0000F8B4L, 0x0000F913L, 0x0000F96EL, 0x0000F9C8L, 0x0000FA1FL, 0x0000FA73L, 0x0000FAC5L, 0x0000FB15L, 0x0000FB62L, 0x0000FBADL, 0x0000FBF5L, 0x0000FC3BL, 0x0000FC7FL, 0x0000FCC0L, 0x0000FCFEL, 0x0000FD3BL, 0x0000FD74L, 0x0000FDACL, 0x0000FDE1L, 0x0000FE13L, 0x0000FE43L, 0x0000FE71L, 0x0000FE9CL, 0x0000FEC4L, 0x0000FEEBL, 0x0000FF0EL, 0x0000FF30L, 0x0000FF4EL, 0x0000FF6BL, 0x0000FF85L, 0x0000FF9CL, 0x0000FFB1L, 0x0000FFC4L, 0x0000FFD4L, 0x0000FFE1L, 0x0000FFECL, 0x0000FFF5L, 0x0000FFFBL, 0x0000FFFFL, 0x00010000L, }; /* the difference of the angle for two adjacent values in the table * expressed as EggFixed number */ #define CFX_SIN_STEP 0x00000192 /* */ const double _magic = 68719476736.0 * 1.5; /* Where in the 64 bits of double is the mantisa */ #if (__FLOAT_WORD_ORDER == 1234) #define _CFX_MAN 0 #elif (__FLOAT_WORD_ORDER == 4321) #define _CFX_MAN 1 #else #define CFX_NO_FAST_CONVERSIONS #endif /* * egg_double_to_fixed : * @value: value to be converted * * A fast conversion from double precision floating to fixed point * * Return value: Fixed point representation of the value * * Since: 0.2 */ EggFixed egg_double_to_fixed (double val) { #ifdef CFX_NO_FAST_CONVERSIONS return (EggFixed)(val * (double)CFX_ONE); #else union { double d; unsigned int i[2]; } dbl; dbl.d = val; dbl.d = dbl.d + _magic; return dbl.i[_CFX_MAN]; #endif } /* * egg_double_to_int : * @value: value to be converted * * A fast conversion from doulbe precision floatint point to int; * used this instead of casting double/float to int. * * Return value: Integer part of the double * * Since: 0.2 */ gint egg_double_to_int (double val) { #ifdef CFX_NO_FAST_CONVERSIONS return (gint)(val); #else union { double d; unsigned int i[2]; } dbl; dbl.d = val; dbl.d = dbl.d + _magic; return ((int)dbl.i[_CFX_MAN]) >> 16; #endif } guint egg_double_to_uint (double val) { #ifdef CFX_NO_FAST_CONVERSIONS return (guint)(val); #else union { double d; unsigned int i[2]; } dbl; dbl.d = val; dbl.d = dbl.d + _magic; return (dbl.i[_CFX_MAN]) >> 16; #endif } #undef _CFX_MAN /** * egg_sinx: * @angle: a #EggFixed angle in radians * * Fixed point implementation of sine function * * Return value: #EggFixed sine value. * * Since: 0.2 */ EggFixed egg_sinx (EggFixed angle) { int sign = 1, indx1, indx2; EggFixed low, high, d1, d2; /* convert negative angle to positive + sign */ if ((int)angle < 0) { sign = 1 + ~sign; angle = 1 + ~angle; } /* reduce to <0, 2*pi) */ angle = angle % CFX_2PI; /* reduce to first quadrant and sign */ if (angle > CFX_PI) { sign = 1 + ~sign; if (angle > CFX_PI + CFX_PI_2) { /* fourth qudrant */ angle = CFX_2PI - angle; } else { /* third quadrant */ angle -= CFX_PI; } } else { if (angle > CFX_PI_2) { /* second quadrant */ angle = CFX_PI - angle; } } /* Calculate indices of the two nearest values in our table * and return weighted average * * Handle the end of the table gracefully */ indx1 = EGG_FIXED_DIV (angle, CFX_SIN_STEP); indx1 = EGG_FIXED_TO_INT (indx1); if (indx1 == sizeof (sin_tbl)/sizeof (EggFixed) - 1) { indx2 = indx1; indx1 = indx2 - 1; } else { indx2 = indx1 + 1; } low = sin_tbl[indx1]; high = sin_tbl[indx2]; d1 = angle - indx1 * CFX_SIN_STEP; d2 = indx2 * CFX_SIN_STEP - angle; angle = ((low * d2 + high * d1) / (CFX_SIN_STEP)); if (sign < 0) angle = (1 + ~angle); return angle; } /** * egg_sini: * @angle: a #EggAngle * * Very fast fixed point implementation of sine function. * * EggAngle is an integer such that 1024 represents * full circle. * * Return value: #EggFixed sine value. * * Since: 0.2 */ EggFixed egg_sini (EggAngle angle) { int sign = 1; EggFixed result; /* reduce negative angle to positive + sign */ if (angle < 0) { sign = 1 + ~sign; angle = 1 + ~angle; } /* reduce to <0, 2*pi) */ angle &= 0x3ff; /* reduce to first quadrant and sign */ if (angle > 512) { sign = 1 + ~sign; if (angle > 768) { /* fourth qudrant */ angle = 1024 - angle; } else { /* third quadrant */ angle -= 512; } } else { if (angle > 256) { /* second quadrant */ angle = 512 - angle; } } result = sin_tbl[angle]; if (sign < 0) result = (1 + ~result); return result; } /* pre-computed tan table for 1st quadrant * * Currently contains 257 entries. * */ static EggFixed tan_tbl [] = { 0x00000000L, 0x00000192L, 0x00000324L, 0x000004b7L, 0x00000649L, 0x000007dbL, 0x0000096eL, 0x00000b01L, 0x00000c94L, 0x00000e27L, 0x00000fbaL, 0x0000114eL, 0x000012e2L, 0x00001477L, 0x0000160cL, 0x000017a1L, 0x00001937L, 0x00001acdL, 0x00001c64L, 0x00001dfbL, 0x00001f93L, 0x0000212cL, 0x000022c5L, 0x0000245fL, 0x000025f9L, 0x00002795L, 0x00002931L, 0x00002aceL, 0x00002c6cL, 0x00002e0aL, 0x00002faaL, 0x0000314aL, 0x000032ecL, 0x0000348eL, 0x00003632L, 0x000037d7L, 0x0000397dL, 0x00003b24L, 0x00003cccL, 0x00003e75L, 0x00004020L, 0x000041ccL, 0x00004379L, 0x00004528L, 0x000046d8L, 0x0000488aL, 0x00004a3dL, 0x00004bf2L, 0x00004da8L, 0x00004f60L, 0x0000511aL, 0x000052d5L, 0x00005492L, 0x00005651L, 0x00005812L, 0x000059d5L, 0x00005b99L, 0x00005d60L, 0x00005f28L, 0x000060f3L, 0x000062c0L, 0x0000648fL, 0x00006660L, 0x00006834L, 0x00006a0aL, 0x00006be2L, 0x00006dbdL, 0x00006f9aL, 0x0000717aL, 0x0000735dL, 0x00007542L, 0x0000772aL, 0x00007914L, 0x00007b02L, 0x00007cf2L, 0x00007ee6L, 0x000080dcL, 0x000082d6L, 0x000084d2L, 0x000086d2L, 0x000088d6L, 0x00008adcL, 0x00008ce7L, 0x00008ef4L, 0x00009106L, 0x0000931bL, 0x00009534L, 0x00009750L, 0x00009971L, 0x00009b95L, 0x00009dbeL, 0x00009febL, 0x0000a21cL, 0x0000a452L, 0x0000a68cL, 0x0000a8caL, 0x0000ab0eL, 0x0000ad56L, 0x0000afa3L, 0x0000b1f5L, 0x0000b44cL, 0x0000b6a8L, 0x0000b909L, 0x0000bb70L, 0x0000bdddL, 0x0000c04fL, 0x0000c2c7L, 0x0000c545L, 0x0000c7c9L, 0x0000ca53L, 0x0000cce3L, 0x0000cf7aL, 0x0000d218L, 0x0000d4bcL, 0x0000d768L, 0x0000da1aL, 0x0000dcd4L, 0x0000df95L, 0x0000e25eL, 0x0000e52eL, 0x0000e806L, 0x0000eae7L, 0x0000edd0L, 0x0000f0c1L, 0x0000f3bbL, 0x0000f6bfL, 0x0000f9cbL, 0x0000fce1L, 0x00010000L, 0x00010329L, 0x0001065dL, 0x0001099aL, 0x00010ce3L, 0x00011036L, 0x00011394L, 0x000116feL, 0x00011a74L, 0x00011df6L, 0x00012184L, 0x0001251fL, 0x000128c6L, 0x00012c7cL, 0x0001303fL, 0x00013410L, 0x000137f0L, 0x00013bdfL, 0x00013fddL, 0x000143ebL, 0x00014809L, 0x00014c37L, 0x00015077L, 0x000154c9L, 0x0001592dL, 0x00015da4L, 0x0001622eL, 0x000166ccL, 0x00016b7eL, 0x00017045L, 0x00017523L, 0x00017a17L, 0x00017f22L, 0x00018444L, 0x00018980L, 0x00018ed5L, 0x00019445L, 0x000199cfL, 0x00019f76L, 0x0001a53aL, 0x0001ab1cL, 0x0001b11dL, 0x0001b73fL, 0x0001bd82L, 0x0001c3e7L, 0x0001ca71L, 0x0001d11fL, 0x0001d7f4L, 0x0001def1L, 0x0001e618L, 0x0001ed6aL, 0x0001f4e8L, 0x0001fc96L, 0x00020473L, 0x00020c84L, 0x000214c9L, 0x00021d44L, 0x000225f9L, 0x00022ee9L, 0x00023818L, 0x00024187L, 0x00024b3aL, 0x00025534L, 0x00025f78L, 0x00026a0aL, 0x000274edL, 0x00028026L, 0x00028bb8L, 0x000297a8L, 0x0002a3fbL, 0x0002b0b5L, 0x0002bdddL, 0x0002cb79L, 0x0002d98eL, 0x0002e823L, 0x0002f740L, 0x000306ecL, 0x00031730L, 0x00032816L, 0x000339a6L, 0x00034bebL, 0x00035ef2L, 0x000372c6L, 0x00038776L, 0x00039d11L, 0x0003b3a6L, 0x0003cb48L, 0x0003e40aL, 0x0003fe02L, 0x00041949L, 0x000435f7L, 0x0004542bL, 0x00047405L, 0x000495a9L, 0x0004b940L, 0x0004def6L, 0x00050700L, 0x00053196L, 0x00055ef9L, 0x00058f75L, 0x0005c35dL, 0x0005fb14L, 0x00063709L, 0x000677c0L, 0x0006bdd0L, 0x000709ecL, 0x00075ce6L, 0x0007b7bbL, 0x00081b98L, 0x000889e9L, 0x0009046eL, 0x00098d4dL, 0x000a2736L, 0x000ad593L, 0x000b9cc6L, 0x000c828aL, 0x000d8e82L, 0x000ecb1bL, 0x001046eaL, 0x00121703L, 0x00145b00L, 0x0017448dL, 0x001b2672L, 0x002095afL, 0x0028bc49L, 0x0036519aL, 0x00517bb6L, 0x00a2f8fdL, 0x46d3eab2L, }; /** * egg_tani: * @angle: a #EggAngle * * Very fast fixed point implementation of tan function. * * EggAngle is an integer such that 1024 represents * full circle. * * Return value: #EggFixed sine value. * * Since: 0.3 */ EggFixed egg_tani (EggAngle angle) { int sign = 1; EggFixed result; /* reduce negative angle to positive + sign */ if (angle < 0) { sign = 1 + ~sign; angle = 1 + ~angle; } /* reduce to <0, pi) */ angle &= 0x1ff; /* reduce to first quadrant and sign */ if (angle > 256) { sign = 1 + ~sign; angle = 512 - angle; } result = tan_tbl[angle]; if (sign < 0) result = (1 + ~result); return result; } /* 257-value table of atan. atan_tbl[0] is atan(0.0) and atan_tbl[256] is atan(1). The angles are radians in EggFixed truncated to 16-bit (they're all less than one) */ static guint16 atan_tbl[] = { 0x0000, 0x00FF, 0x01FF, 0x02FF, 0x03FF, 0x04FF, 0x05FF, 0x06FF, 0x07FF, 0x08FF, 0x09FE, 0x0AFE, 0x0BFD, 0x0CFD, 0x0DFC, 0x0EFB, 0x0FFA, 0x10F9, 0x11F8, 0x12F7, 0x13F5, 0x14F3, 0x15F2, 0x16F0, 0x17EE, 0x18EB, 0x19E9, 0x1AE6, 0x1BE3, 0x1CE0, 0x1DDD, 0x1ED9, 0x1FD5, 0x20D1, 0x21CD, 0x22C8, 0x23C3, 0x24BE, 0x25B9, 0x26B3, 0x27AD, 0x28A7, 0x29A1, 0x2A9A, 0x2B93, 0x2C8B, 0x2D83, 0x2E7B, 0x2F72, 0x306A, 0x3160, 0x3257, 0x334D, 0x3442, 0x3538, 0x362D, 0x3721, 0x3815, 0x3909, 0x39FC, 0x3AEF, 0x3BE2, 0x3CD4, 0x3DC5, 0x3EB6, 0x3FA7, 0x4097, 0x4187, 0x4277, 0x4365, 0x4454, 0x4542, 0x462F, 0x471C, 0x4809, 0x48F5, 0x49E0, 0x4ACB, 0x4BB6, 0x4CA0, 0x4D89, 0x4E72, 0x4F5B, 0x5043, 0x512A, 0x5211, 0x52F7, 0x53DD, 0x54C2, 0x55A7, 0x568B, 0x576F, 0x5852, 0x5934, 0x5A16, 0x5AF7, 0x5BD8, 0x5CB8, 0x5D98, 0x5E77, 0x5F55, 0x6033, 0x6110, 0x61ED, 0x62C9, 0x63A4, 0x647F, 0x6559, 0x6633, 0x670C, 0x67E4, 0x68BC, 0x6993, 0x6A6A, 0x6B40, 0x6C15, 0x6CEA, 0x6DBE, 0x6E91, 0x6F64, 0x7036, 0x7108, 0x71D9, 0x72A9, 0x7379, 0x7448, 0x7516, 0x75E4, 0x76B1, 0x777E, 0x7849, 0x7915, 0x79DF, 0x7AA9, 0x7B72, 0x7C3B, 0x7D03, 0x7DCA, 0x7E91, 0x7F57, 0x801C, 0x80E1, 0x81A5, 0x8269, 0x832B, 0x83EE, 0x84AF, 0x8570, 0x8630, 0x86F0, 0x87AF, 0x886D, 0x892A, 0x89E7, 0x8AA4, 0x8B5F, 0x8C1A, 0x8CD5, 0x8D8E, 0x8E47, 0x8F00, 0x8FB8, 0x906F, 0x9125, 0x91DB, 0x9290, 0x9345, 0x93F9, 0x94AC, 0x955F, 0x9611, 0x96C2, 0x9773, 0x9823, 0x98D2, 0x9981, 0x9A2F, 0x9ADD, 0x9B89, 0x9C36, 0x9CE1, 0x9D8C, 0x9E37, 0x9EE0, 0x9F89, 0xA032, 0xA0DA, 0xA181, 0xA228, 0xA2CE, 0xA373, 0xA418, 0xA4BC, 0xA560, 0xA602, 0xA6A5, 0xA746, 0xA7E8, 0xA888, 0xA928, 0xA9C7, 0xAA66, 0xAB04, 0xABA1, 0xAC3E, 0xACDB, 0xAD76, 0xAE11, 0xAEAC, 0xAF46, 0xAFDF, 0xB078, 0xB110, 0xB1A7, 0xB23E, 0xB2D5, 0xB36B, 0xB400, 0xB495, 0xB529, 0xB5BC, 0xB64F, 0xB6E2, 0xB773, 0xB805, 0xB895, 0xB926, 0xB9B5, 0xBA44, 0xBAD3, 0xBB61, 0xBBEE, 0xBC7B, 0xBD07, 0xBD93, 0xBE1E, 0xBEA9, 0xBF33, 0xBFBC, 0xC046, 0xC0CE, 0xC156, 0xC1DD, 0xC264, 0xC2EB, 0xC371, 0xC3F6, 0xC47B, 0xC4FF, 0xC583, 0xC606, 0xC689, 0xC70B, 0xC78D, 0xC80E, 0xC88F, 0xC90F }; /** * egg_atani: * @x: The tangent to calculate the angle for * * Fast fixed-point version of the arctangent function. * * Return value: The angle in radians represented as a #EggFixed * for which the tangent is @x. */ EggFixed egg_atani (EggFixed x) { gboolean negative = FALSE; EggFixed angle; if (x < 0) { negative = TRUE; x = -x; } if (x > CFX_ONE) /* if x > 1 then atan(x) = pi/2 - atan(1/x) */ angle = CFX_PI / 2 - atan_tbl[CFX_QDIV (CFX_ONE, x) >> 8]; else angle = atan_tbl[x >> 8]; return negative ? -angle : angle; } /** * egg_atan2i: * @y: Numerator of tangent * @x: Denominator of tangent * * Calculates the arctangent of @y / @x but uses the sign of both * arguments to return the angle in right quadrant. * * Return value: The arctangent of @y / @x */ EggFixed egg_atan2i (EggFixed y, EggFixed x) { EggFixed angle; if (x == 0) angle = y >= 0 ? CFX_PI_2 : -CFX_PI_2; else { angle = egg_atani (CFX_QDIV (y, x)); if (x < 0) angle += y >= 0 ? CFX_PI : -CFX_PI; } return angle; } EggFixed sqrt_tbl [] = { 0x00000000L, 0x00010000L, 0x00016A0AL, 0x0001BB68L, 0x00020000L, 0x00023C6FL, 0x00027312L, 0x0002A550L, 0x0002D414L, 0x00030000L, 0x0003298BL, 0x0003510EL, 0x000376CFL, 0x00039B05L, 0x0003BDDDL, 0x0003DF7CL, 0x00040000L, 0x00041F84L, 0x00043E1EL, 0x00045BE1L, 0x000478DEL, 0x00049524L, 0x0004B0BFL, 0x0004CBBCL, 0x0004E624L, 0x00050000L, 0x00051959L, 0x00053237L, 0x00054AA0L, 0x0005629AL, 0x00057A2BL, 0x00059159L, 0x0005A828L, 0x0005BE9CL, 0x0005D4B9L, 0x0005EA84L, 0x00060000L, 0x00061530L, 0x00062A17L, 0x00063EB8L, 0x00065316L, 0x00066733L, 0x00067B12L, 0x00068EB4L, 0x0006A21DL, 0x0006B54DL, 0x0006C847L, 0x0006DB0CL, 0x0006ED9FL, 0x00070000L, 0x00071232L, 0x00072435L, 0x0007360BL, 0x000747B5L, 0x00075935L, 0x00076A8CL, 0x00077BBBL, 0x00078CC2L, 0x00079DA3L, 0x0007AE60L, 0x0007BEF8L, 0x0007CF6DL, 0x0007DFBFL, 0x0007EFF0L, 0x00080000L, 0x00080FF0L, 0x00081FC1L, 0x00082F73L, 0x00083F08L, 0x00084E7FL, 0x00085DDAL, 0x00086D18L, 0x00087C3BL, 0x00088B44L, 0x00089A32L, 0x0008A906L, 0x0008B7C2L, 0x0008C664L, 0x0008D4EEL, 0x0008E361L, 0x0008F1BCL, 0x00090000L, 0x00090E2EL, 0x00091C45L, 0x00092A47L, 0x00093834L, 0x0009460CL, 0x000953CFL, 0x0009617EL, 0x00096F19L, 0x00097CA1L, 0x00098A16L, 0x00099777L, 0x0009A4C6L, 0x0009B203L, 0x0009BF2EL, 0x0009CC47L, 0x0009D94FL, 0x0009E645L, 0x0009F32BL, 0x000A0000L, 0x000A0CC5L, 0x000A1979L, 0x000A261EL, 0x000A32B3L, 0x000A3F38L, 0x000A4BAEL, 0x000A5816L, 0x000A646EL, 0x000A70B8L, 0x000A7CF3L, 0x000A8921L, 0x000A9540L, 0x000AA151L, 0x000AAD55L, 0x000AB94BL, 0x000AC534L, 0x000AD110L, 0x000ADCDFL, 0x000AE8A1L, 0x000AF457L, 0x000B0000L, 0x000B0B9DL, 0x000B172DL, 0x000B22B2L, 0x000B2E2BL, 0x000B3998L, 0x000B44F9L, 0x000B504FL, 0x000B5B9AL, 0x000B66D9L, 0x000B720EL, 0x000B7D37L, 0x000B8856L, 0x000B936AL, 0x000B9E74L, 0x000BA973L, 0x000BB467L, 0x000BBF52L, 0x000BCA32L, 0x000BD508L, 0x000BDFD5L, 0x000BEA98L, 0x000BF551L, 0x000C0000L, 0x000C0AA6L, 0x000C1543L, 0x000C1FD6L, 0x000C2A60L, 0x000C34E1L, 0x000C3F59L, 0x000C49C8L, 0x000C542EL, 0x000C5E8CL, 0x000C68E0L, 0x000C732DL, 0x000C7D70L, 0x000C87ACL, 0x000C91DFL, 0x000C9C0AL, 0x000CA62CL, 0x000CB047L, 0x000CBA59L, 0x000CC464L, 0x000CCE66L, 0x000CD861L, 0x000CE254L, 0x000CEC40L, 0x000CF624L, 0x000D0000L, 0x000D09D5L, 0x000D13A2L, 0x000D1D69L, 0x000D2727L, 0x000D30DFL, 0x000D3A90L, 0x000D4439L, 0x000D4DDCL, 0x000D5777L, 0x000D610CL, 0x000D6A9AL, 0x000D7421L, 0x000D7DA1L, 0x000D871BL, 0x000D908EL, 0x000D99FAL, 0x000DA360L, 0x000DACBFL, 0x000DB618L, 0x000DBF6BL, 0x000DC8B7L, 0x000DD1FEL, 0x000DDB3DL, 0x000DE477L, 0x000DEDABL, 0x000DF6D8L, 0x000E0000L, 0x000E0922L, 0x000E123DL, 0x000E1B53L, 0x000E2463L, 0x000E2D6DL, 0x000E3672L, 0x000E3F70L, 0x000E4869L, 0x000E515DL, 0x000E5A4BL, 0x000E6333L, 0x000E6C16L, 0x000E74F3L, 0x000E7DCBL, 0x000E869DL, 0x000E8F6BL, 0x000E9832L, 0x000EA0F5L, 0x000EA9B2L, 0x000EB26BL, 0x000EBB1EL, 0x000EC3CBL, 0x000ECC74L, 0x000ED518L, 0x000EDDB7L, 0x000EE650L, 0x000EEEE5L, 0x000EF775L, 0x000F0000L, 0x000F0886L, 0x000F1107L, 0x000F1984L, 0x000F21FCL, 0x000F2A6FL, 0x000F32DDL, 0x000F3B47L, 0x000F43ACL, 0x000F4C0CL, 0x000F5468L, 0x000F5CBFL, 0x000F6512L, 0x000F6D60L, 0x000F75AAL, 0x000F7DEFL, 0x000F8630L, 0x000F8E6DL, 0x000F96A5L, 0x000F9ED9L, 0x000FA709L, 0x000FAF34L, 0x000FB75BL, 0x000FBF7EL, 0x000FC79DL, 0x000FCFB7L, 0x000FD7CEL, 0x000FDFE0L, 0x000FE7EEL, 0x000FEFF8L, 0x000FF7FEL, 0x00100000L, }; /** * egg_sqrtx: * @x: a #EggFixed * * A fixed point implementation of squre root * * Return value: #EggFixed square root. * * Since: 0.2 */ EggFixed egg_sqrtx (EggFixed x) { /* The idea for this comes from the Alegro library, exploiting the * fact that, * sqrt (x) = sqrt (x/d) * sqrt (d); * * For d == 2^(n): * * sqrt (x) = sqrt (x/2^(2n)) * 2^n * * By locating suitable n for given x such that x >> 2n is in <0,255> * we can use a LUT of precomputed values. * * This algorithm provides both good performance and precission; * on ARM this function is about 5 times faster than c-lib sqrt, whilst * producing errors < 1%. * */ int t = 0; int sh = 0; #ifndef __arm__ unsigned int mask = 0x40000000; #endif unsigned fract = x & 0x0000ffff; unsigned int d1, d2; EggFixed v1, v2; if (x <= 0) return 0; if (x > CFX_255 || x < CFX_ONE) { /* * Find the highest bit set */ #if __arm__ /* This actually requires at least arm v5, but gcc does not seem * to set the architecture defines correctly, and it is I think * very unlikely that anyone will want to use egg on anything * less than v5. */ int bit; __asm__ ("clz %0, %1\n" "rsb %0, %0, #31\n" :"=r"(bit) :"r" (x)); /* make even (2n) */ bit &= 0xfffffffe; #else /* TODO -- add i386 branch using bshr * * NB: it's been said that the bshr instruction is poorly implemented * and that it is possible to write a faster code in C using binary * search -- at some point we should explore this */ int bit = 30; while (bit >= 0) { if (x & mask) break; mask = (mask >> 1 | mask >> 2); bit -= 2; } #endif /* now bit indicates the highest bit set; there are two scenarios * * 1) bit < 23: Our number is smaller so we shift it left to maximase * precision (< 16 really, since <16,23> never goes * through here. * * 2) bit > 23: our number is above the table, so we shift right */ sh = ((bit - 22) >> 1); if (bit >= 8) t = (x >> (16 - 22 + bit)); else t = (x << (22 - 16 - bit)); } else { t = EGG_FIXED_TO_INT (x); } /* Do a weighted average of the two nearest values */ v1 = sqrt_tbl[t]; v2 = sqrt_tbl[t+1]; /* * 12 is fairly arbitrary -- we want integer that is not too big to cost * us precission */ d1 = (unsigned)(fract) >> 12; d2 = ((unsigned)CFX_ONE >> 12) - d1; x = ((v1*d2) + (v2*d1))/(CFX_ONE >> 12); if (sh > 0) x = x << sh; else if (sh < 0) x = (x >> (1 + ~sh)); return x; } /** * egg_sqrti: * @x: integer value * * Very fast fixed point implementation of square root for integers. * * This function is at least 6x faster than clib sqrt() on x86, and (this is * not a typo!) about 500x faster on ARM without FPU. It's error is < 5% * for arguments < #EGG_SQRTI_ARG_5_PERCENT and < 10% for arguments < * #EGG_SQRTI_ARG_10_PERCENT. The maximum argument that can be passed to * this function is EGG_SQRTI_ARG_MAX. * * Return value: integer square root. * * * Since: 0.2 */ gint egg_sqrti (gint number) { #if defined __SSE2__ /* The GCC built-in with SSE2 (sqrtsd) is up to twice as fast as * the pure integer code below. It is also more accurate. */ return __builtin_sqrt (number); #else /* This is a fixed point implementation of the Quake III sqrt algorithm, * described, for example, at * http://www.codemaestro.com/reviews/review00000105.html * * While the original QIII is extremely fast, the use of floating division * and multiplication makes it perform very on arm processors without FPU. * * The key to successfully replacing the floating point operations with * fixed point is in the choice of the fixed point format. The QIII * algorithm does not calculate the square root, but its reciprocal ('y' * below), which is only at the end turned to the inverse value. In order * for the algorithm to produce satisfactory results, the reciprocal value * must be represented with sufficient precission; the 16.16 we use * elsewhere in egg is not good enough, and 10.22 is used instead. */ EggFixed x; guint32 y_1; /* 10.22 fixed point */ guint32 f = 0x600000; /* '1.5' as 10.22 fixed */ union { float f; guint32 i; } flt, flt2; flt.f = number; x = EGG_INT_TO_FIXED (number) / 2; /* The QIII initial estimate */ flt.i = 0x5f3759df - ( flt.i >> 1 ); /* Now, we convert the float to 10.22 fixed. We exploit the mechanism * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. * * We want 22 bit fraction; a single precission float uses 23 bit * mantisa, so we only need to add 2^(23-22) (no need for the 1.5 * multiplier as we are only dealing with positive numbers). * * Note: we have to use two separate variables here -- for some reason, * if we try to use just the flt variable, gcc on ARM optimises the whole * addition out, and it all goes pear shape, since without it, the bits * in the float will not be correctly aligned. */ flt2.f = flt.f + 2.0; flt2.i &= 0x7FFFFF; /* Now we correct the estimate */ y_1 = (flt2.i >> 11) * (flt2.i >> 11); y_1 = (y_1 >> 8) * (x >> 8); y_1 = f - y_1; flt2.i = (flt2.i >> 11) * (y_1 >> 11); /* If the original argument is less than 342, we do another * iteration to improve precission (for arguments >= 342, the single * iteration produces generally better results). */ if (x < 171) { y_1 = (flt2.i >> 11) * (flt2.i >> 11); y_1 = (y_1 >> 8) * (x >> 8); y_1 = f - y_1; flt2.i = (flt2.i >> 11) * (y_1 >> 11); } /* Invert, round and convert from 10.22 to an integer * 0x1e3c68 is a magical rounding constant that produces slightly * better results than 0x200000. */ return (number * flt2.i + 0x1e3c68) >> 22; #endif } /** * egg_qmulx: * @op1: #EggFixed * @op2: #EggFixed * * Multiplies two fixed values using 64bit arithmetic; this provides * significantly better precission than the #EGG_FIXED_MUL macro, * but at performance cost (about 2.7 times slowdown on ARMv5e, and 2 times * on x86). * * Return value: the result of the operation * * Since: 0.4 */ EggFixed egg_qmulx (EggFixed op1, EggFixed op2) { #ifdef __arm__ /* This provides about 12% speedeup on the gcc -O2 optimised * C version * * Based on code found in the following thread: * http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2006-August/014405.html */ int res_low, res_hi; __asm__ ("smull %0, %1, %2, %3 \n" "mov %0, %0, lsr %4 \n" "add %1, %0, %1, lsl %5 \n" : "=r"(res_hi), "=r"(res_low)\ : "r"(op1), "r"(op2), "i"(CFX_Q), "i"(32-CFX_Q)); return (EggFixed) res_low; #else long long r = (long long) op1 * (long long) op2; return (unsigned int)(r >> CFX_Q); #endif } /** * egg_qdivx: * @op1: #EggFixed * @op2: #EggFixed * * Divides two fixed values using 64bit arithmetic; this provides * significantly better precission than the #EGG_FIXED_DIV macro, * but at performance cost. * * Return value: #EggFixed * * Since: 0.4 */ EggFixed egg_qdivx (EggFixed op1, EggFixed op2) { return (EggFixed) ((((gint64) op1) << CFX_Q) / op2); } /* * The log2x() and pow2x() functions * * The implementation of the log2x() and pow2x() exploits the well-documented * fact that the exponent part of IEEE floating number provides a good estimate * of log2 of that number, while the mantisa serves as a good error-correction. * * The implemenation here uses a quadratic error correction as described by * Ian Stephenson at http://www.dctsystems.co.uk/Software/power.html. */ /** * egg_log2x : * @x: value to calculate base 2 logarithm from * * Calculates base 2 logarithm. * * This function is some 2.5 times faster on x86, and over 12 times faster on * fpu-less arm, than using libc log(). * * Return value: base 2 logarithm. * * Since: 0.4 */ EggFixed egg_log2x (guint x) { /* Note: we could easily have a version for EggFixed x, but the int * precission is enough for the current purposes. */ union { float f; EggFixed i; } flt; EggFixed magic = 0x58bb; EggFixed y; /* * Convert x to float, then extract exponent. * * We want the result to be 16.16 fixed, so we shift (23-16) bits only */ flt.f = x; flt.i >>= 7; flt.i -= EGG_INT_TO_FIXED (127); y = EGG_FIXED_FRACTION (flt.i); y = CFX_MUL ((y - CFX_MUL (y, y)), magic); return flt.i + y; } /** * egg_pow2x : * @x: exponent * * Calculates 2 to x power. * * This function is around 11 times faster on x86, and around 22 times faster * on fpu-less arm than libc pow(2, x). * * Return value: 2 in x power. * * Since: 0.4 */ guint egg_pow2x (EggFixed x) { /* Note: we could easily have a version that produces EggFixed result, * but the the range would be limited to x < 15, and the int precission * is enough for the current purposes. */ union { float f; guint32 i; } flt; EggFixed magic = 0x56f7; EggFixed y; flt.i = x; /* * Reverse of the log2x function -- convert the fixed value to a suitable * floating point exponent, and mantisa adjusted with quadratic error * correction y. */ y = EGG_FIXED_FRACTION (x); y = CFX_MUL ((y - CFX_MUL (y, y)), magic); /* Shift the exponent into it's position in the floating point * representation; as our number is not int but 16.16 fixed, shift only * by (23 - 16) */ flt.i += (EGG_INT_TO_FIXED (127) - y); flt.i <<= 7; return EGG_FLOAT_TO_UINT (flt.f); } /** * egg_powx : * @x: base * @y: #EggFixed exponent * * Calculates x to y power. (Note, if x is a constant it will be faster to * calculate the power as egg_pow2x (EGG_FIXED_MUL(y, log2 (x))) * * Return value: x in y power. * * Since: 0.4 */ guint egg_powx (guint x, EggFixed y) { return egg_pow2x (CFX_MUL (y, egg_log2x (x))); } static GTypeInfo _info = { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL, }; static GTypeFundamentalInfo _finfo = { 0, }; static void egg_value_init_fixed (GValue *value) { value->data[0].v_int = 0; } static void egg_value_copy_fixed (const GValue *src, GValue *dest) { dest->data[0].v_int = src->data[0].v_int; } static gchar * egg_value_collect_fixed (GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags) { value->data[0].v_int = collect_values[0].v_int; return NULL; } static gchar * egg_value_lcopy_fixed (const GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags) { gint32 *fixed_p = collect_values[0].v_pointer; if (!fixed_p) return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); *fixed_p = value->data[0].v_int; return NULL; } static void egg_value_transform_fixed_int (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_FIXED_TO_INT (src->data[0].v_int); } static void egg_value_transform_fixed_double (const GValue *src, GValue *dest) { dest->data[0].v_double = EGG_FIXED_TO_DOUBLE (src->data[0].v_int); } static void egg_value_transform_fixed_float (const GValue *src, GValue *dest) { dest->data[0].v_float = EGG_FIXED_TO_FLOAT (src->data[0].v_int); } static void egg_value_transform_int_fixed (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_INT_TO_FIXED (src->data[0].v_int); } static void egg_value_transform_double_fixed (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_FLOAT_TO_FIXED (src->data[0].v_double); } static void egg_value_transform_float_fixed (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_FLOAT_TO_FIXED (src->data[0].v_float); } static const GTypeValueTable _egg_fixed_value_table = { egg_value_init_fixed, NULL, egg_value_copy_fixed, NULL, "i", egg_value_collect_fixed, "p", egg_value_lcopy_fixed }; GType egg_fixed_get_type (void) { static GType _egg_fixed_type = 0; if (G_UNLIKELY (_egg_fixed_type == 0)) { _info.value_table = & _egg_fixed_value_table; _egg_fixed_type = g_type_register_fundamental (g_type_fundamental_next (), I_("EggFixed"), &_info, &_finfo, 0); g_value_register_transform_func (_egg_fixed_type, G_TYPE_INT, egg_value_transform_fixed_int); g_value_register_transform_func (G_TYPE_INT, _egg_fixed_type, egg_value_transform_int_fixed); g_value_register_transform_func (_egg_fixed_type, G_TYPE_FLOAT, egg_value_transform_fixed_float); g_value_register_transform_func (G_TYPE_FLOAT, _egg_fixed_type, egg_value_transform_float_fixed); g_value_register_transform_func (_egg_fixed_type, G_TYPE_DOUBLE, egg_value_transform_fixed_double); g_value_register_transform_func (G_TYPE_DOUBLE, _egg_fixed_type, egg_value_transform_double_fixed); } return _egg_fixed_type; } /** * egg_value_set_fixed: * @value: a #GValue initialized to #EGG_TYPE_FIXED * @fixed_: the fixed point value to set * * Sets @value to @fixed_. * * Since: 0.8 */ void egg_value_set_fixed (GValue *value, EggFixed fixed_) { g_return_if_fail (EGG_VALUE_HOLDS_FIXED (value)); value->data[0].v_int = fixed_; } /** * egg_value_get_fixed: * @value: a #GValue initialized to #EGG_TYPE_FIXED * * Gets the fixed point value stored inside @value. * * Return value: the value inside the passed #GValue * * Since: 0.8 */ EggFixed egg_value_get_fixed (const GValue *value) { g_return_val_if_fail (EGG_VALUE_HOLDS_FIXED (value), 0); return value->data[0].v_int; } static void param_fixed_init (GParamSpec *pspec) { EggParamSpecFixed *fspec = EGG_PARAM_SPEC_FIXED (pspec); fspec->minimum = EGG_MINFIXED; fspec->maximum = EGG_MAXFIXED; fspec->default_value = 0; } static void param_fixed_set_default (GParamSpec *pspec, GValue *value) { value->data[0].v_int = EGG_PARAM_SPEC_FIXED (pspec)->default_value; } static gboolean param_fixed_validate (GParamSpec *pspec, GValue *value) { EggParamSpecFixed *fspec = EGG_PARAM_SPEC_FIXED (pspec); gint oval = EGG_FIXED_TO_INT (value->data[0].v_int); gint min, max, val; g_assert (EGG_IS_PARAM_SPEC_FIXED (pspec)); /* we compare the integer part of the value because the minimum * and maximum values cover just that part of the representation */ min = fspec->minimum; max = fspec->maximum; val = EGG_FIXED_TO_INT (value->data[0].v_int); val = CLAMP (val, min, max); if (val != oval) { value->data[0].v_int = val; return TRUE; } return FALSE; } static gint param_fixed_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2) { if (value1->data[0].v_int < value2->data[0].v_int) return -1; else return value1->data[0].v_int > value2->data[0].v_int; } GType egg_param_fixed_get_type (void) { static GType pspec_type = 0; if (G_UNLIKELY (pspec_type == 0)) { const GParamSpecTypeInfo pspec_info = { sizeof (EggParamSpecFixed), 16, param_fixed_init, EGG_TYPE_FIXED, NULL, param_fixed_set_default, param_fixed_validate, param_fixed_values_cmp, }; pspec_type = g_param_type_register_static (I_("EggParamSpecFixed"), &pspec_info); } return pspec_type; } /** * egg_param_spec_fixed: * @name: name of the property * @nick: short name * @blurb: description (can be translatable) * @minimum: lower boundary * @maximum: higher boundary * @default_value: default value * @flags: flags for the param spec * * Creates a #GParamSpec for properties using #EggFixed values * * Return value: the newly created #GParamSpec * * Since: 0.8 */ GParamSpec * egg_param_spec_fixed (const gchar *name, const gchar *nick, const gchar *blurb, EggUnit minimum, EggUnit maximum, EggUnit default_value, GParamFlags flags) { EggParamSpecFixed *fspec; g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); fspec = g_param_spec_internal (EGG_TYPE_PARAM_FIXED, name, nick, blurb, flags); fspec->minimum = minimum; fspec->maximum = maximum; fspec->default_value = default_value; return G_PARAM_SPEC (fspec); } ./egg/egg-units.c0000644000004100000410000002220113570225707014060 0ustar www-datawww-data/* -*- mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By: Tomas Frydrych * Emmanuele Bassi * * Copyright (C) 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /** * SECTION:egg-units * @short_description: A logical distance unit. * * Egg units are logical units with granularity greater than that of the * device units; they are used by #EggActorBox and the units-based family * of #EggActor functions. To convert between Egg units and device * units, use %EGG_UNITS_FROM_DEVICE and %EGG_UNITS_TO_DEVICE macros. * * #EggUnits can be converted from other units like millimeters, * typographic points (at the current resolution) and percentages. It is * also possible to convert fixed point values to and from #EggUnit * values. * * In order to register a #EggUnit property, the #EggParamSpecUnit * #GParamSpec sub-class should be used: * * |[ * GParamSpec *pspec; * * pspec = egg_param_spec_unit ("width", * "Width", * "Width of the actor, in units", * 0, EGG_MAXUNIT, * 0, * G_PARAM_READWRITE); * g_object_class_install_property (gobject_class, PROP_WIDTH, pspec); * ]| * * A #GValue holding units can be manipulated using egg_value_set_unit() * and egg_value_get_unit(). #GValues containing a #EggUnit * value can also be transformed to #GValues containing integer * values - with a loss of precision: * * |[ * static gboolean * units_to_int (const GValue *src, * GValue *dest) * { * g_return_val_if_fail (EGG_VALUE_HOLDS_UNIT (src), FALSE); * * g_value_init (dest, G_TYPE_INT); * return g_value_transform (src, &dest); * } * ]| * * The code above is equivalent to: * * |[ * static gboolean * units_to_int (const GValue *src, * GValue *dest) * { * g_return_val_if_fail (EGG_VALUE_HOLDS_UNIT (src), FALSE); * * g_value_init (dest, G_TYPE_INT); * g_value_set_int (dest, * EGG_UNITS_TO_INT (egg_value_get_unit (src))); * * return TRUE; * } * ]| * * #EggUnit is available since Egg 0.4 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "egg-units.h" // #include "egg-private.h" #include "egg-hack.h" static GTypeInfo _info = { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, NULL, NULL, }; static GTypeFundamentalInfo _finfo = { 0, }; static void egg_value_init_unit (GValue *value) { value->data[0].v_int = 0; } static void egg_value_copy_unit (const GValue *src, GValue *dest) { dest->data[0].v_int = src->data[0].v_int; } static gchar * egg_value_collect_unit (GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags) { value->data[0].v_int = collect_values[0].v_int; return NULL; } static gchar * egg_value_lcopy_unit (const GValue *value, guint n_collect_values, GTypeCValue *collect_values, guint collect_flags) { gint32 *units_p = collect_values[0].v_pointer; if (!units_p) return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); *units_p = value->data[0].v_int; return NULL; } static void egg_value_transform_unit_int (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_UNITS_TO_INT (src->data[0].v_int); } static void egg_value_transform_int_unit (const GValue *src, GValue *dest) { dest->data[0].v_int = EGG_UNITS_FROM_INT (src->data[0].v_int); } static const GTypeValueTable _egg_unit_value_table = { egg_value_init_unit, NULL, egg_value_copy_unit, NULL, "i", egg_value_collect_unit, "p", egg_value_lcopy_unit }; GType egg_unit_get_type (void) { static GType _egg_unit_type = 0; if (G_UNLIKELY (_egg_unit_type == 0)) { _info.value_table = & _egg_unit_value_table; _egg_unit_type = g_type_register_fundamental (g_type_fundamental_next (), I_("EggUnit"), &_info, &_finfo, 0); g_value_register_transform_func (_egg_unit_type, G_TYPE_INT, egg_value_transform_unit_int); g_value_register_transform_func (G_TYPE_INT, _egg_unit_type, egg_value_transform_int_unit); } return _egg_unit_type; } /** * egg_value_set_unit: * @value: a #GValue initialized to #EGG_TYPE_UNIT * @units: the units to set * * Sets @value to @units * * Since: 0.8 */ void egg_value_set_unit (GValue *value, EggUnit units) { g_return_if_fail (EGG_VALUE_HOLDS_UNIT (value)); value->data[0].v_int = units; } /** * egg_value_get_unit: * @value: a #GValue initialized to #EGG_TYPE_UNIT * * Gets the #EggUnits contained in @value. * * Return value: the units inside the passed #GValue * * Since: 0.8 */ EggUnit egg_value_get_unit (const GValue *value) { g_return_val_if_fail (EGG_VALUE_HOLDS_UNIT (value), 0); return value->data[0].v_int; } static void param_unit_init (GParamSpec *pspec) { EggParamSpecUnit *uspec = EGG_PARAM_SPEC_UNIT (pspec); uspec->minimum = EGG_MINUNIT; uspec->maximum = EGG_MAXUNIT; uspec->default_value = 0; } static void param_unit_set_default (GParamSpec *pspec, GValue *value) { value->data[0].v_int = EGG_PARAM_SPEC_UNIT (pspec)->default_value; } static gboolean param_unit_validate (GParamSpec *pspec, GValue *value) { EggParamSpecUnit *uspec = EGG_PARAM_SPEC_UNIT (pspec); gint oval = EGG_UNITS_TO_INT (value->data[0].v_int); gint min, max, val; g_assert (EGG_IS_PARAM_SPEC_UNIT (pspec)); /* we compare the integer part of the value because the minimum * and maximum values cover just that part of the representation */ min = uspec->minimum; max = uspec->maximum; val = EGG_UNITS_TO_INT (value->data[0].v_int); val = CLAMP (val, min, max); if (val != oval) { value->data[0].v_int = val; return TRUE; } return FALSE; } static gint param_unit_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2) { if (value1->data[0].v_int < value2->data[0].v_int) return -1; else return value1->data[0].v_int > value2->data[0].v_int; } GType egg_param_unit_get_type (void) { static GType pspec_type = 0; if (G_UNLIKELY (pspec_type == 0)) { const GParamSpecTypeInfo pspec_info = { sizeof (EggParamSpecUnit), 16, param_unit_init, EGG_TYPE_UNIT, NULL, param_unit_set_default, param_unit_validate, param_unit_values_cmp, }; pspec_type = g_param_type_register_static (I_("EggParamSpecUnit"), &pspec_info); } return pspec_type; } /** * egg_param_spec_unit: * @name: name of the property * @nick: short name * @blurb: description (can be translatable) * @minimum: lower boundary * @maximum: higher boundary * @default_value: default value * @flags: flags for the param spec * * Creates a #GParamSpec for properties using #EggUnits. * * Return value: the newly created #GParamSpec * * Since: 0.8 */ GParamSpec * egg_param_spec_unit (const gchar *name, const gchar *nick, const gchar *blurb, EggUnit minimum, EggUnit maximum, EggUnit default_value, GParamFlags flags) { EggParamSpecUnit *uspec; g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL); uspec = g_param_spec_internal (EGG_TYPE_PARAM_UNIT, name, nick, blurb, flags); uspec->minimum = minimum; uspec->maximum = maximum; uspec->default_value = default_value; return G_PARAM_SPEC (uspec); } ./egg/egg-debug.h0000644000004100000410000000617313570225707014023 0ustar www-datawww-data#ifndef __EGG_DEBUG_H__ #define __EGG_DEBUG_H__ #include #include "egg-hack.h" G_BEGIN_DECLS typedef enum { EGG_DEBUG_MISC = 1 << 0, EGG_DEBUG_ACTOR = 1 << 1, EGG_DEBUG_TEXTURE = 1 << 2, EGG_DEBUG_EVENT = 1 << 3, EGG_DEBUG_PAINT = 1 << 4, EGG_DEBUG_GL = 1 << 5, EGG_DEBUG_ALPHA = 1 << 6, EGG_DEBUG_BEHAVIOUR = 1 << 7, EGG_DEBUG_PANGO = 1 << 8, EGG_DEBUG_BACKEND = 1 << 9, EGG_DEBUG_SCHEDULER = 1 << 10, EGG_DEBUG_SCRIPT = 1 << 11, EGG_DEBUG_SHADER = 1 << 12, EGG_DEBUG_MULTISTAGE = 1 << 13 } EggDebugFlag; #ifdef EGG_ENABLE_DEBUG #ifdef __GNUC_ #define EGG_NOTE(type,x,a...) G_STMT_START { \ if (egg_debug_flags & EGG_DEBUG_##type) \ { g_message ("[" #type "] " G_STRLOC ": " x, ##a); } \ } G_STMT_END #define EGG_TIMESTAMP(type,x,a...) G_STMT_START { \ if (egg_debug_flags & EGG_DEBUG_##type) \ { g_message ("[" #type "]" " %li:" G_STRLOC ": " \ x, egg_get_timestamp(), ##a); } \ } G_STMT_END #else /* Try the C99 version; unfortunately, this does not allow us to pass * empty arguments to the macro, which means we have to * do an intemediate printf. */ #define EGG_NOTE(type,...) G_STMT_START { \ if (egg_debug_flags & EGG_DEBUG_##type) \ { \ gchar * _fmt = g_strdup_printf (__VA_ARGS__); \ g_message ("[" #type "] " G_STRLOC ": %s",_fmt); \ g_free (_fmt); \ } \ } G_STMT_END #define EGG_TIMESTAMP(type,...) G_STMT_START { \ if (egg_debug_flags & EGG_DEBUG_##type) \ { \ gchar * _fmt = g_strdup_printf (__VA_ARGS__); \ g_message ("[" #type "]" " %li:" G_STRLOC ": %s", \ egg_get_timestamp(), _fmt); \ g_free (_fmt); \ } \ } G_STMT_END #endif #define EGG_MARK() EGG_NOTE(MISC, "== mark ==") #define EGG_DBG(x) { a } #define EGG_GLERR() G_STMT_START { \ if (egg_debug_flags & EGG_DEBUG_GL) \ { GLenum _err = glGetError (); /* roundtrip */ \ if (_err != GL_NO_ERROR) \ g_warning (G_STRLOC ": GL Error %x", _err); \ } } G_STMT_END #else /* !EGG_ENABLE_DEBUG */ #define EGG_NOTE(type,...) #define EGG_MARK() #define EGG_DBG(x) #define EGG_GLERR() #define EGG_TIMESTAMP(type,...) #endif /* EGG_ENABLE_DEBUG */ extern guint egg_debug_flags; G_END_DECLS #endif /* __EGG_DEBUG_H__ */ ./egg/egg-fixed.h0000644000004100000410000002530013570225707014025 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * Tomas Frydrych * * Copyright (C) 2006 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _HAVE_EGG_FIXED_H #define _HAVE_EGG_FIXED_H #include G_BEGIN_DECLS /** * EggFixed: * * Fixed point number (16.16) */ typedef gint32 EggFixed; /** * EggAngle: * * Integer representation of an angle such that 1024 corresponds to * full circle (i.e., 2*Pi). */ typedef gint32 EggAngle; /* angle such that 1024 == 2*PI */ #define EGG_ANGLE_FROM_DEG(x) (EGG_FLOAT_TO_INT (((x) * 1024.0) / 360.0)) #define EGG_ANGLE_FROM_DEGF(x) (EGG_FLOAT_TO_INT (((float)(x) * 1024.0f) / 360.0f)) #define EGG_ANGLE_FROM_DEGX(x) (CFX_INT((((x)/360)*1024) + CFX_HALF)) #define EGG_ANGLE_TO_DEG(x) (((x) * 360.0)/ 1024.0) #define EGG_ANGLE_TO_DEGF(x) (((float)(x) * 360.0)/ 1024.0) #define EGG_ANGLE_TO_DEGX(x) (EGG_INT_TO_FIXED((x) * 45)/128) /* * some commonly used constants */ /** * CFX_Q: * * Size in bits of decimal part of floating point value. */ #define CFX_Q 16 /* Decimal part size in bits */ /** * CFX_ONE: * * 1.0 represented as a fixed point value. */ #define CFX_ONE (1 << CFX_Q) /* 1 */ /** * CFX_HALF: * * 0.5 represented as a fixed point value. */ #define CFX_HALF 32768 /** * CFX_MAX: * * Maximum fixed point value. */ #define CFX_MAX 0x7fffffff /** * CFX_MIN: * * Minimum fixed point value. */ #define CFX_MIN 0x80000000 /** * CFX_PI: * * Fixed point representation of Pi */ #define CFX_PI 0x0003243f /** * CFX_2PI: * * Fixed point representation of Pi*2 */ #define CFX_2PI 0x0006487f /** * CFX_PI_2: * * Fixed point representation of Pi/2 */ #define CFX_PI_2 0x00019220 /* pi/2 */ /** * CFX_PI_4: * * Fixed point representation of Pi/4 */ #define CFX_PI_4 0x0000c910 /* pi/4 */ /** * CFX_360: * * Fixed point representation of the number 360 */ #define CFX_360 EGG_INT_TO_FIXED (360) /** * CFX_240: * * Fixed point representation of the number 240 */ #define CFX_240 EGG_INT_TO_FIXED (240) /** * CFX_180: * * Fixed point representation of the number 180 */ #define CFX_180 EGG_INT_TO_FIXED (180) /** * CFX_120: * * Fixed point representation of the number 120 */ #define CFX_120 EGG_INT_TO_FIXED (120) /** * CFX_60: * * Fixed point representation of the number 60 */ #define CFX_60 EGG_INT_TO_FIXED (60) /** * CFX_RADIANS_TO_DEGREES: * * Fixed point representation of the number 180 / pi */ #define CFX_RADIANS_TO_DEGREES 0x394bb8 /** * CFX_255: * * Fixed point representation of the number 255 */ #define CFX_255 EGG_INT_TO_FIXED (255) /** * EGG_FIXED_TO_FLOAT: * @x: a fixed point value * * Convert a fixed point value to float. */ #define EGG_FIXED_TO_FLOAT(x) ((float) ((int)(x) / 65536.0)) /** * EGG_FIXED_TO_DOUBLE: * @x: a fixed point value * * Convert a fixed point value to double. */ #define EGG_FIXED_TO_DOUBLE(x) ((double) ((int)(x) / 65536.0)) /** * EGG_FLOAT_TO_FIXED: * @x: a floating point value * * Convert a float value to fixed. */ #define EGG_FLOAT_TO_FIXED(x) (egg_double_to_fixed ((x))) /** * EGG_FLOAT_TO_INT: * @x: a floating point value * * Convert a float value to int. */ #define EGG_FLOAT_TO_INT(x) (egg_double_to_int ((x))) /** * EGG_FLOAT_TO_UINT: * @x: a floating point value * * Convert a float value to unsigned int. */ #define EGG_FLOAT_TO_UINT(x) (egg_double_to_uint ((x))) /** * EGG_INT_TO_FIXED: * @x: an integer value * * Convert an integer value to fixed point. */ #define EGG_INT_TO_FIXED(x) ((x) << CFX_Q) /** * EGG_FIXED_TO_INT: * @x: a fixed point value * * Converts a fixed point value to integer (removing the decimal part). * * Since: 0.6 */ #define EGG_FIXED_TO_INT(x) ((x) >> CFX_Q) #ifndef EGG_DISABLE_DEPRECATED /** * EGG_FIXED_INT: * @x: a fixed point value * * Convert a fixed point value to integer (removing decimal part). * * Deprecated:0.6: Use %EGG_FIXED_TO_INT instead */ #define EGG_FIXED_INT(x) EGG_FIXED_TO_INT((x)) #endif /* !EGG_DISABLE_DEPRECATED */ /** * EGG_FIXED_FRACTION: * @x: a fixed point value * * Retrieves the fractionary part of a fixed point value */ #define EGG_FIXED_FRACTION(x) ((x) & ((1 << CFX_Q) - 1)) /** * EGG_FIXED_FLOOR: * @x: a fixed point value * * Round down a fixed point value to an integer. */ #define EGG_FIXED_FLOOR(x) (((x) >= 0) ? ((x) >> CFX_Q) \ : ~((~(x)) >> CFX_Q)) /** * EGG_FIXED_CEIL: * @x: a fixed point value * * Round up a fixed point value to an integer. */ #define EGG_FIXED_CEIL(x) (EGG_FIXED_FLOOR (x + 0xffff)) /** * EGG_FIXED_MUL: * @x: a fixed point value * @y: a fixed point value * * Multiply two fixed point values */ #define EGG_FIXED_MUL(x,y) ((x) >> 8) * ((y) >> 8) /** * EGG_FIXED_DIV: * @x: a fixed point value * @y: a fixed point value * * Divide two fixed point values */ #define EGG_FIXED_DIV(x,y) ((((x) << 8)/(y)) << 8) /* Some handy fixed point short aliases to avoid exessively long lines */ /* FIXME: Remove from public API */ /*< private >*/ #define CFX_INT EGG_FIXED_INT #define CFX_MUL EGG_FIXED_MUL #define CFX_DIV EGG_FIXED_DIV #define CFX_QMUL(x,y) egg_qmulx (x,y) #define CFX_QDIV(x,y) egg_qdivx (x,y) /*< public >*/ /* Fixed point math routines */ G_INLINE_FUNC EggFixed egg_qmulx (EggFixed op1, EggFixed op2); #if defined (G_CAN_INLINE) G_INLINE_FUNC EggFixed egg_qmulx (EggFixed op1, EggFixed op2) { #ifdef __arm__ int res_low, res_hi; __asm__ ("smull %0, %1, %2, %3 \n" "mov %0, %0, lsr %4 \n" "add %1, %0, %1, lsl %5 \n" : "=r"(res_hi), "=r"(res_low)\ : "r"(op1), "r"(op2), "i"(CFX_Q), "i"(32-CFX_Q)); return (EggFixed) res_low; #else long long r = (long long) op1 * (long long) op2; return (unsigned int)(r >> CFX_Q); #endif } #endif G_INLINE_FUNC EggFixed egg_qdivx (EggFixed op1, EggFixed op2); #if defined (G_CAN_INLINE) G_INLINE_FUNC EggFixed egg_qdivx (EggFixed op1, EggFixed op2) { return (EggFixed) ((((gint64) op1) << CFX_Q) / op2); } #endif EggFixed egg_sinx (EggFixed angle); EggFixed egg_sini (EggAngle angle); EggFixed egg_tani (EggAngle angle); EggFixed egg_atani (EggFixed x); EggFixed egg_atan2i (EggFixed y, EggFixed x); /* convenience macros for the cos functions */ /** * egg_cosx: * @angle: a #EggFixed angle in radians * * Fixed point cosine function * * Return value: #EggFixed cosine value. * * Note: Implemneted as a macro. * * Since: 0.2 */ #define egg_cosx(angle) (egg_sinx((angle) + CFX_PI_2)) /** * egg_cosi: * @angle: a #EggAngle angle * * Very fast fixed point implementation of cosine function. * * EggAngle is an integer such that 1024 represents * full circle. * * Return value: #EggFixed cosine value. * * Note: Implemneted as a macro. * * Since: 0.2 */ #define egg_cosi(angle) (egg_sini ((angle) + 256)) /** * EGG_SQRTI_ARG_MAX * * Maximum argument that can be passed to #egg_sqrti function. * * Since: 0.6 */ #ifndef __SSE2__ #define EGG_SQRTI_ARG_MAX 0x3fffff #else #define EGG_SQRTI_ARG_MAX INT_MAX #endif /** * EGG_SQRTI_ARG_5_PERCENT * * Maximum argument that can be passed to #egg_sqrti for which the * resulting error is < 5% * * Since: 0.6 */ #ifndef __SSE2__ #define EGG_SQRTI_ARG_5_PERCENT 210 #else #define EGG_SQRTI_ARG_5_PERCENT INT_MAX #endif /** * EGG_SQRTI_ARG_10_PERCENT * * Maximum argument that can be passed to #egg_sqrti for which the * resulting error is < 10% * * Since: 0.6 */ #ifndef __SSE2__ #define EGG_SQRTI_ARG_10_PERCENT 5590 #else #define EGG_SQRTI_ARG_10_PERCENT INT_MAX #endif EggFixed egg_sqrtx (EggFixed x); gint egg_sqrti (gint x); EggFixed egg_log2x (guint x); guint egg_pow2x (EggFixed x); guint egg_powx (guint x, EggFixed y); #define EGG_TYPE_FIXED (egg_fixed_get_type ()) #define EGG_TYPE_PARAM_FIXED (egg_param_fixed_get_type ()) #define EGG_PARAM_SPEC_FIXED(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), EGG_TYPE_PARAM_FIXED, EggParamSpecFixed)) #define EGG_IS_PARAM_SPEC_FIXED(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), EGG_TYPE_PARAM_FIXED)) /** * EGG_VALUE_HOLDS_FIXED: * @x: a #GValue * * Evaluates to %TRUE if @x holds a #EggFixed. * * Since: 0.8 */ #define EGG_VALUE_HOLDS_FIXED(x) (G_VALUE_HOLDS ((x), EGG_TYPE_FIXED)) typedef struct _EggParamSpecFixed EggParamSpecFixed; /** * EGG_MAXFIXED: * * Higher boundary for #EggFixed * * Since: 0.8 */ #define EGG_MAXFIXED CFX_MAX /** * EGG_MINFIXED: * * Lower boundary for #EggFixed * * Since: 0.8 */ #define EGG_MINFIXED CFX_MIN /** * EggParamSpecFixed * @minimum: lower boundary * @maximum: higher boundary * @default_value: default value * * #GParamSpec subclass for fixed point based properties * * Since: 0.8 */ struct _EggParamSpecFixed { /*< private >*/ GParamSpec parent_instance; /*< public >*/ EggFixed minimum; EggFixed maximum; EggFixed default_value; }; GType egg_fixed_get_type (void) G_GNUC_CONST; GType egg_param_fixed_get_type (void) G_GNUC_CONST; void egg_value_set_fixed (GValue *value, EggFixed fixed_); EggFixed egg_value_get_fixed (const GValue *value); GParamSpec * egg_param_spec_fixed (const gchar *name, const gchar *nick, const gchar *blurb, EggFixed minimum, EggFixed maximum, EggFixed default_value, GParamFlags flags); /* */ extern EggFixed egg_double_to_fixed (double value); extern gint egg_double_to_int (double value); extern guint egg_double_to_unit (double value); G_END_DECLS #endif /* _HAVE_EGG_FIXED_H */ ./egg/egg-units.h0000644000004100000410000001336113570225707014074 0ustar www-datawww-data/* -*- mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Tomas Frydrych * * Copyright (C) 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _HAVE_EGG_UNITS_H #define _HAVE_EGG_UNITS_H #include #include G_BEGIN_DECLS /** * EggUnit: * * Device independent unit used by Egg. The value held can be transformed * into other units, likes pixels. * * Since: 0.4 */ typedef gint32 EggUnit; /* * Currently EGG_UNIT maps directly onto EggFixed. Nevertheless, the * _FROM_FIXED and _TO_FIXED macros should always be used in case that we * decide to change this relationship in the future. */ #define EGG_UNITS_FROM_INT(x) EGG_INT_TO_FIXED ((x)) #define EGG_UNITS_TO_INT(x) EGG_FIXED_TO_INT ((x)) #define EGG_UNITS_FROM_FLOAT(x) EGG_FLOAT_TO_FIXED ((x)) #define EGG_UNITS_TO_FLOAT(x) EGG_FIXED_TO_FLOAT ((x)) #define EGG_UNITS_FROM_FIXED(x) (x) #define EGG_UNITS_TO_FIXED(x) (x) /** * EGG_UNITS_FROM_DEVICE: * @x: value in pixels * * Converts @x from pixels to #EggUnits * * Since: 0.6 */ #define EGG_UNITS_FROM_DEVICE(x) EGG_UNITS_FROM_INT ((x)) /** * EGG_UNITS_TO_DEVICE: * @x: value in #EggUnits * * Converts @x from #EggUnits to pixels * * Since: 0.6 */ #define EGG_UNITS_TO_DEVICE(x) EGG_UNITS_TO_INT ((x)) #define EGG_UNITS_TMP_FROM_DEVICE(x) (x) #define EGG_UNITS_TMP_TO_DEVICE(x) (x) /** * EGG_UNITS_FROM_PANGO_UNIT: * @x: value in Pango units * * Converts a value in Pango units to #EggUnits * * Since: 0.6 */ #define EGG_UNITS_FROM_PANGO_UNIT(x) ((x) << 6) /** * EGG_UNITS_TO_PANGO_UNIT: * @x: value in #EggUnits * * Converts a value in #EggUnits to Pango units * * Since: 0.6 */ #define EGG_UNITS_TO_PANGO_UNIT(x) ((x) >> 6) #define EGG_UNITS_FROM_STAGE_WIDTH_PERCENTAGE(x) \ ((egg_actor_get_widthu (egg_stage_get_default ()) * x) / 100) #define EGG_UNITS_FROM_STAGE_HEIGHT_PERCENTAGE(x) \ ((egg_actor_get_heightu (egg_stage_get_default ()) * x) / 100) #define EGG_UNITS_FROM_PARENT_WIDTH_PERCENTAGE(a, x) \ ((egg_actor_get_widthu (egg_actor_get_parent (a)) * x) / 100) #define EGG_UNITS_FROM_PARENT_HEIGHT_PERCENTAGE(a, x) \ ((egg_actor_get_heightu (egg_actor_get_parent (a)) * x) / 100) /** * EGG_UNITS_FROM_MM: * @x: a value in millimeters * * Converts a value in millimeters into #EggUnits * * Since: 0.6 */ #define EGG_UNITS_FROM_MM(x) \ (EGG_UNITS_FROM_FLOAT ((((x) * egg_stage_get_resolution ((EggStage *) egg_stage_get_default ())) / 25.4))) #define EGG_UNITS_FROM_MMX(x) \ (CFX_DIV (CFX_MUL ((x), egg_stage_get_resolutionx ((EggStage *) egg_stage_get_default ())), 0x196666)) /** * EGG_UNITS_FROM_POINTS: * @x: a value in typographic points * * Converts a value in typographic points into #EggUnits * * Since: 0.6 */ #define EGG_UNITS_FROM_POINTS(x) \ EGG_UNITS_FROM_FLOAT ((((x) * egg_stage_get_resolution ((EggStage *) egg_stage_get_default ())) / 72.0)) #define EGG_UNITS_FROM_POINTSX(x) \ (CFX_MUL ((x), egg_stage_get_resolutionx ((EggStage *) egg_stage_get_default ())) / 72) #define EGG_TYPE_UNIT (egg_unit_get_type ()) #define EGG_TYPE_PARAM_UNIT (egg_param_unit_get_type ()) #define EGG_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), EGG_TYPE_PARAM_UNIT, EggParamSpecUnit)) #define EGG_IS_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), EGG_TYPE_PARAM_UNIT)) /** * EGG_MAXUNIT: * * Higher boundary for a #EggUnit * * Since: 0.8 */ #define EGG_MAXUNIT (0x7fffffff) /** * EGG_MINUNIT: * * Lower boundary for a #EggUnit * * Since: 0.8 */ #define EGG_MINUNIT (0x80000000) /** * EGG_VALUE_HOLDS_UNIT: * @x: a #GValue * * Evaluates to %TRUE if @x holds #EggUnits. * * Since: 0.8 */ #define EGG_VALUE_HOLDS_UNIT(x) (G_VALUE_HOLDS ((x), EGG_TYPE_UNIT)) typedef struct _EggParamSpecUnit EggParamSpecUnit; /** * EggParamSpecUnit: * @minimum: lower boundary * @maximum: higher boundary * @default_value: default value * * #GParamSpec subclass for unit based properties. * * Since: 0.8 */ struct _EggParamSpecUnit { /*< private >*/ GParamSpec parent_instance; /*< public >*/ EggUnit minimum; EggUnit maximum; EggUnit default_value; }; GType egg_unit_get_type (void) G_GNUC_CONST; GType egg_param_unit_get_type (void) G_GNUC_CONST; void egg_value_set_unit (GValue *value, EggUnit units); EggUnit egg_value_get_unit (const GValue *value); GParamSpec *egg_param_spec_unit (const gchar *name, const gchar *nick, const gchar *blurb, EggUnit minimum, EggUnit maximum, EggUnit default_value, GParamFlags flags); G_END_DECLS #endif /* _HAVE_EGG_UNITS_H */ ./egg/test-timeline-smoothness.c0000644000004100000410000000500713570225707017146 0ustar www-datawww-data#include #include #include #define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FRAME_COUNT 20 #define TEST_ERROR_TOLERANCE 5 typedef struct _TestState { EggTimeline *timeline; GTimeVal start_time; GTimeVal prev_frame_time; guint frame; gint completion_count; gint passed; }TestState; static void new_frame_cb (EggTimeline *timeline, gint frame_num, TestState *state) { GTimeVal current_time; glong total_elapsed_ms; glong frame_elapsed_ms = 0; gchar *bump = ""; g_get_current_time (¤t_time); total_elapsed_ms = (current_time.tv_sec - state->start_time.tv_sec) * 1000; total_elapsed_ms += (current_time.tv_usec - state->start_time.tv_usec)/1000; if (state->frame>0) { frame_elapsed_ms = (current_time.tv_sec - state->prev_frame_time.tv_sec) * 1000; frame_elapsed_ms += (current_time.tv_usec - state->prev_frame_time.tv_usec)/1000; if (ABS(frame_elapsed_ms - (1000/TEST_TIMELINE_FPS)) > TEST_ERROR_TOLERANCE) { state->passed = FALSE; bump = " (BUMP)"; } } g_print ("timeline frame=%-2d total elapsed=%-4li(ms) since last frame=%-4li(ms)%s\n", egg_timeline_get_current_frame(state->timeline), total_elapsed_ms, frame_elapsed_ms, bump); state->prev_frame_time = current_time; state->frame++; } static void completed_cb (EggTimeline *timeline, TestState *state) { state->completion_count++; if (state->completion_count == 2) { if (state->passed) { g_print("Passed\n"); exit(EXIT_SUCCESS); } else { g_print("Failed\n"); exit(EXIT_FAILURE); } } } int main(int argc, char **argv) { TestState state; state.timeline = egg_timeline_new (TEST_TIMELINE_FRAME_COUNT, TEST_TIMELINE_FPS); egg_timeline_set_loop (state.timeline, TRUE); g_signal_connect (G_OBJECT(state.timeline), "new-frame", G_CALLBACK(new_frame_cb), &state); g_signal_connect (G_OBJECT(state.timeline), "completed", G_CALLBACK(completed_cb), &state); state.frame = 0; state.completion_count = 0; state.passed = TRUE; g_get_current_time (&state.start_time); egg_timeline_start (state.timeline); egg_main(); return EXIT_FAILURE; } ./egg/egg-alpha.c0000644000004100000410000005576513570225707014030 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * Jorn Baayen * Emmanuele Bassi * Tomas Frydrych * * Copyright (C) 2006, 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /** * SECTION:egg-alpha * @short_description: A class for calculating an alpha value as a function * of time. * * #EggAlpha is a class for calculating an integer value between * 0 and %EGG_ALPHA_MAX_ALPHA as a function of time. You should * provide a #EggTimeline and bind it to the #EggAlpha object; * you should also provide a function returning the alpha value depending * on the position inside the timeline; this function will be executed * each time a new frame in the #EggTimeline is reached. Since the * alpha function is controlled by the timeline instance, you can pause * or stop the #EggAlpha from calling the alpha function by controlling * the #EggTimeline object. * * #EggAlpha is used to "drive" a #EggBehaviour instance. * *
* Graphic representation of some alpha functions * *
* * Since: 0.2 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "egg-alpha.h" #include "egg-hack.h" // #include "egg-marshal.h" // #include "egg-private.h" #include "egg-debug.h" G_DEFINE_TYPE (EggAlpha, egg_alpha, G_TYPE_INITIALLY_UNOWNED); struct _EggAlphaPrivate { EggTimeline *timeline; guint timeline_new_frame_id; guint32 alpha; GClosure *closure; }; enum { PROP_0, PROP_TIMELINE, PROP_ALPHA }; static void timeline_new_frame_cb (EggTimeline *timeline, guint current_frame_num, EggAlpha *alpha) { EggAlphaPrivate *priv = alpha->priv; /* Update alpha value and notify */ priv->alpha = egg_alpha_get_alpha (alpha); g_object_notify (G_OBJECT (alpha), "alpha"); } static void egg_alpha_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { EggAlpha *alpha; alpha = EGG_ALPHA (object); switch (prop_id) { case PROP_TIMELINE: egg_alpha_set_timeline (alpha, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void egg_alpha_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { EggAlpha *alpha; EggAlphaPrivate *priv; alpha = EGG_ALPHA (object); priv = alpha->priv; switch (prop_id) { case PROP_TIMELINE: g_value_set_object (value, priv->timeline); break; case PROP_ALPHA: g_value_set_uint (value, priv->alpha); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void egg_alpha_finalize (GObject *object) { EggAlphaPrivate *priv = EGG_ALPHA (object)->priv; if (priv->closure) g_closure_unref (priv->closure); G_OBJECT_CLASS (egg_alpha_parent_class)->finalize (object); } static void egg_alpha_dispose (GObject *object) { EggAlpha *self = EGG_ALPHA(object); egg_alpha_set_timeline (self, NULL); G_OBJECT_CLASS (egg_alpha_parent_class)->dispose (object); } static void egg_alpha_class_init (EggAlphaClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->set_property = egg_alpha_set_property; object_class->get_property = egg_alpha_get_property; object_class->finalize = egg_alpha_finalize; object_class->dispose = egg_alpha_dispose; g_type_class_add_private (klass, sizeof (EggAlphaPrivate)); /** * EggAlpha:timeline: * * A #EggTimeline instance used to drive the alpha function. * * Since: 0.2 */ g_object_class_install_property (object_class, PROP_TIMELINE, g_param_spec_object ("timeline", "Timeline", "Timeline", EGG_TYPE_TIMELINE, EGG_PARAM_READWRITE)); /** * EggAlpha:alpha: * * The alpha value as computed by the alpha function. * * Since: 0.2 */ g_object_class_install_property (object_class, PROP_ALPHA, g_param_spec_uint ("alpha", "Alpha value", "Alpha value", 0, EGG_ALPHA_MAX_ALPHA, 0, EGG_PARAM_READABLE)); } static void egg_alpha_init (EggAlpha *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_ALPHA, EggAlphaPrivate); } /** * egg_alpha_get_alpha: * @alpha: A #EggAlpha * * Query the current alpha value. * * Return Value: The current alpha value for the alpha * * Since: 0.2 */ guint32 egg_alpha_get_alpha (EggAlpha *alpha) { EggAlphaPrivate *priv; guint32 retval = 0; g_return_val_if_fail (EGG_IS_ALPHA (alpha), 0); priv = alpha->priv; if (G_LIKELY (priv->closure)) { GValue params = { 0, }; GValue result_value = { 0, }; g_object_ref (alpha); g_value_init (&result_value, G_TYPE_UINT); g_value_init (¶ms, EGG_TYPE_ALPHA); g_value_set_object (¶ms, alpha); g_closure_invoke (priv->closure, &result_value, 1, ¶ms, NULL); retval = g_value_get_uint (&result_value); g_value_unset (&result_value); g_value_unset (¶ms); g_object_unref (alpha); } return retval; } /** * egg_alpha_set_closure: * @alpha: A #EggAlpha * @closure: A #GClosure * * Sets the #GClosure used to compute * the alpha value at each frame of the #EggTimeline * bound to @alpha. * * Since: 0.8 */ void egg_alpha_set_closure (EggAlpha *alpha, GClosure *closure) { EggAlphaPrivate *priv; g_return_if_fail (EGG_IS_ALPHA (alpha)); g_return_if_fail (closure != NULL); priv = alpha->priv; if (priv->closure) g_closure_unref (priv->closure); priv->closure = g_closure_ref (closure); g_closure_sink (closure); if (G_CLOSURE_NEEDS_MARSHAL (closure)) { GClosureMarshal marshal = egg_marshal_UINT__VOID; g_closure_set_marshal (closure, marshal); } } /** * egg_alpha_set_func: * @alpha: A #EggAlpha * @func: A #EggAlphaAlphaFunc * @data: user data to be passed to the alpha function, or %NULL * @destroy: notify function used when disposing the alpha function * * Sets the #EggAlphaFunc function used to compute * the alpha value at each frame of the #EggTimeline * bound to @alpha. * * Since: 0.2 */ void egg_alpha_set_func (EggAlpha *alpha, EggAlphaFunc func, gpointer data, GDestroyNotify destroy) { GClosure *closure; g_return_if_fail (EGG_IS_ALPHA (alpha)); g_return_if_fail (func != NULL); closure = g_cclosure_new (G_CALLBACK (func), data, (GClosureNotify) destroy); egg_alpha_set_closure (alpha, closure); } /** * egg_alpha_set_timeline: * @alpha: A #EggAlpha * @timeline: A #EggTimeline * * Binds @alpha to @timeline. * * Since: 0.2 */ void egg_alpha_set_timeline (EggAlpha *alpha, EggTimeline *timeline) { EggAlphaPrivate *priv; g_return_if_fail (EGG_IS_ALPHA (alpha)); g_return_if_fail (timeline == NULL || EGG_IS_TIMELINE (timeline)); priv = alpha->priv; if (priv->timeline) { g_signal_handlers_disconnect_by_func (priv->timeline, timeline_new_frame_cb, alpha); g_object_unref (priv->timeline); priv->timeline = NULL; } if (timeline) { priv->timeline = g_object_ref (timeline); g_signal_connect (priv->timeline, "new-frame", G_CALLBACK (timeline_new_frame_cb), alpha); } } /** * egg_alpha_get_timeline: * @alpha: A #EggAlpha * * Gets the #EggTimeline bound to @alpha. * * Return value: a #EggTimeline instance * * Since: 0.2 */ EggTimeline * egg_alpha_get_timeline (EggAlpha *alpha) { g_return_val_if_fail (EGG_IS_ALPHA (alpha), NULL); return alpha->priv->timeline; } /** * egg_alpha_new: * * Creates a new #EggAlpha instance. You must set a function * to compute the alpha value using egg_alpha_set_func() and * bind a #EggTimeline object to the #EggAlpha instance * using egg_alpha_set_timeline(). * * You should use the newly created #EggAlpha instance inside * a #EggBehaviour object. * * Return value: the newly created empty #EggAlpha instance. * * Since: 0.2 */ EggAlpha * egg_alpha_new (void) { return g_object_new (EGG_TYPE_ALPHA, NULL); } /** * egg_alpha_new_full: * @timeline: #EggTimeline timeline * @func: #EggAlphaFunc alpha function * @data: data to be passed to the alpha function * @destroy: notify to be called when removing the alpha function * * Creates a new #EggAlpha instance and sets the timeline * and alpha function. * * Return Value: the newly created #EggAlpha * * Since: 0.2 */ EggAlpha * egg_alpha_new_full (EggTimeline *timeline, EggAlphaFunc func, gpointer data, GDestroyNotify destroy) { EggAlpha *retval; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), NULL); g_return_val_if_fail (func != NULL, NULL); retval = egg_alpha_new (); egg_alpha_set_timeline (retval, timeline); egg_alpha_set_func (retval, func, data, destroy); return retval; } /** * EGG_ALPHA_RAMP_INC: * * Convenience symbol for egg_ramp_inc_func(). * * Since: 0.2 */ /** * egg_ramp_inc_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a monotonic increasing ramp. You * can use this function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.2 */ guint32 egg_ramp_inc_func (EggAlpha *alpha, gpointer dummy) { EggTimeline *timeline; gint current_frame_num, n_frames; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); return (current_frame_num * EGG_ALPHA_MAX_ALPHA) / n_frames; } /** * EGG_ALPHA_RAMP_DEC: * * Convenience symbol for egg_ramp_dec_func(). * * Since: 0.2 */ /** * egg_ramp_dec_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a monotonic decreasing ramp. You * can use this function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.2 */ guint32 egg_ramp_dec_func (EggAlpha *alpha, gpointer dummy) { EggTimeline *timeline; gint current_frame_num, n_frames; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); return (n_frames - current_frame_num) * EGG_ALPHA_MAX_ALPHA / n_frames; } /** * EGG_ALPHA_RAMP: * * Convenience symbol for egg_ramp_func(). * * Since: 0.2 */ /** * egg_ramp_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a full ramp function (increase for * half the time, decrease for the remaining half). You can use this * function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.2 */ guint32 egg_ramp_func (EggAlpha *alpha, gpointer dummy) { EggTimeline *timeline; gint current_frame_num, n_frames; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); if (current_frame_num > (n_frames / 2)) { return (n_frames - current_frame_num) * EGG_ALPHA_MAX_ALPHA / (n_frames / 2); } else { return current_frame_num * EGG_ALPHA_MAX_ALPHA / (n_frames / 2); } } static guint32 sincx1024_func (EggAlpha *alpha, EggAngle angle, EggFixed offset) { EggTimeline *timeline; gint current_frame_num, n_frames; EggAngle x; unsigned int sine; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = angle * current_frame_num / n_frames; x -= (512 * 512 / angle); sine = ((egg_sini (x) + offset)/2) * EGG_ALPHA_MAX_ALPHA; sine = sine >> CFX_Q; return sine; } #if 0 /* * The following two functions are left in place for reference * purposes. */ static guint32 sincx_func (EggAlpha *alpha, EggFixed angle, EggFixed offset) { EggTimeline *timeline; gint current_frame_num, n_frames; EggFixed x, sine; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = angle * current_frame_num / n_frames; x = EGG_FIXED_MUL (x, CFX_PI) - EGG_FIXED_DIV (CFX_PI, angle); sine = (egg_fixed_sin (x) + offset)/2; EGG_NOTE (ALPHA, "sine: %2f\n", EGG_FIXED_TO_DOUBLE (sine)); return EGG_FIXED_TO_INT (sine * EGG_ALPHA_MAX_ALPHA); } /* NB: angle is not in radians but in muliples of PI, i.e., 2.0 * represents full circle. */ static guint32 sinc_func (EggAlpha *alpha, float angle, float offset) { EggTimeline *timeline; gint current_frame_num, n_frames; gdouble x, sine; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); /* FIXME: fixed point, and fixed point sine() */ x = (gdouble) (current_frame_num * angle * G_PI) / n_frames ; sine = (sin (x - (G_PI / angle)) + offset) * 0.5f; EGG_NOTE (ALPHA, "sine: %2f\n",sine); return EGG_FLOAT_TO_INT ((sine * (gdouble) EGG_ALPHA_MAX_ALPHA)); } #endif /** * EGG_ALPHA_SINE: * * Convenience symbol for egg_sine_func(). * * Since: 0.2 */ /** * egg_sine_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a sine wave. You can use this * function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.2 */ guint32 egg_sine_func (EggAlpha *alpha, gpointer dummy) { #if 0 return sinc_func (alpha, 2.0, 1.0); #else /* 2.0 above represents full circle */ return sincx1024_func (alpha, 1024, CFX_ONE); #endif } /** * EGG_ALPHA_SINE_INC: * * Convenience symbol for egg_sine_inc_func(). * * Since: 0.2 */ /** * egg_sine_inc_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a sine wave over interval [0, pi / 2]. * You can use this function as the alpha function for * egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.2 */ guint32 egg_sine_inc_func (EggAlpha *alpha, gpointer dummy) { EggTimeline * timeline; gint frame; gint n_frames; EggAngle x; EggFixed sine; timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = 256 * frame / n_frames; sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA; return ((guint32)sine) >> CFX_Q; } /** * EGG_ALPHA_SINE_DEC: * * Convenience symbol for egg_sine_dec_func(). * * Since: 0.2 */ /** * egg_sine_dec_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a sine wave over interval [pi / 2, pi]. * You can use this function as the alpha function for * egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.4 */ guint32 egg_sine_dec_func (EggAlpha *alpha, gpointer dummy) { EggTimeline * timeline; gint frame; gint n_frames; EggAngle x; EggFixed sine; timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = 256 * frame / n_frames + 256; sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA; return ((guint32)sine) >> CFX_Q; } /** * EGG_ALPHA_SINE_HALF: * * Convenience symbol for egg_sine_half_func(). * * Since: 0.4 */ /** * egg_sine_half_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a sine wave over interval [0, pi]. * You can use this function as the alpha function for * egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.4 */ guint32 egg_sine_half_func (EggAlpha *alpha, gpointer dummy) { EggTimeline * timeline; gint frame; gint n_frames; EggAngle x; EggFixed sine; timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = 512 * frame / n_frames; sine = egg_sini (x) * EGG_ALPHA_MAX_ALPHA; return ((guint32)sine) >> CFX_Q; } /** * EGG_ALPHA_SQUARE: * * Convenience symbol for egg_square_func(). * * Since: 0.4 */ /** * egg_square_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a square wave. You can use this * function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value * * Since: 0.4 */ guint32 egg_square_func (EggAlpha *alpha, gpointer dummy) { EggTimeline *timeline; gint current_frame_num, n_frames; timeline = egg_alpha_get_timeline (alpha); current_frame_num = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); return (current_frame_num > (n_frames / 2)) ? EGG_ALPHA_MAX_ALPHA : 0; } /** * EGG_ALPHA_SMOOTHSTEP_INC: * * Convenience symbol for egg_smoothstep_inc_func(). * * Since: 0.4 */ /** * egg_smoothstep_inc_func: * @alpha: a #EggAlpha * @dummy: unused * * Convenience alpha function for a smoothstep curve. You can use this * function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value * * Since: 0.4 */ guint32 egg_smoothstep_inc_func (EggAlpha *alpha, gpointer dummy) { EggTimeline *timeline; gint frame; gint n_frames; guint32 r; guint32 x; /* * The smoothstep function uses f(x) = -2x^3 + 3x^2 where x is from <0,1>, * and precission is critical -- we use 8.24 fixed format for this operation. * The earlier operations involve division, which we cannot do in 8.24 for * numbers in <0,1> we use EggFixed. */ timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); /* * Convert x to 8.24 for next step. */ x = CFX_DIV (frame, n_frames) << 8; /* * f(x) = -2x^3 + 3x^2 * * Convert result to EggFixed to avoid overflow in next step. */ r = ((x >> 12) * (x >> 12) * 3 - (x >> 15) * (x >> 16) * (x >> 16)) >> 8; return CFX_INT (r * EGG_ALPHA_MAX_ALPHA); } /** * EGG_ALPHA_SMOOTHSTEP_DEC: * * Convenience symbol for egg_smoothstep_dec_func(). * * Since: 0.4 */ /** * egg_smoothstep_dec_func: * @alpha: a #EggAlpha * @dummy: unused * * Convenience alpha function for a downward smoothstep curve. You can use * this function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value * * Since: 0.4 */ guint32 egg_smoothstep_dec_func (EggAlpha *alpha, gpointer dummy) { return EGG_ALPHA_MAX_ALPHA - egg_smoothstep_inc_func (alpha, dummy); } /** * EGG_ALPHA_EXP_INC: * * Convenience symbol for egg_exp_inc_func() * * Since: 0.4 */ /** * egg_exp_inc_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a 2^x curve. You can use this function as the * alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.4 */ guint32 egg_exp_inc_func (EggAlpha *alpha, gpointer dummy) { EggTimeline * timeline; gint frame; gint n_frames; EggFixed x; EggFixed x_alpha_max = 0x100000; guint32 result; /* * Choose x_alpha_max such that * * (2^x_alpha_max) - 1 == EGG_ALPHA_MAX_ALPHA */ #if EGG_ALPHA_MAX_ALPHA != 0xffff #error Adjust x_alpha_max to match EGG_ALPHA_MAX_ALPHA #endif timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = x_alpha_max * frame / n_frames; result = CLAMP (egg_pow2x (x) - 1, 0, EGG_ALPHA_MAX_ALPHA); return result; } /** * EGG_ALPHA_EXP_DEC: * * Convenience symbold for egg_exp_dec_func(). * * Since: 0.4 */ /** * egg_exp_dec_func: * @alpha: a #EggAlpha * @dummy: unused argument * * Convenience alpha function for a decreasing 2^x curve. You can use this * function as the alpha function for egg_alpha_set_func(). * * Return value: an alpha value. * * Since: 0.4 */ guint32 egg_exp_dec_func (EggAlpha *alpha, gpointer dummy) { EggTimeline * timeline; gint frame; gint n_frames; EggFixed x; EggFixed x_alpha_max = 0x100000; guint32 result; /* * Choose x_alpha_max such that * * (2^x_alpha_max) - 1 == EGG_ALPHA_MAX_ALPHA */ #if EGG_ALPHA_MAX_ALPHA != 0xffff #error Adjust x_alpha_max to match EGG_ALPHA_MAX_ALPHA #endif timeline = egg_alpha_get_timeline (alpha); frame = egg_timeline_get_current_frame (timeline); n_frames = egg_timeline_get_n_frames (timeline); x = (x_alpha_max * (n_frames - frame)) / n_frames; result = CLAMP (egg_pow2x (x) - 1, 0, EGG_ALPHA_MAX_ALPHA); return result; } ./egg/egg-timeline.c0000644000004100000410000013414013570225707014532 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * * Copyright (C) 2006 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /** * SECTION:egg-timeline * @short_description: A class for time-based events * * #EggTimeline is a base class for managing time based events such * as animations. * * Every timeline shares the same #EggTimeoutPool to decrease the * possibility of starving the main loop when using many timelines * at the same time; this might cause problems if you are also using * a library making heavy use of threads with no GLib main loop integration. * * In that case you might disable the common timeline pool by setting * the %EGG_TIMELINE=no-pool environment variable prior to launching * your application. * * One way to visualise a timeline is as a path with marks along its length. * When creating a timeline of @n_frames via egg_timeline_new(), then the * number of frames can be seen as the paths length, and each unit of length * (each frame) is delimited by a mark. * * For a non looping timeline there will be (n_frames + 1) marks along its * length. For a looping timeline, the two ends are joined with one mark. * Technically this mark represents two discrete frame numbers, but for a * looping timeline the start and end frame numbers are considered equivalent. * * When you create a timeline it starts with * egg_timeline_get_current_frame() == 0. * * After starting a timeline, the first timeout is for current_frame_num == 1 * (Notably it isn't 0 since there is a delay before the first timeout signals * so re-asserting the starting frame (0) wouldn't make sense.) * Notably, this implies that actors you intend to be affected by the * timeline's progress, should be manually primed/positioned for frame 0 which * will be displayed before the first timeout. (If you are not careful about * this point you will likely see flashes of incorrect actor state in your * program) * * For a non looping timeline the last timeout would be for * current_frame_num == @n_frames * * For a looping timeline the timeout for current_frame_num == @n_frames would * be followed by a timeout for current_frame_num == 1 (remember frame 0 is * considered == frame (@n_frames)). * * There may be times when a system is not able to meet the frame rate * requested for a timeline, and in this case the frame number will be * interpolated at the next timeout event. The interpolation is calculated from * the time that the timeline was started, not from the time of the last * timeout, so a given timeline should basically elapse in the same - real * world - time on any given system. An invariable here though is that * current_frame_num == @n_frames will always be signaled, but notably frame 1 * can be interpolated past and so never signaled. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "egg-timeout-pool.h" #include "egg-timeline.h" // #include "egg-main.h" // #include "egg-marshal.h" // #include "egg-private.h" #include "egg-hack.h" #include "egg-debug.h" // #include "egg-enum-types.h" G_DEFINE_TYPE (EggTimeline, egg_timeline, G_TYPE_OBJECT); #define FPS_TO_INTERVAL(f) (1000 / (f)) struct _EggTimelinePrivate { EggTimelineDirection direction; guint timeout_id; guint delay_id; gint current_frame_num; guint fps; guint n_frames; guint delay; gint skipped_frames; GTimeVal prev_frame_timeval; guint msecs_delta; GHashTable *markers_by_frame; GHashTable *markers_by_name; guint loop : 1; }; typedef struct { gchar *name; guint frame_num; GQuark quark; } TimelineMarker; enum { PROP_0, PROP_FPS, PROP_NUM_FRAMES, PROP_LOOP, PROP_DELAY, PROP_DURATION, PROP_DIRECTION }; enum { NEW_FRAME, STARTED, PAUSED, COMPLETED, MARKER_REACHED, LAST_SIGNAL }; static guint timeline_signals[LAST_SIGNAL] = { 0 }; static gint timeline_use_pool = -1; static EggTimeoutPool *timeline_pool = NULL; static inline void timeline_pool_init (void) { if (timeline_use_pool == -1) { const gchar *timeline_env; timeline_env = g_getenv ("EGG_TIMELINE"); if (timeline_env && timeline_env[0] != '\0' && strcmp (timeline_env, "no-pool") == 0) { timeline_use_pool = FALSE; } else { timeline_pool = egg_timeout_pool_new (EGG_PRIORITY_TIMELINE); timeline_use_pool = TRUE; } } } static guint timeout_add (guint interval, GSourceFunc func, gpointer data, GDestroyNotify notify) { guint res; if (G_LIKELY (timeline_use_pool)) { g_assert (timeline_pool != NULL); res = egg_timeout_pool_add (timeline_pool, interval, func, data, notify); } else { #if 0 res = egg_threads_add_frame_source_full (EGG_PRIORITY_TIMELINE, interval, func, data, notify); #endif g_assert (G_LIKELY (timeline_use_pool)); /* ie, FAIL */ } return res; } static void timeout_remove (guint tag) { if (G_LIKELY (timeline_use_pool)) { g_assert (timeline_pool != NULL); egg_timeout_pool_remove (timeline_pool, tag); } else g_source_remove (tag); } static TimelineMarker * timeline_marker_new (const gchar *name, guint frame_num) { TimelineMarker *marker = g_slice_new0 (TimelineMarker); marker->name = g_strdup (name); marker->quark = g_quark_from_string (marker->name); marker->frame_num = frame_num; return marker; } static void timeline_marker_free (gpointer data) { if (G_LIKELY (data)) { TimelineMarker *marker = data; g_free (marker->name); g_slice_free (TimelineMarker, marker); } } /* Object */ static void egg_timeline_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { EggTimeline *timeline; EggTimelinePrivate *priv; timeline = EGG_TIMELINE(object); priv = timeline->priv; switch (prop_id) { case PROP_FPS: egg_timeline_set_speed (timeline, g_value_get_uint (value)); break; case PROP_NUM_FRAMES: egg_timeline_set_n_frames (timeline, g_value_get_uint (value)); break; case PROP_LOOP: priv->loop = g_value_get_boolean (value); break; case PROP_DELAY: priv->delay = g_value_get_uint (value); break; case PROP_DURATION: egg_timeline_set_duration (timeline, g_value_get_uint (value)); break; case PROP_DIRECTION: egg_timeline_set_direction (timeline, g_value_get_enum (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void egg_timeline_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { EggTimeline *timeline; EggTimelinePrivate *priv; timeline = EGG_TIMELINE(object); priv = timeline->priv; switch (prop_id) { case PROP_FPS: g_value_set_uint (value, priv->fps); break; case PROP_NUM_FRAMES: g_value_set_uint (value, priv->n_frames); break; case PROP_LOOP: g_value_set_boolean (value, priv->loop); break; case PROP_DELAY: g_value_set_uint (value, priv->delay); break; case PROP_DURATION: g_value_set_uint (value, egg_timeline_get_duration (timeline)); break; case PROP_DIRECTION: g_value_set_enum (value, priv->direction); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void egg_timeline_finalize (GObject *object) { EggTimelinePrivate *priv = EGG_TIMELINE (object)->priv; g_hash_table_destroy (priv->markers_by_frame); g_hash_table_destroy (priv->markers_by_name); G_OBJECT_CLASS (egg_timeline_parent_class)->finalize (object); } static void egg_timeline_dispose (GObject *object) { EggTimeline *self = EGG_TIMELINE(object); EggTimelinePrivate *priv; priv = self->priv; if (priv->delay_id) { timeout_remove (priv->delay_id); priv->delay_id = 0; } if (priv->timeout_id) { timeout_remove (priv->timeout_id); priv->timeout_id = 0; } G_OBJECT_CLASS (egg_timeline_parent_class)->dispose (object); } static void egg_timeline_class_init (EggTimelineClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); timeline_pool_init (); object_class->set_property = egg_timeline_set_property; object_class->get_property = egg_timeline_get_property; object_class->finalize = egg_timeline_finalize; object_class->dispose = egg_timeline_dispose; g_type_class_add_private (klass, sizeof (EggTimelinePrivate)); /** * EggTimeline:fps: * * Timeline frames per second. Because of the nature of the main * loop used by Egg this is to be considered a best approximation. */ g_object_class_install_property (object_class, PROP_FPS, g_param_spec_uint ("fps", "Frames Per Second", "Timeline frames per second", 1, 1000, 60, EGG_PARAM_READWRITE)); /** * EggTimeline:num-frames: * * Total number of frames for the timeline. */ g_object_class_install_property (object_class, PROP_NUM_FRAMES, g_param_spec_uint ("num-frames", "Total number of frames", "Timelines total number of frames", 1, G_MAXUINT, 1, EGG_PARAM_READWRITE)); /** * EggTimeline:loop: * * Whether the timeline should automatically rewind and restart. */ g_object_class_install_property (object_class, PROP_LOOP, g_param_spec_boolean ("loop", "Loop", "Should the timeline automatically restart", FALSE, EGG_PARAM_READWRITE)); /** * EggTimeline:delay: * * A delay, in milliseconds, that should be observed by the * timeline before actually starting. * * Since: 0.4 */ g_object_class_install_property (object_class, PROP_DELAY, g_param_spec_uint ("delay", "Delay", "Delay before start", 0, G_MAXUINT, 0, EGG_PARAM_READWRITE)); /** * EggTimeline:duration: * * Duration of the timeline in milliseconds, depending on the * EggTimeline:fps value. * * Since: 0.6 */ g_object_class_install_property (object_class, PROP_DURATION, g_param_spec_uint ("duration", "Duration", "Duration of the timeline in milliseconds", 0, G_MAXUINT, 1000, EGG_PARAM_READWRITE)); /** * EggTimeline:direction: * * The direction of the timeline, either %EGG_TIMELINE_FORWARD or * %EGG_TIMELINE_BACKWARD. * * Since: 0.6 */ g_object_class_install_property (object_class, PROP_DIRECTION, g_param_spec_enum ("direction", "Direction", "Direction of the timeline", EGG_TYPE_TIMELINE_DIRECTION, EGG_TIMELINE_FORWARD, EGG_PARAM_READWRITE)); /** * EggTimeline::new-frame: * @timeline: the timeline which received the signal * @frame_num: the number of the new frame between 0 and * EggTimeline:num-frames * * The ::new-frame signal is emitted each time a new frame in the * timeline is reached. */ timeline_signals[NEW_FRAME] = g_signal_new ("new-frame", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTimelineClass, new_frame), NULL, NULL, egg_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); /** * EggTimeline::completed: * @timeline: the #EggTimeline which received the signal * * The ::completed signal is emitted when the timeline reaches the * number of frames specified by the EggTimeline:num-frames property. */ timeline_signals[COMPLETED] = g_signal_new ("completed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTimelineClass, completed), NULL, NULL, egg_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * EggTimeline::started: * @timeline: the #EggTimeline which received the signal * * The ::started signal is emitted when the timeline starts its run. * This might be as soon as egg_timeline_start() is invoked or * after the delay set in the EggTimeline:delay property has * expired. */ timeline_signals[STARTED] = g_signal_new ("started", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTimelineClass, started), NULL, NULL, egg_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * EggTimeline::paused: * @timeline: the #EggTimeline which received the signal * * The ::paused signal is emitted when egg_timeline_pause() is invoked. */ timeline_signals[PAUSED] = g_signal_new ("paused", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EggTimelineClass, paused), NULL, NULL, egg_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * EggTimeline::marker-reached: * @timeline: the #EggTimeline which received the signal * @marker_name: the name of the marker reached * @frame_num: the frame number * * The ::marker-reached signal is emitted each time a timeline * reaches a marker set with egg_timeline_add_marker_at_frame() * or egg_timeline_add_marker_at_time(). This signal is * detailed with the name of the marker as well, so it is * possible to connect a callback to the ::marker-reached signal * for a specific marker with: * * * egg_timeline_add_marker_at_frame (timeline, "foo", 24); * egg_timeline_add_marker_at_frame (timeline, "bar", 48); * * g_signal_connect (timeline, "marker-reached", * G_CALLBACK (each_marker_reached), NULL); * g_signal_connect (timeline, "marker-reached::foo", * G_CALLBACK (foo_marker_reached), NULL); * g_signal_connect (timeline, "marker-reached::bar", * G_CALLBACK (bar_marker_reached), NULL); * * * In the example, the first callback will be invoked for both * the "foo" and "bar" marker, while the second and third callbacks * will be invoked for the "foo" or "bar" markers, respectively. * * Since: 0.8 */ timeline_signals[MARKER_REACHED] = g_signal_new ("marker-reached", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (EggTimelineClass, marker_reached), NULL, NULL, egg_marshal_VOID__STRING_INT, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT); } static void egg_timeline_init (EggTimeline *self) { EggTimelinePrivate *priv; self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_TIMELINE, EggTimelinePrivate); priv->fps = egg_get_default_frame_rate (); priv->n_frames = 0; priv->msecs_delta = 0; priv->markers_by_frame = g_hash_table_new (NULL, NULL); priv->markers_by_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, timeline_marker_free); } static gboolean timeline_timeout_func (gpointer data) { EggTimeline *timeline = data; EggTimelinePrivate *priv; GTimeVal timeval; guint n_frames; gulong msecs; priv = timeline->priv; g_object_ref (timeline); /* Figure out potential frame skips */ g_get_current_time (&timeval); EGG_TIMESTAMP (SCHEDULER, "Timeline [%p] activated (cur: %d)\n", timeline, priv->current_frame_num); if (!priv->prev_frame_timeval.tv_sec) { EGG_NOTE (SCHEDULER, "Timeline [%p] recieved timeout before being initialised!", timeline); priv->prev_frame_timeval = timeval; } /* Interpolate the current frame based on the timeval of the * previous frame */ msecs = (timeval.tv_sec - priv->prev_frame_timeval.tv_sec) * 1000; msecs += (timeval.tv_usec - priv->prev_frame_timeval.tv_usec) / 1000; priv->msecs_delta = msecs; n_frames = msecs / (1000 / priv->fps); if (n_frames == 0) n_frames = 1; priv->skipped_frames = n_frames - 1; if (priv->skipped_frames) EGG_TIMESTAMP (SCHEDULER, "Timeline [%p], skipping %d frames\n", timeline, priv->skipped_frames); priv->prev_frame_timeval = timeval; /* Advance frames */ if (priv->direction == EGG_TIMELINE_FORWARD) priv->current_frame_num += n_frames; else priv->current_frame_num -= n_frames; /* If we have not reached the end of the timeline: */ if (!( ((priv->direction == EGG_TIMELINE_FORWARD) && (priv->current_frame_num >= priv->n_frames)) || ((priv->direction == EGG_TIMELINE_BACKWARD) && (priv->current_frame_num <= 0)) )) { gint i; /* Fire off signal */ g_signal_emit (timeline, timeline_signals[NEW_FRAME], 0, priv->current_frame_num); for (i = priv->skipped_frames; i >= 0; i--) { gint frame_num = priv->current_frame_num - i; GSList *markers, *l; markers = g_hash_table_lookup (priv->markers_by_frame, GUINT_TO_POINTER (frame_num)); for (l = markers; l; l = l->next) { TimelineMarker *marker = l->data; EGG_NOTE (SCHEDULER, "Marker `%s' reached", marker->name); g_signal_emit (timeline, timeline_signals[MARKER_REACHED], marker->quark, marker->name, marker->frame_num); } } /* Signal pauses timeline ? */ if (!priv->timeout_id) { g_object_unref (timeline); return FALSE; } g_object_unref (timeline); return TRUE; } else { /* Handle loop or stop */ EggTimelineDirection saved_direction = priv->direction; guint overflow_frame_num = priv->current_frame_num; gint end_frame; /* In case the signal handlers want to take a peek... */ if (priv->direction == EGG_TIMELINE_FORWARD) priv->current_frame_num = priv->n_frames; else if (priv->direction == EGG_TIMELINE_BACKWARD) priv->current_frame_num = 0; end_frame = priv->current_frame_num; /* Fire off signal */ g_signal_emit (timeline, timeline_signals[NEW_FRAME], 0, priv->current_frame_num); /* Did the signal handler modify the current_frame_num */ if (priv->current_frame_num != end_frame) { g_object_unref (timeline); return TRUE; } /* Note: If the new-frame signal handler paused the timeline * on the last frame we will still go ahead and send the * completed signal */ EGG_NOTE (SCHEDULER, "Timeline [%p] completed (cur: %d, tot: %d, drop: %d)", timeline, priv->current_frame_num, priv->n_frames, n_frames - 1); if (!priv->loop && priv->timeout_id) { /* We remove the timeout now, so that the completed signal handler * may choose to re-start the timeline * * ** Perhaps we should remove this earlier, and regardless * of priv->loop. Are we limiting the things that could be done in * the above new-frame signal handler */ timeout_remove (priv->timeout_id); priv->timeout_id = 0; } g_signal_emit (timeline, timeline_signals[COMPLETED], 0); /* Again check to see if the user has manually played with * current_frame_num, before we finally stop or loop the timeline */ if (priv->current_frame_num != end_frame && !(/* Except allow moving from frame 0 -> n_frame (or vica-versa) since these are considered equivalent */ (priv->current_frame_num == 0 && end_frame == priv->n_frames) || (priv->current_frame_num == priv->n_frames && end_frame == 0) )) { g_object_unref (timeline); return TRUE; } if (priv->loop) { /* We try and interpolate smoothly around a loop */ if (saved_direction == EGG_TIMELINE_FORWARD) priv->current_frame_num = overflow_frame_num - priv->n_frames; else priv->current_frame_num = priv->n_frames + overflow_frame_num; /* Or if the direction changed, we try and bounce */ if (priv->direction != saved_direction) { priv->current_frame_num = priv->n_frames - priv->current_frame_num; } g_object_unref (timeline); return TRUE; } else { egg_timeline_rewind (timeline); priv->prev_frame_timeval.tv_sec = 0; priv->prev_frame_timeval.tv_usec = 0; g_object_unref (timeline); return FALSE; } } } static guint timeline_timeout_add (EggTimeline *timeline, guint interval, GSourceFunc func, gpointer data, GDestroyNotify notify) { EggTimelinePrivate *priv; GTimeVal timeval; priv = timeline->priv; if (priv->prev_frame_timeval.tv_sec == 0) { g_get_current_time (&timeval); priv->prev_frame_timeval = timeval; } priv->skipped_frames = 0; priv->msecs_delta = 0; return timeout_add (interval, func, data, notify); } static gboolean delay_timeout_func (gpointer data) { EggTimeline *timeline = data; EggTimelinePrivate *priv = timeline->priv; priv->delay_id = 0; priv->timeout_id = timeline_timeout_add (timeline, FPS_TO_INTERVAL (priv->fps), timeline_timeout_func, timeline, NULL); g_signal_emit (timeline, timeline_signals[STARTED], 0); return FALSE; } /** * egg_timeline_start: * @timeline: A #EggTimeline * * Starts the #EggTimeline playing. **/ void egg_timeline_start (EggTimeline *timeline) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->delay_id || priv->timeout_id) return; if (priv->n_frames == 0) return; if (priv->delay) { priv->delay_id = timeout_add (priv->delay, delay_timeout_func, timeline, NULL); } else { priv->timeout_id = timeline_timeout_add (timeline, FPS_TO_INTERVAL (priv->fps), timeline_timeout_func, timeline, NULL); g_signal_emit (timeline, timeline_signals[STARTED], 0); } } /** * egg_timeline_pause: * @timeline: A #EggTimeline * * Pauses the #EggTimeline on current frame **/ void egg_timeline_pause (EggTimeline *timeline) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->delay_id) { timeout_remove (priv->delay_id); priv->delay_id = 0; } if (priv->timeout_id) { timeout_remove (priv->timeout_id); priv->timeout_id = 0; } priv->prev_frame_timeval.tv_sec = 0; priv->prev_frame_timeval.tv_usec = 0; g_signal_emit (timeline, timeline_signals[PAUSED], 0); } /** * egg_timeline_stop: * @timeline: A #EggTimeline * * Stops the #EggTimeline and moves to frame 0 **/ void egg_timeline_stop (EggTimeline *timeline) { egg_timeline_pause (timeline); egg_timeline_rewind (timeline); } /** * egg_timeline_set_loop: * @timeline: a #EggTimeline * @loop: %TRUE for enable looping * * Sets whether @timeline should loop. */ void egg_timeline_set_loop (EggTimeline *timeline, gboolean loop) { g_return_if_fail (EGG_IS_TIMELINE (timeline)); if (timeline->priv->loop != loop) { timeline->priv->loop = loop; g_object_notify (G_OBJECT (timeline), "loop"); } } /** * egg_timeline_get_loop: * @timeline: a #EggTimeline * * Gets whether @timeline is looping * * Return value: %TRUE if the timeline is looping */ gboolean egg_timeline_get_loop (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), FALSE); return timeline->priv->loop; } /** * egg_timeline_rewind: * @timeline: A #EggTimeline * * Rewinds #EggTimeline to the first frame if its direction is * EGG_TIMELINE_FORWARD and the last frame if it is * EGG_TIMELINE_BACKWARD. **/ void egg_timeline_rewind (EggTimeline *timeline) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->direction == EGG_TIMELINE_FORWARD) egg_timeline_advance (timeline, 0); else if (priv->direction == EGG_TIMELINE_BACKWARD) egg_timeline_advance (timeline, priv->n_frames); } /** * egg_timeline_skip: * @timeline: A #EggTimeline * @n_frames: Number of frames to skip * * Advance timeline by requested number of frames. **/ void egg_timeline_skip (EggTimeline *timeline, guint n_frames) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->direction == EGG_TIMELINE_FORWARD) { priv->current_frame_num += n_frames; if (priv->current_frame_num > priv->n_frames) priv->current_frame_num = 1; } else if (priv->direction == EGG_TIMELINE_BACKWARD) { priv->current_frame_num -= n_frames; if (priv->current_frame_num < 1) priv->current_frame_num = priv->n_frames - 1; } } /** * egg_timeline_advance: * @timeline: A #EggTimeline * @frame_num: Frame number to advance to * * Advance timeline to requested frame number **/ void egg_timeline_advance (EggTimeline *timeline, guint frame_num) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; priv->current_frame_num = CLAMP (frame_num, 0, priv->n_frames); } /** * egg_timeline_get_current_frame: * @timeline: A #EggTimeline * * Request the current frame number of the timeline. * * Return Value: current frame number **/ gint egg_timeline_get_current_frame (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); return timeline->priv->current_frame_num; } /** * egg_timeline_get_n_frames: * @timeline: A #EggTimeline * * Request the total number of frames for the #EggTimeline. * * Return Value: Number of frames for this #EggTimeline. **/ guint egg_timeline_get_n_frames (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); return timeline->priv->n_frames; } /** * egg_timeline_set_n_frames: * @timeline: a #EggTimeline * @n_frames: the number of frames * * Sets the total number of frames for @timeline */ void egg_timeline_set_n_frames (EggTimeline *timeline, guint n_frames) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (n_frames > 0); priv = timeline->priv; if (priv->n_frames != n_frames) { g_object_ref (timeline); g_object_freeze_notify (G_OBJECT (timeline)); priv->n_frames = n_frames; g_object_notify (G_OBJECT (timeline), "num-frames"); g_object_notify (G_OBJECT (timeline), "duration"); g_object_thaw_notify (G_OBJECT (timeline)); g_object_unref (timeline); } } /** * egg_timeline_set_speed: * @timeline: A #EggTimeline * @fps: New speed of timeline as frames per second * * Set the speed in frames per second of the timeline. **/ void egg_timeline_set_speed (EggTimeline *timeline, guint fps) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (fps > 0); priv = timeline->priv; if (priv->fps != fps) { g_object_ref (timeline); priv->fps = fps; /* if the timeline is playing restart */ if (priv->timeout_id) { timeout_remove (priv->timeout_id); priv->timeout_id = timeline_timeout_add (timeline, FPS_TO_INTERVAL (priv->fps), timeline_timeout_func, timeline, NULL); } g_object_freeze_notify (G_OBJECT (timeline)); g_object_notify (G_OBJECT (timeline), "duration"); g_object_notify (G_OBJECT (timeline), "fps"); g_object_thaw_notify (G_OBJECT (timeline)); g_object_unref (timeline); } } /** * egg_timeline_get_speed: * @timeline: a #EggTimeline * * Gets the frames per second played by @timeline * * Return value: the number of frames per second. */ guint egg_timeline_get_speed (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); return timeline->priv->fps; } /** * egg_timeline_is_playing: * @timeline: A #EggTimeline * * Query state of a #EggTimeline instance. * * Return Value: TRUE if timeline is currently playing, FALSE if not. */ gboolean egg_timeline_is_playing (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), FALSE); return (timeline->priv->timeout_id != 0); } /** * egg_timeline_clone: * @timeline: #EggTimeline to duplicate. * * Create a new #EggTimeline instance which has property values * matching that of supplied timeline. The cloned timeline will not * be started and will not be positioned to the current position of * @timeline: you will have to start it with egg_timeline_start(). * * Return Value: a new #EggTimeline, cloned from @timeline * * Since 0.4 */ EggTimeline * egg_timeline_clone (EggTimeline *timeline) { EggTimeline *copy; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), NULL); copy = g_object_new (EGG_TYPE_TIMELINE, "fps", egg_timeline_get_speed (timeline), "num-frames", egg_timeline_get_n_frames (timeline), "loop", egg_timeline_get_loop (timeline), "delay", egg_timeline_get_delay (timeline), "direction", egg_timeline_get_direction (timeline), NULL); return copy; } /** * egg_timeline_new_for_duration: * @msecs: Duration of the timeline in milliseconds * * Creates a new #EggTimeline with a duration of @msecs using * the value of the EggTimeline:fps property to compute the * equivalent number of frames. * * Return value: the newly created #EggTimeline * * Since: 0.6 */ EggTimeline * egg_timeline_new_for_duration (guint msecs) { return g_object_new (EGG_TYPE_TIMELINE, "duration", msecs, NULL); } /** * egg_timeline_new: * @n_frames: the number of frames * @fps: the number of frames per second * * Create a new #EggTimeline instance. * * Return Value: a new #EggTimeline */ EggTimeline* egg_timeline_new (guint n_frames, guint fps) { g_return_val_if_fail (n_frames > 0, NULL); g_return_val_if_fail (fps > 0, NULL); return g_object_new (EGG_TYPE_TIMELINE, "fps", fps, "num-frames", n_frames, NULL); } /** * egg_timeline_get_delay: * @timeline: a #EggTimeline * * Retrieves the delay set using egg_timeline_set_delay(). * * Return value: the delay in milliseconds. * * Since: 0.4 */ guint egg_timeline_get_delay (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); return timeline->priv->delay; } /** * egg_timeline_set_delay: * @timeline: a #EggTimeline * @msecs: delay in milliseconds * * Sets the delay, in milliseconds, before @timeline should start. * * Since: 0.4 */ void egg_timeline_set_delay (EggTimeline *timeline, guint msecs) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->delay != msecs) { priv->delay = msecs; g_object_notify (G_OBJECT (timeline), "delay"); } } /** * egg_timeline_get_duration: * @timeline: a #EggTimeline * * Retrieves the duration of a #EggTimeline in milliseconds. * See egg_timeline_set_duration(). * * Return value: the duration of the timeline, in milliseconds. * * Since: 0.6 */ guint egg_timeline_get_duration (EggTimeline *timeline) { EggTimelinePrivate *priv; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); priv = timeline->priv; return priv->n_frames * 1000 / priv->fps; } /** * egg_timeline_set_duration: * @timeline: a #EggTimeline * @msecs: duration of the timeline in milliseconds * * Sets the duration of the timeline, in milliseconds. The speed * of the timeline depends on the EggTimeline:fps setting. * * Since: 0.6 */ void egg_timeline_set_duration (EggTimeline *timeline, guint msecs) { EggTimelinePrivate *priv; guint n_frames; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; n_frames = msecs * priv->fps / 1000; if (n_frames < 1) n_frames = 1; egg_timeline_set_n_frames (timeline, n_frames); } /** * egg_timeline_get_progress: * @timeline: a #EggTimeline * * The position of the timeline in a [0, 1] interval. * * Return value: the position of the timeline. * * Since: 0.6 */ gdouble egg_timeline_get_progress (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0.); return EGG_FIXED_TO_DOUBLE (egg_timeline_get_progressx (timeline)); } /** * egg_timeline_get_progressx: * @timeline: a #EggTimeline * * Fixed point version of egg_timeline_get_progress(). * * Return value: the position of the timeline as a fixed point value * * Since: 0.6 */ EggFixed egg_timeline_get_progressx (EggTimeline *timeline) { EggTimelinePrivate *priv; EggFixed progress; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); priv = timeline->priv; progress = egg_qdivx (EGG_INT_TO_FIXED (priv->current_frame_num), EGG_INT_TO_FIXED (priv->n_frames)); if (priv->direction == EGG_TIMELINE_BACKWARD) progress = CFX_ONE - progress; return progress; } /** * egg_timeline_get_direction: * @timeline: a #EggTimeline * * Retrieves the direction of the timeline set with * egg_timeline_set_direction(). * * Return value: the direction of the timeline * * Since: 0.6 */ EggTimelineDirection egg_timeline_get_direction (EggTimeline *timeline) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), EGG_TIMELINE_FORWARD); return timeline->priv->direction; } /** * egg_timeline_set_direction: * @timeline: a #EggTimeline * @direction: the direction of the timeline * * Sets the direction of @timeline, either %EGG_TIMELINE_FORWARD or * %EGG_TIMELINE_BACKWARD. * * Since: 0.6 */ void egg_timeline_set_direction (EggTimeline *timeline, EggTimelineDirection direction) { EggTimelinePrivate *priv; g_return_if_fail (EGG_IS_TIMELINE (timeline)); priv = timeline->priv; if (priv->direction != direction) { priv->direction = direction; if (priv->current_frame_num == 0) priv->current_frame_num = priv->n_frames; g_object_notify (G_OBJECT (timeline), "direction"); } } /** * egg_timeline_get_delta: * @timeline: a #EggTimeline * @msecs: return location for the milliseconds elapsed since the last * frame, or %NULL * * Retrieves the number of frames and the amount of time elapsed since * the last EggTimeline::new-frame signal. * * This function is only useful inside handlers for the ::new-frame * signal, and its behaviour is undefined if the timeline is not * playing. * * Return value: the amount of frames elapsed since the last one * * Since: 0.6 */ guint egg_timeline_get_delta (EggTimeline *timeline, guint *msecs) { EggTimelinePrivate *priv; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), 0); if (!egg_timeline_is_playing (timeline)) { if (msecs) *msecs = 0; return 0; } priv = timeline->priv; if (msecs) *msecs = timeline->priv->msecs_delta; return priv->skipped_frames + 1; } static inline void egg_timeline_add_marker_internal (EggTimeline *timeline, const gchar *marker_name, guint frame_num) { EggTimelinePrivate *priv = timeline->priv; TimelineMarker *marker; GSList *markers; marker = g_hash_table_lookup (priv->markers_by_name, marker_name); if (G_UNLIKELY (marker)) { g_warning ("A marker named `%s' already exists on frame %d", marker->name, marker->frame_num); return; } marker = timeline_marker_new (marker_name, frame_num); g_hash_table_insert (priv->markers_by_name, marker->name, marker); markers = g_hash_table_lookup (priv->markers_by_frame, GUINT_TO_POINTER (frame_num)); if (!markers) { markers = g_slist_prepend (NULL, marker); g_hash_table_insert (priv->markers_by_frame, GUINT_TO_POINTER (frame_num), markers); } else { markers = g_slist_prepend (markers, marker); g_hash_table_replace (priv->markers_by_frame, GUINT_TO_POINTER (frame_num), markers); } } /** * egg_timeline_add_marker_at_frame: * @timeline: a #EggTimeline * @marker_name: the unique name for this marker * @frame_num: the marker's frame * * Adds a named marker at @frame_num. Markers are unique string identifiers * for a specific frame. Once @timeline reaches @frame_num, it will emit * a ::marker-reached signal for each marker attached to that frame. * * A marker can be removed with egg_timeline_remove_marker(). The * timeline can be advanced to a marker using * egg_timeline_advance_to_marker(). * * Since: 0.8 */ void egg_timeline_add_marker_at_frame (EggTimeline *timeline, const gchar *marker_name, guint frame_num) { g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (marker_name != NULL); g_return_if_fail (frame_num <= egg_timeline_get_n_frames (timeline)); egg_timeline_add_marker_internal (timeline, marker_name, frame_num); } /** * egg_timeline_add_marker_at_time: * @timeline: a #EggTimeline * @marker_name: the unique name for this marker * @msecs: position of the marker in milliseconds * * Time-based variant of egg_timeline_add_marker_at_frame(). * * Adds a named marker at @msecs. * * Since: 0.8 */ void egg_timeline_add_marker_at_time (EggTimeline *timeline, const gchar *marker_name, guint msecs) { guint frame_num; g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (marker_name != NULL); g_return_if_fail (msecs <= egg_timeline_get_duration (timeline)); frame_num = msecs * timeline->priv->fps / 1000; egg_timeline_add_marker_internal (timeline, marker_name, frame_num); } /** * egg_timeline_list_markers: * @timeline: a #EggTimeline * @frame_num: the frame number to check, or -1 * @n_markers: the number of markers returned * * Retrieves the list of markers at @frame_num. If @frame_num is a * negative integer, all the markers attached to @timeline will be * returned. * * Return value: a newly allocated, %NULL terminated string array * containing the names of the markers. Use g_strfreev() when * done. * * Since: 0.8 */ gchar ** egg_timeline_list_markers (EggTimeline *timeline, gint frame_num, gsize *n_markers) { EggTimelinePrivate *priv; gchar **retval = NULL; gsize i; g_return_val_if_fail (EGG_IS_TIMELINE (timeline), NULL); priv = timeline->priv; if (frame_num < 0) { GList *markers, *l; markers = g_hash_table_get_keys (priv->markers_by_name); retval = g_new0 (gchar*, g_list_length (markers) + 1); for (i = 0, l = markers; l != NULL; i++, l = l->next) retval[i] = g_strdup (l->data); g_list_free (markers); } else { GSList *markers, *l; markers = g_hash_table_lookup (priv->markers_by_frame, GUINT_TO_POINTER (frame_num)); retval = g_new0 (gchar*, g_slist_length (markers) + 1); for (i = 0, l = markers; l != NULL; i++, l = l->next) retval[i] = g_strdup (((TimelineMarker *) l->data)->name); } if (n_markers) *n_markers = i; return retval; } /** * egg_timeline_advance_to_marker: * @timeline: a #EggTimeline * @marker_name: the name of the marker * * Advances @timeline to the frame of the given @marker_name. * * Since: 0.8 */ void egg_timeline_advance_to_marker (EggTimeline *timeline, const gchar *marker_name) { EggTimelinePrivate *priv; TimelineMarker *marker; g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (marker_name != NULL); priv = timeline->priv; marker = g_hash_table_lookup (priv->markers_by_name, marker_name); if (!marker) { g_warning ("No marker named `%s' found.", marker_name); return; } egg_timeline_advance (timeline, marker->frame_num); } /** * egg_timeline_remove_marker: * @timeline: a #EggTimeline * @marker_name: the name of the marker to remove * * Removes @marker_name, if found, from @timeline. * * Since: 0.8 */ void egg_timeline_remove_marker (EggTimeline *timeline, const gchar *marker_name) { EggTimelinePrivate *priv; TimelineMarker *marker; GSList *markers; g_return_if_fail (EGG_IS_TIMELINE (timeline)); g_return_if_fail (marker_name != NULL); priv = timeline->priv; marker = g_hash_table_lookup (priv->markers_by_name, marker_name); if (!marker) { g_warning ("No marker named `%s' found.", marker_name); return; } /* remove from the list of markers at the same frame */ markers = g_hash_table_lookup (priv->markers_by_frame, GUINT_TO_POINTER (marker->frame_num)); if (G_LIKELY (markers)) { markers = g_slist_remove (markers, marker); if (!markers) { /* no markers left, remove the slot */ g_hash_table_remove (priv->markers_by_frame, GUINT_TO_POINTER (marker->frame_num)); } else g_hash_table_replace (priv->markers_by_frame, GUINT_TO_POINTER (marker->frame_num), markers); } else { /* uh-oh, dangling marker; this should never happen */ g_warning ("Dangling marker %s at frame %d", marker->name, marker->frame_num); } /* this will take care of freeing the marker as well */ g_hash_table_remove (priv->markers_by_name, marker_name); } /** * egg_timeline_has_marker: * @timeline: a #EggTimeline * @marker_name: the name of the marker * * Checks whether @timeline has a marker set with the given name. * * Return value: %TRUE if the marker was found * * Since: 0.8 */ gboolean egg_timeline_has_marker (EggTimeline *timeline, const gchar *marker_name) { g_return_val_if_fail (EGG_IS_TIMELINE (timeline), FALSE); g_return_val_if_fail (marker_name != NULL, FALSE); return NULL != g_hash_table_lookup (timeline->priv->markers_by_name, marker_name); } ./egg/egg-alpha.h0000644000004100000410000001352713570225707014023 0ustar www-datawww-data/* * Clutter. * * An OpenGL based 'interactive canvas' library. * * Authored By Matthew Allum * Jorn Baayen * Emmanuele Bassi * Tomas Frydrych * * Copyright (C) 2006, 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __EGG_ALPHA_H__ #define __EGG_ALPHA_H__ #include #include #include G_BEGIN_DECLS #define EGG_TYPE_ALPHA egg_alpha_get_type() #define EGG_ALPHA(obj) \ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ EGG_TYPE_ALPHA, EggAlpha)) #define EGG_ALPHA_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST ((klass), \ EGG_TYPE_ALPHA, EggAlphaClass)) #define EGG_IS_ALPHA(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ EGG_TYPE_ALPHA)) #define EGG_IS_ALPHA_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), \ EGG_TYPE_ALPHA)) #define EGG_ALPHA_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ EGG_TYPE_ALPHA, EggAlphaClass)) typedef struct _EggAlpha EggAlpha; typedef struct _EggAlphaClass EggAlphaClass; typedef struct _EggAlphaPrivate EggAlphaPrivate; /** * EggAlphaFunc: * @alpha: a #EggAlpha * @user_data: user data passed to the function * * A function of time, which returns a value between 0 and * %EGG_ALPHA_MAX_ALPHA. * * Return value: an unsigned integer value, between 0 and * %EGG_ALPHA_MAX_ALPHA. * * Since: 0.2 */ typedef guint32 (*EggAlphaFunc) (EggAlpha *alpha, gpointer user_data); /** * EggAlpha: * * #EggAlpha combines a #EggTimeline and a function. * The contents of the #EggAlpha structure are private and should * only be accessed using the provided API. * * Since: 0.2 */ struct _EggAlpha { /*< private >*/ GInitiallyUnowned parent; EggAlphaPrivate *priv; }; /** * EggAlphaClass: * * Base class for #EggAlpha * * Since: 0.2 */ struct _EggAlphaClass { /*< private >*/ GInitiallyUnownedClass parent_class; void (*_egg_alpha_1) (void); void (*_egg_alpha_2) (void); void (*_egg_alpha_3) (void); void (*_egg_alpha_4) (void); void (*_egg_alpha_5) (void); }; /** * EGG_ALPHA_MAX_ALPHA: * * Maximum value returned by #EggAlphaFunc * * Since: 0.2 */ #define EGG_ALPHA_MAX_ALPHA 0xffff GType egg_alpha_get_type (void) G_GNUC_CONST; EggAlpha * egg_alpha_new (void); EggAlpha * egg_alpha_new_full (EggTimeline *timeline, EggAlphaFunc func, gpointer data, GDestroyNotify destroy); guint32 egg_alpha_get_alpha (EggAlpha *alpha); void egg_alpha_set_func (EggAlpha *alpha, EggAlphaFunc func, gpointer data, GDestroyNotify destroy); void egg_alpha_set_closure (EggAlpha *alpha, GClosure *closure); void egg_alpha_set_timeline (EggAlpha *alpha, EggTimeline *timeline); EggTimeline *egg_alpha_get_timeline (EggAlpha *alpha); /* convenience functions */ #define EGG_ALPHA_RAMP_INC egg_ramp_inc_func #define EGG_ALPHA_RAMP_DEC egg_ramp_dec_func #define EGG_ALPHA_RAMP egg_ramp_func #define EGG_ALPHA_SINE egg_sine_func #define EGG_ALPHA_SINE_INC egg_sine_inc_func #define EGG_ALPHA_SINE_DEC egg_sine_dec_func #define EGG_ALPHA_SINE_HALF egg_sine_half_func #define EGG_ALPHA_SQUARE egg_square_func #define EGG_ALPHA_SMOOTHSTEP_INC egg_smoothstep_inc_func #define EGG_ALPHA_SMOOTHSTEP_DEC egg_smoothstep_dec_func #define EGG_ALPHA_EXP_INC egg_exp_inc_func #define EGG_ALPHA_EXP_DEC egg_exp_dec_func guint32 egg_ramp_inc_func (EggAlpha *alpha, gpointer dummy); guint32 egg_ramp_dec_func (EggAlpha *alpha, gpointer dummy); guint32 egg_ramp_func (EggAlpha *alpha, gpointer dummy); guint32 egg_sine_func (EggAlpha *alpha, gpointer dummy); guint32 egg_sine_inc_func (EggAlpha *alpha, gpointer dummy); guint32 egg_sine_dec_func (EggAlpha *alpha, gpointer dummy); guint32 egg_sine_half_func (EggAlpha *alpha, gpointer dummy); guint32 egg_square_func (EggAlpha *alpha, gpointer dummy); guint32 egg_smoothstep_inc_func (EggAlpha *alpha, gpointer dummy); guint32 egg_smoothstep_dec_func (EggAlpha *alpha, gpointer dummy); guint32 egg_exp_inc_func (EggAlpha *alpha, gpointer dummy); guint32 egg_exp_dec_func (EggAlpha *alpha, gpointer dummy); G_END_DECLS #endif /* __EGG_ALPHA_H__ */ ./egg/test-timeline-interpolate.c0000644000004100000410000001013013570225707017263 0ustar www-datawww-data#include #include #include /* We ask for 1 frame per millisecond. * Whenever this rate can't be achieved then the timeline * will interpolate the number frames that should have * passed between timeouts. */ #define TEST_TIMELINE_FPS 1000 #define TEST_TIMELINE_FRAME_COUNT 5000 /* We are at the mercy of the system scheduler so this * may not be a very reliable tolerance. */ #define TEST_ERROR_TOLERANCE 20 typedef struct _TestState { EggTimeline *timeline; GTimeVal start_time; guint new_frame_counter; gint expected_frame; gint completion_count; gboolean passed; }TestState; static void new_frame_cb (EggTimeline *timeline, gint frame_num, TestState *state) { GTimeVal current_time; gint current_frame; glong msec_diff; gint loop_overflow = 0; static gint step = 1; g_get_current_time (¤t_time); current_frame = egg_timeline_get_current_frame (state->timeline); msec_diff = (current_time.tv_sec - state->start_time.tv_sec) * 1000; msec_diff += (current_time.tv_usec - state->start_time.tv_usec)/1000; /* If we expect to have interpolated past the end of the timeline * we keep track of the overflow so we can determine when * the next timeout will happen. We then clip expected_frames * to TEST_TIMELINE_FRAME_COUNT since egg-timeline * semantics guaranty this frame is always signaled before * looping */ if (state->expected_frame > TEST_TIMELINE_FRAME_COUNT) { loop_overflow = state->expected_frame - TEST_TIMELINE_FRAME_COUNT; state->expected_frame = TEST_TIMELINE_FRAME_COUNT; } if (current_frame >= (state->expected_frame-TEST_ERROR_TOLERANCE) && current_frame <= (state->expected_frame+TEST_ERROR_TOLERANCE)) { g_print ("\nelapsed milliseconds=%-5li expected frame=%-4i actual frame=%-4i (OK)\n", msec_diff, state->expected_frame, current_frame); } else { g_print ("\nelapsed milliseconds=%-5li expected frame=%-4i actual frame=%-4i (FAILED)\n", msec_diff, state->expected_frame, current_frame); state->passed = FALSE; } if (step>0) { state->expected_frame = current_frame + (TEST_TIMELINE_FPS / 4); g_print ("Sleeping for 250ms so next frame should be (%i + %i) = %i\n", current_frame, (TEST_TIMELINE_FPS / 4), state->expected_frame); g_usleep (250000); } else { state->expected_frame = current_frame + TEST_TIMELINE_FPS; g_print ("Sleeping for 1sec so next frame should be (%i + %i) = %i\n", current_frame, TEST_TIMELINE_FPS, state->expected_frame); g_usleep (1000000); } if (current_frame >= TEST_TIMELINE_FRAME_COUNT) { state->expected_frame += loop_overflow; state->expected_frame -= TEST_TIMELINE_FRAME_COUNT; g_print ("End of timeline reached: Wrapping expected frame too %i\n", state->expected_frame); } state->new_frame_counter++; step = -step; } static void completed_cb (EggTimeline *timeline, TestState *state) { state->completion_count++; if (state->completion_count == 2) { if (state->passed) { g_print("Passed\n"); exit(EXIT_SUCCESS); } else { g_print("Failed\n"); exit(EXIT_FAILURE); } } } int main (int argc, char **argv) { TestState state; state.timeline = egg_timeline_new (TEST_TIMELINE_FRAME_COUNT, TEST_TIMELINE_FPS); egg_timeline_set_loop (state.timeline, TRUE); g_signal_connect (G_OBJECT(state.timeline), "new-frame", G_CALLBACK(new_frame_cb), &state); g_signal_connect (G_OBJECT(state.timeline), "completed", G_CALLBACK(completed_cb), &state); state.completion_count = 0; state.new_frame_counter = 0; state.passed = TRUE; state.expected_frame = 0; g_get_current_time (&state.start_time); egg_timeline_start (state.timeline); egg_main(); return EXIT_FAILURE; } ./ChangeLog0000644000004100000410000000003013570225707013016 0ustar www-datawww-datause: bzr log | less ./manual-tests/0000755000004100000410000000000013570225707013670 5ustar www-datawww-data./manual-tests/average-background-color.txt0000644000004100000410000000144113570225707021274 0ustar www-datawww-data1.) Verify that the correct X11-property is available with: xlsatoms -name _GNOME_BACKGROUND_REPRESENTATIVE_COLORS If you don't get a reply from that command (it just returns to the prompt) any notification you trigger (step 3.) will have a dark grey background. 2.) Right-click on the desktop to bring up the context-menu and select the change wallpaper menu-item. 3.) Trigger a dummy notification with: notify-send "Test" "This is just a simple test." -i info Note the tint of the notifications background and wait for the notification to close (don't keep the mouse-pointer hovering over the notification). 4.) Change the wallpaper to an image with an overall different tint as the current one. 5.) Repeat step 3.) 6.) The tint of the notifications background should now be different. ./manual-tests/avoid-position-in-invisible-area.txt0000644000004100000410000000222313570225707022670 0ustar www-datawww-data1.) Have a two-monitor setup and configure the displays in such a way that the vertical resolution between the two monitors differs by at least 100 pixels. Align the displays at the bottom edge! Make the monitor with the lower vertical resolution the primary display. Depending on your GPU/driver combination, you can use the GNOME display-settings for setting this up or you have to use a tool like nvidia-settings. 2.) Kill and restart notify-osd by doing... killall -15 notify-osd /usr/lib/notify-osd/notify-osd 2.) Set focus-follow off and gravity to 1 with... gsettings set com.canonical.notify-osd multihead-mode "dont-focus-follow" gsettings set com.canonical.notify-osd gravity 1 4.) Trigger two notifications (a synchronous one and a regular one) with these commands... notify-send "Test bubble" "A regular notification used for testing." -i info notify-send " " " " -i info -h string:"x-canonical-private-icon-only":1 -h string:"x-canonical-private-synchronous":1 -i info 5.) You should now see both notifications fully at the visible top-right corner of the whole screen area. 6.) For RTL-locales you have to flip 1.) - 5.) side-ways of course. ./tests/0000755000004100000410000000000013570225707012415 5ustar www-datawww-data./tests/test-bubble.c0000644000004100000410000000775513570225707015007 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-bubble.c - implements unit-tests for rendering/displaying a bubble ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include "bubble.h" #include "util.h" static gboolean stop_main_loop (GMainLoop *loop) { g_main_loop_quit (loop); return FALSE; } static void test_bubble_new (gpointer fixture, gconstpointer user_data) { Bubble* bubble; Defaults* defaults; defaults = defaults_new (); bubble = bubble_new (defaults); g_assert (bubble != NULL); g_object_unref (bubble); g_object_unref (defaults); } static void test_bubble_del (gpointer fixture, gconstpointer user_data) { Bubble* bubble; Defaults* defaults; defaults = defaults_new (); bubble = bubble_new (defaults); g_assert (bubble != NULL); g_object_unref (bubble); g_object_unref (defaults); } static void test_bubble_set_attributes (gpointer fixture, gconstpointer user_data) { Bubble* bubble; GMainLoop* loop; Defaults* defaults; defaults = defaults_new (); bubble = bubble_new (defaults); bubble_set_icon (bubble, "/usr/share/icons/Human/scalable/status/notification-message-im.svg"); bubble_set_title (bubble, "Unit Testing"); bubble_set_message_body (bubble, "Long text that is hopefully wrapped"); bubble_determine_layout (bubble); bubble_move (bubble, 30, 30); bubble_show (bubble); /* let the main loop run */ loop = g_main_loop_new (NULL, FALSE); g_timeout_add (2000, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); g_object_unref (bubble); g_object_unref (defaults); } static void test_bubble_get_attributes (gpointer fixture, gconstpointer user_data) { Bubble* bubble; Defaults* defaults; defaults = defaults_new (); bubble = bubble_new (defaults); bubble_set_title (bubble, "Foo Bar"); bubble_set_message_body (bubble, "Some message-body text."); bubble_set_value (bubble, 42); g_assert_cmpstr (bubble_get_title (bubble), ==, "Foo Bar"); g_assert_cmpstr (bubble_get_message_body (bubble), ==, "Some message-body text."); g_assert_cmpint (bubble_get_value (bubble), ==, 42); g_object_unref (bubble); g_object_unref (defaults); } GTestSuite * test_bubble_create_test_suite (void) { GTestSuite *ts = NULL; GTestCase *tc = NULL; ts = g_test_create_suite ("bubble"); tc = g_test_create_case ("can create a new bubble", 0, NULL, NULL, test_bubble_new, NULL); g_test_suite_add (ts, tc); g_test_suite_add(ts, g_test_create_case ("can delete a bubble", 0, NULL, NULL, test_bubble_del, NULL) ); g_test_suite_add (ts, g_test_create_case ("can set bubble attributes", 0, NULL, NULL, test_bubble_set_attributes, NULL)); g_test_suite_add (ts, g_test_create_case ("can get bubble attributes", 0, NULL, NULL, test_bubble_get_attributes, NULL)); return ts; } ./tests/test-scroll-text.c0000644000004100000410000006366513570225707016036 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // test-scroll-text // // test-scroll-text.c - test using tile to animate scrolling text in a bubble // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include "raico-blur.h" #include "tile.h" #include "util.h" #define BUBBLE_SHADOW_SIZE 10.0f #define CORNER_RADIUS 6.0f #define BUBBLE_WIDTH 320.0f #define BUBBLE_HEIGHT 175.0f #define BUBBLE_BG_COLOR_R 0.2f #define BUBBLE_BG_COLOR_G 0.2f #define BUBBLE_BG_COLOR_B 0.2f #define POS_X 0 #define POS_Y 30 gboolean g_composited = FALSE; gboolean g_mouse_over = FALSE; tile_t* g_tile = NULL; tile_t* g_text = NULL; gfloat g_distance = 1.0f; gint g_offset = -50; gint g_step = 1; cairo_surface_t* render_text_to_surface (gchar* text, gint width, gint height, const cairo_font_options_t* font_opts, gdouble dpi) { cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc; PangoLayout* layout; // sanity check if (!text || width <= 0 || height <= 0) return NULL; // create surface surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) return NULL; // create context cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } // clear context cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // layout = pango_cairo_create_layout (cr); desc = pango_font_description_new (); pango_font_description_set_size (desc, 12 * PANGO_SCALE); pango_font_description_set_family_static (desc, "Candara"); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_height (layout, height * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); // print and layout string (pango-wise) pango_layout_set_text (layout, text, -1); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts); pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi); pango_layout_context_changed (layout); // draw pango-text to our cairo-context cairo_move_to (cr, 0.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); // this call leaks 3803 bytes, I've no idea how to fix that pango_cairo_show_layout (cr, layout); // clean up g_object_unref (layout); cairo_destroy (cr); return surface; } void draw_round_rect (cairo_t* cr, gdouble aspect, // aspect-ratio gdouble x, // top-left corner gdouble y, // top-left corner gdouble corner_radius, // "size" of the corners gdouble width, // width of the rectangle gdouble height) // height of the rectangle { gdouble radius = corner_radius / aspect; // top-left, right of the corner cairo_move_to (cr, x + radius, y); // top-right, left of the corner cairo_line_to (cr, x + width - radius, y); // top-right, below the corner cairo_arc (cr, x + width - radius, y + radius, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); // bottom-right, above the corner cairo_line_to (cr, x + width, y + height - radius); // bottom-right, left of the corner cairo_arc (cr, x + width - radius, y + height - radius, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); // bottom-left, right of the corner cairo_line_to (cr, x + radius, y + height); // bottom-left, above the corner cairo_arc (cr, x + radius, y + height - radius, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); // top-left, below the corner cairo_line_to (cr, x, y + radius); // top-left, right of the corner cairo_arc (cr, x + radius, y + radius, radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); } void screen_changed_handler (GtkWidget* window, GdkScreen* old_screen, gpointer data) { GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (window)); GdkVisual* visual = gdk_screen_get_rgba_visual (screen); if (!visual) visual = gdk_screen_get_system_visual (screen); gtk_widget_set_visual (GTK_WIDGET (window), visual); } static void update_input_shape (GtkWidget* window, gint width, gint height) { cairo_region_t* region = NULL; const cairo_rectangle_int_t rect = {0, 0, 1, 1}; region = cairo_region_create_rectangle (&rect); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_input_shape_combine_region (window, NULL); gtk_widget_input_shape_combine_region (window, region); } } static void update_shape (GtkWidget* window, gint radius, gint shadow_size) { if (g_composited) { /* remove any current shape-mask */ gtk_widget_input_shape_combine_region (window, NULL); return; } int width; int height; gtk_widget_get_size_request (window, &width, &height); const cairo_rectangle_int_t rects[] = {{2, 0, width - 4, height}, {1, 1, width - 2, height - 2}, {0, 2, width, height - 4}}; cairo_region_t* region = NULL; region = cairo_region_create_rectangles (rects, 3); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_shape_combine_region (window, NULL); gtk_widget_shape_combine_region (window, region); } } void composited_changed_handler (GtkWidget* window, gpointer data) { g_composited = gdk_screen_is_composited(gtk_widget_get_screen (window)); update_shape (window, (gint) CORNER_RADIUS, (gint) BUBBLE_SHADOW_SIZE); } void draw_shadow (cairo_t* cr, gdouble width, gdouble height, gint shadow_radius, gint corner_radius) { cairo_surface_t* tmp_surface = NULL; cairo_surface_t* new_surface = NULL; cairo_pattern_t* pattern = NULL; cairo_t* cr_surf = NULL; cairo_matrix_t matrix; raico_blur_t* blur = NULL; tmp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4 * shadow_radius, 4 * shadow_radius); if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS) return; cr_surf = cairo_create (tmp_surface); if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); return; } cairo_scale (cr_surf, 1.0f, 1.0f); cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR); cairo_paint (cr_surf); cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 0.75f); cairo_arc (cr_surf, 2 * shadow_radius, 2 * shadow_radius, 2.0f * corner_radius, 0.0f, 360.0f * (G_PI / 180.f)); cairo_fill (cr_surf); cairo_destroy (cr_surf); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, shadow_radius); // now blur it raico_blur_apply (blur, tmp_surface); // blur no longer needed raico_blur_destroy (blur); new_surface = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (tmp_surface), cairo_image_surface_get_format (tmp_surface), cairo_image_surface_get_width (tmp_surface) / 2, cairo_image_surface_get_height (tmp_surface) / 2, cairo_image_surface_get_stride (tmp_surface)); pattern = cairo_pattern_create_for_surface (new_surface); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); return; } // top left cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0.0f, 0.0f, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0.0f, 2 * shadow_radius, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - 2 * shadow_radius, 0.0f, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -width, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 2 * shadow_radius, height - 2 * shadow_radius, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // clean up cairo_pattern_destroy (pattern); cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); } gboolean expose_handler (GtkWidget* window, cairo_t* cr, gpointer data) { cairo_pattern_t* pattern = NULL; cairo_pattern_t* mask = NULL; // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_distance < 1.0f) { tile_paint (g_tile, cr, 0.0f, 0.0f, g_distance, 1.0f - g_distance); cairo_push_group (cr); tile_paint (g_text, cr, 2 * BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE - g_offset, g_distance, 1.0f - g_distance); pattern = cairo_pop_group (cr); cairo_set_source (cr, pattern); mask = cairo_pattern_create_linear (0.0f, 2 * BUBBLE_SHADOW_SIZE, 0.0f, BUBBLE_HEIGHT); cairo_pattern_add_color_stop_rgba (mask, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_pattern_add_color_stop_rgba (mask, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 0.8f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_mask (cr, mask); cairo_pattern_destroy (mask); cairo_pattern_destroy (pattern); gtk_widget_set_opacity (window, 0.3f + g_distance * 0.7f); } else { tile_paint (g_tile, cr, 0.0f, 0.0f, g_distance, 0.0f); cairo_push_group (cr); tile_paint (g_text, cr, 2 * BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE - g_offset, g_distance, 0.0f); pattern = cairo_pop_group (cr); cairo_set_source (cr, pattern); mask = cairo_pattern_create_linear (0.0f, 2 * BUBBLE_SHADOW_SIZE, 0.0f, BUBBLE_HEIGHT); cairo_pattern_add_color_stop_rgba (mask, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_pattern_add_color_stop_rgba (mask, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 0.8f, 0.0f, 0.0f, 0.0f, 1.0f); cairo_pattern_add_color_stop_rgba (mask, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); cairo_mask (cr, mask); cairo_pattern_destroy (pattern); gtk_widget_set_opacity (window, 1.0f); } return TRUE; } void set_bg_blur (GtkWidget* window, gboolean blur) { GtkAllocation a; GdkWindow* gdkwindow; gint shadow = BUBBLE_SHADOW_SIZE; if (!window) return; gtk_widget_get_allocation (window, &a); gdkwindow = gtk_widget_get_window (window); if (blur) { glong data[] = { 2, // threshold 0, // filter NorthWestGravity, // gravity of top-left shadow, // x-coord of top-left -a.height/2 + shadow, // y-coord of top-left NorthWestGravity, // gravity of bottom-right a.width - shadow, // bottom-right x-coord a.height/2 - shadow}; // bottom-right y-coord XChangeProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom(GDK_WINDOW_XDISPLAY(gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE), XA_INTEGER, 32, PropModeReplace, (guchar *) data, 8); } else { XDeleteProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom(GDK_WINDOW_XDISPLAY(gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE)); } } gboolean quit (gpointer data) { gtk_main_quit (); return FALSE; } gboolean pointer_update (GtkWidget* window) { gint pointer_rel_x; gint pointer_rel_y; gint pointer_abs_x; gint pointer_abs_y; gint win_x; gint win_y; gint width; gint height; gboolean old_mouse_over; if (!GTK_IS_WINDOW (window)) return FALSE; old_mouse_over = g_mouse_over; if (gtk_widget_get_realized (window)) { GdkDeviceManager *device_manager; GdkDevice *device; gint distance_x; gint distance_y; device_manager = gdk_display_get_device_manager (gtk_widget_get_display (window)); device = gdk_device_manager_get_client_pointer (device_manager); gdk_window_get_device_position (gtk_widget_get_window (window), device, &pointer_rel_x, &pointer_rel_y, NULL); gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y); pointer_abs_x = win_x + pointer_rel_x; pointer_abs_y = win_y + pointer_rel_y; gtk_window_get_size (GTK_WINDOW (window), &width, &height); if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width && pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) g_mouse_over = TRUE; else g_mouse_over = FALSE; if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width) distance_x = 0; else { if (pointer_abs_x < win_x) distance_x = abs (pointer_rel_x); if (pointer_abs_x > win_x + width) distance_x = abs (pointer_rel_x - width); } if (pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) distance_y = 0; else { if (pointer_abs_y < win_y) distance_y = abs (pointer_rel_y); if (pointer_abs_y > win_y + height) distance_y = abs (pointer_rel_y - height); } g_distance = sqrt (distance_x * distance_x + distance_y * distance_y) / (double) 40; } if (old_mouse_over != g_mouse_over) set_bg_blur (window, !g_mouse_over); if (g_offset < -50) g_step = 1; if (g_offset > 150) g_step = -1; g_offset += g_step; gtk_widget_queue_draw (window); return TRUE; } tile_t* setup_text_tile (const cairo_font_options_t* font_opts, gdouble dpi, gint w, gint h) { tile_t* tile = NULL; cairo_status_t status; cairo_surface_t* surface = NULL; cairo_surface_t* text = NULL; cairo_surface_t* shadow = NULL; cairo_t* cr; gdouble width = (gdouble) w; gdouble height = (gdouble) h; raico_blur_t* blur = NULL; cairo_pattern_t* pattern = NULL; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); status = cairo_surface_status (surface); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); cr = cairo_create (surface); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); text = render_text_to_surface ( "After an evening of hacking at the" " Fataga hotel here at GUADEC I " "can present you even text-scroll " "with blur-cache and fade-out mask" " and I dedicate this to Behdad who" " sadly burst his upper lip during " "the evening and had to go to the " "hospital. Some spanish KDE-folks " "kindly accompanied him to help out" " with translation. True collaboration!\0", width, height, font_opts, dpi); shadow = render_text_to_surface ( "After an evening of hacking at the" " Fataga hotel here at GUADEC I " "can present you even text-scroll " "with blur-cache and fade-out mask" " and I dedicate this to Behdad who" " sadly burst his upper lip during " "the evening and had to go to the " "hospital. Some spanish KDE-folks " "kindly accompanied him to help out" " with translation. True collaboration!\0", width, height, font_opts, dpi); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 4); // now blur it raico_blur_apply (blur, shadow); // blur no longer needed raico_blur_destroy (blur); cairo_push_group (cr); cairo_set_source_surface (cr, shadow, 0.0f, 0.0f); cairo_paint (cr); pattern = cairo_pop_group (cr); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); cairo_mask (cr, pattern); cairo_surface_destroy (shadow); cairo_pattern_destroy (pattern); cairo_set_source_surface (cr, text, 0.0f, 0.0f); cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (text); tile = tile_new (surface, 6); cairo_surface_destroy (surface); return tile; } void setup_tile (gint w, gint h) { cairo_status_t status; cairo_t* cr = NULL; cairo_surface_t* cr_surf = NULL; gdouble width = (gdouble) w; gdouble height = (gdouble) h; cairo_surface_t* tmp = NULL; cairo_surface_t* dummy_surf = NULL; cairo_surface_t* norm_surf = NULL; cairo_surface_t* blur_surf = NULL; raico_blur_t* blur = NULL; tile_t* tile = NULL; // create tmp. surface for scratch cr_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE); status = cairo_surface_status (cr_surf); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); // create context for that tmp. scratch surface cr = cairo_create (cr_surf); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (cr_surf); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear, render drop-shadow and bubble-background in scratch-surface cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_composited) { draw_shadow (cr, width, height, BUBBLE_SHADOW_SIZE, CORNER_RADIUS); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); draw_round_rect (cr, 1.0f, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f* BUBBLE_SHADOW_SIZE)); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B, 0.95f); } else cairo_set_source_rgb (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B); draw_round_rect (cr, 1.0f, BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE, CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f * BUBBLE_SHADOW_SIZE)); cairo_fill (cr); // create tmp. copy of scratch-surface tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (cr_surf), cairo_image_surface_get_format (cr_surf), 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (cr_surf)); dummy_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // create normal-state surface for tile from copy of scratch-surface tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); norm_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // blur tmp. copy of scratch-surface blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 6); raico_blur_apply (blur, dummy_surf); raico_blur_destroy (blur); // create blurred-state surface for tile tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); blur_surf = copy_surface (tmp); cairo_surface_destroy (tmp); // actually create the tile with padding in mind tile = tile_new_for_padding (norm_surf, blur_surf, width, height); cairo_surface_destroy (norm_surf); cairo_surface_destroy (blur_surf); cairo_surface_destroy (dummy_surf); cairo_destroy (cr); cairo_surface_destroy (cr_surf); norm_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (norm_surf); cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); tile_paint_with_padding (tile, cr, 0.0f, 0.0f, w, h, 1.0f, 0.0f); cairo_destroy (cr); blur_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (blur_surf); cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); tile_paint_with_padding (tile, cr, 0.0f, 0.0f, w, h, 0.0f, 1.0f); cairo_destroy (cr); g_tile = tile_new_for_padding (norm_surf, blur_surf, width, height); // clean up tile_destroy (tile); cairo_surface_destroy (norm_surf); cairo_surface_destroy (blur_surf); } int main (int argc, char** argv) { GtkWidget* window; GdkRGBA transparent = {0.0, 0.0, 0.0, 0.0}; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (!window) return 0; gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DOCK); gtk_widget_add_events (window, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); // hook up input/event handlers to window g_signal_connect (G_OBJECT (window), "screen-changed", G_CALLBACK (screen_changed_handler), NULL); g_signal_connect (G_OBJECT (window), "composited-changed", G_CALLBACK (composited_changed_handler), NULL); gtk_window_move (GTK_WINDOW (window), POS_X, POS_Y); // make sure the window opens with a RGBA-visual screen_changed_handler (window, NULL, NULL); gtk_widget_realize (window); gdk_window_set_background_rgba (gtk_widget_get_window (window), &transparent); // hook up window-event handlers to window g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (expose_handler), NULL); // FIXME: read out current mouse-pointer position every 1/25 second g_timeout_add (1000/40, (GSourceFunc) pointer_update, (gpointer) window); g_timeout_add (10000, (GSourceFunc) quit, NULL); // "clear" input-mask, set title/icon/attributes gtk_widget_set_app_paintable (window, TRUE); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_window_set_accept_focus (GTK_WINDOW (window), FALSE); gtk_widget_set_opacity (window, 1.0f); gtk_widget_set_size_request (window, (gint) (BUBBLE_WIDTH + 2.0f * BUBBLE_SHADOW_SIZE), (gint) (BUBBLE_HEIGHT + 2.0f * BUBBLE_SHADOW_SIZE)); gtk_widget_show (window); g_composited = gdk_screen_is_composited(gtk_widget_get_screen (window)); update_input_shape (window, 1, 1); update_shape (window, (gint) CORNER_RADIUS, (gint) BUBBLE_SHADOW_SIZE); set_bg_blur (window, TRUE); setup_tile ((gint) (BUBBLE_WIDTH + 2.0f * BUBBLE_SHADOW_SIZE), (gint) (BUBBLE_HEIGHT + 2.0f * BUBBLE_SHADOW_SIZE)); g_text = setup_text_tile (gdk_screen_get_font_options ( gtk_widget_get_screen (window)), gdk_screen_get_resolution ( gtk_widget_get_screen (window)), (gint) (BUBBLE_WIDTH - 2*BUBBLE_SHADOW_SIZE), (gint) (3.0f * BUBBLE_HEIGHT)); g_print ("This test will run for 10 seconds and then quit.\n"); gtk_main (); tile_destroy (g_tile); tile_destroy (g_text); return 0; } ./tests/test-withlib.c0000644000004100000410000002501613570225707015204 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-withlib.c - libnotify based unit-tests ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include "dbus.h" #include "stack.h" #include "config.h" /* #define DBUS_NAME "org.freedesktop.Notifications" */ static gboolean stop_main_loop (GMainLoop *loop) { g_main_loop_quit (loop); return FALSE; } static void test_withlib_setup (gpointer fixture, gconstpointer user_data) { notify_init ("libnotify"); } static void test_withlib_get_server_information (gpointer fixture, gconstpointer user_data) { gchar *name = NULL, *vendor = NULL, *version = NULL, *specver = NULL; gboolean ret = FALSE; ret = notify_get_server_info (&name, &vendor, &version, &specver); g_assert (ret); g_assert (g_strrstr (name, "notify-osd")); g_assert (g_strrstr (specver, "1.1")); } static void test_withlib_get_server_caps (gpointer fixture, gconstpointer user_data) { GList *cap, *caps = NULL; gboolean test = FALSE; caps = notify_get_server_caps (); g_assert (caps); for (cap = g_list_first (caps); cap != NULL; cap = g_list_next (cap)) { if (!g_strcmp0 (cap->data, "x-canonical-private-synchronous") || !g_strcmp0 (cap->data, "x-canonical-append") || !g_strcmp0 (cap->data, "x-canonical-private-icon-only") || !g_strcmp0 (cap->data, "x-canonical-truncation")) test = TRUE; } g_assert (test); } static void test_withlib_show_notification (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; n = notify_notification_new ("Test", "You should see a normal notification", ""); notify_notification_show (n, NULL); sleep (3); g_object_unref(G_OBJECT(n)); } static void test_withlib_update_notification (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; gboolean res = FALSE; n = notify_notification_new ("Test", "New notification", ""); res = notify_notification_show (n, NULL); g_assert (res); sleep (1); res = notify_notification_update (n, "Test (updated)", "The message body has been updated...", ""); g_assert (res); res = notify_notification_show (n, NULL); g_assert (res); sleep (3); g_object_unref(G_OBJECT(n)); } static void test_withlib_pass_icon_data (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; GdkPixbuf* pixbuf; GMainLoop* loop; n = notify_notification_new ("Image Test", "You should see an image", ""); g_print ("iconpath: %s\n", SRCDIR"/icons/avatar.png"); pixbuf = gdk_pixbuf_new_from_file_at_scale (SRCDIR"/icons/avatar.png", 64, 64, TRUE, NULL); notify_notification_set_icon_from_pixbuf (n, pixbuf); notify_notification_show (n, NULL); loop = g_main_loop_new(NULL, FALSE); g_timeout_add (2000, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); g_object_unref(G_OBJECT(n)); } static void test_withlib_priority (gpointer fixture, gconstpointer user_data) { NotifyNotification *n1, *n2, *n3, *n4; GMainLoop* loop; n1 = notify_notification_new ("Dummy Notification", "This is a test notification", ""); notify_notification_show (n1, NULL); n2 = notify_notification_new ("Normal Notification", "You should see this *after* the urgent notification.", ""); notify_notification_set_urgency (n2, NOTIFY_URGENCY_LOW); notify_notification_show (n2, NULL); n3 = notify_notification_new ("Synchronous Notification", "You should immediately see this notification.", ""); notify_notification_set_hint_string (n3, "synchronous", "test"); notify_notification_set_urgency (n3, NOTIFY_URGENCY_NORMAL); notify_notification_show (n3, NULL); n4 = notify_notification_new ("Urgent Notification", "You should see a dialog box, and after, a normal notification.", ""); notify_notification_set_urgency (n4, NOTIFY_URGENCY_CRITICAL); notify_notification_show (n4, NULL); loop = g_main_loop_new(NULL, FALSE); g_timeout_add (8000, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); g_object_unref(G_OBJECT(n1)); g_object_unref(G_OBJECT(n2)); g_object_unref(G_OBJECT(n3)); g_object_unref(G_OBJECT(n4)); } static GMainLoop* loop; static char* test_action_callback_data = "Some string to pass to the action callback"; static void callback (NotifyNotification *n, const char *action, void *user_data) { g_assert (g_strcmp0 (action, "action") == 0); g_assert (user_data == test_action_callback_data); g_main_loop_quit (loop); } static void test_withlib_actions (gpointer fixture, gconstpointer user_data) { NotifyNotification *n1; n1 = notify_notification_new ("Notification with an action", "You should see that in a dialog box. Click the 'Action' button for the test to succeed.", ""); notify_notification_add_action (n1, "action", "Action", (NotifyActionCallback)callback, test_action_callback_data, NULL); notify_notification_show (n1, NULL); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run (loop); g_object_unref(G_OBJECT(n1)); } static void test_withlib_close_notification (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; GMainLoop* loop; gboolean res = FALSE; n = notify_notification_new ("Test Title", "This notification will be closed prematurely...", ""); notify_notification_show (n, NULL); loop = g_main_loop_new(NULL, FALSE); g_timeout_add (1000, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); res = notify_notification_close (n, NULL); g_assert (res); g_timeout_add (2000, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); g_object_unref(G_OBJECT(n)); } static void test_withlib_append_hint (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; gboolean res = FALSE; /* init notification, supply first line of body-text */ n = notify_notification_new ("Test (append-hint)", "The quick brown fox jumps over the lazy dog.", SRCDIR"/icons/avatar.png"); res = notify_notification_show (n, NULL); g_assert (res); sleep (1); /* append second part of body-text */ res = notify_notification_update (n, " ", "Polyfon zwitschernd aßen Mäxchens Vögel Rüben, Joghurt und Quark. (first append)", NULL); notify_notification_set_hint_string (n, "append", "allowed"); g_assert (res); res = notify_notification_show (n, NULL); g_assert (res); sleep (1); /* append third part of body-text */ res = notify_notification_update (n, " ", "Съешь ещё этих мягких французских булок, да выпей чаю. (last append)", NULL); notify_notification_set_hint_string (n, "append", "allowed"); g_assert (res); res = notify_notification_show (n, NULL); g_assert (res); sleep (1); g_object_unref(G_OBJECT(n)); } static void test_withlib_icon_only_hint (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; gboolean res = FALSE; /* init notification, supply first line of body-text */ n = notify_notification_new (" ", /* needs this to be non-NULL */ NULL, "notification-audio-play"); notify_notification_set_hint_string (n, "icon-only", "allowed"); res = notify_notification_show (n, NULL); g_assert (res); sleep (1); g_object_unref(G_OBJECT(n)); } static void test_withlib_swallow_markup (gpointer fixture, gconstpointer user_data) { NotifyNotification *n; gboolean res = FALSE; n = notify_notification_new ("Swallow markup test", "This text is hopefully neither bold, italic nor underlined.\n\nA little math-notation:\n\n\ta > b < c = 0", SRCDIR"/icons/avatar.png"); res = notify_notification_show (n, NULL); g_assert (res); sleep (2); g_object_unref(G_OBJECT(n)); } static void test_withlib_throttle (gpointer fixture, gconstpointer user_data) { NotifyNotification* n; gint i; gboolean res; gchar buf[20]; GError* error = NULL; // see https://wiki.ubuntu.com/NotifyOSD#Flood%20prevention for (i = 0; i < MAX_STACK_SIZE + 10; i++) { // pretty-ify the output a bit if (i == 0) g_print ("\n"); // create dummy notification snprintf (buf, 19, "Test #%.2d", i); n = notify_notification_new (buf, buf, ""); // inject it into the queue res = notify_notification_show (n, &error); // spit out error from notification-daemon if (!res && error) { g_print ("Error \"%s\" while trying to show #%.2d\n", error->message, i); g_error_free (error); error = NULL; } // check if reaching limit causes error if (i > MAX_STACK_SIZE) g_assert (!res); g_object_unref (n); } } GTestSuite * test_withlib_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("libnotify"); #define ADD_TEST(x) g_test_suite_add(ts, \ g_test_create_case(#x, 0, NULL, test_withlib_setup, x, NULL) \ ) ADD_TEST(test_withlib_get_server_information); ADD_TEST(test_withlib_get_server_caps); ADD_TEST(test_withlib_show_notification); ADD_TEST(test_withlib_update_notification); ADD_TEST(test_withlib_pass_icon_data); ADD_TEST(test_withlib_close_notification); ADD_TEST(test_withlib_priority); ADD_TEST(test_withlib_append_hint); ADD_TEST(test_withlib_icon_only_hint); ADD_TEST(test_withlib_swallow_markup); // FIXME: Disable action test until we can make it non-interactive //ADD_TEST(test_withlib_actions); ADD_TEST(test_withlib_throttle); return ts; } ./tests/test-alpha-animation.c0000644000004100000410000000407313570225707016604 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-alpha-animation.c - implements unit-tests for egg/clutter alphas ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include #include static void fade_cb (EggTimeline *timeline, gint frame_no, EggAlpha *alpha) { g_debug ("new frame %d, alpha=%d", frame_no, egg_alpha_get_alpha (alpha)); } static void completed_cb (EggTimeline *timeline, gpointer *state) { g_debug ("completed"); exit (EXIT_SUCCESS); } int main (int argc, char **argv) { EggTimeline *timeline; EggAlpha *alpha; timeline = egg_timeline_new_for_duration (700); alpha = egg_alpha_new_full (timeline, EGG_ALPHA_SINE_DEC, NULL, NULL); g_signal_connect (G_OBJECT(timeline), "completed", G_CALLBACK(completed_cb), NULL); g_signal_connect (G_OBJECT(timeline), "new-frame", G_CALLBACK(fade_cb), alpha); egg_timeline_start (timeline); egg_main (); return EXIT_FAILURE; } ./tests/test-text-filtering.c0000644000004100000410000001404113570225707016503 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-text-filtering.c - unit-tests for text filtering ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Cody Russell ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include "util.h" typedef struct { const gchar *before; const gchar *expected; } TextComparisons; typedef struct { const gchar* before; guint expected; } IntegerExtraction; static void test_text_filter () { static const TextComparisons tests[] = { { "Ubuntu", "Ubuntu" }, { "Don't rock the boat", "Don't rock the boat" }, { "Kick him while he's down", "Kick him while he's down" }, { "\"Film spectators are quiet vampires.\"", "\"Film spectators are quiet vampires.\"" }, { "Peace & Love", "Peace & Love" }, { "War & Peace", "War & Peace" }, { "Law & Order", "Law & Order" }, { "Love & War", "Love & War" }, { "7 > 3", "7 > 3" }, { "7 > 3", "7 > 3" }, { "7 > 3", "7 > 3" }, { "7 > 3", "7 > 3" }, { "14 < 42", "14 < 42" }, { "14 < 42", "14 < 42" }, { "14 < 42", "14 < 42" }, { "14 < 42", "14 < 42" }, { "><", "><" }, { "<>", "<>" }, { "< this is not a tag >", "< this is not a tag >" }, { "Not italic", "Not italic" }, { "So broken", "So broken" }, { "Nothing to see", "Nothing to see" }, { "Test", "Test" }, { "Bold", "Bold" }, { "Span", "Span" }, { "E-flat", "E-flat" }, { "Sandwich", "Sandwich", }, { "Fry", "Fry" }, { "Testing tag", "Testing tag" }, { "Surrounded by html", "Surrounded by html" }, { "Surrounded by qt", "Surrounded by qt" }, { "First line
\r \n Second line", "First line\nSecond line" }, { "First line\n

\n2nd line\r\n3rd line", "First line\n2nd line\n3rd line" }, { NULL, NULL } }; for (int i = 0; tests[i].before != NULL; i++) { char *filtered = filter_text (tests[i].before); g_assert_cmpstr (filtered, ==, tests[i].expected); g_free (filtered); } } static void test_newline_to_space () { static const TextComparisons tests[] = { { "one\ntwo\nthree\nfour\nfive\nsix", "one two three four five six" }, { "1\n2\n3\n4\n5\n6", "1 2 3 4 5 6" }, { NULL, NULL } }; for (int i = 0; tests[i].before != NULL; i++) { char *filtered = newline_to_space (tests[i].before); g_assert_cmpstr (filtered, ==, tests[i].expected); g_free (filtered); } } static void test_extract_font_face () { static const TextComparisons tests[] = { { "", "" }, { "Sans 10", "Sans " }, { "Candara 9", "Candara " }, { "Bitstream Vera Serif Italic 1", "Bitstream Vera Serif Italic " }, { "Calibri Italic 100", "Calibri Italic " }, { "Century Schoolbook L Italic 10", "Century Schoolbook L Italic " }, { NULL, NULL } }; for (int i = 0; tests[i].before != NULL; i++) { GString* filtered = extract_font_face (tests[i].before); g_assert_cmpstr (filtered->str, ==, tests[i].expected); g_string_free (filtered, TRUE); } } GTestSuite * test_filtering_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("text-filter"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_text_filter)); g_test_suite_add(ts, TC(test_newline_to_space)); g_test_suite_add(ts, TC(test_extract_font_face)); return ts; } ./tests/test-timings.c0000644000004100000410000003221613570225707015214 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // test-timings.c - implements unit-tests for exercising API of timings object // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // Notes: // to see timings working in a more obvious way start it with DEBUG=1 set in // the environment (example: "DEBUG=1 ./test-modules -p /timings") // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include "timings.h" gboolean _stop_main_loop (GMainLoop *loop) { g_main_loop_quit (loop); return FALSE; } gboolean _trigger_pause (gpointer data) { Timings* t; g_assert (data); t = TIMINGS (data); g_assert (t); timings_pause (t); return FALSE; } gboolean _trigger_continue (gpointer data) { Timings* t; g_assert (data); t = TIMINGS (data); g_assert (t); timings_continue (t); return FALSE; } gboolean _trigger_start (gpointer data) { Timings* t; g_assert (data); t = TIMINGS (data); g_assert (t); timings_start (t); return FALSE; } gboolean _trigger_stop (gpointer data) { Timings* t; g_assert (data); t = TIMINGS (data); g_assert (t); timings_stop (t); return FALSE; } void _on_completed (gpointer data) { Timings* t; g_print ("\n_on_completed() called\n"); g_assert (data); t = TIMINGS (data); g_assert (t); timings_stop (t); } void _on_limit_reached (gpointer data) { Timings* t; g_print ("\n_on_limit_reached() called\n"); g_assert (data); t = TIMINGS (data); g_assert (t); timings_stop (t); } static void test_timings_new (gpointer fixture, gconstpointer user_data) { Timings* t; guint initial_duration = 1000; guint max_time_limit = 3000; // create new timings-object t = timings_new (initial_duration, max_time_limit); // test validity of main timings-object g_assert (t); // clean up g_object_unref (t); t = NULL; } static void test_timings_start (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new timings-object t = timings_new (initial_duration, max_time_limit); // test validity of timings-object g_assert (t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_extend (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of main notification object g_assert (t); // try to extend without being started g_assert (timings_extend (t, extension) == FALSE); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // try to extend by 1000 ms after being started g_assert (timings_extend (t, extension)); // try to extend by 0 ms g_assert (timings_extend (t, 0) == FALSE); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_pause (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of timings-object g_assert (t); // trigger pause after 500 ms, this will run into _on_limit_reached() g_timeout_add (500, (GSourceFunc) _trigger_pause, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_continue (gpointer fixture, gconstpointer user_data) { Timings* t = NULL; GMainLoop* loop = NULL; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (initial_duration + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of timings-object g_assert (t != NULL); // trigger pause after 500 ms g_timeout_add (500, (GSourceFunc) _trigger_pause, (gpointer) t); // trigger continue after 750 ms, should still end with _on_completed() g_timeout_add (750, (GSourceFunc) _trigger_continue, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_intercept_pause (gpointer fixture, gconstpointer user_data) { Timings* t = NULL; GMainLoop* loop = NULL; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of timings-object g_assert (t); // trigger 1st pause after 500 ms g_timeout_add (500, (GSourceFunc) _trigger_pause, (gpointer) t); // trigger 2nd pause after 750 ms g_timeout_add (750, (GSourceFunc) _trigger_pause, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_intercept_continue (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of main notification object g_assert (t); // trigger pause after 250 ms g_timeout_add (250, (GSourceFunc) _trigger_pause, (gpointer) t); // trigger 1st continue after 500 ms g_timeout_add (500, (GSourceFunc) _trigger_continue, (gpointer) t); // trigger 2nd continue after 750 ms g_timeout_add (750, (GSourceFunc) _trigger_continue, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_intercept_start (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of main notification object g_assert (t); // trigger start after 750 ms g_timeout_add (750, (GSourceFunc) _trigger_start, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } static void test_timings_intercept_stop (gpointer fixture, gconstpointer user_data) { Timings* t; GMainLoop* loop; guint initial_duration = 1000; guint extension = 1000; guint max_time_limit = 3000; // setup the main loop loop = g_main_loop_new (NULL, FALSE); g_timeout_add (max_time_limit + extension, (GSourceFunc) _stop_main_loop, loop); // create new object t = timings_new (initial_duration, max_time_limit); // test validity of main notification object g_assert (t); // trigger stop after initial_duration+extension ms g_timeout_add (initial_duration + extension, (GSourceFunc) _trigger_stop, (gpointer) t); // hook up to "completed" signal g_signal_connect (t, "completed", G_CALLBACK (_on_completed), (gpointer) t); // hook up to "limit-reached" signal g_signal_connect (t, "limit-reached", G_CALLBACK (_on_limit_reached), (gpointer) t); // start the thing timings_start (t); // let the main loop run g_main_loop_run (loop); // clean up g_object_unref (t); t = NULL; } GTestSuite* test_timings_create_test_suite (void) { GTestSuite* ts = NULL; ts = g_test_create_suite ("timings"); g_test_suite_add (ts, g_test_create_case ("can create", 0, NULL, NULL, test_timings_new, NULL)); g_test_suite_add (ts, g_test_create_case ("can start", 0, NULL, NULL, test_timings_start, NULL)); g_test_suite_add (ts, g_test_create_case ("can extend", 0, NULL, NULL, test_timings_extend, NULL)); g_test_suite_add (ts, g_test_create_case ("can pause", 0, NULL, NULL, test_timings_pause, NULL)); g_test_suite_add (ts, g_test_create_case ("can continue", 0, NULL, NULL, test_timings_continue, NULL)); g_test_suite_add (ts, g_test_create_case ("can intercept pause if paused", 0, NULL, NULL, test_timings_intercept_pause, NULL)); g_test_suite_add (ts, g_test_create_case ( "can intercept continue if running", 0, NULL, NULL, test_timings_intercept_continue, NULL)); g_test_suite_add (ts, g_test_create_case ( "can intercept start if started", 0, NULL, NULL, test_timings_intercept_start, NULL)); g_test_suite_add (ts, g_test_create_case ( "can intercept stop if stopped", 0, NULL, NULL, test_timings_intercept_stop, NULL)); return ts; } ./tests/test-dnd.c0000644000004100000410000000707413570225707014313 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-dnd.c - test the do-not-disturb mode code ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include "dnd.h" #include "util.h" #include #define TEST_DBUS_NAME "org.freedesktop.Notificationstest" static gboolean check_fullscreen (GMainLoop *loop) { g_assert (dnd_has_one_fullscreen_window()); g_main_loop_quit (loop); return FALSE; } static gboolean check_no_fullscreen (GMainLoop *loop) { g_assert (!dnd_has_one_fullscreen_window()); g_main_loop_quit (loop); return FALSE; } // FIXME: fails under compiz, needs to be able handle compiz' viewports static WnckWorkspace * find_free_workspace (WnckScreen *screen) { WnckWorkspace *active_workspace = wnck_screen_get_active_workspace (screen); GList *lst = wnck_screen_get_workspaces (screen); if (lst->data != active_workspace) { return WNCK_WORKSPACE(lst->data); } lst = g_list_next (lst); g_assert (lst); return WNCK_WORKSPACE(lst->data); } static void test_dnd_fullscreen (gpointer fixture, gconstpointer user_data) { g_assert (!dnd_has_one_fullscreen_window()); GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_show_now (window); GMainLoop* loop = g_main_loop_new (NULL, FALSE); g_timeout_add (2000, (GSourceFunc) check_fullscreen, loop); g_main_loop_run (loop); // Move window to a free workspace, dnd_has_one_fullscreen_window should // not find it anymore WnckScreen *screen = wnck_screen_get_default (); WnckWindow *wnck_window = wnck_screen_get_active_window (screen); g_assert (wnck_window); WnckWorkspace *free_workspace = find_free_workspace (screen); g_assert (free_workspace); wnck_window_move_to_workspace (wnck_window, free_workspace); g_timeout_add (2000, (GSourceFunc) check_no_fullscreen, loop); g_main_loop_run (loop); gtk_widget_destroy (window); } GTestSuite * test_dnd_create_test_suite (void) { GTestSuite* ts = NULL; gchar* wm_name = NULL; ts = g_test_create_suite ("dnd"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) // FIXME: test_dnd_fullscreen() fails under compiz because of it using // viewports instead of workspaces wm_name = get_wm_name (gdk_x11_display_get_xdisplay (gdk_display_get_default ())); if (wm_name && g_ascii_strcasecmp (WM_NAME_COMPIZ, wm_name)) g_test_suite_add (ts, TC(test_dnd_fullscreen)); else { g_print ("*** WARNING: Skipping /dnd/test_dnd_fullscreen "); g_print ("because it does currently not work under compiz!\n"); } return ts; } ./tests/test-dbus.c0000644000004100000410000000706613570225707014504 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-dbus.c - implements unit-tests for dbus glue-code ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include "dbus.h" #include "stack.h" #define TEST_DBUS_NAME "org.freedesktop.Notificationstest" static void test_dbus_instance (gpointer fixture, gconstpointer user_data) { DBusGConnection* connection = NULL; connection = dbus_create_service_instance (TEST_DBUS_NAME); g_assert (connection != NULL); } static void test_dbus_collision (gpointer fixture, gconstpointer user_data) { //DBusGConnection* connection = NULL; /* HACK: as we did not destroy the instance after the first test above, this second creation should fail */ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) { dbus_create_service_instance (TEST_DBUS_NAME); exit (0); /* should never be triggered */ } g_test_trap_assert_failed(); } static void test_dbus_get_capabilities (gpointer fixture, gconstpointer user_data) { char **caps = NULL; gboolean ret = FALSE; ret = stack_get_capabilities (NULL, &caps); g_assert (ret); g_assert (!g_strcmp0 (caps[0], "body")); int i = 0; while (caps[i] != NULL) { g_assert (!g_strrstr (caps[i++], "actions")); } } static void test_dbus_get_server_information (gpointer fixture, gconstpointer user_data) { gchar *name = NULL, *vendor = NULL, *version = NULL, *specver = NULL; gboolean ret = FALSE; ret = stack_get_server_information (NULL, &name, &vendor, &version, &specver); g_assert (ret); g_assert (g_strrstr (name, "notify-osd")); g_assert (g_strrstr (specver, "1.1")); } GTestSuite * test_dbus_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("dbus"); g_test_suite_add(ts, g_test_create_case ("can create an instance on the bus", 0, NULL, NULL, (GTestFixtureFunc) test_dbus_instance, NULL) ); g_test_suite_add(ts, g_test_create_case ("refuse to have multiple instance on the bus", 0, NULL, NULL, (GTestFixtureFunc) test_dbus_collision, NULL) ); g_test_suite_add(ts, g_test_create_case ("can get server capabilities", 0, NULL, NULL, (GTestFixtureFunc) test_dbus_get_capabilities, NULL) ); g_test_suite_add(ts, g_test_create_case ("can get server info", 0, NULL, NULL, (GTestFixtureFunc) test_dbus_get_server_information, NULL) ); return ts; } ./tests/test-notification.c0000644000004100000410000004122113570225707016224 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // test-notification.c - implements unit-tests for exercising API of abstract // notification object // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #define _XOPEN_SOURCE 500 // needed for usleep() from unistd.h #include #include "notification.h" static void test_notification_new (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; GTimeVal* timestamp; // create new object n = notification_new (); // test validity of main notification object g_assert (n); // test validity of initialized notification object g_assert_cmpint (notification_get_id (n), ==, -1); g_assert (!notification_get_title (n)); g_assert (!notification_get_body (n)); g_assert_cmpint (notification_get_value (n), ==, -2); g_assert (!notification_get_icon_themename (n)); g_assert (!notification_get_icon_filename (n)); g_assert (!notification_get_icon_pixbuf (n)); g_assert_cmpint (notification_get_onscreen_time (n), ==, 0); g_assert (!notification_get_sender_name (n)); g_assert_cmpint (notification_get_sender_pid (n), ==, 0); timestamp = notification_get_timestamp (n); g_assert_cmpint (timestamp->tv_sec, ==, 0); g_assert_cmpint (timestamp->tv_usec, ==, 0); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NONE); // clean up g_object_unref (n); n = NULL; } static void test_notification_destroy (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // test validity of main notification object g_assert (n != NULL); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_id (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if nothing has been set yet it should return -1 g_assert_cmpint (notification_get_id (n), ==, -1); // a negative id should not be stored notification_set_id (n, -3); g_assert_cmpint (notification_get_id (n), >=, -1); // smallest possible id is 0 notification_set_id (n, 0); g_assert_cmpint (notification_get_id (n), ==, 0); // largest possible id is G_MAXINT notification_set_id (n, G_MAXINT); g_assert_cmpint (notification_get_id (n), ==, G_MAXINT); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_title (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no title has been set yet it should return NULL g_assert (notification_get_title (n) == NULL); // set an initial title-text and verify it notification_set_title (n, "Some title text"); g_assert_cmpstr (notification_get_title (n), ==, "Some title text"); // set a new title-text and verify it notification_set_title (n, "The new summary"); g_assert_cmpstr (notification_get_title (n), !=, "Some title text"); g_assert_cmpstr (notification_get_title (n), ==, "The new summary"); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_body (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no body has been set yet it should return NULL g_assert (notification_get_body (n) == NULL); // set an initial body-text and verify it notification_set_body (n, "Example body text"); g_assert_cmpstr (notification_get_body (n), ==, "Example body text"); // set a new body-text and verify it notification_set_body (n, "Some new body text"); g_assert_cmpstr (notification_get_body (n), !=, "Example body text"); g_assert_cmpstr (notification_get_body (n), ==, "Some new body text"); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_value (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no value has been set yet it should return 0 g_assert_cmpint (notification_get_value (n), ==, -2); // set an initial value and verify it notification_set_value (n, 25); g_assert_cmpint (notification_get_value (n), ==, 25); // set a new value and verify it notification_set_value (n, 45); g_assert_cmpint (notification_get_value (n), !=, 25); g_assert_cmpint (notification_get_value (n), ==, 45); // test allowed range notification_set_value (n, NOTIFICATION_VALUE_MAX_ALLOWED + 1); g_assert_cmpint (notification_get_value (n), ==, NOTIFICATION_VALUE_MAX_ALLOWED); notification_set_value (n, NOTIFICATION_VALUE_MIN_ALLOWED - 2); g_assert_cmpint (notification_get_value (n), ==, NOTIFICATION_VALUE_MIN_ALLOWED); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_icon_themename (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no icon-themename has been set yet it should return NULL g_assert (notification_get_icon_themename (n) == NULL); // set an initial icon-themename and verify it notification_set_icon_themename (n, "notification-message-im"); g_assert_cmpstr (notification_get_icon_themename (n), ==, "notification-message-im"); // set a new icon-themename and verify it notification_set_icon_themename (n, "notification-device-usb"); g_assert_cmpstr (notification_get_icon_themename (n), !=, "notification-message-im"); g_assert_cmpstr (notification_get_icon_themename (n), ==, "notification-device-usb"); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_icon_filename (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no icon-filename has been set yet it should return NULL g_assert (notification_get_icon_filename (n) == NULL); // set an initial icon-filename and verify it notification_set_icon_filename (n, "/usr/share/icon/photo.png"); g_assert_cmpstr (notification_get_icon_filename (n), ==, "/usr/share/icon/photo.png"); // set a new icon-filename and verify it notification_set_icon_filename (n, "/tmp/drawing.svg"); g_assert_cmpstr (notification_get_icon_filename (n), !=, "/usr/share/icon/photo.png"); g_assert_cmpstr (notification_get_icon_filename (n), ==, "/tmp/drawing.svg"); // passing an invalid/NULL pointer should not change the stored // icon-filename notification_set_icon_filename (n, NULL); g_assert_cmpstr (notification_get_icon_filename (n), ==, "/tmp/drawing.svg"); // pass an empty (but not NULL) strings notification_set_icon_filename (n, ""); g_assert_cmpstr (notification_get_icon_filename (n), ==, ""); notification_set_icon_filename (n, "\0"); g_assert_cmpstr (notification_get_icon_filename (n), ==, "\0"); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_icon_pixbuf (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; GdkPixbuf* pixbuf = NULL; // create new object n = notification_new (); // if no icon-pixbuf has been set yet it should return NULL g_assert (notification_get_icon_pixbuf (n) == NULL); // create pixbuf for testing pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 100, 100); // set an initial icon-pixbuf and verify it g_assert (pixbuf); notification_set_icon_pixbuf (n, pixbuf); g_assert (notification_get_icon_pixbuf (n) != NULL); // passing an invalid/NULL pointer should not change the stored // icon-pixbuf notification_set_icon_pixbuf (n, NULL); g_assert (notification_get_icon_pixbuf (n) != NULL); // clean up g_object_unref (n); n = NULL; // more clean up g_object_unref (pixbuf); pixbuf = NULL; } static void test_notification_setget_onscreen_time (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no onscreen-time has been set yet it should return 0 g_assert_cmpint (notification_get_onscreen_time (n), ==, 0); // setting a negative onscreen-time should fail notification_set_onscreen_time (n, -1); g_assert_cmpint (notification_get_onscreen_time (n), ==, 0); // set an positive onscreen-time and verify it notification_set_onscreen_time (n, 1000); g_assert_cmpint (notification_get_onscreen_time (n), ==, 1000); // set a new onscreen-time and verify it notification_set_onscreen_time (n, 5000); g_assert_cmpint (notification_get_onscreen_time (n), !=, 1000); g_assert_cmpint (notification_get_onscreen_time (n), ==, 5000); // setting a new onscreen-time smaller than the currently stored one // should fail notification_set_onscreen_time (n, 4000); g_assert_cmpint (notification_get_onscreen_time (n), ==, 5000); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_sender_name (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no sender-name has been set yet it should return NULL g_assert (notification_get_sender_name (n) == NULL); // set an initial sender-name and verify it notification_set_sender_name (n, "evolution"); g_assert_cmpstr (notification_get_sender_name (n), ==, "evolution"); // set a new sender-name and verify it notification_set_sender_name (n, "pidgin"); g_assert_cmpstr (notification_get_sender_name (n), !=, "evolution"); g_assert_cmpstr (notification_get_sender_name (n), ==, "pidgin"); // passing an invalid/NULL pointer should not change the stored // sender-name notification_set_sender_name (n, NULL); g_assert_cmpstr (notification_get_sender_name (n), ==, "pidgin"); // pass an empty (but not NULL) strings notification_set_sender_name (n, ""); g_assert_cmpstr (notification_get_sender_name (n), ==, ""); notification_set_sender_name (n, "\0"); g_assert_cmpstr (notification_get_sender_name (n), ==, "\0"); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_sender_pid (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if nothing has been set yet it should return 0 g_assert_cmpint (notification_get_sender_pid (n), ==, 0); // a negative pid makes no sense and should therefore not be stored notification_set_sender_pid (n, -1); g_assert_cmpint (notification_get_sender_pid (n), ==, 0); // smallest possible pid is 1 notification_set_sender_pid (n, 1); g_assert_cmpint (notification_get_sender_pid (n), ==, 1); // largest possible id is G_MAXINT notification_set_sender_pid (n, G_MAXINT); g_assert_cmpint (notification_get_sender_pid (n), ==, G_MAXINT); // a pid of 0 would mean something before the init process is sending us // a notification, leave the stored pid untouched notification_set_sender_pid (n, 0); g_assert_cmpint (notification_get_sender_pid (n), ==, G_MAXINT); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_timestamp (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; GTimeVal* tvptr = NULL; GTimeVal tv_old; GTimeVal tv_new; // create new object n = notification_new (); // if no reception-time has been set yet it should return 0/0 tvptr = notification_get_timestamp (n); g_assert_cmpint (tvptr->tv_sec, ==, 0); g_assert_cmpint (tvptr->tv_usec, ==, 0); // ehm... well, get current time g_get_current_time (&tv_old); // store current time as reception-time and verify it notification_set_timestamp (n, &tv_old); tvptr = notification_get_timestamp (n); g_assert_cmpint (tvptr->tv_sec, ==, tv_old.tv_sec); g_assert_cmpint (tvptr->tv_usec, ==, tv_old.tv_usec); // wait at least two seconds sleep (2); // get current time g_get_current_time (&tv_new); // trying to store an older timestamp over a newer one should fail // second-granularity notification_set_timestamp (n, &tv_new); notification_set_timestamp (n, &tv_old); tvptr = notification_get_timestamp (n); g_assert_cmpint (tvptr->tv_sec, !=, tv_old.tv_sec); g_assert_cmpint (tvptr->tv_sec, ==, tv_new.tv_sec); // get current time g_get_current_time (&tv_old); notification_set_timestamp (n, &tv_old); // wait some micro-seconds usleep (10000); // get current time g_get_current_time (&tv_new); // trying to store an older timestamp over a newer one should fail // microsecond-granularity notification_set_timestamp (n, &tv_new); notification_set_timestamp (n, &tv_old); tvptr = notification_get_timestamp (n); g_assert_cmpint (tvptr->tv_usec, !=, tv_old.tv_usec); g_assert_cmpint (tvptr->tv_usec, ==, tv_new.tv_usec); // clean up g_object_unref (n); n = NULL; } static void test_notification_setget_urgency (gpointer fixture, gconstpointer user_data) { Notification* n = NULL; // create new object n = notification_new (); // if no urgency has been set yet it should return urgency-none g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NONE); // test all three urgency-levels notification_set_urgency (n, URGENCY_HIGH); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_HIGH); notification_set_urgency (n, URGENCY_LOW); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_LOW); notification_set_urgency (n, URGENCY_NORMAL); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NORMAL); // test non-urgency levels, last valid urgency should be returned notification_set_urgency (n, 5); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NORMAL); notification_set_urgency (n, 23); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NORMAL); notification_set_urgency (n, -2); g_assert_cmpint (notification_get_urgency (n), ==, URGENCY_NORMAL); // clean up g_object_unref (n); n = NULL; } GTestSuite * test_notification_create_test_suite (void) { GTestSuite *ts = NULL; GTestCase *tc = NULL; ts = g_test_create_suite ("notification"); tc = g_test_create_case ("can create", 0, NULL, NULL, test_notification_new, NULL); g_test_suite_add (ts, tc); g_test_suite_add ( ts, g_test_create_case ( "can destroy", 0, NULL, NULL, test_notification_destroy, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get id", 0, NULL, NULL, test_notification_setget_id, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get title", 0, NULL, NULL, test_notification_setget_title, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get body", 0, NULL, NULL, test_notification_setget_body, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get value", 0, NULL, NULL, test_notification_setget_value, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get icon-themename", 0, NULL, NULL, test_notification_setget_icon_themename, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get icon-filename", 0, NULL, NULL, test_notification_setget_icon_filename, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get icon-pixbuf", 0, NULL, NULL, test_notification_setget_icon_pixbuf, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get onscreen-time", 0, NULL, NULL, test_notification_setget_onscreen_time, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get sender-name", 0, NULL, NULL, test_notification_setget_sender_name, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get sender-pid", 0, NULL, NULL, test_notification_setget_sender_pid, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get timestamp", 0, NULL, NULL, test_notification_setget_timestamp, NULL)); g_test_suite_add ( ts, g_test_create_case ( "can set|get urgency", 0, NULL, NULL, test_notification_setget_urgency, NULL)); return ts; } ./tests/test-stack.c0000644000004100000410000001520413570225707014645 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-stack.c - unit-tests for stack class ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include "stack.h" #include "defaults.h" #include "bubble.h" static void test_stack_new () { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); stack = stack_new (defaults, observer); g_assert (stack != NULL); } static void test_stack_del () { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); stack = stack_new (defaults, observer); stack_del (stack); } static void test_stack_push () { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); Bubble* bubble = bubble_new (defaults); guint id = -1; guint replaced_id = -1; stack = stack_new (defaults, observer); id = stack_push_bubble (stack, bubble); g_assert (id > 0); replaced_id = stack_push_bubble (stack, bubble); g_assert (replaced_id == id); g_object_unref (G_OBJECT (stack)); } static void test_stack_slots () { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); gint x; gint y; Bubble* one; Bubble* two; stack = stack_new (defaults, observer); // check if stack_is_slot_vacant() can take "crap" without crashing g_assert_cmpint (stack_is_slot_vacant (NULL, SLOT_TOP), ==, FALSE); g_assert_cmpint (stack_is_slot_vacant (stack, 832), ==, FALSE); g_assert_cmpint (stack_is_slot_vacant (NULL, 4321), ==, FALSE); // check if stack_get_slot_position can take "crap" without crashing stack_get_slot_position (NULL, SLOT_TOP, 0, &x, &y); g_assert_cmpint (x, ==, -1); g_assert_cmpint (y, ==, -1); stack_get_slot_position (stack, 4711, 0, &x, &y); g_assert_cmpint (x, ==, -1); g_assert_cmpint (y, ==, -1); stack_get_slot_position (NULL, 42, 0, NULL, NULL); // check if stack_allocate_slot() can take "crap" without crashing one = bubble_new (defaults); two = bubble_new (defaults); g_assert_cmpint (stack_allocate_slot (NULL, one, SLOT_TOP), ==, FALSE); g_assert_cmpint (stack_allocate_slot (stack, NULL, SLOT_TOP), ==, FALSE); g_assert_cmpint (stack_allocate_slot (stack, one, 4711), ==, FALSE); // check if stack_free_slot() can take "crap" without crashing g_assert_cmpint (stack_free_slot (NULL, two), ==, FALSE); g_assert_cmpint (stack_free_slot (stack, NULL), ==, FALSE); // initially both slots should be empty g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, VACANT); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, VACANT); g_object_unref (one); g_object_unref (two); // fill top slot, verify it's occupied, free it, verify again one = bubble_new (defaults); g_assert_cmpint (stack_allocate_slot (stack, one, SLOT_TOP), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, OCCUPIED); g_assert_cmpint (stack_free_slot (stack, one), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, VACANT); g_object_unref (one); // fill bottom slot, verify it's occupied, free it, verify again two = bubble_new (defaults); g_assert_cmpint (stack_allocate_slot (stack, two, SLOT_BOTTOM), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, OCCUPIED); g_assert_cmpint (stack_free_slot (stack, two), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, VACANT); g_object_unref (two); // try to free vacant slots one = bubble_new (defaults); two = bubble_new (defaults); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, VACANT); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, VACANT); g_assert_cmpint (stack_free_slot (stack, one), ==, FALSE); g_assert_cmpint (stack_free_slot (stack, two), ==, FALSE); g_object_unref (one); g_object_unref (two); // allocate top slot, verify, try to allocate top slot again one = bubble_new (defaults); two = bubble_new (defaults); g_assert_cmpint (stack_allocate_slot (stack, one, SLOT_TOP), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, OCCUPIED); g_assert_cmpint (stack_allocate_slot (stack, two, SLOT_TOP), ==, FALSE); g_assert_cmpint (stack_free_slot (stack, one), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_TOP), ==, VACANT); g_object_unref (one); g_object_unref (two); // allocate bottom slot, verify, try to allocate bottom slot again one = bubble_new (defaults); two = bubble_new (defaults); g_assert_cmpint (stack_allocate_slot (stack, one, SLOT_BOTTOM), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, OCCUPIED); g_assert_cmpint (stack_allocate_slot (stack, two, SLOT_BOTTOM), ==, FALSE); g_assert_cmpint (stack_free_slot (stack, one), ==, TRUE); g_assert_cmpint (stack_is_slot_vacant (stack, SLOT_BOTTOM), ==, VACANT); g_object_unref (one); g_object_unref (two); // check if we can get reasonable values from stack_get_slot_position() // FIXME: disabled this test for the moment, hopefully it works within // a real environment /*stack_get_slot_position (stack, SLOT_TOP, &x, &y); g_assert_cmpint (x, >, -1); g_assert_cmpint (y, >, -1); stack_get_slot_position (stack, SLOT_BOTTOM, &x, &y); g_assert_cmpint (x, >, -1); g_assert_cmpint (y, >, -1);*/ g_object_unref (G_OBJECT (stack)); } GTestSuite * test_stack_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("stack"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_stack_new)); g_test_suite_add(ts, TC(test_stack_del)); g_test_suite_add(ts, TC(test_stack_push)); g_test_suite_add(ts, TC(test_stack_slots)); return ts; } ./tests/test-modules-main.c0000644000004100000410000000602013570225707016126 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-modules-main.c - pulling together all the unit-tests ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include /* Declare entries located in the individual test modules (avoids a superflous .h file) */ GTestSuite *test_bubble_create_test_suite (void); GTestSuite *test_defaults_create_test_suite (void); GTestSuite *test_notification_create_test_suite (void); GTestSuite *test_observer_create_test_suite (void); GTestSuite *test_stack_create_test_suite (void); GTestSuite *test_dbus_create_test_suite (void); GTestSuite *test_apport_create_test_suite (void); GTestSuite *test_i18n_create_test_suite (void); GTestSuite *test_withlib_create_test_suite (void); GTestSuite *test_synchronous_create_test_suite (void); GTestSuite *test_dnd_create_test_suite (void); GTestSuite *test_filtering_create_test_suite (void); GTestSuite *test_timings_create_test_suite (void); int main (int argc, char** argv) { gint result; g_test_init (&argc, &argv, NULL); gtk_init (&argc, &argv); GTestSuite *suite = NULL; suite = g_test_get_root (); g_test_suite_add_suite (suite, test_bubble_create_test_suite ()); g_test_suite_add_suite (suite, test_defaults_create_test_suite ()); g_test_suite_add_suite (suite, test_notification_create_test_suite ()); g_test_suite_add_suite (suite, test_observer_create_test_suite ()); g_test_suite_add_suite (suite, test_stack_create_test_suite ()); g_test_suite_add_suite (suite, test_filtering_create_test_suite ()); g_test_suite_add_suite (suite, test_dbus_create_test_suite ()); g_test_suite_add_suite (suite, test_apport_create_test_suite ()); g_test_suite_add_suite (suite, test_i18n_create_test_suite ()); g_test_suite_add_suite (suite, test_withlib_create_test_suite ()); g_test_suite_add_suite (suite, test_synchronous_create_test_suite ()); g_test_suite_add_suite (suite, test_dnd_create_test_suite ()); g_test_suite_add_suite (suite, test_timings_create_test_suite ()); result = g_test_run (); return result; } ./tests/test-grow-bubble.c0000644000004100000410000004621313570225707015753 0ustar www-datawww-data//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // test-grow-bubble // // test-grow-bubble.c - test using tile to animate growing bubble // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include "raico-blur.h" #include "tile.h" #include "util.h" #define BUBBLE_SHADOW_SIZE 10.0f #define CORNER_RADIUS 6.0f #define BUBBLE_WIDTH 320.0f #define BUBBLE_HEIGHT 125.0f #define BUBBLE_BG_COLOR_R 0.2f #define BUBBLE_BG_COLOR_G 0.2f #define BUBBLE_BG_COLOR_B 0.2f #define POS_X 0 #define POS_Y 30 gboolean g_composited = FALSE; gboolean g_mouse_over = FALSE; tile_t* g_tile = NULL; gfloat g_distance = 1.0f; gfloat g_step = 5.0f; void draw_round_rect (cairo_t* cr, gdouble aspect, /* aspect-ratio */ gdouble x, /* top-left corner */ gdouble y, /* top-left corner */ gdouble corner_radius, /* "size" of the corners */ gdouble width, /* width of the rectangle */ gdouble height /* height of the rectangle */) { gdouble radius = corner_radius / aspect; /* top-left, right of the corner */ cairo_move_to (cr, x + radius, y); /* top-right, left of the corner */ cairo_line_to (cr, x + width - radius, y); /* top-right, below the corner */ cairo_arc (cr, x + width - radius, y + radius, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); /* bottom-right, above the corner */ cairo_line_to (cr, x + width, y + height - radius); /* bottom-right, left of the corner */ cairo_arc (cr, x + width - radius, y + height - radius, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); /* bottom-left, right of the corner */ cairo_line_to (cr, x + radius, y + height); /* bottom-left, above the corner */ cairo_arc (cr, x + radius, y + height - radius, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); /* top-left, below the corner */ cairo_line_to (cr, x, y + radius); /* top-left, right of the corner */ cairo_arc (cr, x + radius, y + radius, radius, 180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f); } void screen_changed_handler (GtkWidget* window, GdkScreen* old_screen, gpointer data) { GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (window)); GdkVisual* visual = gdk_screen_get_rgba_visual (screen); if (!visual) visual = gdk_screen_get_system_visual (screen); gtk_widget_set_visual (GTK_WIDGET (window), visual); } static void update_input_shape (GtkWidget* window, gint width, gint height) { cairo_region_t* region = NULL; const cairo_rectangle_int_t rect = {0, 0, 1, 1}; region = cairo_region_create_rectangle (&rect); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_input_shape_combine_region (window, NULL); gtk_widget_input_shape_combine_region (window, region); } } static void update_shape (GtkWidget* window, gint radius, gint shadow_size) { if (g_composited) { /* remove any current shape-mask */ gtk_widget_input_shape_combine_region (window, NULL); return; } int width; int height; gtk_widget_get_size_request (window, &width, &height); const cairo_rectangle_int_t rects[] = {{2, 0, width - 4, height}, {1, 1, width - 2, height - 2}, {0, 2, width, height - 4}}; cairo_region_t* region = NULL; region = cairo_region_create_rectangles (rects, 3); if (cairo_region_status (region) == CAIRO_STATUS_SUCCESS) { gtk_widget_shape_combine_region (window, NULL); gtk_widget_shape_combine_region (window, region); } } void composited_changed_handler (GtkWidget* window, gpointer data) { g_composited = gdk_screen_is_composited(gtk_widget_get_screen (window)); update_shape (window, (gint) CORNER_RADIUS, (gint) BUBBLE_SHADOW_SIZE); } void draw_shadow (cairo_t* cr, gdouble width, gdouble height, gint shadow_radius, gint corner_radius) { cairo_surface_t* tmp_surface = NULL; cairo_surface_t* new_surface = NULL; cairo_pattern_t* pattern = NULL; cairo_t* cr_surf = NULL; cairo_matrix_t matrix; raico_blur_t* blur = NULL; tmp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4 * shadow_radius, 4 * shadow_radius); if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS) return; cr_surf = cairo_create (tmp_surface); if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); return; } cairo_scale (cr_surf, 1.0f, 1.0f); cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR); cairo_paint (cr_surf); cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 0.75f); cairo_arc (cr_surf, 2 * shadow_radius, 2 * shadow_radius, 2.0f * corner_radius, 0.0f, 360.0f * (G_PI / 180.f)); cairo_fill (cr_surf); cairo_destroy (cr_surf); // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, shadow_radius); // now blur it raico_blur_apply (blur, tmp_surface); // blur no longer needed raico_blur_destroy (blur); new_surface = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (tmp_surface), cairo_image_surface_get_format (tmp_surface), cairo_image_surface_get_width (tmp_surface) / 2, cairo_image_surface_get_height (tmp_surface) / 2, cairo_image_surface_get_stride (tmp_surface)); pattern = cairo_pattern_create_for_surface (new_surface); if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); return; } // top left cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_rectangle (cr, 0.0f, 0.0f, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // bottom left cairo_matrix_init_scale (&matrix, 1.0f, -1.0f); cairo_matrix_translate (&matrix, 0.0f, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 0.0f, 2 * shadow_radius, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // top right cairo_matrix_init_scale (&matrix, -1.0f, 1.0f); cairo_matrix_translate (&matrix, -width, 0.0f); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, width - 2 * shadow_radius, 0.0f, 2 * shadow_radius, height - 2 * shadow_radius); cairo_fill (cr); // bottom right cairo_matrix_init_scale (&matrix, -1.0f, -1.0f); cairo_matrix_translate (&matrix, -width, -height); cairo_pattern_set_matrix (pattern, &matrix); cairo_rectangle (cr, 2 * shadow_radius, height - 2 * shadow_radius, width - 2 * shadow_radius, 2 * shadow_radius); cairo_fill (cr); // clean up cairo_pattern_destroy (pattern); cairo_surface_destroy (tmp_surface); cairo_surface_destroy (new_surface); } gboolean expose_handler (GtkWidget* window, cairo_t* cr, gpointer data) { GtkAllocation a; gtk_widget_get_allocation (window, &a); /* clear and render drop-shadow and bubble-background */ cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_distance < 1.0f) { tile_paint_with_padding (g_tile, cr, 0.0f, 0.0f, a.width, a.height, g_distance, 1.0f - g_distance); gtk_widget_set_opacity (window, 0.3f + g_distance * 0.7f); } else { tile_paint_with_padding (g_tile, cr, 0.0f, 0.0f, a.width, a.height, g_distance, 0.0f); gtk_widget_set_opacity (window, 1.0f); } return TRUE; } void set_bg_blur (GtkWidget* window, gboolean blur) { GtkAllocation a; GdkWindow *gdkwindow; gint shadow = BUBBLE_SHADOW_SIZE; if (!window) return; gtk_widget_get_allocation (window, &a); gdkwindow = gtk_widget_get_window (window); if (blur) { glong data[] = { 2, /* threshold */ 0, /* filter */ NorthWestGravity, /* gravity of top-left */ shadow, /* x-coord of top-left */ -a.height/2 + shadow,/* y-coord of top-left */ NorthWestGravity, /* gravity of bottom-right */ a.width - shadow, /* bottom-right x-coord */ a.height/2 - shadow /* bottom-right y-coord */}; XChangeProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom(GDK_WINDOW_XDISPLAY(gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE), XA_INTEGER, 32, PropModeReplace, (guchar *) data, 8); } else { XDeleteProperty (GDK_WINDOW_XDISPLAY (gdkwindow), GDK_WINDOW_XID (gdkwindow), XInternAtom(GDK_WINDOW_XDISPLAY(gdkwindow), "_COMPIZ_WM_WINDOW_BLUR", FALSE)); } } gboolean quit (gpointer data) { gtk_main_quit (); return FALSE; } gboolean grow (GtkWidget* window); gboolean shrink (GtkWidget* window) { gint width = 0; gint height = 0; if (!GTK_IS_WINDOW (window)) return TRUE; gtk_widget_get_size_request (window, &width, &height); if (g_step <= 2.0f) { g_step = 5.0f; g_timeout_add (1000/40, (GSourceFunc) grow, (gpointer) window); return FALSE; } height -= (gint) g_step; g_step /= 1.125f; gtk_widget_set_size_request (window, width, height); gtk_widget_queue_draw (window); return TRUE; } gboolean grow (GtkWidget* window) { gint width = 0; gint height = 0; if (!GTK_IS_WINDOW (window)) return TRUE; gtk_widget_get_size_request (window, &width, &height); if (g_step <= 2.0f) { g_step = 5.0f; g_timeout_add (1000/40, (GSourceFunc) shrink, (gpointer) window); return FALSE; } height += (gint) g_step; g_step /= 1.125f; gtk_widget_set_size_request (window, width, height); gtk_widget_queue_draw (window); return TRUE; } gboolean pointer_update (GtkWidget* window) { gint pointer_rel_x; gint pointer_rel_y; gint pointer_abs_x; gint pointer_abs_y; gint win_x; gint win_y; gint width; gint height; gboolean old_mouse_over; gfloat old_distance = 0; if (!GTK_IS_WINDOW (window)) return FALSE; old_mouse_over = g_mouse_over; if (gtk_widget_get_realized (window)) { GdkDeviceManager *device_manager; GdkDevice *device; gint distance_x; gint distance_y; device_manager = gdk_display_get_device_manager (gtk_widget_get_display (window)); device = gdk_device_manager_get_client_pointer (device_manager); gdk_window_get_device_position (gtk_widget_get_window (window), device, &pointer_rel_x, &pointer_rel_y, NULL); gtk_window_get_position (GTK_WINDOW (window), &win_x, &win_y); pointer_abs_x = win_x + pointer_rel_x; pointer_abs_y = win_y + pointer_rel_y; gtk_window_get_size (GTK_WINDOW (window), &width, &height); if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width && pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) g_mouse_over = TRUE; else g_mouse_over = FALSE; if (pointer_abs_x >= win_x && pointer_abs_x <= win_x + width) distance_x = 0; else { if (pointer_abs_x < win_x) distance_x = abs (pointer_rel_x); if (pointer_abs_x > win_x + width) distance_x = abs (pointer_rel_x - width); } if (pointer_abs_y >= win_y && pointer_abs_y <= win_y + height) distance_y = 0; else { if (pointer_abs_y < win_y) distance_y = abs (pointer_rel_y); if (pointer_abs_y > win_y + height) distance_y = abs (pointer_rel_y - height); } old_distance = g_distance; g_distance = sqrt (distance_x * distance_x + distance_y * distance_y) / (double) 40; } if (old_mouse_over != g_mouse_over) set_bg_blur (window, !g_mouse_over); if (old_distance != g_distance) gtk_widget_queue_draw (window); return TRUE; } void setup_tile (gint w, gint h) { cairo_status_t status; cairo_t* cr = NULL; cairo_surface_t* cr_surf = NULL; cairo_surface_t* tmp = NULL; cairo_surface_t* dummy_surf = NULL; cairo_surface_t* norm_surf = NULL; cairo_surface_t* blur_surf = NULL; gdouble width = (gdouble) w; gdouble height = (gdouble) h; raico_blur_t* blur = NULL; cr_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE); status = cairo_surface_status (cr_surf); if (status != CAIRO_STATUS_SUCCESS) g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); cr = cairo_create (cr_surf); status = cairo_status (cr); if (status != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (cr_surf); g_print ("Error: \"%s\"\n", cairo_status_to_string (status)); } // clear and render drop-shadow and bubble-background cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (g_composited) { draw_shadow (cr, width, height, BUBBLE_SHADOW_SIZE, CORNER_RADIUS); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); draw_round_rect (cr, 1.0f, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) BUBBLE_SHADOW_SIZE, (gdouble) CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f* BUBBLE_SHADOW_SIZE)); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B, 0.95f); } else cairo_set_source_rgb (cr, BUBBLE_BG_COLOR_R, BUBBLE_BG_COLOR_G, BUBBLE_BG_COLOR_B); draw_round_rect (cr, 1.0f, BUBBLE_SHADOW_SIZE, BUBBLE_SHADOW_SIZE, CORNER_RADIUS, (gdouble) (width - 2.0f * BUBBLE_SHADOW_SIZE), (gdouble) (height - 2.0f * BUBBLE_SHADOW_SIZE)); cairo_fill (cr); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (cr_surf), cairo_image_surface_get_format (cr_surf), 3 * BUBBLE_SHADOW_SIZE, 3 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (cr_surf)); dummy_surf = copy_surface (tmp); cairo_surface_destroy (tmp); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); norm_surf = copy_surface (tmp); cairo_surface_destroy (tmp); blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 6); raico_blur_apply (blur, dummy_surf); raico_blur_destroy (blur); tmp = cairo_image_surface_create_for_data ( cairo_image_surface_get_data (dummy_surf), cairo_image_surface_get_format (dummy_surf), 2 * BUBBLE_SHADOW_SIZE, 2 * BUBBLE_SHADOW_SIZE, cairo_image_surface_get_stride (dummy_surf)); blur_surf = copy_surface (tmp); cairo_surface_destroy (tmp); cairo_surface_destroy (dummy_surf); g_tile = tile_new_for_padding (norm_surf, blur_surf, width, height); cairo_surface_destroy (norm_surf); cairo_surface_destroy (blur_surf); cairo_surface_destroy (cr_surf); cairo_destroy (cr); } int main (int argc, char** argv) { GtkWidget* window; GdkRGBA transparent = {0.0, 0.0, 0.0, 0.0}; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (!window) return 0; gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DOCK); gtk_widget_add_events (window, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); // hook up input/event handlers to window g_signal_connect (G_OBJECT (window), "screen-changed", G_CALLBACK (screen_changed_handler), NULL); g_signal_connect (G_OBJECT (window), "composited-changed", G_CALLBACK (composited_changed_handler), NULL); gtk_window_move (GTK_WINDOW (window), POS_X, POS_Y); // make sure the window opens with a RGBA-visual screen_changed_handler (window, NULL, NULL); gtk_widget_realize (window); gdk_window_set_background_rgba (gtk_widget_get_window (window), &transparent); // hook up window-event handlers to window g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (expose_handler), NULL); // FIXME: read out current mouse-pointer position every 1/25 second g_timeout_add (1000/40, (GSourceFunc) pointer_update, (gpointer) window); g_timeout_add (10000, (GSourceFunc) quit, NULL); g_timeout_add (1000/40, (GSourceFunc) grow, (gpointer) window); // "clear" input-mask, set title/icon/attributes gtk_widget_set_app_paintable (window, TRUE); gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_window_set_accept_focus (GTK_WINDOW (window), FALSE); gtk_widget_set_opacity (window, 1.0f); gtk_widget_set_size_request (window, (gint) (BUBBLE_WIDTH + 2.0f * BUBBLE_SHADOW_SIZE), (gint) (BUBBLE_HEIGHT + 2.0f * BUBBLE_SHADOW_SIZE)); gtk_widget_show (window); g_composited = gdk_screen_is_composited(gtk_widget_get_screen (window)); update_input_shape (window, 1, 1); update_shape (window, (gint) CORNER_RADIUS, (gint) BUBBLE_SHADOW_SIZE); set_bg_blur (window, TRUE); setup_tile ((gint) (BUBBLE_WIDTH + 2.0f * BUBBLE_SHADOW_SIZE), (gint) (BUBBLE_HEIGHT + 2.0f * BUBBLE_SHADOW_SIZE)); g_print ("This test will run for 10 seconds and then quit.\n"); gtk_main (); tile_destroy (g_tile); return 0; } ./tests/test-i18n.c0000644000004100000410000001227013570225707014317 0ustar www-datawww-data/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-i18n.c - unit-tests for internationalization ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller ** David Barth ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . ** *******************************************************************************/ #include #include #include #include "bubble.h" #include "stack.h" #include "observer.h" #include "defaults.h" static gboolean stop_main_loop (GMainLoop *loop) { g_main_loop_quit (loop); return FALSE; } static void wait_a_little (guint interval) { /* let the main loop run to have the slide being performed */ GMainLoop *loop; loop = g_main_loop_new (NULL, FALSE); g_timeout_add (interval, (GSourceFunc) stop_main_loop, loop); g_main_loop_run (loop); } static void test_stack_layout (gpointer fixture, gconstpointer user_data) { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); stack = stack_new (defaults, observer); g_assert (stack != NULL); gtk_widget_set_default_direction (GTK_TEXT_DIR_LTR); Bubble *bubble = bubble_new (defaults); bubble_set_icon (bubble, SRCDIR"/icons/chat.svg"); bubble_set_title (bubble, "LTR Text"); bubble_set_message_body (bubble, "This should be displayed at the right of your screen. Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu"); bubble_determine_layout (bubble); stack_push_bubble (stack, bubble); wait_a_little (10000); stack_del (stack); } static void test_stack_layout_rtl (gpointer fixture, gconstpointer user_data) { Stack* stack = NULL; Defaults* defaults = defaults_new (); Observer* observer = observer_new (); stack = stack_new (defaults, observer); g_assert (stack != NULL); gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL); Bubble *bubble = bubble_new (defaults); bubble_set_icon (bubble, SRCDIR"/icons/chat.svg"); bubble_set_title (bubble, "RTL Text"); bubble_set_message_body (bubble, "This should be displayed at the left of your screen. Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu Ubuntu"); bubble_determine_layout (bubble); stack_push_bubble (stack, bubble); wait_a_little (10000); stack_del (stack); } #define GENERATE(x, y) \ static void x (gpointer fixture, gconstpointer user_data) \ { \ Defaults* defaults = defaults_new (); \ Bubble *bubble = bubble_new (defaults); \ bubble_set_icon (bubble, SRCDIR"/icons/chat.svg"); \ bubble_set_title (bubble, y); \ bubble_set_message_body (bubble, #y#y#y#y#y); \ bubble_determine_layout (bubble); \ bubble_move (bubble, 30, 30); \ bubble_show (bubble); \ wait_a_little (1000); \ g_object_unref (G_OBJECT(bubble)); \ g_object_unref (defaults); \ } GENERATE(en, "About Ubuntu") GENERATE(ca, "Quant a Ubuntu") GENERATE(da, "Om Ubuntu") GENERATE(de, "Über Ubuntu") GENERATE(el, "Περί Ubuntu") GENERATE(es, "Acerca de Ubuntu") GENERATE(fa, "درباره Ubuntu") GENERATE(fi, "Tietoja Ubuntusta") GENERATE(fr, "À propos d'Ubuntu") GENERATE(he, "אודות אובונטו") GENERATE(hu, "Az Ubuntu névjegye") GENERATE(is, "Um Ubuntu") GENERATE(it, "Informazioni su Ubuntu") GENERATE(nl, "Over Ubuntu") GENERATE(pt, "Sobre o Ubuntu") GENERATE(pt_BR, "Sobre o Ubuntu") GENERATE(ro, "Despre Ubuntu") GENERATE(sk, "O Ubuntu") GENERATE(sv, "Om Ubuntu") GENERATE(xh, "Malunga ne-Ubuntu") GENERATE(zh_CN, "关于 Ubuntu") GTestSuite * test_i18n_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("i18n"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_stack_layout)); g_test_suite_add(ts, TC(test_stack_layout_rtl)); g_test_suite_add(ts, TC(en)); g_test_suite_add(ts, TC(ca)); g_test_suite_add(ts, TC(da)); g_test_suite_add(ts, TC(de)); g_test_suite_add(ts, TC(el)); g_test_suite_add(ts, TC(es)); g_test_suite_add(ts, TC(fa)); g_test_suite_add(ts, TC(fi)); g_test_suite_add(ts, TC(fr)); g_test_suite_add(ts, TC(he)); g_test_suite_add(ts, TC(hu)); g_test_suite_add(ts, TC(is)); g_test_suite_add(ts, TC(it)); g_test_suite_add(ts, TC(nl)); g_test_suite_add(ts, TC(pt)); g_test_suite_add(ts, TC(pt_BR)); g_test_suite_add(ts, TC(ro)); g_test_suite_add(ts, TC(sk)); g_test_suite_add(ts, TC(sv)); g_test_suite_add(ts, TC(xh)); g_test_suite_add(ts, TC(zh_CN)); return ts; } ./tests/notifyosd.py0000755000004100000410000000410513570225707015010 0ustar www-datawww-data#!/usr/bin/python import sys import time from optparse import OptionParser import gtk import pynotify ICON_ONLY_HINT = "x-canonical-private-icon-only" APPEND_HINT = "x-canonical-append" SYNCHRONOUS_HINT = "x-canonical-private-synchronous" VALUE_HINT = "value" def create_gauge_notification(title, icon, value): n = pynotify.Notification(title, "", icon) n.set_hint_string(SYNCHRONOUS_HINT, "") n.set_hint_int32(VALUE_HINT, value) return n def create_icon_only_notification(title, icon): n = pynotify.Notification(title, "", icon) n.set_hint_string(ICON_ONLY_HINT, "") return n USAGE = \ """%prog [options] [<body-text>] If body-text is "-" %prog will display the content of stdin. """ def main (): if not pynotify.init("notifyosd"): return 1 parser = OptionParser() parser.usage = USAGE parser.add_option("-i", "--icon", dest="icon", help = "Name of the icon to show") parser.add_option("--icon-data", dest="icon_data", help = "Load icon data from a custom file") parser.add_option("-v", "--value", dest="value", help = "Start in value mode and display the percentage VALUE in a gauge") parser.add_option("--icon-only", dest="icon_only", help = "Only show icon, ignoring body", action="store_true", default=False) (options, args) = parser.parse_args() if len(args) == 0: parser.print_usage() return 1 title = args[0] if len(args) > 1: if args[1] == "-": body = sys.stdin.read() else: body = " ".join(args[1:]) else: body = "" if options.value: if body: print "Note: ignoring body in value mode" n = create_gauge_notification(title, options.icon, int(options.value)) elif options.icon_only: if body: print "Note: ignoring body in icon_only mode" if not options.icon: print "Error: icon name is missing" return 1 n = create_icon_only_notification(title, options.icon) else: n = pynotify.Notification(title, body, options.icon) if options.icon_data: pixbuf = gtk.gdk.pixbuf_new_from_file(options.icon_data) n.set_icon_from_pixbuf(pixbuf) n.show () if __name__ == "__main__": sys.exit (main ()) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/test-synchronous.c��������������������������������������������������������������������������0000644�0000041�0000041�00000005767�13570225707�016147� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-synchronous.c - unit-tests for synchronous bubbles ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** David Barth <david.barth@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include <unistd.h> #include <glib.h> #include <libnotify/notify.h> #include "dbus.h" static void send_normal (const gchar *message) { NotifyNotification *n; n = notify_notification_new ("Test notification", g_strdup (message), ""); notify_notification_show (n, NULL); g_object_unref(G_OBJECT(n)); } static void send_synchronous (const char *type, const char *icon, gint value) { static NotifyNotification *n = NULL; if (n == NULL) n = notify_notification_new (" ", "", g_strdup (icon)); else notify_notification_update (n, " ", "", g_strdup (icon)); notify_notification_set_hint_int32(n, "value", value); notify_notification_set_hint_string(n, "x-canonical-private-synchronous", g_strdup (type)); notify_notification_show (n, NULL); } #define set_volume(x) send_synchronous ("volume", "notification-audio-volume-medium", x) #define set_brightness(x) send_synchronous ("brightness", "notification-display-brightness-medium", x) static void test_synchronous_layout (gpointer fixture, gconstpointer user_data) { notify_init (__FILE__); send_normal ("Hey, what about this restaurant? http://www.blafasel.org" "" "Would you go from your place by train or should I pick you up from work? What do you think?" ); sleep (1); set_volume (0); sleep (1); set_volume (75); sleep (1); set_volume (90); sleep (1); set_volume (100); sleep (1); send_normal ("Ok, let's go for this one"); sleep (1); set_volume (99); } GTestSuite * test_synchronous_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("synchronous"); g_test_suite_add(ts, g_test_create_case ("synchronous layout", 0, NULL, NULL, (GTestFixtureFunc) test_synchronous_layout, NULL) ); return ts; } ���������./tests/tests.suppression���������������������������������������������������������������������������0000644�0000041�0000041�00000012300�13570225707�016067� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Valgrind suppression file for Gtk+ 2.12 # # Format specification: # http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress # # # glibc Ubuntu Edgy # { libc: getpwnam_r Memcheck:Addr4 obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libc-*.so obj:/lib/ld-*.so fun:__libc_dlopen_mode fun:__nss_lookup_function obj:/lib/tls/i686/cmov/libc-*.so fun:__nss_passwd_lookup fun:getpwnam_r fun:g_get_any_init_do fun:g_get_home_dir fun:gtk_rc_add_initial_default_files fun:_gtk_rc_init fun:post_parse_hook fun:g_option_context_parse fun:gtk_parse_args fun:gtk_init_check fun:gtk_init } { libc: getpwnam_r Memcheck:Addr4 obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libc-*.so obj:/lib/ld-*.so fun:__libc_dlopen_mode fun:__nss_lookup_function obj:/lib/tls/i686/cmov/libc-*.so fun:__nss_passwd_lookup fun:getpwnam_r fun:g_get_any_init_do fun:g_get_home_dir fun:gtk_rc_add_initial_default_files fun:_gtk_rc_init fun:post_parse_hook fun:g_option_context_parse fun:gtk_parse_args fun:gtk_init_check fun:gtk_init } { libc: getpwnam_r Memcheck:Addr4 obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libc-*.so obj:/lib/ld-*.so fun:__libc_dlopen_mode fun:__nss_lookup_function fun:__nss_next fun:getpwnam_r fun:g_get_any_init_do fun:g_get_home_dir fun:gtk_rc_add_initial_default_files fun:_gtk_rc_init fun:post_parse_hook fun:g_option_context_parse fun:gtk_parse_args fun:gtk_init_check fun:gtk_init } { libc: getpwnam_r Memcheck:Addr4 obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libc-*.so obj:/lib/ld-*.so fun:__libc_dlopen_mode fun:__nss_lookup_function fun:__nss_next fun:getpwnam_r fun:g_get_any_init_do fun:g_get_home_dir fun:gtk_rc_add_initial_default_files fun:_gtk_rc_init fun:post_parse_hook fun:g_option_context_parse fun:gtk_parse_args fun:gtk_init_check fun:gtk_init } # # glibc Ubuntu feisty # { getpwnam_r Memcheck:Leak fun:malloc obj:/lib/libc-2.5.so fun:__nss_database_lookup obj:* obj:* fun:getpwnam_r } # # X # { XSupportsLocale Memcheck:Addr4 obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libdl-*.so obj:/lib/ld-*.so obj:/lib/tls/i686/cmov/libdl-*.so fun:dlopen obj:/usr/lib/libX11.so.6.2.0 fun:_XlcDynamicLoad fun:_XOpenLC fun:_XlcCurrentLC fun:XSupportsLocale fun:_gdk_x11_initialize_locale fun:_gdk_windowing_init fun:gdk_pre_parse_libgtk_only fun:pre_parse_hook fun:g_option_context_parse fun:gtk_parse_args fun:gtk_init_check fun:gtk_init fun:main } { Xcursor Memcheck:Leak fun:malloc obj:/usr/lib/libXcursor.so.1.0.2 obj:/usr/lib/libXcursor.so.1.0.2 fun:XcursorXcFileLoadImages fun:XcursorFileLoadImages fun:XcursorLibraryLoadImages fun:XcursorShapeLoadImages fun:XcursorTryShapeCursor fun:XCreateGlyphCursor fun:XCreateFontCursor fun:gdk_cursor_new_for_display } { XcursorGetTheme Memcheck:Leak fun:malloc fun:/usr/lib/libX11.so.6.2.0 fun:/usr/lib/libX11.so.6.2.0 fun:XrmGetStringDatabase fun:XGetDefault fun:_XcursorGetDisplayInfo fun:XcursorGetTheme } { XOpenDisplay Memcheck:Leak fun:calloc fun:XOpenDisplay } { XOpenDisplay Memcheck:Leak fun:malloc fun:XOpenDisplay } # # fontconfig # { fontconfig Memcheck:Leak fun:realloc fun:FcPatternObjectInsertElt fun:FcPatternObjectAddWithBinding } { pango_fc_font_map_load_fontset Memcheck:Leak fun:malloc fun:FcLangSetCreate fun:FcLangSetCopy fun:FcValueSave fun:FcPatternObjectAddWithBinding fun:FcPatternObjectAdd fun:FcFontRenderPrepare fun:pango_fc_font_map_load_fontset fun:pango_font_map_load_fontset } { pango_font_map_load_fontset Memcheck:Leak fun:malloc fun:FcPatternObjectAddWithBinding fun:FcPatternObjectAdd fun:FcFontRenderPrepare fun:pango_fc_font_map_load_fontset fun:pango_font_map_load_fontset } { pango_fc_font_map_load_fontset Memcheck:Leak fun:malloc fun:FcStrStaticName fun:FcPatternObjectAddWithBinding fun:FcPatternObjectAdd fun:FcFontRenderPrepare fun:pango_fc_font_map_load_fontset } { pango_fc_font_map_list_families Memcheck:Leak fun:malloc fun:FcStrStaticName fun:FcPatternObjectAddWithBinding fun:FcPatternAdd fun:FcFontSetList fun:FcFontList fun:pango_fc_font_map_list_families } # # freetype # { freetype FT_Init_FreeType Memcheck:Leak fun:malloc obj:/usr/lib/libfreetype.so.6.3.10 fun:ft_mem_qalloc fun:ft_mem_alloc fun:FT_New_Library fun:FT_Init_FreeType } # # glib # { glib g_rand_new Memcheck:Leak fun:calloc fun:g_malloc0 fun:g_rand_new_with_seed_array fun:g_rand_new fun:g_random_int } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/test-tile.c���������������������������������������������������������������������������������0000644�0000041�0000041�00000016135�13570225707�014501� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // tile-test.c - exercises the tile-API doing surface- and blur-caching // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// #include <gtk/gtk.h> #include <cairo.h> #include <pango/pangocairo.h> #include "tile.h" #define WIDTH 270 #define HEIGHT 320 #define TILE_WIDTH 250 #define TILE_HEIGHT 100 #define BLUR_RADIUS 6 cairo_surface_t* render_text_to_surface (gchar* text, gint width, gint height, guint blur_radius) { cairo_surface_t* surface; cairo_t* cr; PangoFontDescription* desc; PangoLayout* layout; PangoRectangle ink_rect; PangoRectangle log_rect; const cairo_font_options_t* font_opts; gdouble dpi; // sanity check if (!text || width <= 0 || height <= 0) return NULL; // create surface surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) return NULL; // create context cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); return NULL; } // clear context cairo_scale (cr, 1.0f, 1.0f); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); // setup pango's layout and font-decription structures layout = pango_cairo_create_layout (cr); desc = pango_font_description_new (); pango_font_description_set_size (desc, 15 * PANGO_SCALE); pango_font_description_set_family_static (desc, "Candara"); pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL); pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_wrap (layout, PANGO_WRAP_WORD); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_width (layout, (width - 2 * blur_radius) * PANGO_SCALE); pango_layout_set_height (layout, (height - 2 * blur_radius) * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); // get font-options and screen-DPI font_opts = gdk_screen_get_font_options (gdk_screen_get_default ()); dpi = gdk_screen_get_resolution (gdk_screen_get_default ()); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account pango_cairo_context_set_font_options (pango_layout_get_context (layout), font_opts); pango_cairo_context_set_resolution (pango_layout_get_context (layout), dpi); pango_layout_context_changed (layout); // print and layout string (pango-wise) pango_layout_set_text (layout, text, -1); pango_layout_get_extents (layout, &ink_rect, &log_rect); cairo_move_to (cr, (gdouble) blur_radius, (gdouble) blur_radius); // draw pango-text as path to our cairo-context cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); pango_cairo_show_layout (cr, layout); // clean up g_object_unref (layout); cairo_destroy (cr); return surface; } gboolean on_expose (GtkWidget* widget, GdkEventExpose* event, gpointer data) { tile_t* tile = (tile_t*) data; cairo_pattern_t* pattern = NULL; cairo_t* cr = NULL; // create and setup result-surface and context cr = gdk_cairo_create (gtk_widget_get_window (widget)); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { g_debug ("Could not create context for rendering to window!"); return FALSE; } // use the tile for drawing onto result-surface cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba (cr, 0.75f, 0.75f, 0.75f, 1.0f); cairo_paint (cr); // colored drop-shadow trick cairo_push_group (cr); tile_paint (tile, cr, 10.0f, 10.0f, 0.0f, 1.0f); pattern = cairo_pop_group (cr); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.75f); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); // draw the normal tile-state over drop-shadow, but slightly offset-ed tile_paint (tile, cr, 8.5f, 8.5f, 1.0f, 0.0f); // just draw the normal tile-state tile_paint (tile, cr, 10.0f, 110.0f, 1.0f, 0.0f); // just draw the blurred tile-state tile_paint (tile, cr, 10.0f, 210.0f, 0.0f, 1.0f); // clean up cairo_destroy (cr); return FALSE; } gboolean on_delete (GtkWidget* widget, GdkEvent* event, gpointer data) { gtk_main_quit (); return FALSE; } int main (int argc, char** argv) { GtkWidget* window = NULL; cairo_surface_t* tile_surface = NULL; cairo_t* cr = NULL; tile_t* tile = NULL; // needed because we want to make use of the system-wide font-settings gtk_init (&argc, &argv); // create main window window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (!window) { g_debug ("Could not create window!"); return 1; } // create and setup image-surface and context tile_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, TILE_WIDTH, TILE_HEIGHT); if (cairo_surface_status (tile_surface) != CAIRO_STATUS_SUCCESS) { g_debug ("Could not create tile-surface!"); return 2; } cr = cairo_create (tile_surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (tile_surface); g_debug ("Could not create context for tile-surface!"); return 3; } // draw something onto the tile-surface tile_surface = render_text_to_surface ( "Polyfon zwitschernd aßen Mäxchens" " Vögel Rüben, Joghurt und Quark.\0", TILE_WIDTH, TILE_HEIGHT, BLUR_RADIUS); // create and setup tile from that with a blur-radius of 6px tile = tile_new (tile_surface, BLUR_RADIUS); cairo_surface_destroy (tile_surface); cairo_destroy (cr); // setup window gtk_widget_set_size_request (window, WIDTH, HEIGHT); gtk_window_set_resizable (GTK_WINDOW (window), FALSE); gtk_widget_set_app_paintable (window, TRUE); gtk_widget_show_all (window); g_signal_connect (G_OBJECT (window), "expose-event", G_CALLBACK (on_expose), tile); g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (on_delete), NULL); // enter event-loop gtk_main (); // clean up tile_destroy (tile); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/test-raico.c��������������������������������������������������������������������������������0000644�0000041�0000041�00000005011�13570225707�014630� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // notify-osd // // raico-test.c - exercises the raico-API for blurring cairo image-surfaces // // Copyright 2009 Canonical Ltd. // // Authors: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// #include <cairo.h> #include "raico-blur.h" #define WIDTH 500 #define HEIGHT 500 int main (int argc, char** argv) { cairo_surface_t* surface = NULL; cairo_t* cr = NULL; raico_blur_t* blur = NULL; // create and setup image-surface and context surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { g_debug ("Could not create image-surface!"); return 1; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy (surface); g_debug ("Could not create cairo-context!"); return 2; } // create and setup blur blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW); raico_blur_set_radius (blur, 5); // draw something cairo_scale (cr, WIDTH, HEIGHT); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); cairo_paint (cr); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 1.0f); cairo_set_line_width (cr, 0.02f); cairo_arc (cr, 0.5f, 0.5f, 0.4f, 0.0f, 360.0f * G_PI / 180.0f); cairo_stroke (cr); // now blur it raico_blur_apply (blur, surface); // save surface to a PNG-file cairo_surface_write_to_png (surface, "./raico-result.png"); g_print ("See file raico-result.png in current directory for output.\n"); // clean up cairo_destroy (cr); cairo_surface_destroy (surface); raico_blur_destroy (blur); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/test-defaults.c�����������������������������������������������������������������������������0000644�0000041�0000041�00000011000�13570225707�015335� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** notify-osd ** ** test-defaults.c - implements unit-tests for defaults class ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** David Barth <david.barth@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include <glib.h> #include "defaults.h" static void test_defaults_new () { Defaults* defaults = NULL; defaults = defaults_new (); g_assert (defaults != NULL); g_object_unref (defaults); } static void test_defaults_del () { Defaults* defaults = NULL; defaults = defaults_new (); g_object_unref (defaults); } static void test_defaults_get_desktop_width () { Defaults* defaults = NULL; defaults = defaults_new (); g_assert_cmpint (defaults_get_desktop_width (defaults), <=, G_MAXINT); g_assert_cmpint (defaults_get_desktop_width (defaults), >=, 640); g_object_unref (defaults); } static void test_defaults_get_desktop_height () { Defaults* defaults = NULL; defaults = defaults_new (); g_assert_cmpint (defaults_get_desktop_height (defaults), <=, G_MAXINT); g_assert_cmpint (defaults_get_desktop_height (defaults), >=, 600); g_object_unref (defaults); } static void test_defaults_get_stack_height () { Defaults* defaults = NULL; defaults = defaults_new (); g_assert_cmpint (defaults_get_stack_height (defaults), <=, G_MAXINT); g_assert_cmpint (defaults_get_stack_height (defaults), >=, 0); g_object_unref (defaults); } static void test_defaults_get_bubble_width () { Defaults* defaults = NULL; defaults = defaults_new (); g_assert_cmpfloat (defaults_get_bubble_width (defaults), <=, 256.0f); g_assert_cmpfloat (defaults_get_bubble_width (defaults), >=, 0.0f); g_object_unref (defaults); } static void test_defaults_get_gravity () { Defaults* defaults = defaults_new (); // upon creation the gravity should not be unset g_assert_cmpint (defaults_get_gravity (defaults), !=, GRAVITY_NONE); // currently the default value should be NE (top-right) gravity g_assert_cmpint (defaults_get_gravity (defaults), ==, GRAVITY_NORTH_EAST); // check if we can pass "crap" to the call without causing a crash g_assert_cmpint (defaults_get_gravity (NULL), ==, GRAVITY_NONE); g_object_unref (G_OBJECT (defaults)); } static void test_defaults_get_slot_allocation () { Defaults* defaults = defaults_new (); // upon creation slot-allocation should not be unset g_assert_cmpint (defaults_get_slot_allocation (defaults), !=, SLOT_ALLOCATION_NONE); // currently the default value should be SLOT_ALLOCATION_FIXED g_assert_cmpint (defaults_get_slot_allocation (defaults), ==, SLOT_ALLOCATION_FIXED); // check if we can pass "crap" to the call without causing a crash g_assert_cmpint (defaults_get_slot_allocation (NULL), ==, SLOT_ALLOCATION_NONE); g_object_unref (G_OBJECT (defaults)); } GTestSuite * test_defaults_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("defaults"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_defaults_new)); g_test_suite_add(ts, TC(test_defaults_del)); g_test_suite_add(ts, TC(test_defaults_get_desktop_width)); g_test_suite_add(ts, TC(test_defaults_get_desktop_height)); g_test_suite_add(ts, TC(test_defaults_get_stack_height)); g_test_suite_add(ts, TC(test_defaults_get_bubble_width)); g_test_suite_add(ts, TC(test_defaults_get_gravity)); g_test_suite_add(ts, TC(test_defaults_get_slot_allocation)); return ts; } ./tests/test-observer.c�����������������������������������������������������������������������������0000644�0000041�0000041�00000004506�13570225707�015372� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-observer.c - unit-tests for observer class ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** David Barth <david.barth@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include <glib.h> #include "observer.h" static void test_observer_new () { Observer* observer = NULL; observer = observer_new (); g_assert (observer != NULL); observer_del (observer); } static void test_observer_del () { Observer* observer = NULL; observer = observer_new (); observer_del (observer); /*g_assert (observer == NULL);*/ } static void test_observer_get_x () { Observer* observer = NULL; observer = observer_new (); g_assert_cmpint (observer_get_x (observer), <=, 4096); g_assert_cmpint (observer_get_x (observer), >=, 0); observer_del (observer); } static void test_observer_get_y () { Observer* observer = NULL; observer = observer_new (); g_assert_cmpint (observer_get_y (observer), <=, 4096); g_assert_cmpint (observer_get_y (observer), >=, 0); observer_del (observer); } GTestSuite * test_observer_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("observer"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_observer_new)); g_test_suite_add(ts, TC(test_observer_del)); g_test_suite_add(ts, TC(test_observer_get_x)); g_test_suite_add(ts, TC(test_observer_get_y)); return ts; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/Makefile.am���������������������������������������������������������������������������������0000644�0000041�0000041�00000011434�13570225707�014454� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������noinst_PROGRAMS = test-modules \ test-timeline \ test-timeline-dup-frames \ test-timeline-interpolate \ test-timeline-rewind \ test-timeline-smoothness \ test-alpha-animation \ test-raico \ test-tile \ test-grow-bubble \ test-scroll-text check_PROGRAMS = test-modules TESTS = test-modules GCOV_CFLAGS = -fprofile-arcs -ftest-coverage test_modules_SOURCES = \ $(top_srcdir)/src/bubble.c \ $(top_srcdir)/src/defaults.c \ $(top_srcdir)/src/dialog.c \ $(top_srcdir)/src/notification.c \ $(top_srcdir)/src/observer.c \ $(top_srcdir)/src/stack.c \ $(top_srcdir)/src/dbus.c \ $(top_srcdir)/src/dnd.c \ $(top_srcdir)/src/apport.c \ $(top_srcdir)/src/util.c \ $(top_srcdir)/src/stack-blur.c \ $(top_srcdir)/src/exponential-blur.c \ $(top_srcdir)/src/gaussian-blur.c \ $(top_srcdir)/src/raico-blur.c \ $(top_srcdir)/src/tile.c \ $(top_srcdir)/src/bubble-window.c \ $(top_srcdir)/src/bubble-window-accessible.c \ $(top_srcdir)/src/bubble-window-accessible-factory.c \ $(top_srcdir)/src/log.c \ $(top_srcdir)/src/timings.c \ $(EGG_MODULES) \ test-modules-main.c \ test-apport.c \ test-dbus.c \ test-withlib.c \ test-bubble.c \ test-defaults.c \ test-notification.c \ test-observer.c \ test-i18n.c \ test-synchronous.c \ test-dnd.c \ test-stack.c \ test-timings.c \ test-text-filtering.c test_modules_CFLAGS = \ $(GCOV_CFLAGS) \ -Wall \ $(GLIB_CFLAGS) \ $(GTK_CFLAGS) \ -DWNCK_I_KNOW_THIS_IS_UNSTABLE \ $(WNCK_CFLAGS) \ $(DBUS_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ -DSRCDIR=\""$(abs_top_srcdir)"\" \ -I$(top_srcdir)/src \ -I$(top_srcdir)/ test_modules_LDADD = \ $(LIBM) \ $(X_LIBS) \ $(GLIB_LIBS) \ $(WNCK_LIBS) \ $(DBUS_LIBS) \ $(LIBNOTIFY_LIBS) \ $(NOTIFY_OSD_LIBS) \ $(GTK_LIBS) \ -lnotify EGG_MODULES = \ $(top_srcdir)/egg/egg-fixed.c \ $(top_srcdir)/egg/egg-units.c \ $(top_srcdir)/egg/egg-timeline.c \ $(top_srcdir)/egg/egg-timeout-pool.c \ $(top_srcdir)/egg/egg-alpha.c \ $(top_srcdir)/egg/egg-hack.c VALGRIND_FLAGS = \ --tool=memcheck --suppressions=$(srcdir)/tests.suppression \ --leak-check=yes --show-reachable=yes OLD_ENVIRONMENT = $(ENV) AM_CFLAGS = \ $(GCOV_CFLAGS) \ -Wall \ $(GLIB_CFLAGS) \ -I$(top_srcdir)/src -I$(top_srcdir)/egg -I$(top_srcdir) LDADD = $(GLIB_LIBS) -lm test_timeline_SOURCES = $(top_srcdir)/egg/test-timeline.c \ $(EGG_MODULES) test_timeline_dup_frames_SOURCES = $(top_srcdir)/egg/test-timeline-dup-frames.c \ $(EGG_MODULES) test_timeline_interpolate_SOURCES = $(top_srcdir)/egg/test-timeline-interpolate.c \ $(EGG_MODULES) test_timeline_rewind_SOURCES = $(top_srcdir)/egg/test-timeline-rewind.c \ $(EGG_MODULES) test_timeline_smoothness_SOURCES = $(top_srcdir)/egg/test-timeline-smoothness.c \ $(EGG_MODULES) test_alpha_animation_SOURCES = test-alpha-animation.c \ $(EGG_MODULES) RAICO_MODULES = \ $(top_srcdir)/src/stack-blur.c \ $(top_srcdir)/src/exponential-blur.c \ $(top_srcdir)/src/gaussian-blur.c \ $(top_srcdir)/src/raico-blur.c test_raico_SOURCES = \ $(RAICO_MODULES) \ test-raico.c test_raico_CFLAGS = \ -Wall -O0 -ggdb \ $(GTK_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/ test_raico_LDADD = \ $(LIBM) \ $(NOTIFY_OSD_LIBS) \ $(GTK_LIBS) TILE_MODULES = \ $(RAICO_MODULES) \ $(top_srcdir)/src/util.c \ $(top_srcdir)/src/tile.c test_tile_SOURCES = \ $(TILE_MODULES) \ test-tile.c test_tile_CFLAGS = \ -Wall -O0 -ggdb \ $(GTK_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir) test_tile_LDADD = \ $(LIBM) \ $(X_LIBS) \ $(NOTIFY_OSD_LIBS) \ $(GTK_LIBS) GROW_BUBBLE_MODULES = \ $(RAICO_MODULES) \ $(top_srcdir)/src/tile.c test_grow_bubble_SOURCES = \ $(TILE_MODULES) \ test-grow-bubble.c test_grow_bubble_CFLAGS = \ -Wall -O0 -ggdb \ $(GTK_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir) test_grow_bubble_LDADD = \ $(LIBM) \ $(X_LIBS) \ $(NOTIFY_OSD_LIBS) \ $(GTK_LIBS) SCROLL_TEXT_MODULES = \ $(RAICO_MODULES) \ ../src/tile.c test_scroll_text_SOURCES = \ $(TILE_MODULES) \ test-scroll-text.c test_scroll_text_CFLAGS = \ -Wall -O0 -ggdb \ $(GTK_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/ test_scroll_text_LDADD = \ $(LIBM) \ $(X_LIBS) \ $(NOTIFY_OSD_LIBS) \ $(GTK_LIBS) check-valgrind: $(MAKE) $(AM_MAKEFLAGS) check G_SLICE=always-malloc G_DEBUG=gc-friendly TESTS_ENVIRONMENT='$(OLD_ENVIRONMENT) $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log test: test-modules gtester -o=test-modules.xml -k ./test-modules i18n: test-modules gtester --verbose -p=/i18n -k ./test-modules test-report-html: test gtester-report test-modules.xml >test-modules.html test-report-display: test-report-html gnome-open test-modules.html distclean-local: rm -rf *.gcno rm -rf *.gcda ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./tests/test-apport.c�������������������������������������������������������������������������������0000644�0000041�0000041�00000003020�13570225707�015036� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Codename "alsdorf" ** ** test-apport.c - implements unit-tests for apport hooks ** ** Copyright 2009 Canonical Ltd. ** ** Authors: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** David Barth <david.barth@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include <glib.h> #include "apport.h" static void test_apport () { if (g_test_thorough ()) { g_assert (0 == 1); // ie, fail... } } GTestSuite * test_apport_create_test_suite (void) { GTestSuite *ts = NULL; ts = g_test_create_suite ("apport"); #define TC(x) g_test_create_case(#x, 0, NULL, NULL, x, NULL) g_test_suite_add(ts, TC(test_apport)); return ts; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./TODO����������������������������������������������������������������������������������������������0000644�0000041�0000041�00000000141�13570225707�011737� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������TODO * remove the bubble->visible attribute and turn the method calls into gdk_window_is_visible�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./Makefile.am���������������������������������������������������������������������������������������0000644�0000041�0000041�00000000255�13570225707�013311� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������EXTRA_DIST = icons SUBDIRS = src tests data examples test: check tests: check test-report: check check-valgrind: all cd tests && $(MAKE) $(AM_MAKEFLAGS) check-valgrind ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/�����������������������������������������������������������������������������������������0000755�0000041�0000041�00000000000�13570225707�013071� 5����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-only.c������������������������������������������������������������������������������0000644�0000041�0000041�00000004653�13570225707�015154� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` icon-only.c example-util.c -o icon-only ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("icon-only")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the icon-only case */ if (has_cap (CAP_LAYOUT_ICON_ONLY)) { notification = notify_notification_new ( "Eject", /* for a11y-reasons put something meaningfull here */ NULL, "notification-device-eject"); notify_notification_set_hint_string (notification, "x-canonical-private-icon-only", "true"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); } else g_print ("The daemon does not support the x-canonical-private-icon-only hint!\n"); notify_uninit (); return 0; } �������������������������������������������������������������������������������������./examples/append-hint-example.py�������������������������������������������������������������������0000755�0000041�0000041�00000012067�13570225707�017314� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x append-hint-example.py ## ./append-hint-example.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import time import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" def pushNotification (title, body, icon): n = pynotify.Notification (title, body, icon); n.set_hint_string ("x-canonical-append", "true"); n.show () time.sleep (3) # simulate a user typing if __name__ == '__main__': if not pynotify.init ("append-hint-example"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the append-hint if capabilities['x-canonical-append']: pushNotification ("Cole Raby", "Hey Bro Coly!", "notification-message-im"); pushNotification ("Cole Raby", "What's up dude?", "notification-message-im"); pushNotification ("Cole Raby", "Did you watch the air-race in Oshkosh last week?", "notification-message-im"); pushNotification ("Cole Raby", "Phil owned the place like no one before him!", "notification-message-im"); pushNotification ("Cole Raby", "Did really everything in the race work according to regulations?", "notification-message-im"); pushNotification ("Cole Raby", "Somehow I think to remember Burt Williams did cut corners and was not punished for this.", "notification-message-im"); pushNotification ("Cole Raby", "Hopefully the referees will watch the videos of the race.", "notification-message-im"); pushNotification ("Cole Raby", "Burt could get fined with US$ 50000 for that rule-violation :)", "notification-message-im"); else: print "The daemon does not support the x-canonical-append hint!" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/urgent-urgency.py������������������������������������������������������������������������0000755�0000041�0000041�00000007663�13570225707�016440� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x urgent-urgency.py ## ./urgent-urgency.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("urgent-urgency"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary-body case n = pynotify.Notification ("Cole Raby", "Dude, this is so urgent you have no idea :)", "notification-message-im") n.set_urgency (pynotify.URGENCY_CRITICAL) n.show () �����������������������������������������������������������������������������./examples/append-hint-example.cs�������������������������������������������������������������������0000644�0000041�0000041�00000006100�13570225707�017255� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp -r:Mono.Posix.dll example-util.cs \ // append-hint-example.cs -out:append-hint-example.exe // mono append-hint-example.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class AppendHintExample { public static void pushNotification (String title, String body, String icon) { Notification n = new Notification (title, body, icon); n.AddHint ("x-canonical-append", ""); n.Show (); Mono.Unix.Native.Syscall.sleep (3); // simulate typing } public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the append-hint if (ExampleUtil.HasCap (ExampleUtil.Capability.CAP_APPEND)) { pushNotification ("Cole Raby", "Hey Bro Coly!", "notification-message-im"); pushNotification ("Cole Raby", "What's up dude?", "notification-message-im"); pushNotification ("Cole Raby", "Did you watch the air-race in Oshkosh last week?", "notification-message-im"); pushNotification ("Cole Raby", "Phil owned the place like no one before him!", "notification-message-im"); pushNotification ("Cole Raby", "Did really everything in the race work according to regulations?", "notification-message-im"); pushNotification ("Cole Raby", "Somehow I think to remember Burt Williams did cut corners and was not punished for this.", "notification-message-im"); pushNotification ("Cole Raby", "Hopefully the referees will watch the videos of the race.", "notification-message-im"); pushNotification ("Cole Raby", "Burt could get fined with US$ 50000 for that rule-violation :)", "notification-message-im"); } else Console.WriteLine ("The daemon does not support the x-canonical-append hint!"); } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/sync-icon-only.py������������������������������������������������������������������������0000755�0000041�0000041�00000010252�13570225707�016327� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x sync-icon-only.py ## ./sync-icon-only.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("sync-icon-only"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try sync. icon-only if capabilities['x-canonical-private-icon-only'] and capabilities['x-canonical-private-synchronous']: n = pynotify.Notification ("Eject", # for a11y-reasons put something meaningfull here "", "notification-device-eject") n.set_hint_string ("x-canonical-private-icon-only", "true"); n.set_hint_string ("x-canonical-private-synchronous", "true"); n.show () else: print "The daemon does not support sync. icon-only!" ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/sync-icon-only.c�������������������������������������������������������������������������0000644�0000041�0000041�00000005275�13570225707�016127� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` sync-icon-only.c example-util.c -o sync-icon-only ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("sync-icon-only")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the sync. icon-only case */ if (has_cap (CAP_LAYOUT_ICON_ONLY) && has_cap (CAP_SYNCHRONOUS)) { notification = notify_notification_new ( "Eject", /* for a11y-reasons put something meaningfull here */ NULL, "notification-device-eject"); notify_notification_set_hint_string (notification, "x-canonical-private-icon-only", "true"); notify_notification_set_hint_string (notification, "x-canonical-private-synchronous", "true"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); } else { g_print ("The daemon does not support the x-canonical-private-icon-only hint!\n"); g_print ("The daemon does not support the x-canonical-private-synchronous hint!\n"); } notify_uninit (); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-summary-body.c����������������������������������������������������������������������0000644�0000041�0000041�00000004336�13570225707�016621� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` icon-summary-body.c example-util.c -o icon-summary-body ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("icon-summary-body")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the icon-summary-body case */ notification = notify_notification_new ( "Cole Raby", "Hey pal, what's up with the party " "next weekend? Will you join me " "and Anna?", "notification-message-im"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/example-util.h���������������������������������������������������������������������������0000644�0000041�0000041�00000004647�13570225707�015663� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Header for some utility-functions for notification examples demonstrating ** how to use libnotify correctly and at the same time comply to the new ** jaunty notification spec (read: visual guidelines) ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #ifndef __EXAMPLE_UTIL_H #define __EXAMPLE_UTIL_H #include <glib.h> #include <unistd.h> #include <libnotify/notify.h> typedef enum _Capability { CAP_ACTIONS = 0, CAP_BODY, CAP_BODY_HYPERLINKS, CAP_BODY_IMAGES, CAP_BODY_MARKUP, CAP_ICON_MULTI, CAP_ICON_STATIC, CAP_SOUND, CAP_IMAGE_SVG, CAP_SYNCHRONOUS, CAP_APPEND, CAP_LAYOUT_ICON_ONLY, CAP_TRUNCATION, CAP_MAX } Capability; #define ACTIONS "actions" #define BODY "body" #define BODY_HYPERLINKS "body-hyperlinks" #define BODY_IMAGES "body-images" #define BODY_MARKUP "body-markup" #define ICON_MULTI "icon-multi" #define ICON_STATIC "icon-static" #define SOUND "sound" #define IMAGE_SVG "image/svg+xml" #define SYNCHRONOUS "x-canonical-private-synchronous" #define APPEND "x-canonical-append" #define LAYOUT_ICON_ONLY "x-canonical-private-icon-only" #define TRUNCATION "x-canonical-truncation" void closed_handler (NotifyNotification* notification, gpointer data); void set_cap (gpointer data, gpointer user_data); void init_caps (void); gboolean has_cap (Capability cap); void print_caps (void); #endif /* __EXAMPLE_UTIL_H */ �����������������������������������������������������������������������������������������./examples/update-notifications.py������������������������������������������������������������������0000755�0000041�0000041�00000011344�13570225707�017602� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x update-notifications.py ## ./update-notifications.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import time import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("update-notifications"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary-body case n = pynotify.Notification ( "Inital notification (1. notification)", "This is the original content of this notification-bubble.", "notification-message-im") n.show () time.sleep (4); # simulate app activity # update the current notification with new content n.update ("Updated notification (1. notification)", "Here the same bubble with new title- and body-text, even the icon can be changed on the update.", "notification-message-email") n.show (); time.sleep (10); # wait longer now # create a new bubble using the icon-summary-body layout n = pynotify.Notification ( "Initial layout (2. notification)", "This bubble uses the icon-title-body layout.", "notification-message-im"); n.show () time.sleep (4); # simulate app activity # now update current bubble again, but change the layout n.update ("Updated layout (2. notification)", "After the update we now have a bubble using the title-body layout.", " ") n.show () ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-value.py����������������������������������������������������������������������������0000755�0000041�0000041�00000011625�13570225707�015515� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x icon-value.py ## ./icon-value.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import time import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" def pushNotification (icon, value): n = pynotify.Notification ("Brightness", # for a11y-reasons supply something meaning full "", # this needs to be empty! icon); n.set_hint_int32 ("value", value); n.set_hint_string ("x-canonical-private-synchronous", "true"); n.show () time.sleep (1) if __name__ == '__main__': if not pynotify.init ("icon-value"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-value case if capabilities['x-canonical-private-icon-only']: pushNotification ("notification-keyboard-brightness-low", 25); pushNotification ("notification-keyboard-brightness-medium", 50); pushNotification ("notification-keyboard-brightness-high", 75); pushNotification ("notification-keyboard-brightness-full", 100); # trigger "overshoot"-effect pushNotification ("notification-keyboard-brightness-full", 101); pushNotification ("notification-keyboard-brightness-high", 75); pushNotification ("notification-keyboard-brightness-medium", 50); pushNotification ("notification-keyboard-brightness-low", 25); pushNotification ("notification-keyboard-brightness-off", 0); # trigger "undershoot"-effect pushNotification ("notification-keyboard-brightness-off", -1); else: print "The daemon does not support the x-canonical-private-icon-only hint!" �����������������������������������������������������������������������������������������������������������./examples/update-notifications.cs������������������������������������������������������������������0000644�0000041�0000041�00000005244�13570225707�017556� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp -r:Mono.Posix.dll example-util.cs \ // update-notifications.cs -out:update-notifications.exe // mono update-notifications.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class UpdateNotifications { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-summary-body case Notification n = new Notification ( "Inital notification", "This is the original content of this notification-bubble.", "notification-message-im"); n.Show (); Mono.Unix.Native.Syscall.sleep (3); // simulate app activity // update the current notification with new content n.Summary = "Updated notification"; n.Body = "Here the same bubble with new title- and body-text, even the icon can be changed on the update."; n.IconName = "notification-message-email"; n.Show (); Mono.Unix.Native.Syscall.sleep (6); // wait longer now // create a new bubble using the icon-summary-body layout n = new Notification ( "Initial layout", "This bubble uses the icon-title-body layout.", "notification-message-im"); n.Show (); Mono.Unix.Native.Syscall.sleep (3); // simulate app activity // now update current bubble again, but change the layout n.Summary = "Updated layout"; n.Body = "After the update we now have a bubble using the title-body layout."; n.IconName = " "; n.Show (); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/summary-only.py��������������������������������������������������������������������������0000755�0000041�0000041�00000007462�13570225707�016133� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x summary-only.py ## ./summary-only.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("summary-only"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the summary-only case n = pynotify.Notification ("Summary-only", "") n.show () ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/example-util.cs��������������������������������������������������������������������������0000644�0000041�0000041�00000013722�13570225707�016033� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp -r:Mono.Posix.dll append-hint-example.cs \ // -out:append-hint-example.exe // mono append-hint-example.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; static class ExampleUtil { public enum Capability { CAP_ACTIONS = 0, CAP_BODY, CAP_BODY_HYPERLINKS, CAP_BODY_IMAGES, CAP_BODY_MARKUP, CAP_ICON_MULTI, CAP_ICON_STATIC, CAP_SOUND, CAP_IMAGE_SVG, CAP_SYNCHRONOUS, CAP_APPEND, CAP_LAYOUT_ICON_ONLY, CAP_TRUNCATION, CAP_MAX} static bool[] m_capabilities = {false, // actions false, // body false, // body-hyperlinks false, // body-imges false, // body-markup false, // icon-multi false, // icon-static false, // sound false, // image/svg+xml false, // synchronous-hint false, // append-hint false, // icon-only-hint false}; // truncation-hint public static void InitCaps () { if (Global.Capabilities == null) return; if (Array.IndexOf (Global.Capabilities, "actions") > -1) m_capabilities[(int) Capability.CAP_ACTIONS] = true; if (Array.IndexOf (Global.Capabilities, "body") > -1) m_capabilities[(int) Capability.CAP_BODY] = true; if (Array.IndexOf (Global.Capabilities, "body-hyperlinks") > -1) m_capabilities[(int) Capability.CAP_BODY_HYPERLINKS] = true; if (Array.IndexOf (Global.Capabilities, "body-images") > -1) m_capabilities[(int) Capability.CAP_BODY_IMAGES] = true; if (Array.IndexOf (Global.Capabilities, "body-markup") > -1) m_capabilities[(int) Capability.CAP_BODY_MARKUP] = true; if (Array.IndexOf (Global.Capabilities, "icon-multi") > -1) m_capabilities[(int) Capability.CAP_ICON_MULTI] = true; if (Array.IndexOf (Global.Capabilities, "icon-static") > -1) m_capabilities[(int) Capability.CAP_ICON_STATIC] = true; if (Array.IndexOf (Global.Capabilities, "sound") > -1) m_capabilities[(int) Capability.CAP_SOUND] = true; if (Array.IndexOf (Global.Capabilities, "image/svg+xml") > -1) m_capabilities[(int) Capability.CAP_IMAGE_SVG] = true; if (Array.IndexOf (Global.Capabilities, "x-canonical-private-synchronous") > -1) m_capabilities[(int) Capability.CAP_SYNCHRONOUS] = true; if (Array.IndexOf (Global.Capabilities, "x-canonical-append") > -1) m_capabilities[(int) Capability.CAP_APPEND] = true; if (Array.IndexOf (Global.Capabilities, "x-canonical-private-icon-only") > -1) m_capabilities[(int) Capability.CAP_LAYOUT_ICON_ONLY] = true; if (Array.IndexOf (Global.Capabilities, "x-canonical-truncation") > -1) m_capabilities[(int) Capability.CAP_TRUNCATION] = true; } public static bool HasCap (Capability capability) { return m_capabilities[(int) capability]; } public static void PrintCaps () { Console.WriteLine ("Name: " + Global.ServerInformation.Name); Console.WriteLine ("Vendor: " + Global.ServerInformation.Vendor); Console.WriteLine ("Version: " + Global.ServerInformation.Version); Console.WriteLine ("Spec. Version: " + Global.ServerInformation.SpecVersion); Console.WriteLine ("Supported capabilities/hints:"); if (m_capabilities[(int) Capability.CAP_ACTIONS]) Console.WriteLine ("\tactions"); if (m_capabilities[(int) Capability.CAP_BODY]) Console.WriteLine ("\tbody"); if (m_capabilities[(int) Capability.CAP_BODY_HYPERLINKS]) Console.WriteLine ("\tbody-hyperlinks"); if (m_capabilities[(int) Capability.CAP_BODY_IMAGES]) Console.WriteLine ("\tbody-images"); if (m_capabilities[(int) Capability.CAP_BODY_MARKUP]) Console.WriteLine ("\tbody-markup"); if (m_capabilities[(int) Capability.CAP_ICON_MULTI]) Console.WriteLine ("\ticon-multi"); if (m_capabilities[(int) Capability.CAP_ICON_STATIC]) Console.WriteLine ("\ticon-static"); if (m_capabilities[(int) Capability.CAP_SOUND]) Console.WriteLine ("\tsound"); if (m_capabilities[(int) Capability.CAP_IMAGE_SVG]) Console.WriteLine ("\timage/svg+xml"); if (m_capabilities[(int) Capability.CAP_SYNCHRONOUS]) Console.WriteLine ("\tx-canonical-private-synchronous"); if (m_capabilities[(int) Capability.CAP_APPEND]) Console.WriteLine ("\tx-canonical-append"); if (m_capabilities[(int) Capability.CAP_LAYOUT_ICON_ONLY]) Console.WriteLine ("\tx-canonical-private-icon-only"); if (m_capabilities[(int) Capability.CAP_TRUNCATION]) Console.WriteLine ("\tx-canonical-truncation"); Console.WriteLine ("Notes:"); if (Global.ServerInformation.Name == "notify-osd") { Console.WriteLine ("\tx- and y-coordinates hints are ignored"); Console.WriteLine ("\texpire-timeout is ignored"); Console.WriteLine ("\tbody-markup is accepted but filtered"); } else Console.WriteLine ("\tnone"); } } // ExampleUtil.InitCaps () // ExampleUtil.HasCaps (capability) // ExampleUtil.PrintCaps () ����������������������������������������������./examples/summary-body.py��������������������������������������������������������������������������0000755�0000041�0000041�00000007515�13570225707�016106� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x summary-body.py ## ./summary-body.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("summary-body"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the summary-body case n = pynotify.Notification ("Totem", "This is a superfluous notification") n.show () �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/normal-urgency.py������������������������������������������������������������������������0000755�0000041�0000041�00000007744�13570225707�016424� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x normal-urgency.py ## ./normal-urgency.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("normal-urgency"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary-body case n = pynotify.Notification ("Cole Raby", "Hey pal, what's up with the party " "next weekend? Will you join me " "and Anna?", "notification-message-im") n.set_urgency (pynotify.URGENCY_NORMAL) n.show () ����������������������������./examples/low-urgency.py���������������������������������������������������������������������������0000755�0000041�0000041�00000007647�13570225707�015737� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x low-urgency.py ## ./low-urgency.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("low-urgency"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary-body case n = pynotify.Notification ("Gerhard Gepard", "No, I'd rather see paint dry, pal *yawn*", "notification-message-im") n.set_urgency (pynotify.URGENCY_LOW) n.show () �����������������������������������������������������������������������������������������./examples/icon-summary.py��������������������������������������������������������������������������0000755�0000041�0000041�00000007557�13570225707�016107� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x icon-summary.py ## ./icon-summary.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("icon-summary"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary case n = pynotify.Notification ("WiFi connection lost", "", "notification-network-wireless-disconnected") n.show () �������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-summary-body.py���������������������������������������������������������������������0000755�0000041�0000041�00000007703�13570225707�017033� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x icon-summary-body.py ## ./icon-summary-body.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("icon-summary-body"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-summary-body case n = pynotify.Notification ("Cole Raby", "Hey pal, what's up with the party " "next weekend? Will you join me " "and Anna?", "notification-message-im") n.show () �������������������������������������������������������������./examples/icon-only.cs�����������������������������������������������������������������������������0000644�0000041�0000041�00000003763�13570225707�015340� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs icon-only.cs -out:icon-only.exe // mono icon-only.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class IconOnly { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-sonly case if (ExampleUtil.HasCap (ExampleUtil.Capability.CAP_LAYOUT_ICON_ONLY)) { Notification n = new Notification ("Eject", // for a11y-reasons supply something meaning full "", // this needs to be empty! "notification-device-eject"); n.AddHint ("x-canonical-private-icon-only", ""); n.Show (); } else Console.WriteLine ("The daemon does not support the x-canonical-private-icon-only hint!"); } } �������������./examples/sync-icon-only.cs������������������������������������������������������������������������0000644�0000041�0000041�00000004162�13570225707�016304� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs sync-icon-only.cs \ // -out:sync-icon-only.exe // mono sync-icon-only.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class SyncIconOnly { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-sonly case if (ExampleUtil.HasCap (ExampleUtil.Capability.CAP_LAYOUT_ICON_ONLY) && ExampleUtil.HasCap (ExampleUtil.Capability.CAP_SYNCHRONOUS)) { Notification n = new Notification ("Eject", // for a11y-reasons supply something meaning full "", // this needs to be empty! "notification-device-eject"); n.AddHint ("x-canonical-private-icon-only", ""); n.AddHint ("x-canonical-private-synchronous", ""); n.Show (); } else Console.WriteLine ("The daemon does not support sync. icon-only!"); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-summary.c���������������������������������������������������������������������������0000644�0000041�0000041�00000004222�13570225707�015660� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` icon-summary.c example-util.c -o icon-summary ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("icon-summary")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the icon-summary case */ notification = notify_notification_new ( "WiFi connection lost", NULL, "notification-network-wireless-disconnected"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/summary-only.cs��������������������������������������������������������������������������0000644�0000041�0000041�00000003242�13570225707�016075� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs summary-only.cs \ // -out:summary-only.exe // mono summary-only.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class SummaryOnly { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the summary-only case Notification n = new Notification ("Summary-only", ""); n.Show (); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/summary-only.c���������������������������������������������������������������������������0000644�0000041�0000041�00000004143�13570225707�015713� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` summary-only.c example-util.c -o summary-only ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("summary-only")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the summary-only case */ notification = notify_notification_new ( "Summary-only", NULL, NULL); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/example-util.c���������������������������������������������������������������������������0000644�0000041�0000041�00000012713�13570225707�015647� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Implementation for some utility-functions for notification examples ** demonstrating how to use libnotify correctly and at the same time comply ** to the new jaunty notification spec (read: visual guidelines) ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" /* this is globally nasty :), do something nicer in your own code */ gboolean g_capabilities[CAP_MAX] = {FALSE, /* actions */ FALSE, /* body */ FALSE, /* body-hyperlinks */ FALSE, /* body-imges */ FALSE, /* body-markup */ FALSE, /* icon-multi */ FALSE, /* icon-static */ FALSE, /* sound */ FALSE, /* image/svg+xml */ FALSE, /* synchronous-hint */ FALSE, /* append-hint */ FALSE, /* icon-only-hint */ FALSE /* truncation-hint */}; void closed_handler (NotifyNotification* notification, gpointer data) { g_print ("closed_handler() called"); return; } void set_cap (gpointer data, gpointer user_data) { /* test for "actions" */ if (!g_strcmp0 (ACTIONS, (gchar*) data)) g_capabilities[CAP_ACTIONS] = TRUE; /* test for "body" */ if (!g_strcmp0 (BODY, (gchar*) data)) g_capabilities[CAP_BODY] = TRUE; /* test for "body-hyperlinks" */ if (!g_strcmp0 (BODY_HYPERLINKS, (gchar*) data)) g_capabilities[CAP_BODY_HYPERLINKS] = TRUE; /* test for "body-images" */ if (!g_strcmp0 (BODY_IMAGES, (gchar*) data)) g_capabilities[CAP_BODY_IMAGES] = TRUE; /* test for "body-markup" */ if (!g_strcmp0 (BODY_MARKUP, (gchar*) data)) g_capabilities[CAP_BODY_MARKUP] = TRUE; /* test for "icon-multi" */ if (!g_strcmp0 (ICON_MULTI, (gchar*) data)) g_capabilities[CAP_ICON_MULTI] = TRUE; /* test for "icon-static" */ if (!g_strcmp0 (ICON_STATIC, (gchar*) data)) g_capabilities[CAP_ICON_STATIC] = TRUE; /* test for "sound" */ if (!g_strcmp0 (SOUND, (gchar*) data)) g_capabilities[CAP_SOUND] = TRUE; /* test for "image/svg+xml" */ if (!g_strcmp0 (IMAGE_SVG, (gchar*) data)) g_capabilities[CAP_IMAGE_SVG] = TRUE; /* test for "x-canonical-private-synchronous" */ if (!g_strcmp0 (SYNCHRONOUS, (gchar*) data)) g_capabilities[CAP_SYNCHRONOUS] = TRUE; /* test for "x-canonical-append" */ if (!g_strcmp0 (APPEND, (gchar*) data)) g_capabilities[CAP_APPEND] = TRUE; /* test for "x-canonical-private-icon-only" */ if (!g_strcmp0 (LAYOUT_ICON_ONLY, (gchar*) data)) g_capabilities[CAP_LAYOUT_ICON_ONLY] = TRUE; /* test for "x-canonical-truncation" */ if (!g_strcmp0 (TRUNCATION, (gchar*) data)) g_capabilities[CAP_TRUNCATION] = TRUE; } void init_caps (void) { GList* caps_list; caps_list = notify_get_server_caps (); if (caps_list) { g_list_foreach (caps_list, set_cap, NULL); g_list_foreach (caps_list, (GFunc) g_free, NULL); g_list_free (caps_list); } } gboolean has_cap (Capability cap) { return g_capabilities[cap]; } void print_caps (void) { gchar* name; gchar* vendor; gchar* version; gchar* spec_version; notify_get_server_info (&name, &vendor, &version, &spec_version); g_print ("Name: %s\n" "Vendor: %s\n" "Version: %s\n" "Spec. Version: %s\n", name, vendor, version, spec_version); g_print ("Supported capabilities/hints:\n"); if (has_cap (CAP_ACTIONS)) g_print ("\tactions\n"); if (has_cap (CAP_BODY)) g_print ("\tbody\n"); if (has_cap (CAP_BODY_HYPERLINKS)) g_print ("\tbody-hyperlinks\n"); if (has_cap (CAP_BODY_IMAGES)) g_print ("\tbody-images\n"); if (has_cap (CAP_BODY_MARKUP)) g_print ("\tbody-markup\n"); if (has_cap (CAP_ICON_MULTI)) g_print ("\ticon-multi\n"); if (has_cap (CAP_ICON_STATIC)) g_print ("\ticon-static\n"); if (has_cap (CAP_SOUND)) g_print ("\tsound\n"); if (has_cap (CAP_IMAGE_SVG)) g_print ("\timage/svg+xml\n"); if (has_cap (CAP_SYNCHRONOUS)) g_print ("\tx-canonical-private-synchronous\n"); if (has_cap (CAP_APPEND)) g_print ("\tx-canonical-append\n"); if (has_cap (CAP_LAYOUT_ICON_ONLY)) g_print ("\tx-canonical-private-icon-only\n"); if (has_cap (CAP_TRUNCATION)) g_print ("\tx-canonical-truncation\n"); g_print ("Notes:\n"); if (!g_strcmp0 ("notify-osd", name)) { g_print ("\tx- and y-coordinates hints are ignored\n"); g_print ("\texpire-timeout is ignored\n"); g_print ("\tbody-markup is accepted but filtered\n"); } else g_print ("\tnone"); g_free ((gpointer) name); g_free ((gpointer) vendor); g_free ((gpointer) version); g_free ((gpointer) spec_version); } �����������������������������������������������������./examples/summary-body.c���������������������������������������������������������������������������0000644�0000041�0000041�00000004173�13570225707�015672� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` summary-body.c example-util.c -o summary-body ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("summary-body")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the summary-body case */ notification = notify_notification_new ( "Totem", "This is a superfluous notification", NULL); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/summary-body.cs��������������������������������������������������������������������������0000644�0000041�0000041�00000003343�13570225707�016053� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs summary-body.cs \ // -out:summary-body.exe // mono summary-body.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class SummaryBody { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the summary-body case Notification n = new Notification ("Totem", "This is a superfluous notification."); n.Show (); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-value.c�����������������������������������������������������������������������������0000644�0000041�0000041�00000006657�13570225707�015315� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` icon-value.c example-util.c -o icon-value ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" void push_notification (gchar* icon, gint value) { NotifyNotification* notification; gboolean success; GError* error = NULL; notification = notify_notification_new ( "Brightness", /* for a11y-reasons put something meaningfull here */ NULL, icon); notify_notification_set_hint_int32 (notification, "value", value); notify_notification_set_hint_string (notification, "x-canonical-private-synchronous", "true"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); g_object_unref (G_OBJECT (notification)); sleep (1); } int main (int argc, char** argv) { if (!notify_init ("icon-value")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the value-icon case, usually used for synchronous bubbles */ if (has_cap (CAP_SYNCHRONOUS)) { push_notification ("notification-keyboard-brightness-low", 25); push_notification ("notification-keyboard-brightness-medium", 50); push_notification ("notification-keyboard-brightness-high", 75); push_notification ("notification-keyboard-brightness-full", 100); /* trigger "overshoot"-effect */ push_notification ("notification-keyboard-brightness-full", 101); push_notification ("notification-keyboard-brightness-high", 75); push_notification ("notification-keyboard-brightness-medium", 50); push_notification ("notification-keyboard-brightness-low", 25); push_notification ("notification-keyboard-brightness-off", 0); /* trigger "undershoot"-effect */ push_notification ("notification-keyboard-brightness-off", -1); } else g_print ("The daemon does not support the x-canonical-private-synchronous hint!\n"); notify_uninit (); return 0; } ���������������������������������������������������������������������������������./examples/icon-updating.c��������������������������������������������������������������������������0000644�0000041�0000041�00000007171�13570225707�016004� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` icon-updating.c example-util.c -o icon-updating ** ** Copyright 2010 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification = NULL; gboolean success; GError* error = NULL; GdkPixbuf* pixbuf = NULL; if (!notify_init ("icon-updating")) return 1; // call this so we can savely use has_cap(CAP_SOMETHING) later init_caps (); // show what's supported print_caps (); // create new notification, set icon using hint "image_path" notification = notify_notification_new ( "Test 1/3", "Set icon via hint \"image_path\" to logo-icon.", NULL); notify_notification_set_hint_string ( notification, "image_path", "/usr/share/icons/Humanity/places/64/distributor-logo.svg"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("Could not show notification: \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); sleep (4); // wait a bit // update notification using hint image_data notify_notification_clear_hints (notification); success = notify_notification_update ( notification, "Test 2/3", "Set icon via hint \"image_data\" to avatar-photo.", NULL); error = NULL; pixbuf = gdk_pixbuf_new_from_file ("../icons/avatar.png", &error); if (!pixbuf) { g_print ("Could not load image: \"%s\".\n", error->message); g_error_free (error); } notify_notification_set_icon_from_pixbuf (notification, pixbuf); g_object_unref (pixbuf); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("Could not show notification: \"%s\".\n", error->message); g_error_free (error); } sleep (4); // wait a bit // update notification using icon-parameter directly notify_notification_clear_hints (notification); success = notify_notification_update ( notification, "Test 3/3", "Set icon via icon-parameter directly to totem-icon.", "totem"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("Could not show notification: \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/append-hint-example.c��������������������������������������������������������������������0000644�0000041�0000041�00000007010�13570225707�017073� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` append-hint-example.c example-util.c -o append-hint-example ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" void push_notification (gchar* title, gchar* body, gchar* icon) { NotifyNotification* notification; gboolean success; GError* error = NULL; /* initial notification */ notification = notify_notification_new (title, body, icon); notify_notification_set_hint_string (notification, "x-canonical-append", "true"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); g_object_unref (G_OBJECT (notification)); sleep (3); /* simulate a user typing */ } int main (int argc, char** argv) { if (!notify_init ("append-hint-example")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the append-hint */ if (has_cap (CAP_APPEND)) { push_notification ("Cole Raby", "Hey Bro Coly!", "notification-message-im"); push_notification ("Cole Raby", "What's up dude?", "notification-message-im"); push_notification ("Cole Raby", "Did you watch the air-race in Oshkosh last week?", "notification-message-im"); push_notification ("Cole Raby", "Phil owned the place like no one before him!", "notification-message-im"); push_notification ("Cole Raby", "Did really everything in the race work according to regulations?", "notification-message-im"); push_notification ("Cole Raby", "Somehow I think to remember Burt Williams did cut corners and was not punished for this.", "notification-message-im"); push_notification ("Cole Raby", "Hopefully the referees will watch the videos of the race.", "notification-message-im"); push_notification ("Cole Raby", "Burt could get fined with US$ 50000 for that rule-violation :)", "notification-message-im"); } else { g_print ("The daemon does not support the x-canonical-append hint!"); } notify_uninit (); return 0; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-value.cs����������������������������������������������������������������������������0000644�0000041�0000041�00000005716�13570225707�015473� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs icon-value.cs -out:icon-value.exe // mono icon-value.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class IconValue { public static void pushNotification (String icon, int val) { Notification n = new Notification ("Brightness", // for a11y-reasons supply something meaning full "", // this needs to be empty! icon); n.AddHint ("value", val); n.AddHint ("x-canonical-private-synchronous", ""); n.Show (); Mono.Unix.Native.Syscall.sleep (1); } public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-value case, usually used for synchronous bubbles if (ExampleUtil.HasCap (ExampleUtil.Capability.CAP_SYNCHRONOUS)) { pushNotification ("notification-keyboard-brightness-low", 25); pushNotification ("notification-keyboard-brightness-medium", 50); pushNotification ("notification-keyboard-brightness-high", 75); pushNotification ("notification-keyboard-brightness-full", 100); // trigger "overshoot"-effect pushNotification ("notification-keyboard-brightness-full", 101); pushNotification ("notification-keyboard-brightness-high", 75); pushNotification ("notification-keyboard-brightness-medium", 50); pushNotification ("notification-keyboard-brightness-low", 25); pushNotification ("notification-keyboard-brightness-off", 0); // trigger "undershoot"-effect pushNotification ("notification-keyboard-brightness-off", -1); } else Console.WriteLine ("The daemon does not support the x-canonical-private-synchronous hint!"); } } ��������������������������������������������������./examples/icon-summary-body.cs���������������������������������������������������������������������0000644�0000041�0000041�00000003546�13570225707�017006� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs icon-summary-body.cs \ // -out:icon-summary-body.exe // mono icon-summary-body.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class IconSummaryBody { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-summary-body case Notification n = new Notification ("Cole Raby", "Hey pal, what's up with the party next weekend? Will you join me and Anna?", "notification-message-im"); n.Show (); } } ����������������������������������������������������������������������������������������������������������������������������������������������������������./examples/icon-summary.cs��������������������������������������������������������������������������0000644�0000041�0000041�00000003404�13570225707�016044� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//////////////////////////////////////////////////////////////////////////////// //3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 // 10 20 30 40 50 60 70 80 // // Info: // Example of how to use libnotify correctly and at the same time comply to // the new jaunty notification spec (read: visual guidelines) // // Compile and run: // gmcs -pkg:notify-sharp example-util.cs icon-summary.cs \ // -out:icon-summary.exe // mono icon-summary.exe // // Copyright 2009 Canonical Ltd. // // Author: // Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License version 3, as published // by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranties of // MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR // PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see <http://www.gnu.org/licenses/>. // //////////////////////////////////////////////////////////////////////////////// using System; using Notifications; public class IconSummary { public static void Main () { // call this so we can savely use the m_capabilities array later ExampleUtil.InitCaps (); // show what's supported ExampleUtil.PrintCaps (); // try the icon-summary case Notification n = new Notification ("WiFi connection lost", "", // this needs to be empty "notification-network-wireless-disconnected"); n.Show (); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/Makefile.am������������������������������������������������������������������������������0000644�0000041�0000041�00000011661�13570225707�015132� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������EXTRA_DIST = append-hint-example.py \ icon-only.py \ icon-summary-body.py \ icon-summary.py \ icon-value.py \ low-urgency.py \ normal-urgency.py \ summary-body.py \ summary-only.py \ sync-icon-only.py \ update-notifications.py \ urgent-urgency.py if BUILD_C_EXAMPLES noinst_PROGRAMS = icon-only \ sync-icon-only \ icon-summary-body \ icon-summary \ icon-value \ summary-body \ summary-only \ append-hint-example \ update-notifications \ icon-updating icon_only_SOURCES = example-util.c example-util.h icon-only.c sync_icon_only_SOURCES = sync-icon-only.c example-util.h example-util.c icon_summary_body_SOURCES = icon-summary-body.c example-util.h example-util.c icon_summary_SOURCES = icon-summary.c example-util.c example-util.h icon_value_SOURCES = icon-value.c example-util.c example-util.h summary_body_SOURCES = summary-body.c example-util.c example-util.h summary_only_SOURCES = summary-only.c example-util.c example-util.h append_hint_example_SOURCES = append-hint-example.c example-util.c example-util.h update_notifications_SOURCES = update-notifications.c example-util.c example-util.h icon_updating_SOURCES = icon-updating.c example-util.c example-util.h icon_only_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` sync_icon_only_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` icon_summary_body_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` icon_summary_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` icon_value_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` summary_body_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` summary_only_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` append_hint_example_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` update_notifications_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` icon_updating_CFLAGS = -I. -O0 -ggdb -Wall -Werror `pkg-config --cflags libnotify glib-2.0` icon_only_LDFLAGS = `pkg-config --libs libnotify glib-2.0` sync_icon_only_LDFLAGS = `pkg-config --libs libnotify glib-2.0` icon_summary_body_LDFLAGS = `pkg-config --libs libnotify glib-2.0` icon_summary_LDFLAGS = `pkg-config --libs libnotify glib-2.0` icon_value_LDFLAGS = `pkg-config --libs libnotify glib-2.0` summary_body_LDFLAGS = `pkg-config --libs libnotify glib-2.0` summary_only_LDFLAGS = `pkg-config --libs libnotify glib-2.0` append_hint_example_LDFLAGS = `pkg-config --libs libnotify glib-2.0` update_notifications_LDFLAGS = `pkg-config --libs libnotify glib-2.0` icon_updating_LDFLAGS = `pkg-config --libs libnotify glib-2.0` endif if BUILD_MONO_EXAMPLES noinst_PROGRAMS = icon-only.exe \ sync-icon-only.exe \ icon-summary-body.exe \ icon-summary.exe \ icon-value.exe \ summary-body.exe \ summary-only.exe \ append-hint-example.exe \ update-notifications.exe icon_only_exe_SOURCES = example-util.cs icon-only.cs sync_icon_only_exe_SOURCES = sync-icon-only.cs example-util.cs icon_summary_body_exe_SOURCES = icon-summary-body.cs example-util.cs icon_summary_exe_SOURCES = icon-summary.cs example-util.cs icon_value_exe_SOURCES = icon-value.cs example-util.cs summary_body_exe_SOURCES = summary-body.cs example-util.cs summary_only_exe_SOURCES = summary-only.cs example-util.cs append_hint_example_exe_SOURCES = append-hint-example.cs example-util.cs update_notifications_exe_SOURCES = update-notifications.cs example-util.cs icon-only.exe: $(icon_only_exe_SOURCES) gmcs -pkg:notify-sharp $(icon_only_exe_SOURCES) -out:icon-only.exe sync-icon-only.exe: $(sync_icon_only_exe_SOURCES) gmcs -pkg:notify-sharp $(sync_icon_only_exe_SOURCES) -out:sync-icon-only.exe icon-summary-body.exe: $(icon_summary_body_exe_SOURCES) gmcs -pkg:notify-sharp $(icon_summary_body_exe_SOURCES) -out:icon-summary-body.exe icon-summary.exe: $(icon_summary_exe_SOURCES) gmcs -pkg:notify-sharp $(icon_summary_exe_SOURCES) -out:icon-summary.exe icon-value.exe: $(icon_value_exe_SOURCES) gmcs -pkg:notify-sharp -r:Mono.Posix.dll $(icon_value_exe_SOURCES) -out:icon-value.exe summary-body.exe: $(summary_body_exe_SOURCES) gmcs -pkg:notify-sharp $(summary_body_exe_SOURCES) -out:summary-body.exe summary-only.exe: $(summary_only_exe_SOURCES) gmcs -pkg:notify-sharp $(summary_only_exe_SOURCES) -out:summary-only.exe append-hint-example.exe: $(append_hint_example_exe_SOURCES) gmcs -pkg:notify-sharp -r:Mono.Posix.dll $(append_hint_example_exe_SOURCES) -out:append-hint-example.exe update-notifications.exe: $(update_notifications_exe_SOURCES) gmcs -pkg:notify-sharp -r:Mono.Posix.dll $(update_notifications_exe_SOURCES) -out:update-notifications.exe endif �������������������������������������������������������������������������������./examples/icon-only.py�����������������������������������������������������������������������������0000755�0000041�0000041�00000010155�13570225707�015357� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/python ################################################################################ ##3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ## 10 20 30 40 50 60 70 80 ## ## Info: ## Example of how to use libnotify correctly and at the same time comply to ## the new jaunty notification spec (read: visual guidelines) ## ## Run: ## chmod +x icon-only.py ## ./icon-only.py ## ## Copyright 2009 Canonical Ltd. ## ## Author: ## Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ## ## This program is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License version 3, as published ## by the Free Software Foundation. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranties of ## MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ## PURPOSE. See the GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License along ## with this program. If not, see <http://www.gnu.org/licenses/>. ## ################################################################################ import sys import pynotify # even in Python this is globally nasty :), do something nicer in your own code capabilities = {'actions': False, 'body': False, 'body-hyperlinks': False, 'body-images': False, 'body-markup': False, 'icon-multi': False, 'icon-static': False, 'sound': False, 'image/svg+xml': False, 'x-canonical-private-synchronous': False, 'x-canonical-append': False, 'x-canonical-private-icon-only': False, 'x-canonical-truncation': False} def initCaps (): caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) for cap in caps: capabilities[cap] = True def printCaps (): info = pynotify.get_server_info () print "Name: " + info["name"] print "Vendor: " + info["vendor"] print "Version: " + info["version"] print "Spec. Version: " + info["spec-version"] caps = pynotify.get_server_caps () if caps is None: print "Failed to receive server caps." sys.exit (1) print "Supported capabilities/hints:" if capabilities['actions']: print "\tactions" if capabilities['body']: print "\tbody" if capabilities['body-hyperlinks']: print "\tbody-hyperlinks" if capabilities['body-images']: print "\tbody-images" if capabilities['body-markup']: print "\tbody-markup" if capabilities['icon-multi']: print "\ticon-multi" if capabilities['icon-static']: print "\ticon-static" if capabilities['sound']: print "\tsound" if capabilities['image/svg+xml']: print "\timage/svg+xml" if capabilities['x-canonical-private-synchronous']: print "\tx-canonical-private-synchronous" if capabilities['x-canonical-append']: print "\tx-canonical-append" if capabilities['x-canonical-private-icon-only']: print "\tx-canonical-private-icon-only" if capabilities['x-canonical-truncation']: print "\tx-canonical-truncation" print "Notes:" if info["name"] == "notify-osd": print "\tx- and y-coordinates hints are ignored" print "\texpire-timeout is ignored" print "\tbody-markup is accepted but filtered" else: print "\tnone" if __name__ == '__main__': if not pynotify.init ("icon-only"): sys.exit (1) # call this so we can savely use capabilities dictionary later initCaps () # show what's supported printCaps () # try the icon-only case if capabilities['x-canonical-private-icon-only']: n = pynotify.Notification ("", # for a11y-reasons put something meaningfull here "", # for a11y-reasons put something meaningfull here "notification-device-eject") n.set_hint_string ("x-canonical-private-icon-only", "true"); n.show () else: print "The daemon does not support the x-canonical-private-icon-only hint!" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./examples/update-notifications.c�������������������������������������������������������������������0000644�0000041�0000041�00000007705�13570225707�017377� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************************************* **3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 ** 10 20 30 40 50 60 70 80 ** ** Info: ** Example of how to use libnotify correctly and at the same time comply to ** the new jaunty notification spec (read: visual guidelines) ** ** Compile: ** gcc -O0 -ggdb -Wall -Werror `pkg-config --cflags --libs libnotify \ ** glib-2.0` update-notifications.c example-util.c -o update-notifications ** ** Copyright 2009 Canonical Ltd. ** ** Author: ** Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> ** ** This program is free software: you can redistribute it and/or modify it ** under the terms of the GNU General Public License version 3, as published ** by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranties of ** MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see <http://www.gnu.org/licenses/>. ** *******************************************************************************/ #include "example-util.h" int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("update-notifications")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the icon-summary-body case */ notification = notify_notification_new ( "Inital notification", "This is the original content of " "this notification-bubble.", "notification-message-im"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); sleep (3); /* simulate some app activity */ /* update the current notification with new content */ success = notify_notification_update (notification, "Updated notification", "Here the same bubble with new " "title- and body-text, even the " "icon can be changed on the update.", "notification-message-email"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); sleep (6); /* wait long enough to have the current bubble expire */ /* create a new bubble using the icon-summary-body layout */ notification = notify_notification_new ( "Initial layout", "This bubble uses the icon-title-body " "layout.", "notification-message-im"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); sleep (3); /* again simulate some app activity */ /* now update current bubble again, but change the layout */ success = notify_notification_update (notification, "Updated layout", "After the update we now have a " "bubble using the title-body layout.", " "); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); notify_uninit (); return 0; } �����������������������������������������������������������./configure.in��������������������������������������������������������������������������������������0000644�0000041�0000041�00000010074�13570225707�013566� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_INIT(notify-osd, 0.9.34, dx-team@canonical.com) AC_CONFIG_SRCDIR(src/main.c) AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) GNOME_COMMON_INIT GNOME_COMPILE_WARNINGS(maximum) AM_MAINTAINER_MODE AM_DISABLE_STATIC AM_PROG_LIBTOOL AC_SUBST(ACLOCAL_AMFLAGS, "$ACLOCAL_FLAGS -I m4") AC_PROG_CC AC_PROG_CC_C99 AM_PROG_CC_C_O AC_PROG_INSTALL # # pkg-config # PKG_PROG_PKG_CONFIG # # use all the GSettings-magic # GLIB_GSETTINGS # # glib, we need 2.16.0 for the unit-tests # PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.36.0 gthread-2.0 gio-2.0]) # # libwnck used by the dnd code # PKG_CHECK_MODULES([WNCK], [libwnck-3.0]) AC_CHECK_LIB(wnck-3,wnck_shutdown, have_wnck_shutdown=yes,) if test "$have_wnck_shutdown" = "yes"; then AC_DEFINE(HAVE_WNCK_SHUTDOWN, 1, [Define to 1 if libwnck provides wnck_shutdown()]) fi # # libnotify, used unit-tests # PKG_CHECK_MODULES([LIBNOTIFY], [libnotify >= 0.4.5]) # # dbus # PKG_CHECK_MODULES([DBUS], [dbus-glib-1 >= 0.76]) DBUS_GLIB_BIN="`$PKG_CONFIG --variable=exec_prefix dbus-glib-1`/bin" AC_SUBST(DBUS_GLIB_BIN) # # libX11 # # # Gnome/GTK checks # PKG_CHECK_MODULES([X], [x11]) AC_SUBST(X_CFLAGS) AC_SUBST(X_LIBS) AM_PATH_GTK_3_0 PKG_CHECK_MODULES([NOTIFY_OSD], [pixman-1 gtk+-3.0 >= 3.8.0]) AC_SUBST(NOTIFY_OSD_CFLAGS) AC_SUBST(NOTIFY_OSD_LIBS) # # libm # AC_CHECK_LIBM AC_SUBST(LIBM) # # checks for building C- or C#-examples # AC_DEFUN([CHECK_FOR_MONO_STUFF], [ NAME="gmcs" AC_PATH_PROG(GMCS, $NAME, no) AC_SUBST(GMCS) if test "x$GMCS" = "xno"; then AC_MSG_ERROR([You need to install '$NAME']) fi NAME="Mono.Posix" AC_MSG_CHECKING([for Mono 2.0 GAC $NAME.dll]) if test -e "$(pkg-config --variable=libdir mono)/mono/2.0/$NAME.dll"; then AC_MSG_RESULT([found]) else AC_MSG_RESULT([not found]) AC_MSG_ERROR([missing reqired Mono 2.0 assembly $NAME.dll]) fi NAME="notify-sharp" AC_MSG_CHECKING([for Mono 2.0 CIL $NAME]) pkg-config --exists $NAME if test "$?" == "0" then AC_MSG_RESULT([found]) else AC_MSG_RESULT([not found]) AC_MSG_ERROR([missing reqired Mono 2.0 CIL $NAME]) fi ]) AC_ARG_WITH(examples, [ --with-examples=[[all/c/mono]] build C or C#-examples using libnotify demonstrating special features of notify-osd there are Python-examples too, but they don't need to be build]) c_examples=no csharp_examples=no if test "x$with_examples" = "xc"; then c_examples=yes AC_MSG_NOTICE([Build with ANSI-C examples]) fi if test "x$with_examples" = "xmono"; then CHECK_FOR_MONO_STUFF csharp_examples=yes AC_MSG_NOTICE([Build with C-sharp examples]) fi if test "x$with_examples" = "xall"; then CHECK_FOR_MONO_STUFF c_examples=yes csharp_examples=yes AC_MSG_NOTICE([Build with ANSI-C examples]) AC_MSG_NOTICE([Build with C-sharp examples]) fi AM_CONDITIONAL(BUILD_C_EXAMPLES, test "x$c_examples" != "xno") AM_CONDITIONAL(BUILD_MONO_EXAMPLES, test "x$csharp_examples" != "xno") dnl CFLAGS CFLAGS="$CFLAGS -Wall" AC_ARG_ENABLE([deprecations], [AS_HELP_STRING([--enable-deprecations], [allow deprecated API usage @<:@default=yes@:>@])], [], [enable_deprecations=yes]) AS_IF([test "x$enable_deprecations" = xno], [CFLAGS="$CFLAGS -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE"] ) AC_OUTPUT([ Makefile src/Makefile tests/Makefile examples/Makefile data/Makefile data/icons/Makefile data/icons/scalable/Makefile ]) echo "" echo " Notify OSD $VERSION" echo " ============================" echo "" echo " prefix: ${prefix}" echo "" echo " Build C Examples: ${c_examples}" echo "" echo " Build C# Examples: ${csharp_examples}" echo "" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./m4/�����������������������������������������������������������������������������������������������0000755�0000041�0000041�00000000000�13570225707�011573� 5����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./m4/python.m4��������������������������������������������������������������������������������������0000644�0000041�0000041�00000003452�13570225707�013362� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������## this one is commonly used with AM_PATH_PYTHONDIR ... dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) dnl Check if a module containing a given symbol is visible to python. AC_DEFUN([AM_CHECK_PYMOD], [AC_REQUIRE([AM_PATH_PYTHON]) py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1) AC_CACHE_VAL(py_cv_mod_$py_mod_var, [ ifelse([$2],[], [prog=" import sys try: import $1 except ImportError: sys.exit(1) except: sys.exit(0) sys.exit(0)"], [prog=" import $1 $1.$2"]) if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC then eval "py_cv_mod_$py_mod_var=yes" else eval "py_cv_mod_$py_mod_var=no" fi ]) py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"` if test "x$py_val" != xno; then AC_MSG_RESULT(yes) ifelse([$3], [],, [$3 ])dnl else AC_MSG_RESULT(no) ifelse([$4], [],, [$4 ])dnl fi ]) dnl a macro to check for ability to create python extensions dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) dnl function also defines PYTHON_INCLUDES AC_DEFUN([AM_CHECK_PYTHON_HEADERS], [AC_REQUIRE([AM_PATH_PYTHON]) AC_MSG_CHECKING(for headers required to compile python extensions) dnl deduce PYTHON_INCLUDES py_prefix=`$PYTHON -c "import sys; print sys.prefix"` py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" if test "$py_prefix" != "$py_exec_prefix"; then PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" fi AC_SUBST(PYTHON_INCLUDES) dnl check if the headers exist: save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" AC_TRY_CPP([#include <Python.h>],dnl [AC_MSG_RESULT(found) $1],dnl [AC_MSG_RESULT(not found) $2]) CPPFLAGS="$save_CPPFLAGS" ]) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./AUTHORS�������������������������������������������������������������������������������������������0000644�0000041�0000041�00000001447�13570225707�012331� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Development lead: - Mirco "MacSlow" Mueller <mirco.mueller@canonical.com> Additional development: - David Barth <david.barth@canonical.com> Contributors (in no particular order): - Frederic "fredp" Peters <fpeters@gnome.org> - Eitan Isaacson <eitan@ascender.com> - Neil J. Patel <neil.patel@canonical.com> - Chow Loong Jin <hyperair@gmail.com> - Abhishek Mukherjee <abhishek.mukher.g@gmail.com> - Aurélien Gâteau <aurelien.gateau@canonical.com> - Ted Gould <ted@canonical.com> - Bastian "hadess" Nocera <hadess@hadess.net> - Alexander Sack <asac@ubuntu.com> - Karl Lattimer <karl.lattimer@codethink.co.uk> - Martin Pitt <martin.pitt@canonical.com> - Michael Terry <michael.terry@canonical.com> - Tony Wang <wwwjfy@gmail.com> - Peter Clifton <pcjc2@cam.ac.uk> - John Ledbetter <john.ledbetter@gmail.com> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/���������������������������������������������������������������������������������������������0000755�0000041�0000041�00000000000�13570225707�012164� 5����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/���������������������������������������������������������������������������������������0000755�0000041�0000041�00000000000�13570225707�013277� 5����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/������������������������������������������������������������������������������0000755�0000041�0000041�00000000000�13570225707�015045� 5����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-message-im.svg���������������������������������������������������0000644�0000041�0000041�00000034004�13570225707�022302� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48px" height="48px" id="svg2108" sodipodi:version="0.32" inkscape:version="0.45" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/stock/generic" sodipodi:docname="stock_person.svg" inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-icon-theme/48x48/stock/generic/stock_person.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs3"> <linearGradient id="linearGradient4562"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop4564" /> <stop style="stop-color:#d6d6d2;stop-opacity:1;" offset="1" id="stop4566" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient4356"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop4358" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop4360" /> </linearGradient> <linearGradient id="linearGradient3824"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3826" /> <stop style="stop-color:#c9c9c9;stop-opacity:1.0000000;" offset="1.0000000" id="stop3828" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3816"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3818" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3820" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3816" id="radialGradient3822" cx="31.112698" cy="19.008621" fx="31.112698" fy="19.008621" r="8.6620579" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4356" id="linearGradient4362" x1="20.661695" y1="35.817974" x2="22.626925" y2="36.217758" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.3161,0.243028,-0.243028,1.3161,-9.262129,-16.07396)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4356" id="linearGradient4366" gradientUnits="userSpaceOnUse" x1="22.686766" y1="36.390400" x2="21.408455" y2="35.739632" gradientTransform="matrix(-1.308485,0.281154,0.281154,1.308485,57.41196,-17.2385)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4356" id="linearGradient1366" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.308485,0.281154,0.281154,1.308485,39.09106,-26.21225)" x1="22.686766" y1="36.390400" x2="21.408455" y2="35.739632" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3824" id="linearGradient1372" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.338350,0.000000,0.000000,1.338350,-33.47918,-20.70004)" x1="30.935921" y1="29.553486" x2="30.935921" y2="35.803486" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4562" id="radialGradient4568" cx="24.753788" cy="26.814409" fx="24.753788" fy="26.814409" r="17.986024" gradientTransform="matrix(1.354517,4.451877e-16,-3.340511e-8,1.366395,-8.947464,-9.871365)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient4562" id="radialGradient3816" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.558489,1.477485e-16,-1.377346e-8,0.563387,14.87134,4.364123)" cx="29.922075" cy="17.727694" fx="29.922075" fy="17.727694" r="17.986024" /> <filter inkscape:collect="always" x="-0.076111111" width="1.1522222" y="-0.28344828" height="1.5668966" id="filter5655"> <feGaussianBlur inkscape:collect="always" stdDeviation="1.4531044" id="feGaussianBlur5657" /> </filter> </defs> <sodipodi:namedview inkscape:showpageshadow="false" id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="0.16862745" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="31.500535" inkscape:cy="28.945566" inkscape:current-layer="layer2" showgrid="false" inkscape:grid-bbox="true" inkscape:document-units="px" fill="#9db029" stroke="#727e0a" inkscape:window-width="872" inkscape:window-height="815" inkscape:window-x="202" inkscape:window-y="68" /> <metadata id="metadata4"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title>Person</dc:title> <dc:creator> <cc:Agent> <dc:title>Jakub Steiner</dc:title> </cc:Agent> </dc:creator> <dc:source>http://jimmac.musichall.cz</dc:source> <dc:subject> <rdf:Bag> <rdf:li>user</rdf:li> <rdf:li>person</rdf:li> </rdf:Bag> </dc:subject> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="cipek" inkscape:groupmode="layer" style="display:inline"> <path style="opacity:1;color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 13.365469,24.850231 L 19.043607,24.850231 L 15.731361,21.774572 L 15.021593,22.720929 L 14.311825,22.011162 L 13.365469,24.850231 z " id="path4173" /> <path sodipodi:nodetypes="cccc" id="path4370" d="M 19.882923,32.490544 C 21.530768,31.712992 22.297815,29.810737 22.297815,29.810737 C 21.014177,24.39981 16.976336,20.652646 16.976336,20.652646 C 16.976336,20.652646 20.274824,29.141269 19.882923,32.490544 z " style="opacity:0.22784807;color:#000000;fill:url(#linearGradient1366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="dalsi cipek" style="display:inline"> <rect style="opacity:0.34857143;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000001;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;filter:url(#filter5655);enable-background:accumulate" id="rect4608" width="38.183765" height="10.253048" x="5.3033009" y="35.448853" rx="5.126524" ry="5.126524" transform="matrix(0.9351852,0,0,0.9351852,1.5811694,2.2763322)" /> <path style="opacity:1;color:#000000;fill:url(#radialGradient4568);fill-opacity:1.0;fill-rule:evenodd;stroke:#888a85;stroke-width:0.99999982px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 17.918908,43.517006 L 32.114254,43.517006 C 36.136269,43.517006 40.118235,42.042236 41.577816,37.838868 C 42.963864,33.847271 41.814406,26.246002 32.824021,20.094686 L 16.026195,20.094686 C 7.0358098,25.772823 5.9122958,33.538186 7.9821665,38.075456 C 10.090864,42.697836 13.660304,43.517006 17.918908,43.517006 z " id="path4308" sodipodi:nodetypes="cczcczc" /> <path sodipodi:nodetypes="cccc" id="path4364" d="M 38.203826,41.464292 C 39.851671,40.68674 40.618718,38.784486 40.618718,38.784486 C 39.33508,33.373558 35.297238,29.626395 35.297238,29.626395 C 35.297238,29.626395 38.595727,38.115017 38.203826,41.464292 z " style="opacity:0.29120878;color:#000000;fill:url(#linearGradient4366);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" inkscape:r_cx="true" inkscape:r_cy="true" /> <path style="opacity:0.54945056;color:#000000;fill:url(#linearGradient4362);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 11.642995,42.046125 C 9.9732599,41.316765 9.2259419,39.559099 9.2259419,39.559099 C 10.351871,34.11317 14.204505,30.128795 14.204505,30.128795 C 14.204505,30.128795 11.153975,38.709646 11.642995,42.046125 z " id="path4354" sodipodi:nodetypes="cccc" inkscape:r_cx="true" inkscape:r_cy="true" /> <path sodipodi:nodetypes="cczcczc" id="path4314" d="M 17.593144,42.482789 L 32.120832,42.452196 C 35.775407,42.452196 39.393589,41.112158 40.719828,37.292799 C 41.97925,33.665864 40.58869,26.759027 32.419643,21.169679 L 16.464198,20.833163 C 8.295151,25.99256 6.714018,33.0485 8.6253819,37.507773 C 10.536748,41.967046 13.325894,42.452196 17.593144,42.482789 z " style="opacity:0.64285714;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> <path d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" sodipodi:ry="8.6620579" sodipodi:rx="8.6620579" sodipodi:cy="19.008621" sodipodi:cx="31.112698" id="path4318" style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" sodipodi:type="arc" transform="matrix(1.338350,0.000000,0.000000,1.338350,-17.02698,-7.522361)" /> <path sodipodi:type="arc" style="opacity:1;color:#000000;fill:url(#radialGradient3816);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.74718857px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path4320" sodipodi:cx="31.112698" sodipodi:cy="19.008621" sodipodi:rx="8.6620579" sodipodi:ry="8.6620579" d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" transform="matrix(1.338350,0.000000,0.000000,1.338350,-16.85969,-12.20659)" /> <path d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" sodipodi:ry="8.6620579" sodipodi:rx="8.6620579" sodipodi:cy="19.008621" sodipodi:cx="31.112698" id="path4322" style="opacity:0.19620254;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.82296228px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" sodipodi:type="arc" transform="matrix(1.215123,0.000000,0.000000,1.215123,-13.02574,-9.864199)" /> </g> </svg> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-message-email.svg������������������������������������������������0000644�0000041�0000041�00000040603�13570225707�022766� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docname="notification-message-email.svg" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 24 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="48 : 24 : 1" inkscape:persp3d-origin="24 : 16 : 1" id="perspective54" /> <linearGradient id="linearGradient2378"> <stop id="stop2380" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop style="stop-color:#fefede;stop-opacity:0.91836733;" offset="0.25" id="stop4146" /> <stop style="stop-color:#f5f328;stop-opacity:1;" offset="0.5" id="stop2386" /> <stop id="stop2382" offset="1" style="stop-color:#f5f32d;stop-opacity:0.12234043;" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6934"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6936" /> <stop style="stop-color:#babdb6;stop-opacity:0" offset="1" id="stop6938" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5060"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop5062" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5064" /> </linearGradient> <linearGradient id="linearGradient5048"> <stop style="stop-color:black;stop-opacity:0;" offset="0" id="stop5050" /> <stop id="stop5056" offset="0.5" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5052" /> </linearGradient> <linearGradient id="linearGradient6945" inkscape:collect="always"> <stop id="stop6947" offset="0" style="stop-color:#ffffff;stop-opacity:1" /> <stop id="stop6949" offset="1" style="stop-color:#d3d7cf;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7063" inkscape:collect="always"> <stop id="stop7065" offset="0" style="stop-color:#000000;stop-opacity:1;" /> <stop id="stop7067" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5048" id="linearGradient10235" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" x1="302.85715" y1="366.64789" x2="302.85715" y2="609.50507" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient10237" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient10239" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6945" id="radialGradient10241" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.0135589,0,0,1.7460565,-12.669486,-9.185985)" cx="12.5" cy="15.927882" fx="12.5" fy="15.927882" r="18.5" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7063" id="linearGradient10243" gradientUnits="userSpaceOnUse" x1="12.875" y1="35.314098" x2="12.875" y2="15.75" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6945" id="radialGradient10245" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.6083242,0,0,2.218814,-74.941381,-118.61799)" cx="13.107393" cy="61.48016" fx="13.107393" fy="61.48016" r="18.5" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6934" id="linearGradient10247" gradientUnits="userSpaceOnUse" gradientTransform="translate(1,-42)" x1="14.125" y1="79.81311" x2="14.125" y2="75.499176" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient2378" id="radialGradient10249" gradientUnits="userSpaceOnUse" cx="38.658855" cy="9.3411446" fx="38.658855" fy="9.3411446" r="8.341651" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="0.37647059" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="118.00152" inkscape:cy="16.07457" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:window-width="872" inkscape:window-height="848" inkscape:window-x="209" inkscape:window-y="67" borderlayer="true" showgrid="false" inkscape:grid-points="true" showborder="true" showguides="true" inkscape:guide-bbox="false" inkscape:object-paths="false" inkscape:grid-bbox="true"> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="0.5px" spacingy="0.5px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="2" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Mail stuff</dc:title> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1"> <g id="g11036" inkscape:label="Livello 1" transform="translate(0,-1)"> <g transform="matrix(2.2162751e-2,0,0,1.0695181e-2,44.21234,36.053672)" id="g11038" style="opacity:0.7;display:inline"> <rect style="opacity:0.39195981;fill:url(#linearGradient10235);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect11040" width="1339.6335" height="478.35718" x="-1559.2523" y="-150.69685" /> <path style="opacity:0.40206185;fill:url(#radialGradient10237);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z" id="path11042" sodipodi:nodetypes="cccc" /> <path sodipodi:nodetypes="cccc" id="path11044" d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z" style="opacity:0.40206185;fill:url(#radialGradient10239);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> </g> <rect ry="1.5340841" rx="1.5340841" y="12.499999" x="6.5" height="25" width="36" id="rect11046" style="opacity:1;fill:url(#radialGradient10241);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" /> <path sodipodi:nodetypes="cccccssscccccc" id="path11048" d="M 7.90625,12.9375 C 7.356972,12.9375 6.9375,13.35697 6.9375,13.90625 L 6.9375,15.3125 L 16.03125,26.90625 L 17.15625,25.65625 C 17.625623,25.186876 18.0906,24.571266 19.125,24.15625 C 20.1594,23.741234 21.70864,23.5 24.5,23.5 C 27.280132,23.499999 28.838454,23.741631 29.875,24.15625 C 30.911546,24.570869 31.373047,25.185547 31.84375,25.65625 L 32.96875,26.90625 L 42.0625,15.3125 L 42.0625,13.90625 C 42.0625,13.356972 41.64303,12.9375 41.09375,12.9375 L 7.90625,12.9375 z" style="opacity:0.23134329;fill:url(#linearGradient10243);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> <path sodipodi:nodetypes="ccssscccccc" id="path11050" d="M 7,37 L 17.15625,25.65625 C 17.625623,25.186876 18.0906,24.571266 19.125,24.15625 C 20.1594,23.741234 21.70864,23.5 24.5,23.5 C 27.280132,23.499999 28.838454,23.741631 29.875,24.15625 C 30.911546,24.570869 31.373047,25.185547 31.84375,25.65625 L 42,37 L 31.84375,26.65625 C 29.799743,24.686656 27.325503,24.384093 24.5,24.5 C 21.82915,24.54954 19.035697,24.49967 17.15625,26.65625 L 7,37 z" style="fill:#888a85;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccccccc" id="path11052" d="M 7,37.021499 L 17.15625,27.677749 C 19.035697,25.521169 21.82915,25.571039 24.5,25.521499 C 27.325503,25.405592 29.799743,25.708155 31.84375,27.677749 L 42,37.021499 L 31.84375,26.677749 C 29.799743,24.708155 27.325503,24.405592 24.5,24.521499 C 21.82915,24.571039 19.035697,24.521169 17.15625,26.677749 L 7,37.021499 z" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path transform="translate(50,0)" d="M -42.09375,12.9375 C -42.643028,12.9375 -43.0625,13.35697 -43.0625,13.90625 L -43.0625,15.3125 L -32.1875,26.1875 C -31.660276,26.714725 -31.377256,27.12932 -30.53125,27.46875 C -29.685244,27.80818 -28.234677,28.0625 -25.5,28.0625 C -22.776784,28.062501 -21.318209,27.808534 -20.46875,27.46875 C -19.619291,27.128966 -19.338542,26.713542 -18.8125,26.1875 L -7.9375,15.3125 L -7.9375,13.90625 C -7.9375,13.356972 -8.3569702,12.9375 -8.90625,12.9375 L -42.09375,12.9375 z" id="path11054" style="fill:url(#radialGradient10245);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" inkscape:original="M -42.09375 12.5 C -42.877224 12.5 -43.5 13.122774 -43.5 13.90625 L -43.5 15.5 L -32.5 26.5 C -31.5 27.500002 -31.022703 28.5 -25.5 28.5 C -20 28.500002 -19.5 27.5 -18.5 26.5 L -7.5 15.5 L -7.5 13.90625 C -7.5 13.122776 -8.122774 12.5 -8.90625 12.5 L -42.09375 12.5 z " inkscape:radius="-0.44194174" sodipodi:type="inkscape:offset" /> <path sodipodi:nodetypes="ccssscccccc" id="path11056" d="M 7,15.5 L 17.15625,26.84375 C 17.625623,27.313124 18.0906,27.928734 19.125,28.34375 C 20.1594,28.758766 21.70864,29 24.5,29 C 27.280132,29.000001 28.838454,28.758369 29.875,28.34375 C 30.911546,27.929131 31.373047,27.314453 31.84375,26.84375 L 42,15.5 L 31.84375,25.84375 C 29.799743,27.813344 27.325503,28.115907 24.5,28 C 21.82915,27.95046 19.035697,28.00033 17.15625,25.84375 L 7,15.5 z" style="fill:#888a85;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccccccc" id="path11058" d="M 7,15.5 L 17.15625,24.84375 C 19.035697,27.00033 21.82915,26.95046 24.5,27 C 27.325503,27.115907 29.799743,26.813344 31.84375,24.84375 L 42,15.5 L 31.84375,25.84375 C 29.799743,27.813344 27.325503,28.115907 24.5,28 C 21.82915,27.95046 19.035697,28.00033 17.15625,25.84375 L 7,15.5 z" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path transform="translate(1,-42)" d="M 6.90625,55.5 C 6.6497165,55.5 6.5,55.649715 6.5,55.90625 L 6.5,78.09375 C 6.5,78.350281 6.6497152,78.499999 6.90625,78.5 L 40.09375,78.5 C 40.350281,78.5 40.5,78.350281 40.5,78.09375 L 40.5,55.90625 C 40.5,55.649717 40.350284,55.5 40.09375,55.5 L 6.90625,55.5 z" id="path11060" style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" inkscape:original="M 6.90625 54.5 C 6.1227756 54.5 5.5 55.122774 5.5 55.90625 L 5.5 78.09375 C 5.5 78.877224 6.1227756 79.499998 6.90625 79.5 L 40.09375 79.5 C 40.877224 79.5 41.5 78.877224 41.5 78.09375 L 41.5 55.90625 C 41.5 55.122776 40.877226 54.5 40.09375 54.5 L 6.90625 54.5 z " inkscape:radius="-0.99436891" sodipodi:type="inkscape:offset" /> <path sodipodi:nodetypes="ccccccc" id="path11062" d="M 7,32.90625 L 7,36.09375 C 7,36.614757 7.385241,36.999999 7.90625,37 L 41.09375,37 C 41.61476,37 42,36.614757 42,36.09375 L 42,32.90625 L 7,32.90625 z" style="opacity:0.55597014;fill:url(#linearGradient10247);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" /> </g> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/README������������������������������������������������������������������������0000644�0000041�0000041�00000000130�13570225707�015717� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a set of fallback icons for Gnome. Canonical icons are in the Human icon theme. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-device.svg�������������������������������������������������������0000644�0000041�0000041�00000045355�13570225707�021525� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48px" height="48px" id="svg1306" sodipodi:version="0.32" inkscape:version="0.45.1" sodipodi:docbase="/home/lapo/Icone/gnome-icon-theme/scalable/devices" sodipodi:docname="drive-removable-media.svg" inkscape:export-filename="/home/jimmac/Desktop/drive-optical.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs1308"> <linearGradient inkscape:collect="always" id="linearGradient3725"> <stop style="stop-color:#eeeeec;stop-opacity:1;" offset="0" id="stop3727" /> <stop style="stop-color:#eeeeec;stop-opacity:0;" offset="1" id="stop3729" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3709"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3711" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3713" /> </linearGradient> <linearGradient id="linearGradient2809"> <stop style="stop-color:#d3d7cf;stop-opacity:1;" offset="0" id="stop2811" /> <stop style="stop-color:#eeeeec;stop-opacity:0;" offset="1" id="stop2813" /> </linearGradient> <linearGradient id="linearGradient3763"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop3765" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop3767" /> </linearGradient> <linearGradient id="linearGradient3942"> <stop id="stop3944" offset="0" style="stop-color:#888a85;stop-opacity:1" /> <stop id="stop3946" offset="1" style="stop-color:#eeeeec;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient3877"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3879" /> <stop style="stop-color:white;stop-opacity:0.77319586;" offset="1" id="stop3881" /> </linearGradient> <linearGradient id="linearGradient3859"> <stop id="stop3861" offset="0" style="stop-color:#d3d7cf;stop-opacity:1" /> <stop id="stop3037" offset="0.30973485" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:1;" offset="0.88648254" id="stop3039" /> <stop id="stop3863" offset="1" style="stop-color:#d3d7cf;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5060"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop5062" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5064" /> </linearGradient> <linearGradient id="linearGradient5048"> <stop style="stop-color:black;stop-opacity:0;" offset="0" id="stop5050" /> <stop id="stop5056" offset="0.5" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5052" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3859" id="linearGradient2899" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.169513,0,0,1.866794,-4.088508,-5.493268)" x1="39.846634" y1="17.288595" x2="9.0151443" y2="17.469774" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3942" id="linearGradient2925" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.168352,0,0,0.940121,-5.224048,3.708073)" x1="31.259865" y1="28.921469" x2="31.259865" y2="30.105555" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3877" id="linearGradient3883" x1="75" y1="56.9375" x2="75" y2="63.920155" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.196864,0,0,1.232642,-76.53167,-39.77282)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5048" id="linearGradient3903" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" x1="302.85715" y1="366.64789" x2="302.85715" y2="609.50507" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient3905" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient3907" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3763" id="linearGradient3769" x1="36.05172" y1="34.193111" x2="35.23922" y2="32.023624" gradientUnits="userSpaceOnUse" gradientTransform="translate(1,2)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2809" id="linearGradient2815" x1="22.777416" y1="32.072342" x2="22.777416" y2="34.00016" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.166667,0,-2.666667)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3709" id="linearGradient3715" x1="19.5625" y1="31.8125" x2="19.5625" y2="33.65863" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.333333,0,-8.33333)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3725" id="linearGradient3731" x1="29.521708" y1="32.023651" x2="29.521708" y2="33.553349" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.333333,0,-8.33333)" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#c5c5c5" borderopacity="1" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="34.273727" inkscape:cy="22.63914" inkscape:current-layer="layer1" showgrid="false" inkscape:grid-bbox="false" inkscape:document-units="px" stroke="#888a85" fill="#babdb6" inkscape:window-width="1262" inkscape:window-height="813" inkscape:window-x="376" inkscape:window-y="129" inkscape:showpageshadow="false" inkscape:guide-points="false" inkscape:object-points="false" inkscape:object-paths="false" inkscape:guide-bbox="true" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:grid-points="true" showguides="false" showborder="true" inkscape:object-bbox="true"> <sodipodi:guide orientation="horizontal" position="2.8125" id="guide2906" /> </sodipodi:namedview> <metadata id="metadata1311"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title>Drive Removable Media</dc:title> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:description /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:source>http://www.gnome.org</dc:source> <dc:contributor> <cc:Agent> <dc:title>Jakub Steiner</dc:title> </cc:Agent> </dc:contributor> <dc:date>2006</dc:date> <dc:subject> <rdf:Bag> <rdf:li>drive</rdf:li> <rdf:li>removable</rdf:li> <rdf:li>media</rdf:li> </rdf:Bag> </dc:subject> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> <g transform="matrix(2.364027e-2,0,0,3.669526e-2,45.52649,31.53641)" id="g3895"> <rect style="opacity:0.40206185;color:black;fill:url(#linearGradient3903);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect3897" width="1339.6335" height="478.35718" x="-1559.2523" y="-150.69685" /> <path style="opacity:0.40206185;color:black;fill:url(#radialGradient3905);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z " id="path3899" sodipodi:nodetypes="cccc" /> <path sodipodi:nodetypes="cccc" id="path3901" d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z " style="opacity:0.40206185;color:black;fill:url(#radialGradient3907);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> </g> <path style="fill:url(#linearGradient2899);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.06704879px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" d="M 12.84375,8.53125 C 10.231846,8.5312502 8.4897001,10.328989 7.53125,13.34375 C 7.5312501,13.34375 3.78125,30.40625 3.78125,30.40625 C 3.5381132,31.422188 3.5313229,32.466344 3.5,33.5 C 3.5,37.372271 6.6277285,40.500001 10.5,40.5 L 38.5,40.5 C 42.372271,40.5 45.500001,37.372271 45.5,33.5 C 45.4683,32.106734 45.393092,30.781091 45.09375,29.40625 L 40.8125,13.03125 C 39.878744,10.453666 38.12813,8.53125 35.625,8.53125 L 12.84375,8.53125 z " id="path2897" sodipodi:nodetypes="cccsccscccc" /> <path style="opacity:0.4;fill:none;fill-rule:evenodd;stroke:white;stroke-width:0.99999964px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" d="M 39.663187,26.21104 L 36.556647,10.554471" id="path3925" sodipodi:nodetypes="cc" /> <path style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:white;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 12.815683,9.6325097 C 10.75685,9.6325097 9.4360576,10.870456 8.6847245,13.436363 C 8.6847245,13.436363 5.0003906,30.503147 5.0003906,30.503147 C 4.5061245,33.442804 5.9863446,38.132348 10.636644,39.196455 L 38.372114,39.196455 C 43.735507,38.991426 45.340775,34.210036 44.122253,30.127393 C 44.122253,30.127393 39.790203,13.654526 39.790203,13.654526 C 38.996151,11.214602 37.453588,9.5109602 35.48279,9.5109602 L 12.815683,9.6325097 z " id="path2960" sodipodi:nodetypes="ccccccccc" /> <rect style="opacity:1;color:black;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:white;stroke-width:0.99999911;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2909" width="39.993874" height="11.979301" x="4.5061245" y="27.520699" rx="5.8864155" ry="5.9896455" /> <rect ry="4.9305935" rx="4.7874789" y="28.5" x="5.5" height="10" width="38" id="rect2898" style="opacity:0.3;color:black;fill:#babdb6;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3883);stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> <rect style="fill:#babdb6;fill-opacity:1;stroke:url(#linearGradient3769);stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect1949" width="5.9999943" height="1.999993" x="34.560654" y="34.527767" rx="0.99999648" ry="0.99999648" /> <rect style="opacity:1;fill:#d3d7cf;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect1916" width="31" height="4" x="9" y="30" rx="1.09375" ry="1.09375" /> <rect style="opacity:0.8;fill:url(#linearGradient2815);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect2807" width="11" height="7" x="19" y="30" rx="0" ry="0" /> <rect style="opacity:0.5;fill:url(#linearGradient3731);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect3704" width="1" height="4" x="29" y="33" /> <rect style="opacity:0.1;fill:url(#linearGradient3715);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect3706" width="1" height="4" x="19" y="33" /> <path style="fill:#babdb6;fill-opacity:1;stroke:url(#linearGradient2925);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 10.125903,30.500018 L 38.874097,30.500018 C 39.220847,30.500018 39.5,30.72464 39.5,31.003655 L 39.5,31.990388 C 39.5,32.269403 39.220847,32.494025 38.874097,32.494025 L 30,32.494025 L 28.5,33.5 L 20.5,33.5 L 19,32.494025 L 10.125903,32.494025 C 9.7791528,32.494025 9.5,32.269403 9.5,31.990388 L 9.5,31.003655 C 9.5,30.72464 9.7791528,30.500018 10.125903,30.500018 z " id="rect1951" sodipodi:nodetypes="ccccccccccccc" /> <g id="g1933" transform="translate(-1,3)"> <rect ry="0.5" rx="0.51535469" y="32.532925" x="9.5883884" height="1" width="3" id="rect1965" style="fill:#eeeeec;fill-opacity:1;stroke:#eeeeec;stroke-width:0.99999934;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> <path transform="matrix(1.678725,0,0,2.171835,-111.8336,-100.6562)" d="M 73.078125 61.46875 A 0.484375 0.359375 0 1 1 72.109375,61.46875 A 0.484375 0.359375 0 1 1 73.078125 61.46875 z" sodipodi:ry="0.359375" sodipodi:rx="0.484375" sodipodi:cy="61.46875" sodipodi:cx="72.59375" id="path3893" style="color:black;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" sodipodi:type="arc" /> </g> <path style="opacity:1;fill:none;fill-rule:evenodd;stroke:white;stroke-width:0.99999964px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" d="M 8.4628116,26.476205 L 11.677347,10.856247" id="path3921" sodipodi:nodetypes="cc" /> <path style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:white;stroke-width:1.15657115px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" d="M 12.541942,26.343134 L 13.88327,10.410708" id="path3923" sodipodi:nodetypes="cc" /> <path style="opacity:0.4;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.15657115px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" d="M 36.467941,26.254746 L 34.357005,10.406266" id="path3927" sodipodi:nodetypes="cc" /> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-volume-medium.svg������������������������������������������0000644�0000041�0000041�00000104723�13570225707�024145� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="audio-volume-medium.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient id="linearGradient6958"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop6960" /> <stop id="stop6966" offset="0.60000002" style="stop-color:#729fcf;stop-opacity:1;" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop6962" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6700"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6702" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6704" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6628"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6630" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6632" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6546"> <stop style="stop-color:#555753;stop-opacity:1;" offset="0" id="stop6548" /> <stop style="stop-color:#888a85;stop-opacity:1" offset="1" id="stop6550" /> </linearGradient> <linearGradient id="linearGradient6667" inkscape:collect="always"> <stop id="stop6669" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop6671" offset="1" style="stop-color:#555753;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6651"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6653" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6655" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6645" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop6647" /> </linearGradient> <linearGradient id="linearGradient6633" inkscape:collect="always"> <stop id="stop6635" offset="0" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop id="stop6637" offset="1" style="stop-color:#61635f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient6627"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6629" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6631" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6607"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop6609" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6611" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6589"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6591" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6593" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6573"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6575" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6577" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6531"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6533" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6535" /> </linearGradient> <linearGradient id="linearGradient5533"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop5535" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop5537" /> </linearGradient> <linearGradient id="linearGradient21662"> <stop id="stop21664" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.81927711" id="stop21666" /> <stop id="stop21668" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21644"> <stop id="stop21646" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.73493975" id="stop21648" /> <stop id="stop21650" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21622"> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0" id="stop21624" /> <stop id="stop21630" offset="0.85542166" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:1" offset="1" id="stop21626" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient17123"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop17125" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop17127" /> </linearGradient> <linearGradient id="linearGradient9086"> <stop id="stop9088" offset="0" style="stop-color:black;stop-opacity:1;" /> <stop id="stop9090" offset="1" style="stop-color:black;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6387"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop6389" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6391" /> </linearGradient> <linearGradient id="linearGradient6379"> <stop style="stop-color:white;stop-opacity:0;" offset="0" id="stop6381" /> <stop id="stop21606" offset="0.5" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6383" /> </linearGradient> <linearGradient id="linearGradient2793"> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="0" id="stop2795" /> <stop id="stop2801" offset="0.25301206" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop2797" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6387" id="linearGradient6393" x1="17.25" y1="18.81151" x2="16.1875" y2="32.629498" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient9086" id="radialGradient8199" cx="7.1396246" cy="22.5" fx="7.1396246" fy="22.5" r="6" gradientTransform="matrix(1.914836,-0.506192,0.654838,2.477012,-48.62381,-29.61876)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21622" id="radialGradient21684" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21662" id="radialGradient21686" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21644" id="radialGradient21688" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2793" id="linearGradient5545" gradientUnits="userSpaceOnUse" x1="78.5" y1="-4.0065207" x2="78.5" y2="14.00099" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5533" id="linearGradient5547" gradientUnits="userSpaceOnUse" x1="80.0625" y1="14" x2="80.0625" y2="-4.0087729" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6531" id="linearGradient6537" x1="3.8448932" y1="15.561477" x2="3.8448932" y2="39.884338" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6627" id="linearGradient6545" x1="7.75" y1="33.046577" x2="4.6431866" y2="12.063652" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9114584,0,0,0.8787879,2.7005208,4.6666545)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6633" id="radialGradient6553" cx="9.3203983" cy="18.817093" fx="9.3203983" fy="18.817093" r="12.5" gradientTransform="matrix(0.7132478,0.5221478,-0.9280778,1.1784895,22.517143,-6.7083001)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6573" id="linearGradient6579" x1="12.197592" y1="9.2597418" x2="12.197592" y2="47.496857" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6667" id="radialGradient6595" cx="23.164974" cy="30.23279" fx="23.164974" fy="30.23279" r="8.1890125" gradientTransform="matrix(1.7346265,-0.1698771,0.327755,3.6175226,-27.429343,-73.69679)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6589" id="radialGradient6603" cx="20.8839" cy="20.434256" fx="20.8839" fy="20.434256" r="3.9999842" gradientTransform="matrix(1.3093938,0,0,1.5604932,-8.3886376,-9.784483)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6379" id="linearGradient6641" gradientUnits="userSpaceOnUse" x1="20.226221" y1="20.33363" x2="11.4375" y2="21.75" gradientTransform="matrix(0.6666667,0,0,1,2,-1)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6651" id="radialGradient6657" cx="23.986883" cy="27.053167" fx="23.986883" fy="27.053167" r="7.75" gradientTransform="matrix(-0.2432942,0,0,-1.2543129,25.221399,61.870636)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6546" id="linearGradient6558" gradientUnits="userSpaceOnUse" x1="80.693359" y1="31.561478" x2="77.125" y2="14" gradientTransform="translate(-70,2)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6607" id="radialGradient6625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.9866298,0.1169977,0,-2.530036,-104.62676,112.74341)" cx="30.685316" cy="42.261425" fx="30.685316" fy="42.261425" r="8.22791" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6628" id="linearGradient6634" x1="23.238182" y1="12.158657" x2="29.892563" y2="26.354361" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6700" id="linearGradient6706" x1="17.5" y1="25.587416" x2="28.555141" y2="25.699326" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6643" id="linearGradient6801" gradientUnits="userSpaceOnUse" x1="33.430557" y1="45.052155" x2="33.430557" y2="0.31037101" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6976" cx="70.53125" cy="22.734375" fx="70.53125" fy="22.734375" r="3.5975378" gradientTransform="matrix(1.8087117,0,0,3.5234273,-57.039447,-57.368542)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6984" cx="60.640625" cy="22.65625" fx="60.640625" fy="22.65625" r="2.6194003" gradientTransform="matrix(2.1454532,0,0,3.0191635,-69.461,-45.746674)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient17123" id="radialGradient7118" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.330579,0,24.67693)" cx="11.402097" cy="36.863068" fx="11.402097" fy="36.863068" r="10.69499" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="24" inkscape:cy="42.911478" inkscape:document-units="px" inkscape:current-layer="layer2" width="48px" height="48px" inkscape:showpageshadow="false" borderlayer="true" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:window-width="1051" inkscape:window-height="936" inkscape:window-x="14" inkscape:window-y="43" inkscape:guide-points="false" inkscape:grid-points="true" showguides="false" inkscape:guide-bbox="true" showborder="false" inkscape:grid-bbox="true"> <sodipodi:guide orientation="vertical" position="22" id="guide21670" /> <sodipodi:guide orientation="horizontal" position="26" id="guide21672" /> <sodipodi:guide orientation="vertical" position="32" id="guide6673" /> <inkscape:grid type="xygrid" id="grid6385" /> <sodipodi:guide orientation="horizontal" position="2.5" id="guide6925" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Ulisse Perusin</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Audio Volume High</dc:title> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="constr" style="display:none"> <path style="opacity:0.83011588;fill:url(#radialGradient8199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -8.21875,10.5 L -20.21875,22.5 L -8.21875,34.5 L -8.21875,10.5 z " id="path7288" sodipodi:nodetypes="cccc" /> <path style="opacity:0.76833975;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6393);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -7,10.5 L -19,22.5 L -7,34.5 L -7,10.5 z " id="path2791" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50000006" inkscape:original="M 19.5 9.5 C 18 15 12 14 7.5 22.5 C 12 31 18 30 19.5 35.5 L 19.5 9.5 z " style="opacity:0.63320462;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" id="path21580" d="M 19.375,9 C 19.200644,9.0530225 19.06894,9.1967002 19.03125,9.375 C 18.327802,11.954311 16.604417,12.961638 14.34375,14.46875 C 12.083083,15.975862 9.3592888,17.942871 7.0625,22.28125 C 6.9953198,22.419346 6.9953198,22.580654 7.0625,22.71875 C 9.3592888,27.057129 12.083083,29.024138 14.34375,30.53125 C 16.604417,32.038362 18.327802,33.045689 19.03125,35.625 C 19.110592,35.845992 19.333006,35.982016 19.565879,35.951968 C 19.798752,35.92192 19.979353,35.733894 20,35.5 L 20,9.5 C 20.005,9.3425939 19.935556,9.1920293 19.812581,9.0936489 C 19.689605,8.9952685 19.527469,8.9605689 19.375,9 z " transform="translate(-42,0)" /> <path style="fill:none;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -47.5,22.5 L -20,-8 L -20,56 L -47.5,22.5 z " id="path21676" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21684);fill-opacity:1;stroke:#204a87;stroke-width:0.12515022;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21678" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(7.990397,0,0,7.990397,-220.7725,-152.0403)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21686);fill-opacity:1;stroke:#204a87;stroke-width:0.18086948;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21680" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(5.528848,0,0,5.528848,-169.4646,-98.27085)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21688);fill-opacity:1;stroke:#204a87;stroke-width:0.29248634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21682" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(3.418962,0,0,3.418962,-125.4867,-52.18304)" /> </g> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.2;fill:url(#radialGradient7118);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" id="path16236" sodipodi:cx="11.402097" sodipodi:cy="36.863068" sodipodi:rx="10.69499" sodipodi:ry="3.5355339" d="M 22.097087 36.863068 A 10.69499 3.5355339 0 1 1 0.70710659,36.863068 A 10.69499 3.5355339 0 1 1 22.097087 36.863068 z" transform="matrix(1.5365906,0,0,2.4199734,-1.1723206,-56.384863)" /> <path sodipodi:type="arc" style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:1.30267787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path5330" sodipodi:cx="4" sodipodi:cy="25" sodipodi:rx="4" sodipodi:ry="7" d="M 8 25 A 4 7 0 1 1 0,25 A 4 7 0 1 1 8 25 z" transform="matrix(0.75,0,0,0.7857143,1.5,4.357156)" /> <path sodipodi:type="arc" style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6659" sodipodi:cx="3.75" sodipodi:cy="20.75" sodipodi:rx="0.75" sodipodi:ry="0.75" d="M 4.5 20.75 A 0.75 0.75 0 1 1 3,20.75 A 0.75 0.75 0 1 1 4.5 20.75 z" transform="translate(-1.53125,0.65625)" /> <path style="fill:url(#linearGradient5545);fill-opacity:1;stroke:url(#linearGradient5547);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 6.125,15.500014 C 4.1240036,15.500014 2.5000009,19.308036 2.5,24.000014 C 2.5,28.691991 4.1240036,32.500015 6.125,32.500014 L 9.75,32.500014 C 11.750996,32.500014 13.375,28.69199 13.375,24.000014 C 13.375,19.308037 11.750996,15.500014 9.75,15.500014 L 6.125,15.500014 z " id="path2766" sodipodi:nodetypes="csccscc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0054175" inkscape:original="M 5.5 13.5 C 3.292004 13.5 1.500001 17.308022 1.5 22 C 1.5 26.691978 3.292004 30.500001 5.5 30.5 L 9.5 30.5 C 11.707996 30.500001 13.5 26.691976 13.5 22 C 13.5 17.308024 11.707996 13.5 9.5 13.5 L 5.5 13.5 z " style="opacity:0.6;fill:none;fill-opacity:1;stroke:url(#linearGradient6537);stroke-width:1.0577718;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path5556" d="M 5.5,14.5 C 4.974,14.5 4.2339165,15.045895 3.59375,16.40625 C 2.9535835,17.766605 2.5000005,19.78201 2.5,22 C 2.5,24.21799 2.9535834,26.233394 3.59375,27.59375 C 4.2339166,28.954106 4.9740003,29.5 5.5,29.5 L 9.5,29.5 C 10.025999,29.5 10.766083,28.954106 11.40625,27.59375 C 12.046417,26.233394 12.5,24.217988 12.5,22 C 12.5,19.782012 12.046417,17.766606 11.40625,16.40625 C 10.766083,15.045894 10.026,14.5 9.5,14.5 L 5.5,14.5 z " transform="matrix(0.89375,0,0,1,1.265625,2)" /> <path style="opacity:1;fill:url(#linearGradient6558);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 9.696925,16 C 7.656226,16 6.000001,19.57702 6,23.984375 C 6,28.391729 7.656226,31.968751 9.696925,31.96875 L 10.334325,31.96875 C 12.375024,31.96875 14.03125,28.391728 14.03125,23.984375 C 14.03125,19.577021 12.375024,16 10.334325,16 L 9.696925,16 z " id="path6556" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#radialGradient6553);fill-opacity:1;stroke:url(#linearGradient6545);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 8.6250003,24 C 8.6250003,33.227273 17.811975,38.499999 23.500002,38.499999 C 27.437502,38.499999 30.500002,32.003996 30.500002,24 C 30.500002,15.996003 27.437502,9.5000001 23.500002,9.5000001 C 17.811975,9.5000001 8.6250003,14.772728 8.6250003,24 z " id="path1871" sodipodi:nodetypes="cssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6657);fill-opacity:1;stroke:none;stroke-width:0.87802505;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6649" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.3225807,0,0,1.026415,-12.145162,-4.6754711)" /> <path style="opacity:0.7335907;fill:url(#linearGradient6641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M 16,13.375 C 13.416667,14.769678 10.541667,17.570921 8,21.5 C 10.69956,20.373913 13.491292,19.539527 16,19.75 L 16,13.375 z " id="path6639" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0125009" inkscape:original="M 22.8125 5.5 C 16.571923 5.5000002 6.5 11.5 6.5 22 C 6.5 32.500001 16.571923 38.5 22.8125 38.5 C 27.1325 38.499999 30.5 31.107996 30.5 22 C 30.5 12.892005 27.1325 5.5 22.8125 5.5 z " style="opacity:0.58620689;fill:none;fill-opacity:1;stroke:url(#linearGradient6579);stroke-width:1.12734473;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6567" d="M 22.8125,6.5 C 20.016701,6.5000001 16.088488,7.9333131 12.96875,10.59375 C 9.8490125,13.254187 7.5,17.073741 7.5,22 C 7.5,26.92626 9.8490125,30.745813 12.96875,33.40625 C 16.088487,36.066687 20.016701,37.5 22.8125,37.5 C 24.394999,37.5 26.045271,36.056265 27.34375,33.25 C 28.642229,30.443735 29.5,26.429214 29.5,22 C 29.5,17.570787 28.642229,13.556265 27.34375,10.75 C 26.045271,7.943735 24.394999,6.5 22.8125,6.5 z " transform="matrix(0.9034091,0,0,0.8709678,2.8494318,4.8387095)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6595);fill-opacity:1;stroke:url(#linearGradient6801);stroke-width:0.83240509;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path1873" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.2258059,0,0,1.1773585,-8.9515943,-8.892453)" /> <path style="fill:url(#radialGradient6603);fill-opacity:1;stroke:#555753;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 21.616117,24.000008 C 21.616117,26.484005 19.233185,28.49999 17.549734,28.49999 C 15.866281,28.49999 14.500001,26.483992 14.500001,23.999995 C 14.500001,21.515998 15.866281,19.5 17.549734,19.5 C 19.233185,19.5 21.616117,21.51601 21.616117,24.000008 z " id="path3672" sodipodi:nodetypes="csssc" /> <path style="opacity:1;fill:url(#radialGradient6625);fill-opacity:1;stroke:none;stroke-width:0.90347975;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 22,5 C 19.367552,4.9999999 17.141972,7.2498264 15.5625,10.6875 C 13.983028,14.125173 13.03125,18.830125 13.03125,24 C 13.03125,29.169874 13.983028,33.874826 15.5625,37.3125 C 17.141972,40.750172 19.367552,43 22,43 C 24.632449,43 26.858028,40.750173 28.4375,37.3125 C 29.42467,35.163953 30.174611,32.501281 30.59375,29.5625 C 30.606967,29.469828 30.612431,29.374514 30.625,29.28125 C 30.701405,28.714302 30.760731,28.149758 30.8125,27.5625 C 30.863372,27.016086 30.910141,26.469464 30.9375,25.90625 C 30.938938,25.875286 30.936131,25.843507 30.9375,25.8125 C 30.964969,25.216652 30.96875,24.611754 30.96875,24 C 30.96875,23.355639 30.96794,22.720382 30.9375,22.09375 C 30.911649,21.537127 30.860238,20.979033 30.8125,20.4375 C 30.760731,19.850242 30.701405,19.285698 30.625,18.71875 C 30.611503,18.623565 30.607961,18.532009 30.59375,18.4375 C 30.174611,15.498719 29.42467,12.836046 28.4375,10.6875 C 26.858028,7.249826 24.632449,5 22,5 z M 22.5,7 C 24.422274,7.0000002 26.280368,8.7656497 27.6875,11.84375 C 28.566957,13.767562 29.264379,16.179117 29.65625,18.875 C 29.734624,19.414177 29.789845,19.97021 29.84375,20.53125 C 29.89121,21.056658 29.942834,21.584653 29.96875,22.125 C 30.000626,22.745494 30.03125,23.361156 30.03125,24 C 30.03125,24.595745 29.99653,25.170104 29.96875,25.75 C 29.966916,25.790974 29.970711,25.834105 29.96875,25.875 C 29.941175,26.411772 29.893755,26.948299 29.84375,27.46875 C 29.789845,28.029789 29.734624,28.585823 29.65625,29.125 C 29.264379,31.820883 28.566957,34.232438 27.6875,36.15625 C 26.280368,39.23435 24.422274,41 22.5,41 C 20.577727,40.999998 18.719632,39.234351 17.3125,36.15625 C 15.905367,33.078149 14.96875,28.765963 14.96875,24 C 14.96875,19.234036 15.905368,14.92185 17.3125,11.84375 C 18.719631,8.7656496 20.577727,7 22.5,7 z " id="path6605" sodipodi:nodetypes="cssssssssssssssssccssssssssssssssc" /> <path sodipodi:type="arc" style="opacity:0.36637932;fill:none;fill-opacity:1;stroke:url(#linearGradient6634);stroke-width:1.05419946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6615" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(0.9032258,0,0,0.9962264,-0.3064529,-3.8320749)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6661" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-16,5.3125)" /> <path sodipodi:type="arc" style="opacity:0.65517243;fill:none;fill-opacity:1;stroke:url(#linearGradient6706);stroke-width:0.90347946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6698" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.0967748,0,0,1.1169811,-5.6935592,-7.2056602)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path5501" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-5,-1.875)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="waves"> <g style="stroke:#729fcf;display:inline" id="g27916" transform="matrix(0.5164697,0,0,1.2242975,3.5433952,-4.22187)"> <path sodipodi:nodetypes="csc" id="path21632" d="M 67.5625,34.78125 C 71.176369,31.899733 73.499999,27.47788 73.5,22.5 C 73.5,17.793936 71.43603,13.569699 68.15625,10.6875" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6976);stroke-width:1.25757563;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> <g style="stroke:#729fcf;display:inline" id="g28807" transform="matrix(0.3535062,0,0,1.2242975,13.43562,-3.80102)"> <path sodipodi:nodetypes="csc" id="path27920" d="M 58.78125,30.15625 C 61.050824,28.375887 62.5,25.606103 62.5,22.5 C 62.5,19.560794 61.188424,16.939552 59.125,15.15625" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6984);stroke-width:1.52005064;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> </g> </svg> ���������������������������������������������./data/icons/scalable/notification-device-eject.svg�������������������������������������������������0000644�0000041�0000041�00000032667�13570225707�022617� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg7854" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions" sodipodi:docname="media-eject.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/lapo/Desktop/media-icons.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <defs id="defs7856"> <linearGradient id="linearGradient7577"> <stop style="stop-color:#000000;stop-opacity:0.3137255;" offset="0" id="stop7579" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop7581" /> </linearGradient> <linearGradient id="linearGradient7305"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop7307" /> <stop id="stop7313" offset="0.20971029" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.81065089;" offset="0.34936365" id="stop7329" /> <stop id="stop7321" offset="0.42850056" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.52134049" id="stop7323" /> <stop id="stop7317" offset="0.55746967" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.56804734;" offset="0.71001518" id="stop7319" /> <stop id="stop7416" offset="0.74394959" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop7309" /> </linearGradient> <linearGradient id="linearGradient5578" inkscape:collect="always"> <stop id="stop5580" offset="0" style="stop-color:#dedfdd;stop-opacity:1;" /> <stop id="stop5582" offset="1" style="stop-color:#92948f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient5590" inkscape:collect="always"> <stop id="stop5592" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop5594" offset="1" style="stop-color:#ffffff;stop-opacity:0;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7577" id="linearGradient7386" gradientUnits="userSpaceOnUse" x1="23.41782" y1="31.488117" x2="23.67593" y2="36.456322" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7577" id="linearGradient7389" gradientUnits="userSpaceOnUse" x1="22.18045" y1="13.177" x2="24.81955" y2="25.137793" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5578" id="linearGradient7391" gradientUnits="userSpaceOnUse" gradientTransform="translate(-1e-6,0.9375)" x1="24.0625" y1="24.90625" x2="24.0625" y2="11.03125" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5590" id="linearGradient7393" gradientUnits="userSpaceOnUse" x1="21.421875" y1="20.53125" x2="27.488358" y2="46.418182" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7305" id="linearGradient7395" gradientUnits="userSpaceOnUse" x1="0.23498324" y1="37.813007" x2="48.206966" y2="10.116367" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#afafaf" borderopacity="1" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="-137.53856" inkscape:cy="10.827794" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:window-width="872" inkscape:window-height="971" inkscape:window-x="117" inkscape:window-y="27" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:grid-points="true" showborder="true" showguides="false" inkscape:guide-bbox="true" borderlayer="true"> <sodipodi:guide orientation="horizontal" position="13.125" id="guide7377" /> <sodipodi:guide orientation="horizontal" position="5.4800776" id="guide7379" /> <sodipodi:guide orientation="horizontal" position="35" id="guide7492" /> <sodipodi:guide orientation="horizontal" position="48" id="guide7046" /> <sodipodi:guide orientation="horizontal" position="-17.5" id="guide7233" /> <sodipodi:guide orientation="horizontal" position="-29" id="guide7235" /> <sodipodi:guide orientation="horizontal" position="22.097087" id="guide7556" /> <sodipodi:guide orientation="vertical" position="-76.125" id="guide7644" /> <sodipodi:guide orientation="vertical" position="-26.125" id="guide7646" /> <sodipodi:guide orientation="vertical" position="24" id="guide7648" /> <sodipodi:guide orientation="vertical" position="-125.28125" id="guide7665" /> <sodipodi:guide orientation="vertical" position="-175.125" id="guide7667" /> <sodipodi:guide orientation="vertical" position="-225.83223" id="guide7685" /> <sodipodi:guide orientation="vertical" position="-326.06462" id="guide7695" /> </sodipodi:namedview> <metadata id="metadata7859"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Jakub Steiner</dc:title> </cc:Agent> </dc:creator> <dc:source>http://jimmac.musichall.cz</dc:source> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Eject</dc:title> <dc:subject> <rdf:Bag> <rdf:li>media</rdf:li> <rdf:li>eject</rdf:li> <rdf:li>unmount</rdf:li> </rdf:Bag> </dc:subject> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g7422" transform="translate(-88,0)" /> <g id="g7377"> <path sodipodi:nodetypes="ccccccccc" id="path7342" d="M 9.125,30.90625 C 7.9751604,30.90625 6.96875,31.899555 6.96875,33.0625 L 6.96875,36.8125 C 6.96875,37.975447 7.9751547,38.96875 9.125,38.96875 L 38.875,38.96875 C 40.02484,38.96875 41.031253,37.97545 41.03125,36.8125 L 41.03125,33.0625 C 41.03125,31.89955 40.024847,30.90625 38.875,30.90625 L 9.125,30.90625 z " style="opacity:0.4;color:#000000;fill:url(#linearGradient7386);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" /> <rect ry="0.63725162" rx="0.62257558" y="32.4375" x="8.499999" height="5" width="31.000002" id="rect4595" style="color:#000000;fill:#dedfdd;fill-opacity:1;fill-rule:nonzero;stroke:#555753;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" /> <path sodipodi:nodetypes="cccsccsccc" id="path7339" d="M 23.78125,6.90625 C 23.321479,6.9301871 22.896874,7.1597036 22.625,7.53125 L 8.125,27.5625 C 7.7817975,28.030059 7.7321882,28.651386 7.9968518,29.16748 C 8.2615154,29.683574 8.7950298,30.005862 9.375,30 L 38.75,30 C 39.324346,29.994086 39.847091,29.66728 40.10396,29.153542 C 40.360829,28.639805 40.308626,28.025525 39.96875,27.5625 L 25.09375,7.53125 C 24.789314,7.1153075 24.296053,6.8804216 23.78125,6.90625 z " style="opacity:0.4;color:#000000;fill:url(#linearGradient7389);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" /> <path id="path5566" d="M 9.374999,28.46875 L 38.749999,28.46875 L 23.874999,8.4374999 L 9.374999,28.46875 z " style="color:#000000;fill:url(#linearGradient7391);fill-opacity:1;fill-rule:nonzero;stroke:#555753;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" /> <path transform="matrix(1.025279,0,0,1.0257353,-0.6078818,-0.5474494)" d="M 23.875,10.34375 L 11.5625,27.34375 L 36.53125,27.34375 L 23.875,10.34375 z " inkscape:href="#path5566" id="path5586" style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient7393);stroke-width:0.97512734;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" xlink:href="#path5566" inkscape:original="M 23.875 8.4375 L 9.375 28.46875 L 38.75 28.46875 L 23.875 8.4375 z " inkscape:radius="-1.116814" sodipodi:type="inkscape:offset" /> <rect style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" id="rect5598" width="29" height="3" x="9.500001" y="33.4375" /> <path d="M 23.875,9.34375 L 10.4375,27.9375 L 37.6875,27.9375 L 23.875,9.34375 z M 9.125,32.96875 C 9.0648063,32.96875 9.03125,32.995933 9.03125,33.0625 L 9.03125,36.8125 C 9.03125,36.879063 9.064808,36.90625 9.125,36.90625 L 38.875,36.90625 C 38.935194,36.90625 38.96875,36.879065 38.96875,36.8125 L 38.96875,33.0625 C 38.96875,32.995938 38.93519,32.96875 38.875,32.96875 L 9.125,32.96875 z " id="path7326" style="opacity:0.15;color:#000000;fill:url(#linearGradient7395);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate" inkscape:original="M 23.875 8.4375 L 9.375 28.46875 L 38.75 28.46875 L 23.875 8.4375 z M 9.125 32.4375 C 8.7800931 32.4375 8.5 32.709461 8.5 33.0625 L 8.5 36.8125 C 8.5 37.165537 8.7800929 37.4375 9.125 37.4375 L 38.875 37.4375 C 39.219907 37.4375 39.500001 37.165539 39.5 36.8125 L 39.5 33.0625 C 39.5 32.709463 39.219906 32.4375 38.875 32.4375 L 9.125 32.4375 z " inkscape:radius="-0.5416193" sodipodi:type="inkscape:offset" /> </g> </g> </svg> �������������������������������������������������������������������������./data/icons/scalable/notification-keyboard-brightness.svg������������������������������������������0000644�0000041�0000041�00000210707�13570225707�024227� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48.000000px" height="48.000000px" id="svg3304" sodipodi:version="0.32" inkscape:version="0.45" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/devices" sodipodi:docname="input-keyboard.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs3306"> <linearGradient id="linearGradient3042"> <stop style="stop-color:black;stop-opacity:0;" offset="0" id="stop3044" /> <stop id="stop3050" offset="0.5" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3046" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3028"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop3030" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop3032" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5259"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop5261" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5263" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5251"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop5253" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop5255" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient1558"> <stop style="stop-color:#babdb6" offset="0" id="stop1560" /> <stop style="stop-color:#eeeeec" offset="1" id="stop1562" /> </linearGradient> <linearGradient id="linearGradient3907"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3909" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3911" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3899"> <stop style="stop-color:#eeeeec" offset="0" id="stop3901" /> <stop style="stop-color:#d3d7cf" offset="1" id="stop3903" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient3915" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1685" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1687" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1689" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1691" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1693" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1695" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1697" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1699" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1701" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1703" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1705" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1707" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1709" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1711" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1713" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1715" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1717" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1719" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1721" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1723" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1725" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1727" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1729" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1731" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1733" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1735" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1737" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1739" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1741" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1743" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1745" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1747" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1749" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1751" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1753" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1755" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1757" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1759" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1761" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1763" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1765" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1767" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1769" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1771" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1773" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1775" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1777" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1779" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1783" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1785" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1787" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1789" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1791" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1793" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1795" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1797" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1799" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1801" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1803" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3907" id="radialGradient1805" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.382603,3.581398e-5,0,0.171503,-6.729684,34.0972)" cx="20.913568" cy="47.045319" fx="20.913568" fy="47.045319" r="19.5" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient1558" id="linearGradient1564" x1="16.396038" y1="19.659277" x2="16.396038" y2="32.448051" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5251" id="linearGradient5257" x1="32.864544" y1="13.794194" x2="32.864544" y2="5.5441942" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5259" id="linearGradient5265" x1="18.390438" y1="15.705806" x2="18.390438" y2="5.0808058" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.973504,0,1.228642)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3899" id="linearGradient3018" x1="26.5" y1="43.249905" x2="26.5" y2="35.75" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3028" id="radialGradient3034" cx="2.9999995" cy="33.214287" fx="2.9999995" fy="33.214287" r="3" gradientTransform="matrix(0,-0.750002,1.333334,0,-40.28573,35.00001)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3028" id="radialGradient3038" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0,-0.750002,1.333334,0,-88.28573,-30.49999)" cx="2.9999995" cy="33.214287" fx="2.9999995" fy="33.214287" r="3" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3042" id="linearGradient3048" x1="37.03125" y1="35.062885" x2="37.03125" y2="29.995127" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.888889,0,3.833333)" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#849193" borderopacity="1.0000000" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="47.386599" inkscape:cy="0.8079723" inkscape:current-layer="layer3" showgrid="false" inkscape:grid-bbox="true" inkscape:document-units="px" inkscape:showpageshadow="false" showborder="false" inkscape:window-width="1041" inkscape:window-height="745" inkscape:window-x="229" inkscape:window-y="229" showguides="true" inkscape:guide-bbox="true" inkscape:grid-points="false" stroke="#babdb6" fill="#888a85" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" borderlayer="top" /> <metadata id="metadata3309"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title>Keyboard</dc:title> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:subject> <rdf:Bag /> </dc:subject> <dc:contributor> <cc:Agent> <dc:title>Jakub Steiner</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="tastiera" style="display:inline"> <g style="display:inline" id="g2932"> <path sodipodi:nodetypes="czzc" id="path1541" d="M 33.050044,28.000002 C 25.031634,17.205412 50,24.993444 46.5,19.639172 C 43,14.2849 17,21.58618 19,16.231908 C 20.840343,11.305061 34.5,17.205412 32,5.0366119" style="opacity:0.10112359;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5265);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" /> <path sodipodi:nodetypes="czzc" id="path4172" d="M 33.050044,27.088388 C 25.031634,16 50,24 46.5,18.5 C 43,13 17,20.5 19,15 C 20.840343,9.939058 34.5,16 32,3.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5257);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" /> </g> <g id="g3052" style="opacity:0.4"> <rect y="30.5" x="0" height="4.5" width="4" id="rect3026" style="opacity:1;fill:url(#radialGradient3034);fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <rect transform="scale(-1,-1)" y="-35" x="-48" height="4.5" width="4" id="rect3036" style="opacity:1;fill:url(#radialGradient3038);fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" /> <rect y="30.5" x="4" height="4.5" width="40" id="rect3040" style="opacity:1;fill:url(#linearGradient3048);fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> </g> <g id="g2928" transform="translate(0,-12)"> <path sodipodi:nodetypes="ccccccccc" id="rect2024" d="M 5.3125,37.5 C 4.344614,37.5 3.4647369,37.878926 2.875,39.15625 L 1.0625,43.03125 C 0.253847,44.43186 0.90611493,45.5 3.65625,45.5 L 44.09375,45.5 C 46.843885,45.5 47.496153,44.43186 46.6875,43.03125 L 44.875,39.15625 C 44.285263,37.878926 43.405386,37.5 42.4375,37.5 L 5.3125,37.5 z " style="opacity:1;fill:url(#linearGradient3018);fill-opacity:1;stroke:#888a85;stroke-width:1.00000393;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" /> <path d="M 5.3125,38.5 C 4.6056131,38.5 4.2438621,38.560518 3.78125,39.5625 C 3.7814128,39.572916 3.7814128,39.583334 3.78125,39.59375 L 1.96875,43.46875 C 1.9590645,43.489941 1.9486415,43.510787 1.9375,43.53125 C 1.7919626,43.783325 1.7523439,43.95868 1.75,44.03125 C 1.7476561,44.10382 1.7146856,44.086521 1.75,44.125 C 1.8206288,44.201958 2.4106476,44.5 3.65625,44.5 L 44.09375,44.5 C 45.339352,44.5 45.929371,44.201958 46,44.125 C 46.035314,44.086521 46.002344,44.10382 46,44.03125 C 45.997656,43.95868 45.958037,43.783325 45.8125,43.53125 C 45.801358,43.510787 45.790935,43.489941 45.78125,43.46875 L 43.96875,39.59375 C 43.968587,39.583334 43.968587,39.572916 43.96875,39.5625 C 43.506138,38.560518 43.144387,38.5 42.4375,38.5 L 5.3125,38.5 z " id="path2920" style="opacity:1;fill:none;fill-opacity:0.46875;stroke:white;stroke-width:1.00000393;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;display:inline" inkscape:original="M 5.3125 37.5 C 4.344614 37.5 3.4647369 37.878926 2.875 39.15625 L 1.0625 43.03125 C 0.253847 44.43186 0.90611493 45.5 3.65625 45.5 L 44.09375 45.5 C 46.843885 45.5 47.496153 44.43186 46.6875 43.03125 L 44.875 39.15625 C 44.285263 37.878926 43.405386 37.5 42.4375 37.5 L 5.3125 37.5 z " inkscape:radius="-1" sodipodi:type="inkscape:offset" /> </g> <g id="g3270" inkscape:label="Shadow" transform="translate(-54,0.18088)" /> <g transform="translate(-54,15.24691)" inkscape:label="Shadow" id="g2611" /> <g transform="translate(-54,15.24691)" style="display:inline" inkscape:label="Lavoro" id="g2613" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="tasti" style="display:inline"> <g id="g2937" transform="translate(0,-5.891786e-3)"> <path sodipodi:nodetypes="csssssssccssssssssssssccccssscccccccccssssssssssssccsssssssssccccccc" id="path2318" d="M 6.4347661,24.507053 C 6.4317205,24.510744 6.4375418,24.53537 6.4347661,24.538265 C 6.4200966,24.543167 6.3845459,24.56252 6.3695323,24.56948 C 6.3645221,24.572029 6.3419152,24.566699 6.3369154,24.56948 C 6.3319424,24.572491 6.3092285,24.597449 6.3042985,24.600693 C 6.2945571,24.607645 6.2810884,24.624016 6.2716816,24.631905 C 6.2670862,24.636085 6.2435357,24.658704 6.2390646,24.663119 C 6.2347341,24.66777 6.2106216,24.689443 6.2064478,24.694332 C 6.1415771,24.784354 6.0732619,24.940856 5.9781294,25.131316 L 3.7505791,29.875725 C 3.7505791,29.881659 3.7503509,29.900989 3.7505791,29.906936 C 3.7510318,29.912892 3.7499054,29.932195 3.7505791,29.938149 C 3.75147,29.944102 3.7494744,29.963422 3.7505791,29.969364 C 3.7532082,29.981212 3.779749,30.020039 3.783196,30.031789 C 3.7851186,30.037631 3.7810782,30.057198 3.783196,30.063004 C 3.7901248,30.080277 3.8072241,30.108662 3.8158129,30.125428 C 3.8249331,30.141993 3.8377813,30.172006 3.8484298,30.187856 C 3.8521419,30.193047 3.8771758,30.213972 3.8810467,30.219068 C 3.8850729,30.224062 3.9094858,30.245397 3.9136636,30.250283 C 3.9396179,30.27891 3.980694,30.320118 4.0115143,30.34392 C 4.0167734,30.347735 4.0387534,30.37148 4.0441313,30.375135 C 4.0606293,30.384623 4.0914877,30.397744 4.1093651,30.406347 C 4.2295926,30.459179 4.3886481,30.499987 4.5333849,30.499987 L 27.648028,30.499987 L 27.550177,24.50706 L 6.7609352,24.507053 C 6.6924209,24.507053 6.6171731,24.504727 6.5652338,24.507053 C 6.553081,24.507121 6.5132034,24.507666 6.5,24.507053 C 6.4959728,24.507082 6.4710409,24.506796 6.467383,24.507053 C 6.4645589,24.509905 6.4378118,24.503362 6.4347661,24.507053 z M 29.474575,24.50706 L 29.572425,26.504703 L 35.215151,26.504703 L 34.954216,24.50706 L 29.474575,24.50706 z M 36.91123,24.50706 L 38.08544,30.499987 L 43.304145,30.499987 C 43.448881,30.499987 43.607937,30.459179 43.728165,30.406347 C 43.746042,30.397744 43.7769,30.384623 43.793398,30.375135 C 43.798775,30.37148 43.820755,30.347735 43.826015,30.34392 C 43.856836,30.320118 43.897912,30.27891 43.923866,30.250283 C 43.928044,30.245397 43.952458,30.224062 43.956482,30.219068 C 43.960354,30.213972 43.985388,30.193047 43.9891,30.187856 C 43.999748,30.172006 44.012596,30.141993 44.021717,30.125428 C 44.030306,30.108662 44.047405,30.080277 44.054334,30.063004 C 44.056451,30.057198 44.052411,30.037631 44.054334,30.031789 C 44.057781,30.020039 44.084321,29.981212 44.086951,29.969364 C 44.088055,29.963422 44.086059,29.944102 44.086951,29.938149 C 44.087624,29.932195 44.086497,29.912892 44.086951,29.906936 C 44.08718,29.900989 44.086951,29.881659 44.086951,29.875725 L 42.260936,25.131316 C 42.165803,24.940857 42.097488,24.784354 42.032617,24.694332 C 42.028443,24.689443 42.00433,24.66777 42,24.663119 C 41.995529,24.658704 41.971979,24.636085 41.967383,24.631905 C 41.957976,24.624016 41.944507,24.607645 41.934766,24.600693 C 41.929837,24.597449 41.907123,24.572491 41.90215,24.56948 C 41.897149,24.566699 41.874542,24.572029 41.869533,24.56948 C 41.854519,24.56252 41.818969,24.543167 41.804299,24.538265 C 41.788182,24.534545 41.762732,24.513592 41.739064,24.507053 C 41.727189,24.504057 41.684711,24.508748 41.673831,24.507053 C 41.621891,24.504727 41.546644,24.507053 41.47813,24.507053 L 36.91123,24.50706 z M 30.779252,28.502344 L 29.735511,30.499987 L 35.737022,30.499987 L 34.432345,28.502344 L 30.779252,28.502344 z " style="color:black;fill:url(#linearGradient1564);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:0.99999934;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> <g transform="translate(0,-14)" style="opacity:1;fill:url(#radialGradient3915);fill-opacity:1" id="g3822"> <rect style="opacity:1;color:black;fill:url(#radialGradient1685);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2340" width="1" height="1" x="7" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1687);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2342" width="1" height="1" x="9" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1689);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2344" width="1" height="1" x="11" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1691);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2346" width="1" height="1" x="13" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1693);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2348" width="1" height="1" x="15" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1695);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2350" width="1" height="1" x="17" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1697);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2352" width="1" height="1" x="19" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1699);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2354" width="1" height="1" x="21" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1701);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2356" width="1" height="1" x="6" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1703);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2358" width="1" height="1" x="8" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1705);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2360" width="1" height="1" x="10" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1707);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2362" width="1" height="1" x="12" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1709);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2364" width="1" height="1" x="14" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1711);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2366" width="1" height="1" x="16" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1713);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2368" width="1" height="1" x="18" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2370" width="1" height="1" x="20" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2372" width="1" height="1" x="7" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2374" width="1" height="1" x="9" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1721);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2376" width="1" height="1" x="11" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1723);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2378" width="1" height="1" x="13" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1725);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2380" width="1" height="1" x="15" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1727);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2382" width="1" height="1" x="17" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1729);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2384" width="1" height="1" x="19" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1731);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2386" width="1" height="1" x="21" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1733);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2388" width="1" height="1" x="6" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1735);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2390" width="1" height="1" x="8" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1737);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2392" width="1" height="1" x="10" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1739);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2394" width="1" height="1" x="12" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1741);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2396" width="1" height="1" x="14" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1743);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2398" width="1" height="1" x="16" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1745);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2400" width="1" height="1" x="18" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1747);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2402" width="1" height="1" x="20" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1749);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2412" width="1" height="1" x="5" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1751);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2414" width="1" height="1" x="7" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1753);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2428" width="1" height="1" x="22" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1755);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2430" width="1" height="1" x="23" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1757);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2432" width="1" height="1" x="22" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1759);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2434" width="1" height="1" x="23" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1761);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2436" width="1" height="1" x="24" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1763);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2438" width="1" height="1" x="25" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1765);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2440" width="1" height="1" x="26" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1767);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2442" width="1" height="1" x="25" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1769);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2444" width="1" height="1" x="24" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1771);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2446" width="1" height="1" x="26" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1773);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2448" width="1" height="1" x="25" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1775);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2450" width="1" height="1" x="23" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1777);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2454" width="1" height="1" x="31" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1779);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2456" width="1" height="1" x="33" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1783);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2462" width="1" height="1" x="31" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1785);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2464" width="1" height="1" x="33" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1787);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2466" width="1" height="1" x="37" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1789);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2468" width="1" height="1" x="38" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1791);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2470" width="1" height="1" x="39" y="39" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1793);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2474" width="1" height="1" x="41" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1795);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2476" width="1" height="1" x="39" y="41" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1797);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2480" width="1" height="1" x="38" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1799);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect2482" width="1" height="1" x="40" y="42" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1801);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect3810" width="1" height="1" x="41" y="43" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1803);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect3812" width="1" height="1" x="40" y="40" rx="0.26516503" ry="0.26516503" /> <rect style="opacity:1;color:black;fill:url(#radialGradient1805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="rect3814" width="1" height="1" x="43" y="43" rx="0.26516503" ry="0.26516503" /> </g> </g> </g> </svg> ���������������������������������������������������������./data/icons/scalable/notification-audio-play.svg���������������������������������������������������0000644�0000041�0000041�00000023364�13570225707�022326� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg7854" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions" sodipodi:docname="media-playback-start.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/lapo/Desktop/media-icons.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <defs id="defs7856"> <linearGradient id="linearGradient7577"> <stop style="stop-color:#000000;stop-opacity:0.3137255;" offset="0" id="stop7579" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop7581" /> </linearGradient> <linearGradient id="linearGradient7305"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop7307" /> <stop id="stop7313" offset="0.20971029" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.81065089;" offset="0.34936365" id="stop7329" /> <stop id="stop7321" offset="0.42850056" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.52134049" id="stop7323" /> <stop id="stop7317" offset="0.55746967" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.56804734;" offset="0.71001518" id="stop7319" /> <stop id="stop7416" offset="0.74394959" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop7309" /> </linearGradient> <linearGradient id="linearGradient7344" inkscape:collect="always"> <stop id="stop7346" offset="0" style="stop-color:#eeeeec;stop-opacity:1" /> <stop id="stop7348" offset="1" style="stop-color:#92948f;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7577" id="linearGradient7865" gradientUnits="userSpaceOnUse" x1="-177.27766" y1="9.2039175" x2="-172.82857" y2="25.808161" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient7867" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.7391664,0,0,2.2478596,-274.85735,-10.683483)" cx="36.126339" cy="18.020473" fx="36.126339" fy="18.020473" r="13.55237" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7305" id="linearGradient7869" gradientUnits="userSpaceOnUse" x1="-0.11694507" y1="10.14653" x2="48.025963" y2="37.941853" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#afafaf" borderopacity="1" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="-137.53856" inkscape:cy="10.827794" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:window-width="872" inkscape:window-height="971" inkscape:window-x="117" inkscape:window-y="27" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:grid-points="true" showborder="true" showguides="false" inkscape:guide-bbox="true" borderlayer="true"> <sodipodi:guide orientation="horizontal" position="13.125" id="guide7377" /> <sodipodi:guide orientation="horizontal" position="5.4800776" id="guide7379" /> <sodipodi:guide orientation="horizontal" position="35" id="guide7492" /> <sodipodi:guide orientation="horizontal" position="48" id="guide7046" /> <sodipodi:guide orientation="horizontal" position="-17.5" id="guide7233" /> <sodipodi:guide orientation="horizontal" position="-29" id="guide7235" /> <sodipodi:guide orientation="horizontal" position="22.097087" id="guide7556" /> <sodipodi:guide orientation="vertical" position="-76.125" id="guide7644" /> <sodipodi:guide orientation="vertical" position="-26.125" id="guide7646" /> <sodipodi:guide orientation="vertical" position="24" id="guide7648" /> <sodipodi:guide orientation="vertical" position="-125.28125" id="guide7665" /> <sodipodi:guide orientation="vertical" position="-175.125" id="guide7667" /> <sodipodi:guide orientation="vertical" position="-225.83223" id="guide7685" /> <sodipodi:guide orientation="vertical" position="-326.06462" id="guide7695" /> </sodipodi:namedview> <metadata id="metadata7859"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:source /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Play</dc:title> <dc:subject> <rdf:Bag> <rdf:li>play</rdf:li> <rdf:li>playback</rdf:li> <rdf:li>start</rdf:li> <rdf:li>begin</rdf:li> </rdf:Bag> </dc:subject> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g7138" transform="translate(200,0)"> <path d="M -186.59375,9 C -187.38473,9.0508993 -188.00018,9.7073844 -188,10.5 L -188,37.5 C -187.99205,38.031998 -187.70339,38.520136 -187.24104,38.783419 C -186.77869,39.046702 -186.21158,39.045877 -185.75,38.78125 L -162.75,25.28125 C -162.30425,25.008049 -162.03253,24.522812 -162.03253,24 C -162.03253,23.477188 -162.30425,22.991951 -162.75,22.71875 L -185.75,9.21875 C -186.00346,9.0640763 -186.29707,8.9879569 -186.59375,9 L -186.59375,9 z " id="path7671" style="opacity:0.4;fill:url(#linearGradient7865);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999982;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M -186.5 10.5 L -186.5 37.5 L -163.5 24 L -186.5 10.5 z " inkscape:radius="1.5026019" sodipodi:type="inkscape:offset" /> <g id="g7515"> <path sodipodi:nodetypes="cccc" id="path7812" d="M -186.5,37.500001 L -186.5,10.500456 L -163.5,24.012458 L -186.5,37.500001 z " style="fill:url(#radialGradient7867);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:0.99999982;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:nodetypes="cccc" id="path7828" d="M -185.5,35.750028 L -185.5,12.250428 L -165.5,24.010872 L -185.5,35.750028 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999982;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.5" inkscape:original="M 13.5 10.5 C 13.5 19.499848 13.5 28.500152 13.5 37.5 C 21.166667 33.004153 28.833333 28.495847 36.5 24 C 28.833333 19.495999 21.166667 15.004001 13.5 10.5 z " style="opacity:0.15;fill:url(#linearGradient7869);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999982;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" id="path7354" d="M 14,11.375 C 14,19.791551 14,28.208449 14,36.625 C 21.167154,32.421341 28.332238,28.204015 35.5,24 C 28.332835,19.790152 21.16775,15.585191 14,11.375 z " transform="matrix(1,0,0,-1,-200,48)" /> </g> </g> </g> </svg> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-network-wireless.svg���������������������������������������������0000644�0000041�0000041�00000040411�13570225707�023576� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" inkscape:label="Pozadí" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/devices" sodipodi:docname="network-wireless.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/cornelius/Desktop/rb-radio.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <defs id="defs3"> <linearGradient id="linearGradient6979"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop6981" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6983" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6963"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6965" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6967" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7153"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7155" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7157" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7131"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop7133" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop7135" /> </linearGradient> <linearGradient id="linearGradient7101"> <stop id="stop7103" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop7105" offset="1" style="stop-color:#ffffff;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3374"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop3376" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop3378" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3362"> <stop style="stop-color:#3465a4;stop-opacity:1;" offset="0" id="stop3364" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="1" id="stop3366" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3268"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3270" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3272" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3268" id="radialGradient5998" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.3025696,0,13.599894)" cx="10.737437" cy="19.5" fx="10.737437" fy="19.5" r="8.2625628" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3374" id="radialGradient6000" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8273492,0,1.1222303)" cx="10.28125" cy="8.0709476" fx="10.28125" fy="8.0709476" r="4.5250292" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="radialGradient6002" gradientUnits="userSpaceOnUse" gradientTransform="matrix(4.680847,0,0,1.2767377,-37.843708,-3.3008494)" cx="10.28125" cy="9.8424416" fx="10.28125" fy="9.8424416" r="4.5250292" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3374" id="radialGradient6004" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.6984472,0,0,0.5778597,3.1003396,2.7439118)" cx="10.28125" cy="7.8249326" fx="10.28125" fy="7.8249326" r="4.5250292" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="radialGradient6006" gradientUnits="userSpaceOnUse" gradientTransform="matrix(4.680847,0,0,1.2767377,-37.843708,-3.3008494)" cx="10.28125" cy="9.8424416" fx="10.28125" fy="9.8424416" r="4.5250292" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7101" id="linearGradient7121" gradientUnits="userSpaceOnUse" x1="24.837126" y1="44.528019" x2="21.036427" y2="21.041553" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3374" id="radialGradient7127" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.8273492,0,1.1222303)" cx="10.28125" cy="8.0709476" fx="10.28125" fy="8.0709476" r="4.5250292" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3362" id="radialGradient7129" gradientUnits="userSpaceOnUse" gradientTransform="matrix(4.680847,0,0,1.2767377,-37.843708,-3.3008494)" cx="10.28125" cy="10.018439" fx="10.28125" fy="10.018439" r="4.5250292" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7131" id="radialGradient7137" cx="8.9057236" cy="1.7286602" fx="8.9057236" fy="1.7286602" r="1.9952321" gradientTransform="matrix(0.7375073,0,0,0.7201806,2.4345312,0.6617371)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7153" id="radialGradient7159" cx="8.3046875" cy="1.1256332" fx="8.3046875" fy="1.1256332" r="2.0507698" gradientTransform="matrix(1.8597707,0,0,1.8172614,-7.1401269,-0.8942366)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6963" id="linearGradient6969" x1="11.22532" y1="43.135109" x2="11.22532" y2="23.038107" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6979" id="linearGradient6985" x1="39.06765" y1="28.5" x2="39.421204" y2="10.934953" gradientUnits="userSpaceOnUse" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="25.726296" inkscape:cy="24.620451" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:grid-points="true" inkscape:guide-points="true" showgrid="false" inkscape:window-width="949" inkscape:window-height="791" inkscape:window-x="15" inkscape:window-y="72" showborder="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" showguides="false" inkscape:guide-bbox="true"> <sodipodi:guide orientation="vertical" position="24" id="guide6037" /> <sodipodi:guide orientation="horizontal" position="33" id="guide6039" /> </sodipodi:namedview> <metadata id="metadata6"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:title>Network Wireless</dc:title> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Vrstva 1" inkscape:groupmode="layer" id="layer1"> <path sodipodi:type="arc" style="opacity:0.1;fill:url(#radialGradient5998);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path3258" sodipodi:cx="10.737437" sodipodi:cy="19.5" sodipodi:rx="8.2625628" sodipodi:ry="2.5" d="M 19 19.5 A 8.2625628 2.5 0 1 1 2.4748745,19.5 A 8.2625628 2.5 0 1 1 19 19.5 z" transform="matrix(2.3050967,0,0,2.3778947,-1.1985194,-5.819495)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient7127);fill-opacity:1;stroke:url(#radialGradient7129);stroke-width:0.19966908;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;opacity:0.6" id="path7125" sodipodi:cx="10.28125" sodipodi:cy="6.5" sodipodi:rx="4.28125" sodipodi:ry="3.5" d="M 14.5625 6.5 A 4.28125 3.5 0 1 1 6,6.5 A 4.28125 3.5 0 1 1 14.5625 6.5 z" transform="matrix(4.5547445,0,0,5.5069915,-22.828467,-20.795445)" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.45069391" inkscape:original="M 24 13 L 8 44 L 11.5 44 L 14.0625 38.6875 L 35.6875 42.3125 L 36.5 44 L 40 44 L 24 13 z M 24 17.96875 L 28 26.3125 L 20.90625 24.46875 L 24 17.96875 z M 20 26.3125 L 27.28125 28.1875 L 16.625 33.375 L 20 26.3125 z M 29.65625 29.78125 L 34.09375 39 L 16.65625 36.09375 L 29.65625 29.78125 z " style="opacity:0.15298504;fill:url(#linearGradient6969);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path6961" d="M 23.875,12.5625 C 23.755186,12.593695 23.653478,12.672801 23.59375,12.78125 L 7.59375,43.78125 C 7.5217395,43.921791 7.5285298,44.089768 7.6116494,44.224038 C 7.694769,44.358309 7.8420946,44.439288 8,44.4375 L 11.5,44.4375 C 11.672029,44.438521 11.829638,44.341531 11.90625,44.1875 L 14.3125,39.1875 L 35.375,42.71875 L 36.09375,44.1875 C 36.170362,44.341531 36.327971,44.438521 36.5,44.4375 L 40,44.4375 C 40.157905,44.439288 40.305231,44.358309 40.388351,44.224038 C 40.47147,44.089768 40.478261,43.921791 40.40625,43.78125 L 24.40625,12.78125 C 24.304601,12.590301 24.081632,12.498491 23.875,12.5625 L 23.875,12.5625 z M 24,19 L 27.1875,25.625 L 21.53125,24.15625 L 24,19 z M 20.25,26.84375 L 25.96875,28.3125 L 17.59375,32.40625 L 20.25,26.84375 z M 29.4375,30.375 L 33.3125,38.4375 L 18.09375,35.875 L 29.4375,30.375 z " transform="matrix(1,0,0,0.4005165,0,26.139566)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6000);fill-opacity:1;stroke:url(#radialGradient6002);stroke-width:0.26853403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;opacity:0.8" id="path3319" sodipodi:cx="10.28125" sodipodi:cy="6.5" sodipodi:rx="4.28125" sodipodi:ry="3.5" d="M 14.5625 6.5 A 4.28125 3.5 0 1 1 6,6.5 A 4.28125 3.5 0 1 1 14.5625 6.5 z" transform="matrix(3.3868613,0,0,4.0945293,-10.821168,-11.614441)" /> <g id="g7115" transform="translate(0,-0.5)"> <path id="path7060" d="M 24,13 L 8,44 L 11.5,44 L 14.0625,38.6875 L 35.6875,42.3125 L 36.5,44 L 40,44 L 24,13 z M 24,17.96875 L 28,26.3125 L 20.90625,24.46875 L 24,17.96875 z M 20,26.3125 L 27.28125,28.1875 L 16.625,33.375 L 20,26.3125 z M 29.65625,29.78125 L 34.09375,39 L 16.65625,36.09375 L 29.65625,29.78125 z " style="fill:url(#linearGradient7121);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient6985);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccc" id="path7092" d="M 38.40625,43.03125 L 24,15.125 L 9.59375,43.03125" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7097" d="M 15.78125,34.90625 L 28.8125,28.5625" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7099" d="M 15.09375,36.84375 L 34.75,40.125" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> </g> <path sodipodi:type="arc" style="fill:url(#radialGradient6004);fill-opacity:1;stroke:url(#radialGradient6006);stroke-width:0.40747008;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path3382" sodipodi:cx="10.28125" sodipodi:cy="6.5" sodipodi:rx="4.28125" sodipodi:ry="3.5" d="M 14.5625 6.5 A 4.28125 3.5 0 1 1 6,6.5 A 4.28125 3.5 0 1 1 14.5625 6.5 z" transform="matrix(2.2189781,0,0,2.7142858,1.1861314,-2.6428575)" /> <g id="g3232" transform="matrix(2.2398427,0,0,2.230092,-19.676933,9.388622)"> <path transform="matrix(1.1130433,0,0,1.1428572,9.2565233,-7.1428636e-2)" d="M 11 2.25 A 1.796875 1.75 0 1 1 7.40625,2.25 A 1.796875 1.75 0 1 1 11 2.25 z" sodipodi:ry="1.75" sodipodi:rx="1.796875" sodipodi:cy="2.25" sodipodi:cx="9.203125" id="path3234" style="opacity:1;fill:url(#radialGradient7137);fill-opacity:1.0;stroke:#555753;stroke-width:0.39671427;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" sodipodi:type="arc" /> <path transform="matrix(1.8125,0,0,1.8125,-16.465404,-0.9288198)" d="M 20 1.5 A 0.5 0.5 0 1 1 19,1.5 A 0.5 0.5 0 1 1 20 1.5 z" sodipodi:ry="0.5" sodipodi:rx="0.5" sodipodi:cy="1.5" sodipodi:cx="19.5" id="path3236" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" sodipodi:type="arc" /> </g> <path sodipodi:type="arc" style="fill:none;fill-opacity:1;stroke:url(#radialGradient7159);stroke-width:0.50778961;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path7147" sodipodi:cx="9.203125" sodipodi:cy="2.25" sodipodi:rx="1.796875" sodipodi:ry="1.75" d="M 11 2.25 A 1.796875 1.75 0 1 1 7.40625,2.25 A 1.796875 1.75 0 1 1 11 2.25 z" transform="matrix(1.9478265,0,0,1.9910495,6.0739089,10.483991)" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-volume-off.svg���������������������������������������������0000644�0000041�0000041�00000102570�13570225707�023435� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.46" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="notification-audio-volume-off.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 24 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="48 : 24 : 1" inkscape:persp3d-origin="24 : 16 : 1" id="perspective134" /> <linearGradient id="linearGradient6958"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop6960" /> <stop id="stop6966" offset="0.60000002" style="stop-color:#729fcf;stop-opacity:1;" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop6962" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6700"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6702" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6704" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6628"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6630" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6632" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6546"> <stop style="stop-color:#555753;stop-opacity:1;" offset="0" id="stop6548" /> <stop style="stop-color:#888a85;stop-opacity:1" offset="1" id="stop6550" /> </linearGradient> <linearGradient id="linearGradient6667" inkscape:collect="always"> <stop id="stop6669" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop6671" offset="1" style="stop-color:#555753;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6651"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6653" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6655" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6645" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop6647" /> </linearGradient> <linearGradient id="linearGradient6633" inkscape:collect="always"> <stop id="stop6635" offset="0" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop id="stop6637" offset="1" style="stop-color:#61635f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient6627"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6629" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6631" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6607"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop6609" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6611" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6589"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6591" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6593" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6573"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6575" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6577" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6531"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6533" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6535" /> </linearGradient> <linearGradient id="linearGradient5533"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop5535" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop5537" /> </linearGradient> <linearGradient id="linearGradient21662"> <stop id="stop21664" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.81927711" id="stop21666" /> <stop id="stop21668" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21644"> <stop id="stop21646" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.73493975" id="stop21648" /> <stop id="stop21650" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21622"> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0" id="stop21624" /> <stop id="stop21630" offset="0.85542166" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:1" offset="1" id="stop21626" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient17123"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop17125" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop17127" /> </linearGradient> <linearGradient id="linearGradient9086"> <stop id="stop9088" offset="0" style="stop-color:black;stop-opacity:1;" /> <stop id="stop9090" offset="1" style="stop-color:black;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6387"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop6389" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6391" /> </linearGradient> <linearGradient id="linearGradient6379"> <stop style="stop-color:white;stop-opacity:0;" offset="0" id="stop6381" /> <stop id="stop21606" offset="0.5" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6383" /> </linearGradient> <linearGradient id="linearGradient2793"> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="0" id="stop2795" /> <stop id="stop2801" offset="0.25301206" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop2797" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6387" id="linearGradient6393" x1="17.25" y1="18.81151" x2="16.1875" y2="32.629498" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient9086" id="radialGradient8199" cx="7.1396246" cy="22.5" fx="7.1396246" fy="22.5" r="6" gradientTransform="matrix(1.914836,-0.506192,0.654838,2.477012,-48.62381,-29.61876)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21622" id="radialGradient21684" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21662" id="radialGradient21686" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21644" id="radialGradient21688" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2793" id="linearGradient5545" gradientUnits="userSpaceOnUse" x1="78.5" y1="-4.0065207" x2="78.5" y2="14.00099" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5533" id="linearGradient5547" gradientUnits="userSpaceOnUse" x1="80.0625" y1="14" x2="80.0625" y2="-4.0087729" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6531" id="linearGradient6537" x1="3.8448932" y1="15.561477" x2="3.8448932" y2="39.884338" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6627" id="linearGradient6545" x1="7.75" y1="33.046577" x2="4.6431866" y2="12.063652" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9114584,0,0,0.8787879,2.7005208,4.6666545)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6633" id="radialGradient6553" cx="9.3203983" cy="18.817093" fx="9.3203983" fy="18.817093" r="12.5" gradientTransform="matrix(0.7132478,0.5221478,-0.9280778,1.1784895,22.517143,-6.7083001)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6573" id="linearGradient6579" x1="12.197592" y1="9.2597418" x2="12.197592" y2="47.496857" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6667" id="radialGradient6595" cx="23.164974" cy="30.23279" fx="23.164974" fy="30.23279" r="8.1890125" gradientTransform="matrix(1.7346265,-0.1698771,0.327755,3.6175226,-27.429343,-73.69679)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6589" id="radialGradient6603" cx="20.8839" cy="20.434256" fx="20.8839" fy="20.434256" r="3.9999842" gradientTransform="matrix(1.3093938,0,0,1.5604932,-8.3886376,-9.784483)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6379" id="linearGradient6641" gradientUnits="userSpaceOnUse" x1="20.226221" y1="20.33363" x2="11.4375" y2="21.75" gradientTransform="matrix(0.6666667,0,0,1,2,-1)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6651" id="radialGradient6657" cx="23.986883" cy="27.053167" fx="23.986883" fy="27.053167" r="7.75" gradientTransform="matrix(-0.2432942,0,0,-1.2543129,25.221399,61.870636)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6546" id="linearGradient6558" gradientUnits="userSpaceOnUse" x1="80.693359" y1="31.561478" x2="77.125" y2="14" gradientTransform="translate(-70,2)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6607" id="radialGradient6625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.9866298,0.1169977,0,-2.530036,-104.62676,112.74341)" cx="30.685316" cy="42.261425" fx="30.685316" fy="42.261425" r="8.22791" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6628" id="linearGradient6634" x1="23.238182" y1="12.158657" x2="29.892563" y2="26.354361" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6700" id="linearGradient6706" x1="17.5" y1="25.587416" x2="28.555141" y2="25.699326" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6643" id="linearGradient6801" gradientUnits="userSpaceOnUse" x1="33.430557" y1="45.052155" x2="33.430557" y2="0.31037101" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6984" cx="60.640625" cy="22.65625" fx="60.640625" fy="22.65625" r="2.6194003" gradientTransform="matrix(2.1454532,0,0,3.0191635,-69.461,-45.746674)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient17123" id="radialGradient7118" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.330579,0,24.67693)" cx="11.402097" cy="36.863068" fx="11.402097" fy="36.863068" r="10.69499" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="24" inkscape:cy="42.911478" inkscape:document-units="px" inkscape:current-layer="layer2" width="48px" height="48px" inkscape:showpageshadow="false" borderlayer="true" showgrid="false" inkscape:window-width="1051" inkscape:window-height="936" inkscape:window-x="14" inkscape:window-y="43" inkscape:guide-points="false" inkscape:grid-points="true" showguides="false" inkscape:guide-bbox="true" showborder="false" inkscape:grid-bbox="true"> <sodipodi:guide orientation="vertical" position="22" id="guide21670" /> <sodipodi:guide orientation="horizontal" position="26" id="guide21672" /> <sodipodi:guide orientation="vertical" position="32" id="guide6673" /> <inkscape:grid type="xygrid" id="grid6385" /> <sodipodi:guide orientation="horizontal" position="2.5" id="guide6925" /> <inkscape:grid id="GridFromPre046Settings" type="xygrid" originx="0px" originy="0px" spacingx="0.5px" spacingy="0.5px" color="#0000ff" empcolor="#0000ff" opacity="0.2" empopacity="0.4" empspacing="2" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Ulisse Perusin</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Audio Volume High</dc:title> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="constr" style="display:none"> <path style="opacity:0.83011588;fill:url(#radialGradient8199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -8.21875,10.5 L -20.21875,22.5 L -8.21875,34.5 L -8.21875,10.5 z " id="path7288" sodipodi:nodetypes="cccc" /> <path style="opacity:0.76833975;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6393);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -7,10.5 L -19,22.5 L -7,34.5 L -7,10.5 z " id="path2791" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50000006" inkscape:original="M 19.5 9.5 C 18 15 12 14 7.5 22.5 C 12 31 18 30 19.5 35.5 L 19.5 9.5 z " style="opacity:0.63320462;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" id="path21580" d="M 19.375,9 C 19.200644,9.0530225 19.06894,9.1967002 19.03125,9.375 C 18.327802,11.954311 16.604417,12.961638 14.34375,14.46875 C 12.083083,15.975862 9.3592888,17.942871 7.0625,22.28125 C 6.9953198,22.419346 6.9953198,22.580654 7.0625,22.71875 C 9.3592888,27.057129 12.083083,29.024138 14.34375,30.53125 C 16.604417,32.038362 18.327802,33.045689 19.03125,35.625 C 19.110592,35.845992 19.333006,35.982016 19.565879,35.951968 C 19.798752,35.92192 19.979353,35.733894 20,35.5 L 20,9.5 C 20.005,9.3425939 19.935556,9.1920293 19.812581,9.0936489 C 19.689605,8.9952685 19.527469,8.9605689 19.375,9 z " transform="translate(-42,0)" /> <path style="fill:none;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -47.5,22.5 L -20,-8 L -20,56 L -47.5,22.5 z " id="path21676" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21684);fill-opacity:1;stroke:#204a87;stroke-width:0.12515022;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21678" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(7.990397,0,0,7.990397,-220.7725,-152.0403)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21686);fill-opacity:1;stroke:#204a87;stroke-width:0.18086948;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21680" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(5.528848,0,0,5.528848,-169.4646,-98.27085)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21688);fill-opacity:1;stroke:#204a87;stroke-width:0.29248634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21682" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(3.418962,0,0,3.418962,-125.4867,-52.18304)" /> </g> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.2;fill:url(#radialGradient7118);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" id="path16236" sodipodi:cx="11.402097" sodipodi:cy="36.863068" sodipodi:rx="10.69499" sodipodi:ry="3.5355339" d="M 22.097087 36.863068 A 10.69499 3.5355339 0 1 1 0.70710659,36.863068 A 10.69499 3.5355339 0 1 1 22.097087 36.863068 z" transform="matrix(1.5365906,0,0,2.4199734,-1.1723206,-56.384863)" /> <path sodipodi:type="arc" style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:1.30267787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path5330" sodipodi:cx="4" sodipodi:cy="25" sodipodi:rx="4" sodipodi:ry="7" d="M 8 25 A 4 7 0 1 1 0,25 A 4 7 0 1 1 8 25 z" transform="matrix(0.75,0,0,0.7857143,1.5,4.357156)" /> <path sodipodi:type="arc" style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6659" sodipodi:cx="3.75" sodipodi:cy="20.75" sodipodi:rx="0.75" sodipodi:ry="0.75" d="M 4.5 20.75 A 0.75 0.75 0 1 1 3,20.75 A 0.75 0.75 0 1 1 4.5 20.75 z" transform="translate(-1.53125,0.65625)" /> <path style="fill:url(#linearGradient5545);fill-opacity:1;stroke:url(#linearGradient5547);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 6.125,15.500014 C 4.1240036,15.500014 2.5000009,19.308036 2.5,24.000014 C 2.5,28.691991 4.1240036,32.500015 6.125,32.500014 L 9.75,32.500014 C 11.750996,32.500014 13.375,28.69199 13.375,24.000014 C 13.375,19.308037 11.750996,15.500014 9.75,15.500014 L 6.125,15.500014 z " id="path2766" sodipodi:nodetypes="csccscc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0054175" inkscape:original="M 5.5 13.5 C 3.292004 13.5 1.500001 17.308022 1.5 22 C 1.5 26.691978 3.292004 30.500001 5.5 30.5 L 9.5 30.5 C 11.707996 30.500001 13.5 26.691976 13.5 22 C 13.5 17.308024 11.707996 13.5 9.5 13.5 L 5.5 13.5 z " style="opacity:0.6;fill:none;fill-opacity:1;stroke:url(#linearGradient6537);stroke-width:1.0577718;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path5556" d="M 5.5,14.5 C 4.974,14.5 4.2339165,15.045895 3.59375,16.40625 C 2.9535835,17.766605 2.5000005,19.78201 2.5,22 C 2.5,24.21799 2.9535834,26.233394 3.59375,27.59375 C 4.2339166,28.954106 4.9740003,29.5 5.5,29.5 L 9.5,29.5 C 10.025999,29.5 10.766083,28.954106 11.40625,27.59375 C 12.046417,26.233394 12.5,24.217988 12.5,22 C 12.5,19.782012 12.046417,17.766606 11.40625,16.40625 C 10.766083,15.045894 10.026,14.5 9.5,14.5 L 5.5,14.5 z " transform="matrix(0.89375,0,0,1,1.265625,2)" /> <path style="opacity:1;fill:url(#linearGradient6558);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 9.696925,16 C 7.656226,16 6.000001,19.57702 6,23.984375 C 6,28.391729 7.656226,31.968751 9.696925,31.96875 L 10.334325,31.96875 C 12.375024,31.96875 14.03125,28.391728 14.03125,23.984375 C 14.03125,19.577021 12.375024,16 10.334325,16 L 9.696925,16 z " id="path6556" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#radialGradient6553);fill-opacity:1;stroke:url(#linearGradient6545);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 8.6250003,24 C 8.6250003,33.227273 17.811975,38.499999 23.500002,38.499999 C 27.437502,38.499999 30.500002,32.003996 30.500002,24 C 30.500002,15.996003 27.437502,9.5000001 23.500002,9.5000001 C 17.811975,9.5000001 8.6250003,14.772728 8.6250003,24 z " id="path1871" sodipodi:nodetypes="cssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6657);fill-opacity:1;stroke:none;stroke-width:0.87802505;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6649" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.3225807,0,0,1.026415,-12.145162,-4.6754711)" /> <path style="opacity:0.7335907;fill:url(#linearGradient6641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M 16,13.375 C 13.416667,14.769678 10.541667,17.570921 8,21.5 C 10.69956,20.373913 13.491292,19.539527 16,19.75 L 16,13.375 z " id="path6639" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0125009" inkscape:original="M 22.8125 5.5 C 16.571923 5.5000002 6.5 11.5 6.5 22 C 6.5 32.500001 16.571923 38.5 22.8125 38.5 C 27.1325 38.499999 30.5 31.107996 30.5 22 C 30.5 12.892005 27.1325 5.5 22.8125 5.5 z " style="opacity:0.58620689;fill:none;fill-opacity:1;stroke:url(#linearGradient6579);stroke-width:1.12734473;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6567" d="M 22.8125,6.5 C 20.016701,6.5000001 16.088488,7.9333131 12.96875,10.59375 C 9.8490125,13.254187 7.5,17.073741 7.5,22 C 7.5,26.92626 9.8490125,30.745813 12.96875,33.40625 C 16.088487,36.066687 20.016701,37.5 22.8125,37.5 C 24.394999,37.5 26.045271,36.056265 27.34375,33.25 C 28.642229,30.443735 29.5,26.429214 29.5,22 C 29.5,17.570787 28.642229,13.556265 27.34375,10.75 C 26.045271,7.943735 24.394999,6.5 22.8125,6.5 z " transform="matrix(0.9034091,0,0,0.8709678,2.8494318,4.8387095)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6595);fill-opacity:1;stroke:url(#linearGradient6801);stroke-width:0.83240509;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path1873" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.2258059,0,0,1.1773585,-8.9515943,-8.892453)" /> <path style="fill:url(#radialGradient6603);fill-opacity:1;stroke:#555753;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 21.616117,24.000008 C 21.616117,26.484005 19.233185,28.49999 17.549734,28.49999 C 15.866281,28.49999 14.500001,26.483992 14.500001,23.999995 C 14.500001,21.515998 15.866281,19.5 17.549734,19.5 C 19.233185,19.5 21.616117,21.51601 21.616117,24.000008 z " id="path3672" sodipodi:nodetypes="csssc" /> <path style="opacity:1;fill:url(#radialGradient6625);fill-opacity:1;stroke:none;stroke-width:0.90347975;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 22,5 C 19.367552,4.9999999 17.141972,7.2498264 15.5625,10.6875 C 13.983028,14.125173 13.03125,18.830125 13.03125,24 C 13.03125,29.169874 13.983028,33.874826 15.5625,37.3125 C 17.141972,40.750172 19.367552,43 22,43 C 24.632449,43 26.858028,40.750173 28.4375,37.3125 C 29.42467,35.163953 30.174611,32.501281 30.59375,29.5625 C 30.606967,29.469828 30.612431,29.374514 30.625,29.28125 C 30.701405,28.714302 30.760731,28.149758 30.8125,27.5625 C 30.863372,27.016086 30.910141,26.469464 30.9375,25.90625 C 30.938938,25.875286 30.936131,25.843507 30.9375,25.8125 C 30.964969,25.216652 30.96875,24.611754 30.96875,24 C 30.96875,23.355639 30.96794,22.720382 30.9375,22.09375 C 30.911649,21.537127 30.860238,20.979033 30.8125,20.4375 C 30.760731,19.850242 30.701405,19.285698 30.625,18.71875 C 30.611503,18.623565 30.607961,18.532009 30.59375,18.4375 C 30.174611,15.498719 29.42467,12.836046 28.4375,10.6875 C 26.858028,7.249826 24.632449,5 22,5 z M 22.5,7 C 24.422274,7.0000002 26.280368,8.7656497 27.6875,11.84375 C 28.566957,13.767562 29.264379,16.179117 29.65625,18.875 C 29.734624,19.414177 29.789845,19.97021 29.84375,20.53125 C 29.89121,21.056658 29.942834,21.584653 29.96875,22.125 C 30.000626,22.745494 30.03125,23.361156 30.03125,24 C 30.03125,24.595745 29.99653,25.170104 29.96875,25.75 C 29.966916,25.790974 29.970711,25.834105 29.96875,25.875 C 29.941175,26.411772 29.893755,26.948299 29.84375,27.46875 C 29.789845,28.029789 29.734624,28.585823 29.65625,29.125 C 29.264379,31.820883 28.566957,34.232438 27.6875,36.15625 C 26.280368,39.23435 24.422274,41 22.5,41 C 20.577727,40.999998 18.719632,39.234351 17.3125,36.15625 C 15.905367,33.078149 14.96875,28.765963 14.96875,24 C 14.96875,19.234036 15.905368,14.92185 17.3125,11.84375 C 18.719631,8.7656496 20.577727,7 22.5,7 z " id="path6605" sodipodi:nodetypes="cssssssssssssssssccssssssssssssssc" /> <path sodipodi:type="arc" style="opacity:0.36637932;fill:none;fill-opacity:1;stroke:url(#linearGradient6634);stroke-width:1.05419946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6615" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(0.9032258,0,0,0.9962264,-0.3064529,-3.8320749)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6661" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-16,5.3125)" /> <path sodipodi:type="arc" style="opacity:0.65517243;fill:none;fill-opacity:1;stroke:url(#linearGradient6706);stroke-width:0.90347946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6698" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.0967748,0,0,1.1169811,-5.6935592,-7.2056602)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path5501" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-5,-1.875)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="waves" /> </svg> ����������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-power.svg��������������������������������������������������������0000644�0000041�0000041�00000074351�13570225707�021420� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="battery-caution.svg" inkscape:export-filename="/home/lapo/Desktop/per jimmac/scalable/devices/battery.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient id="linearGradient6194"> <stop id="stop6196" offset="0" style="stop-color:#cc0000;stop-opacity:1" /> <stop id="stop6198" offset="1" style="stop-color:#ff6969;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient6188"> <stop id="stop6190" offset="0" style="stop-color:#ef2929;stop-opacity:1" /> <stop id="stop6192" offset="1" style="stop-color:#ff4141;stop-opacity:1;" /> </linearGradient> <linearGradient id="linearGradient6179"> <stop id="stop6181" offset="0" style="stop-color:#cc0000;stop-opacity:1" /> <stop style="stop-color:#ff5656;stop-opacity:1;" offset="0.5" id="stop6183" /> <stop id="stop6185" offset="1" style="stop-color:#cc0000;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7507" inkscape:collect="always"> <stop id="stop7509" offset="0" style="stop-color:#888a85;stop-opacity:1" /> <stop id="stop7511" offset="1" style="stop-color:#888a85;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7499"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop7501" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop7503" /> </linearGradient> <linearGradient id="linearGradient7451"> <stop id="stop7453" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop7455" offset="1" style="stop-color:#ffffff;stop-opacity:0.18702289" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3290"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3292" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3294" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3280"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3282" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3284" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3254"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3256" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3258" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3227"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3229" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3231" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3174"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3176" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3178" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3280" id="radialGradient3286" cx="21.34375" cy="14.125" fx="21.34375" fy="14.125" r="11.96875" gradientTransform="matrix(1,0,0,0.302872,0,9.846932)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7451" id="radialGradient3337" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690032,0,0,0.228281,6.615871,10.90053)" cx="19.717636" cy="16.677069" fx="19.717636" fy="16.677069" r="12.46875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3174" id="radialGradient3339" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2532713,-0.3487142,0.1098099,0.4255197,-7.5807449,13.83398)" cx="18.370865" cy="23.649349" fx="18.370865" fy="23.649349" r="12.46875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7507" id="linearGradient3341" gradientUnits="userSpaceOnUse" x1="31.18708" y1="9.9904861" x2="25.531752" y2="18.613125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3227" id="radialGradient3347" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.1160948,0,1.0746735e-5,0.7873934,-21.867432,2.1771112)" cx="19.863604" cy="11.205179" fx="19.863604" fy="11.205179" r="4" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4134" id="linearGradient3384" gradientUnits="userSpaceOnUse" x1="26.472569" y1="10.985043" x2="19.082977" y2="10.985043" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3290" id="linearGradient3398" gradientUnits="userSpaceOnUse" x1="13.96536" y1="10.495919" x2="20.682875" y2="31.382992" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3254" id="linearGradient3401" gradientUnits="userSpaceOnUse" x1="12.25" y1="20.230709" x2="17.125" y2="34.173542" /> <linearGradient id="linearGradient4134"> <stop id="stop4136" offset="0" style="stop-color:#d6d7d5;stop-opacity:1;" /> <stop style="stop-color:#d1d2d0;stop-opacity:1;" offset="0.25" id="stop4148" /> <stop style="stop-color:#a5a6a3;stop-opacity:1.0000000;" offset="0.50000000" id="stop4142" /> <stop id="stop4138" offset="1" style="stop-color:#dddedc;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4134" id="linearGradient6477" x1="11.492082" y1="24.875" x2="37.640503" y2="24.875" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7499" id="linearGradient7505" x1="22" y1="11.375" x2="21.1875" y2="13.25" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6179" id="linearGradient6173" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.952381,0,0,0.6279555,-9.928572,13.115091)" x1="16.375" y1="32.71875" x2="44" y2="32.71875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6188" id="linearGradient6175" gradientUnits="userSpaceOnUse" x1="15.191748" y1="44.376076" x2="15.191748" y2="36.300972" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6194" id="linearGradient6177" gradientUnits="userSpaceOnUse" x1="16.760378" y1="35.750408" x2="16.175068" y2="41.719719" /> <linearGradient inkscape:collect="always" id="linearGradient5060"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop5062" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5064" /> </linearGradient> <linearGradient id="linearGradient5048"> <stop style="stop-color:black;stop-opacity:0;" offset="0" id="stop5050" /> <stop id="stop5056" offset="0.5" style="stop-color:black;stop-opacity:1;" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5052" /> </linearGradient> <linearGradient y2="56.052299" x2="47.319698" y1="11.1133" x1="4.1914001" gradientUnits="userSpaceOnUse" id="linearGradient6525"> <stop id="stop6529" style="stop-color:#ffffff;stop-opacity:1;" offset="0" /> <stop id="stop6531" style="stop-color:#ffffff;stop-opacity:0.34020618;" offset="1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6525" id="linearGradient6465" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.513828,0,-2.236678e-3,0.597575,22.990392,17.281525)" x1="8.5469341" y1="30.281681" x2="30.85088" y2="48.301884" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5048" id="linearGradient6484" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" x1="302.85715" y1="366.64789" x2="302.85715" y2="609.50507" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient6486" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5060" id="radialGradient6488" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)" cx="605.71429" cy="486.64789" fx="605.71429" fy="486.64789" r="117.14286" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="80.402463" inkscape:cy="2.3152073" inkscape:document-units="px" inkscape:current-layer="layer5" showgrid="false" gridempspacing="2" gridspacingx="0.5px" gridspacingy="0.5px" inkscape:window-width="872" inkscape:window-height="771" inkscape:window-x="392" inkscape:window-y="55" stroke="#c4a000" inkscape:grid-points="false" inkscape:grid-bbox="false" fill="#555753" showborder="false" inkscape:showpageshadow="false" showguides="true" inkscape:guide-bbox="true" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:title>Battery Critical</dc:title> <dc:subject> <rdf:Bag> <rdf:li>battery</rdf:li> <rdf:li>power</rdf:li> <rdf:li>acpi</rdf:li> <rdf:li>apm</rdf:li> <rdf:li>warning</rdf:li> <rdf:li>critical</rdf:li> </rdf:Bag> </dc:subject> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer6" inkscape:label="Shadow" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.36567161;color:#000000;fill:url(#radialGradient3286);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3278" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.389034,0,0,1.337644,-8.147196,18.98077)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="Battery" style="display:inline" /> <g inkscape:groupmode="layer" id="layer4" inkscape:label="inner stroke" style="display:inline" /> <g inkscape:groupmode="layer" id="layer5" inkscape:label="tip" style="display:inline"> <path style="color:#000000;fill:url(#linearGradient6477);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 20,10.5 C 14.084021,10.71652 9.5,12.21646 9.5,14 L 9.5,37 C 9.5,38.932 14.876,40.5 21.5,40.5 C 28.124,40.5 33.5,38.932 33.5,37 L 33.5,14 C 33.5,12.068 28.124001,10.5 21.5,10.5 C 21.13775,10.5 20.79161,10.49082 20.4375,10.5 C 20.294038,10.50372 20.141983,10.4948 20,10.5 z " id="path2217" sodipodi:nodetypes="cccsccssc" /> <path sodipodi:type="arc" style="opacity:0.63921569;color:#000000;fill:url(#linearGradient3341);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3263" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.002611,0,0,0.965518,0.100522,0.362061)" /> <path sodipodi:nodetypes="ccsccc" id="path7457" d="M 11.5,32.000001 L 11.5,36.349444 C 11.5,37.537657 15.98,38.508042 21.5,38.508042 C 27.02,38.508042 31.5,37.537657 31.5,36.349444 L 31.5,32.000001 L 11.5,32.000001 z " style="color:#000000;fill:url(#linearGradient6173);fill-opacity:1;fill-rule:nonzero;stroke:#cc0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> <path transform="matrix(1.2761832,0,0,0.5142598,0.8968254,12.179172)" d="M 24.041631 38.542446 A 7.8665628 4.8613591 0 1 1 8.3085051,38.542446 A 7.8665628 4.8613591 0 1 1 24.041631 38.542446 z" sodipodi:ry="4.8613591" sodipodi:rx="7.8665628" sodipodi:cy="38.542446" sodipodi:cx="16.175068" id="path7459" style="color:#000000;fill:url(#linearGradient6175);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient6177);stroke-width:1.23438954;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" /> <path style="opacity:0.52238805;color:#000000;fill:url(#linearGradient3398);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 20,10.5 C 14.084021,10.716519 9.5,12.21646 9.5,14 L 9.5,37 C 9.5,38.932002 14.876,40.500001 21.5,40.5 C 28.124,40.5 33.5,38.932003 33.5,37 L 33.5,14 C 33.5,12.067998 28.124001,10.5 21.5,10.5 C 21.13775,10.5 20.79161,10.490818 20.4375,10.5 C 20.294038,10.50372 20.141983,10.494804 20,10.5 z " id="path3288" sodipodi:nodetypes="csssssssc" /> <path style="opacity:0.49019608;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 19.84375,11.5 C 14.548895,11.680925 10.5,12.74668 10.5,14 C 10.5,15.142813 10.5,35.855219 10.5,37 C 10.5,38.38 15.427994,39.5 21.5,39.5 C 27.572006,39.5 32.5,38.38 32.5,37 C 32.5,35.940784 32.499999,15.059216 32.5,14 C 32.5,12.62 27.572007,11.5 21.5,11.5 C 21.1205,11.5 20.744639,11.49146 20.375,11.5 C 20.201732,11.504003 20.014552,11.494164 19.84375,11.5 z " id="path2206" sodipodi:nodetypes="csssssssc" /> <path sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient3337);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient3339);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3164" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.002611,0,0,0.965518,0.100522,0.362061)" /> <path style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 20,10.5 C 14.084021,10.71652 9.5,12.21646 9.5,14 L 9.5,37 C 9.5,38.932 14.876,40.5 21.5,40.5 C 28.124,40.5 33.5,38.932 33.5,37 L 33.5,14 C 33.5,12.068 28.124001,10.5 21.5,10.5 C 21.13775,10.5 20.79161,10.49082 20.4375,10.5 C 20.294038,10.50372 20.141983,10.4948 20,10.5 z " id="path7448" sodipodi:nodetypes="cccsccssc" /> <path style="opacity:0.58208953;color:#000000;fill:url(#linearGradient3401);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 13,16.375 L 18,17.3125 L 18,40.3125 L 13,39.5 L 13,16.375 z " id="rect3244" sodipodi:nodetypes="ccccc" /> <path style="color:#000000;fill:url(#linearGradient3384);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 21,9.5 C 19.315666,9.5803665 17.950192,10.074035 17.59375,10.6875 C 17.587086,10.699702 17.568368,10.737692 17.5625,10.75 C 17.559767,10.75618 17.533781,10.775045 17.53125,10.78125 C 17.528923,10.78748 17.533372,10.806246 17.53125,10.8125 C 17.521672,10.843887 17.504323,10.905557 17.5,10.9375 C 17.49935,10.943909 17.500435,10.96232 17.5,10.96875 C 17.499782,10.975199 17.5,12.993531 17.5,13 C 17.5,13.006469 17.499782,13.024801 17.5,13.03125 C 17.500435,13.03768 17.49935,13.056091 17.5,13.0625 C 17.504323,13.094443 17.521672,13.156113 17.53125,13.1875 C 17.533372,13.193754 17.528923,13.21252 17.53125,13.21875 C 17.533781,13.224955 17.559767,13.24382 17.5625,13.25 C 17.568368,13.262308 17.587086,13.300298 17.59375,13.3125 C 17.985483,13.986704 19.58525,14.5 21.5,14.5 C 23.41475,14.5 25.014517,13.986704 25.40625,13.3125 C 25.412914,13.300298 25.431632,13.262308 25.4375,13.25 C 25.440233,13.24382 25.466219,13.224955 25.46875,13.21875 C 25.471077,13.21252 25.466628,13.193754 25.46875,13.1875 C 25.478328,13.156113 25.495677,13.094443 25.5,13.0625 C 25.50065,13.056091 25.499565,13.03768 25.5,13.03125 C 25.500218,13.024801 25.5,13.006469 25.5,13 C 25.5,12.993531 25.500218,10.975199 25.5,10.96875 C 25.499565,10.96232 25.50065,10.943909 25.5,10.9375 C 25.495677,10.905557 25.478328,10.843887 25.46875,10.8125 C 25.466628,10.806246 25.471077,10.78748 25.46875,10.78125 C 25.466219,10.775045 25.440233,10.75618 25.4375,10.75 C 25.431632,10.737692 25.412914,10.699702 25.40625,10.6875 C 25.014517,10.013296 23.41475,9.5 21.5,9.5 C 21.3275,9.5 21.166766,9.4920429 21,9.5 z " id="path3198" sodipodi:nodetypes="cssssssssssssssssssssssssssssc" /> <path sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient3347);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3225" sodipodi:cx="21.5" sodipodi:cy="11" sodipodi:rx="4" sodipodi:ry="1.5" d="M 25.5 11 A 4 1.5 0 1 1 17.5,11 A 4 1.5 0 1 1 25.5 11 z" transform="matrix(0.867417,0,0,0.666667,2.820203,3.666665)" /> <path style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient7505);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 21,9.5 C 19.315666,9.5803665 17.950192,10.074035 17.59375,10.6875 C 17.587086,10.699702 17.568368,10.737692 17.5625,10.75 C 17.559767,10.75618 17.533781,10.775045 17.53125,10.78125 C 17.528923,10.78748 17.533372,10.806246 17.53125,10.8125 C 17.521672,10.843887 17.504323,10.905557 17.5,10.9375 C 17.49935,10.943909 17.500435,10.96232 17.5,10.96875 C 17.499782,10.975199 17.5,12.993531 17.5,13 C 17.5,13.006469 17.499782,13.024801 17.5,13.03125 C 17.500435,13.03768 17.49935,13.056091 17.5,13.0625 C 17.504323,13.094443 17.521672,13.156113 17.53125,13.1875 C 17.533372,13.193754 17.528923,13.21252 17.53125,13.21875 C 17.533781,13.224955 17.559767,13.24382 17.5625,13.25 C 17.568368,13.262308 17.587086,13.300298 17.59375,13.3125 C 17.985483,13.986704 19.58525,14.5 21.5,14.5 C 23.41475,14.5 25.014517,13.986704 25.40625,13.3125 C 25.412914,13.300298 25.431632,13.262308 25.4375,13.25 C 25.440233,13.24382 25.466219,13.224955 25.46875,13.21875 C 25.471077,13.21252 25.466628,13.193754 25.46875,13.1875 C 25.478328,13.156113 25.495677,13.094443 25.5,13.0625 C 25.50065,13.056091 25.499565,13.03768 25.5,13.03125 C 25.500218,13.024801 25.5,13.006469 25.5,13 C 25.5,12.993531 25.500218,10.975199 25.5,10.96875 C 25.499565,10.96232 25.50065,10.943909 25.5,10.9375 C 25.495677,10.905557 25.478328,10.843887 25.46875,10.8125 C 25.466628,10.806246 25.471077,10.78748 25.46875,10.78125 C 25.466219,10.775045 25.440233,10.75618 25.4375,10.75 C 25.431632,10.737692 25.412914,10.699702 25.40625,10.6875 C 25.014517,10.013296 23.41475,9.5 21.5,9.5 C 21.3275,9.5 21.166766,9.4920429 21,9.5 z " id="path3205" sodipodi:nodetypes="cssssssssssssssssssssssssssssc" /> <g id="g6707" transform="matrix(1.071946e-2,0,0,9.024553e-3,45.342332,42.354905)" style="opacity:0.65671638;display:inline"> <rect y="-150.69685" x="-1559.2523" height="478.35718" width="1339.6335" id="rect6709" style="opacity:0.40206185;color:#000000;fill:url(#linearGradient6484);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> <path sodipodi:nodetypes="cccc" id="path6711" d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z " style="opacity:0.40206185;color:#000000;fill:url(#radialGradient6486);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> <path style="opacity:0.40206185;color:#000000;fill:url(#radialGradient6488);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z " id="path6713" sodipodi:nodetypes="cccc" /> </g> <g id="g6490" transform="translate(2,0)"> <path style="fill:#f57900;fill-opacity:1;fill-rule:nonzero;stroke:#ce5c00;stroke-width:1.00000095;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 42.055057,41.68373 L 34.833284,27.128912 C 34.625708,26.724611 34.250108,26.5 33.831801,26.5 C 33.413494,26.5 33.035965,26.769533 32.825236,27.173834 L 25.657242,41.728654 C 25.488517,42.088031 25.486589,42.582177 25.694341,42.941555 C 25.902093,43.300933 26.236038,43.480622 26.654345,43.480622 L 41.04411,43.480622 C 41.462417,43.480622 41.83977,43.256011 42.008496,42.896632 C 42.21905,42.537254 42.220802,42.088031 42.055057,41.68373 z " id="path6485" inkscape:r_cx="true" inkscape:r_cy="true" /> <path inkscape:r_cy="true" inkscape:r_cx="true" id="path6496" d="M 28.577086,40.879683 C 28.467936,41.072766 28.575704,41.227232 28.756342,41.227232 L 38.944327,41.227232 C 39.124966,41.227232 39.233963,41.072766 39.126348,40.879683 L 34.000951,30.607693 C 33.893335,30.414611 33.748826,30.414611 33.675802,30.607693 L 28.577086,40.879683 z " style="fill:#fcaf3e;fill-rule:nonzero;stroke:none;stroke-miterlimit:4" /> <path style="opacity:0.5;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient6465);stroke-width:1.00000095;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 40.554382,41.00448 L 34.535392,28.466117 C 34.289695,27.944826 34.20157,27.465075 33.828182,27.465075 C 33.507038,27.465075 33.339007,28.021154 33.106933,28.51321 L 27.026974,40.97933 C 26.695698,41.658176 26.472705,42.022624 26.632159,42.321411 C 26.791611,42.620198 27.05884,42.416426 27.815295,42.435916 L 39.778047,42.498415 C 40.482293,42.50816 41.07843,42.698104 41.208007,42.399318 C 41.369696,42.100531 40.863422,41.613478 40.554382,41.00448 z " id="path1325" sodipodi:nodetypes="ccsccscccc" inkscape:r_cx="true" inkscape:r_cy="true" /> <g style="fill:#121312;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.45324564;stroke-miterlimit:4" transform="matrix(0.339351,0,0,0.370268,25.712542,26.582525)" id="g6498" inkscape:r_cx="true" inkscape:r_cy="true"> <path style="fill:#121312;fill-opacity:1;stroke:none" d="M 22.810356,35.833787 C 21.482134,35.130969 21.104052,33.568631 21.940765,32.24041 C 22.841841,30.810018 24.340642,30.377046 25.771035,31.133927 C 27.201427,31.890808 27.43953,33.242849 26.640625,34.727304 C 25.803912,36.055525 24.240748,36.590668 22.810356,35.833787 L 22.810356,35.833787 z M 23.428093,28.231254 L 21.248844,19.696786 L 27.332546,19.816143 L 25.023066,28.08366 L 23.428093,28.231254 z " id="path6500" inkscape:r_cx="true" inkscape:r_cy="true" sodipodi:nodetypes="csscccccccc" /> </g> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-next.svg���������������������������������������������������0000644�0000041�0000041�00000033523�13570225707�022335� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg7854" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions" sodipodi:docname="media-skip-forward.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/lapo/Desktop/media-icons.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <defs id="defs7856"> <linearGradient id="linearGradient7577"> <stop style="stop-color:#000000;stop-opacity:0.3137255;" offset="0" id="stop7579" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop7581" /> </linearGradient> <linearGradient id="linearGradient7305"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop7307" /> <stop id="stop7313" offset="0.20971029" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.81065089;" offset="0.34936365" id="stop7329" /> <stop id="stop7321" offset="0.42850056" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.52134049" id="stop7323" /> <stop id="stop7317" offset="0.55746967" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.56804734;" offset="0.71001518" id="stop7319" /> <stop id="stop7416" offset="0.74394959" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop7309" /> </linearGradient> <linearGradient id="linearGradient7344" inkscape:collect="always"> <stop id="stop7346" offset="0" style="stop-color:#eeeeec;stop-opacity:1" /> <stop id="stop7348" offset="1" style="stop-color:#92948f;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7577" id="linearGradient7762" gradientUnits="userSpaceOnUse" x1="-77.711723" y1="13.246527" x2="-74.288277" y2="26.023027" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient7764" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.2246612,0,0,2.3034327,-120.62956,-41.851943)" cx="28.541149" cy="31.678772" fx="28.541149" fy="31.678772" r="12.000001" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient7766" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.8811669,0,0,1.5641941,82.169231,0.3959845)" cx="36.455379" cy="17.414564" fx="36.455379" fy="17.414564" r="13.55237" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient7768" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.8811669,0,0,1.5641941,82.169231,0.3959845)" cx="36.455379" cy="17.414564" fx="36.455379" fy="17.414564" r="13.55237" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7305" id="linearGradient7770" gradientUnits="userSpaceOnUse" x1="0.17084506" y1="10.331141" x2="47.954166" y2="37.918854" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#afafaf" borderopacity="1" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="-137.53856" inkscape:cy="10.827794" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:window-width="872" inkscape:window-height="971" inkscape:window-x="117" inkscape:window-y="27" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:grid-points="true" showborder="true" showguides="false" inkscape:guide-bbox="true" borderlayer="true"> <sodipodi:guide orientation="horizontal" position="13.125" id="guide7377" /> <sodipodi:guide orientation="horizontal" position="5.4800776" id="guide7379" /> <sodipodi:guide orientation="horizontal" position="35" id="guide7492" /> <sodipodi:guide orientation="horizontal" position="48" id="guide7046" /> <sodipodi:guide orientation="horizontal" position="-17.5" id="guide7233" /> <sodipodi:guide orientation="horizontal" position="-29" id="guide7235" /> <sodipodi:guide orientation="horizontal" position="22.097087" id="guide7556" /> <sodipodi:guide orientation="vertical" position="-76.125" id="guide7644" /> <sodipodi:guide orientation="vertical" position="-26.125" id="guide7646" /> <sodipodi:guide orientation="vertical" position="24" id="guide7648" /> <sodipodi:guide orientation="vertical" position="-125.28125" id="guide7665" /> <sodipodi:guide orientation="vertical" position="-175.125" id="guide7667" /> <sodipodi:guide orientation="vertical" position="-225.83223" id="guide7685" /> <sodipodi:guide orientation="vertical" position="-326.06462" id="guide7695" /> </sodipodi:namedview> <metadata id="metadata7859"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:source /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Next Song</dc:title> <dc:subject> <rdf:Bag> <rdf:li>skip</rdf:li> <rdf:li>forward</rdf:li> <rdf:li>next</rdf:li> </rdf:Bag> </dc:subject> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g7113" transform="translate(100,0)"> <path d="M -59.9375,11 C -61.083327,11 -62,11.916673 -62,13.0625 L -62,21.0625 L -77.71875,11.71875 C -78.182222,11.438527 -78.760596,11.429252 -79.232814,11.694471 C -79.705033,11.959689 -79.998098,12.458403 -80,13 L -80,21.0625 L -95.71875,11.71875 C -96.182222,11.438527 -96.760596,11.429252 -97.232814,11.694471 C -97.705033,11.959689 -97.998098,12.458403 -98,13 L -98,35 C -97.998098,35.541597 -97.705033,36.040311 -97.232814,36.305529 C -96.760596,36.570748 -96.182222,36.561473 -95.71875,36.28125 L -80,26.9375 L -80,35 C -79.998098,35.541597 -79.705033,36.040311 -79.232814,36.305529 C -78.760596,36.570748 -78.182222,36.561473 -77.71875,36.28125 L -62,26.9375 L -62,34.9375 C -62,36.083333 -61.083342,37.000007 -59.9375,37 L -56.0625,37 C -54.916673,37 -53.999996,36.083333 -54,34.9375 L -54,13.0625 C -54,11.91667 -54.916672,11 -56.0625,11 L -59.9375,11 z " id="path7638" style="opacity:0.4;fill:url(#linearGradient7762);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M -59.9375 12.5 C -60.243545 12.5 -60.5 12.756455 -60.5 13.0625 L -60.5 23.6875 L -78.5 13 L -78.5 23.6875 L -96.5 13 L -96.5 35 L -78.5 24.3125 L -78.5 35 L -60.5 24.3125 L -60.5 34.9375 C -60.5 35.243545 -60.243543 35.500002 -59.9375 35.5 L -56.0625 35.5 C -55.756455 35.5 -55.499999 35.243545 -55.5 34.9375 L -55.5 13.0625 C -55.5 12.756455 -55.756456 12.5 -56.0625 12.5 L -59.9375 12.5 z " inkscape:radius="1.5032517" sodipodi:type="inkscape:offset" /> <g id="g7474"> <rect style="fill:url(#radialGradient7764);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="rect7623" width="4.9886603" height="23.000002" x="-60.488663" y="12.5" rx="0.55242717" ry="0.55242717" /> <g id="g8003" transform="translate(-238,0)"> <path sodipodi:nodetypes="cccc" id="path8005" d="M 141.5,35 L 141.5,13.000461 L 159.99577,24.010194 L 141.5,35 z " style="fill:url(#radialGradient7766);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path transform="translate(120,0)" d="M 22.5,14.78125 L 22.5,33.21875 L 38.03125,24 L 22.5,14.78125 z " id="path8007" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M 21.5 13 L 21.5 35 L 40 24 L 21.5 13 z " inkscape:radius="-1.0054175" sodipodi:type="inkscape:offset" /> </g> <g id="g7999" transform="translate(-220,0)"> <path sodipodi:nodetypes="cccc" id="path7621" d="M 141.5,35 L 141.5,13.000461 L 159.99577,24.010194 L 141.5,35 z " style="fill:url(#radialGradient7768);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path transform="translate(120,0)" d="M 22.5,14.78125 L 22.5,33.21875 L 38.03125,24 L 22.5,14.78125 z " id="path7627" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M 21.5 13 L 21.5 35 L 40 24 L 21.5 13 z " inkscape:radius="-1.0054175" sodipodi:type="inkscape:offset" /> </g> <rect style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="rect7625" width="3.0097761" height="21.000002" x="-59.483948" y="13.5" rx="0" ry="0" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.5" inkscape:original="M 40.0625 12.5 C 39.756455 12.5 39.5 12.756455 39.5 13.0625 L 39.5 23.6875 L 21.5 13 L 21.5 23.6875 L 3.5 13 L 3.5 35 L 21.5 24.3125 L 21.5 35 L 39.5 24.3125 L 39.5 34.9375 C 39.5 35.243545 39.756457 35.500002 40.0625 35.5 L 43.9375 35.5 C 44.243545 35.5 44.500001 35.243545 44.5 34.9375 L 44.5 13.0625 C 44.5 12.756455 44.243544 12.5 43.9375 12.5 L 40.0625 12.5 z " style="opacity:0.15;fill:url(#linearGradient7770);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="path7386" d="M 40.0625,13 C 40.035777,13 40,13.035777 40,13.0625 L 40,23.6875 C 39.995694,23.802981 39.951524,23.913406 39.875,24 C 39.951524,24.086594 39.995694,24.197019 40,24.3125 L 40,34.9375 C 40,34.964221 40.035784,35 40.0625,35 L 43.9375,35 C 43.964223,35 44,34.964221 44,34.9375 L 44,13.0625 C 44,13.035778 43.964221,13 43.9375,13 L 40.0625,13 z M 4,13.875 L 4,34.125 L 21.03125,24 L 4,13.875 z M 22,13.875 L 22,23.6875 C 21.995694,23.802981 21.951524,23.913406 21.875,24 C 21.951524,24.086594 21.995694,24.197019 22,24.3125 L 22,34.125 L 39.03125,24 L 22,13.875 z " transform="matrix(1,0,0,-1,-100,48)" /> </g> </g> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-previous.svg�����������������������������������������������0000644�0000041�0000041�00000033637�13570225707�023241� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg7854" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions" sodipodi:docname="media-skip-backward.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-filename="/home/lapo/Desktop/media-icons.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90"> <defs id="defs7856"> <linearGradient id="linearGradient7577"> <stop style="stop-color:#000000;stop-opacity:0.3137255;" offset="0" id="stop7579" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop7581" /> </linearGradient> <linearGradient id="linearGradient7305"> <stop style="stop-color:#ffffff;stop-opacity:1" offset="0" id="stop7307" /> <stop id="stop7313" offset="0.20971029" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.81065089;" offset="0.34936365" id="stop7329" /> <stop id="stop7321" offset="0.42850056" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0.52134049" id="stop7323" /> <stop id="stop7317" offset="0.55746967" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0.56804734;" offset="0.71001518" id="stop7319" /> <stop id="stop7416" offset="0.74394959" style="stop-color:#ffffff;stop-opacity:0;" /> <stop style="stop-color:#ffffff;stop-opacity:0" offset="1" id="stop7309" /> </linearGradient> <linearGradient id="linearGradient7344" inkscape:collect="always"> <stop id="stop7346" offset="0" style="stop-color:#eeeeec;stop-opacity:1" /> <stop id="stop7348" offset="1" style="stop-color:#92948f;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7577" id="linearGradient8208" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1,0,0,1,-152,0)" x1="-77.711723" y1="13.246527" x2="-74.288277" y2="26.023027" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient8210" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.2246612,0,0,2.605516,-356.62956,-51.421571)" cx="28.541149" cy="31.678772" fx="28.541149" fy="31.678772" r="12.000001" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient8212" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.9143326,0,0,1.5917714,100.35131,1.6193442e-2)" cx="38.40033" cy="17.833462" fx="38.40033" fy="17.833462" r="13.55237" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7344" id="radialGradient8214" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.9143326,0,0,1.5917714,100.35131,1.6193442e-2)" cx="38.204437" cy="17.597876" fx="38.204437" fy="17.597876" r="13.55237" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7305" id="linearGradient8216" gradientUnits="userSpaceOnUse" x1="49.683426" y1="10.023315" x2="98.316566" y2="38.101673" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#afafaf" borderopacity="1" gridtolerance="10000" guidetolerance="10" objecttolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="-137.53856" inkscape:cy="10.827794" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" inkscape:window-width="872" inkscape:window-height="971" inkscape:window-x="117" inkscape:window-y="27" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:grid-points="true" showborder="true" showguides="false" inkscape:guide-bbox="true" borderlayer="true"> <sodipodi:guide orientation="horizontal" position="13.125" id="guide7377" /> <sodipodi:guide orientation="horizontal" position="5.4800776" id="guide7379" /> <sodipodi:guide orientation="horizontal" position="35" id="guide7492" /> <sodipodi:guide orientation="horizontal" position="48" id="guide7046" /> <sodipodi:guide orientation="horizontal" position="-17.5" id="guide7233" /> <sodipodi:guide orientation="horizontal" position="-29" id="guide7235" /> <sodipodi:guide orientation="horizontal" position="22.097087" id="guide7556" /> <sodipodi:guide orientation="vertical" position="-76.125" id="guide7644" /> <sodipodi:guide orientation="vertical" position="-26.125" id="guide7646" /> <sodipodi:guide orientation="vertical" position="24" id="guide7648" /> <sodipodi:guide orientation="vertical" position="-125.28125" id="guide7665" /> <sodipodi:guide orientation="vertical" position="-175.125" id="guide7667" /> <sodipodi:guide orientation="vertical" position="-225.83223" id="guide7685" /> <sodipodi:guide orientation="vertical" position="-326.06462" id="guide7695" /> </sodipodi:namedview> <metadata id="metadata7859"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:source /> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Previous Song</dc:title> <dc:subject> <rdf:Bag> <rdf:li>skip</rdf:li> <rdf:li>backward</rdf:li> <rdf:li>previous</rdf:li> <rdf:li>media</rdf:li> </rdf:Bag> </dc:subject> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> <g id="g7157" transform="translate(300,0)"> <path transform="matrix(-1,0,0,1,-352,0)" d="M -59.9375,11 C -61.083327,11 -62,11.916673 -62,13.0625 L -62,21.0625 L -77.71875,11.71875 C -78.182222,11.438527 -78.760596,11.429252 -79.232814,11.694471 C -79.705033,11.959689 -79.998098,12.458403 -80,13 L -80,21.0625 L -95.71875,11.71875 C -96.182222,11.438527 -96.760596,11.429252 -97.232814,11.694471 C -97.705033,11.959689 -97.998098,12.458403 -98,13 L -98,35 C -97.998098,35.541597 -97.705033,36.040311 -97.232814,36.305529 C -96.760596,36.570748 -96.182222,36.561473 -95.71875,36.28125 L -80,26.9375 L -80,35 C -79.998098,35.541597 -79.705033,36.040311 -79.232814,36.305529 C -78.760596,36.570748 -78.182222,36.561473 -77.71875,36.28125 L -62,26.9375 L -62,34.9375 C -62,36.083333 -61.083342,37.000007 -59.9375,37 L -56.0625,37 C -54.916673,37 -53.999996,36.083333 -54,34.9375 L -54,13.0625 C -54,11.91667 -54.916672,11 -56.0625,11 L -59.9375,11 z " id="path7687" style="opacity:0.4;fill:url(#linearGradient8208);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M -59.9375 12.5 C -60.243545 12.5 -60.5 12.756455 -60.5 13.0625 L -60.5 23.6875 L -78.5 13 L -78.5 23.6875 L -96.5 13 L -96.5 35 L -78.5 24.3125 L -78.5 35 L -60.5 24.3125 L -60.5 34.9375 C -60.5 35.243545 -60.243543 35.500002 -59.9375 35.5 L -56.0625 35.5 C -55.756455 35.5 -55.499999 35.243545 -55.5 34.9375 L -55.5 13.0625 C -55.5 12.756455 -55.756456 12.5 -56.0625 12.5 L -59.9375 12.5 z " inkscape:radius="1.5032517" sodipodi:type="inkscape:offset" /> <g id="g7553"> <rect style="fill:url(#radialGradient8210);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="rect7736" width="4.9886603" height="23.000002" x="-296.48865" y="12.5" rx="0.55242717" ry="0.55242717" /> <g id="g7944" transform="matrix(-1,0,0,1,-234,0)"> <path sodipodi:nodetypes="cccc" id="path7946" d="M 21.5,35 L 21.5,13.000461 L 39.995767,24.010194 L 21.5,35 z " style="fill:url(#radialGradient8212);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path d="M 22.5,14.78125 L 22.5,33.21875 L 38.03125,24 L 22.5,14.78125 z " id="path7948" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M 21.5 13 L 21.5 35 L 40 24 L 21.5 13 z " inkscape:radius="-1.0054175" sodipodi:type="inkscape:offset" /> </g> <g id="g7744" transform="matrix(-1,0,0,1,-252,0)"> <path sodipodi:nodetypes="cccc" id="path7746" d="M 21.5,35 L 21.5,13.000461 L 39.995767,24.010194 L 21.5,35 z " style="fill:url(#radialGradient8214);fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path d="M 22.5,14.78125 L 22.5,33.21875 L 38.03125,24 L 22.5,14.78125 z " id="path7748" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" inkscape:original="M 21.5 13 L 21.5 35 L 40 24 L 21.5 13 z " inkscape:radius="-1.0054175" sodipodi:type="inkscape:offset" /> </g> <rect style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="rect7750" width="3.0097761" height="21.000002" x="-295.48395" y="13.5" rx="0" ry="0" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.49442077" inkscape:original="M 54.0625 12.5 C 53.756455 12.5 53.5 12.756455 53.5 13.0625 L 53.5 34.9375 C 53.5 35.243545 53.756457 35.500002 54.0625 35.5 L 57.9375 35.5 C 58.243545 35.5 58.500001 35.243545 58.5 34.9375 L 58.5 24.3125 L 76.5 35 L 76.5 24.3125 L 94.5 35 L 94.5 13 L 76.5 23.6875 L 76.5 13 L 58.5 23.6875 L 58.5 13.0625 C 58.5 12.756455 58.243544 12.5 57.9375 12.5 L 54.0625 12.5 z " style="opacity:0.15;fill:url(#linearGradient8216);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="path6332" d="M 54.0625,13 C 54.03266,13 54,13.03266 54,13.0625 L 54,34.9375 C 54,34.967338 54.032668,35 54.0625,35 L 57.9375,35 C 57.96734,35 58,34.967338 58,34.9375 L 58,24.3125 C 58.003842,24.196921 58.048073,24.086345 58.125,24 C 58.048073,23.913655 58.003842,23.803079 58,23.6875 L 58,13.0625 C 58,13.032661 57.967338,13 57.9375,13 L 54.0625,13 z M 76,13.875 L 58.96875,24 L 76,34.125 L 76,24.3125 C 76.003842,24.196921 76.048073,24.086345 76.125,24 C 76.048073,23.913655 76.003842,23.803079 76,23.6875 L 76,13.875 z M 94,13.875 L 76.96875,24 L 94,34.125 L 94,13.875 z " transform="matrix(1,0,0,-1,-350,48)" /> </g> </g> </g> </svg> �������������������������������������������������������������������������������������������������./data/icons/scalable/notification-battery-low.svg��������������������������������������������������0000644�0000041�0000041�00000055747�13570225707�022545� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="battery-low.svg" inkscape:export-filename="/home/lapo/Desktop/per jimmac/scalable/devices/battery.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient id="linearGradient7507" inkscape:collect="always"> <stop id="stop7509" offset="0" style="stop-color:#888a85;stop-opacity:1" /> <stop id="stop7511" offset="1" style="stop-color:#888a85;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7499"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop7501" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop7503" /> </linearGradient> <linearGradient id="linearGradient7489"> <stop style="stop-color:#dcc500;stop-opacity:1" offset="0" id="stop7491" /> <stop id="stop7493" offset="0.5" style="stop-color:#fdea50;stop-opacity:1;" /> <stop style="stop-color:#dcc500;stop-opacity:1" offset="1" id="stop7495" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7483"> <stop style="stop-color:#edd400;stop-opacity:1" offset="0" id="stop7485" /> <stop style="stop-color:#fce94f;stop-opacity:1" offset="1" id="stop7487" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7477"> <stop style="stop-color:#c4a000;stop-opacity:1" offset="0" id="stop7479" /> <stop style="stop-color:#fff5a8;stop-opacity:1" offset="1" id="stop7481" /> </linearGradient> <linearGradient id="linearGradient7451"> <stop id="stop7453" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop7455" offset="1" style="stop-color:#ffffff;stop-opacity:0.18702289" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3290"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3292" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3294" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3280"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop3282" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop3284" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3254"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3256" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3258" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3227"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3229" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3231" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient3174"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop3176" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop3178" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3280" id="radialGradient3286" cx="21.34375" cy="14.125" fx="21.34375" fy="14.125" r="11.96875" gradientTransform="matrix(1,0,0,0.302872,8.341852e-16,9.846932)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7451" id="radialGradient3337" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.690032,0,0,0.228281,6.615871,10.90053)" cx="19.717636" cy="16.677069" fx="19.717636" fy="16.677069" r="12.46875" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3174" id="radialGradient3339" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.2532713,-0.3487142,0.1098099,0.4255197,-7.5807449,13.83398)" cx="18.370865" cy="23.649349" fx="18.370865" fy="23.649349" r="12.46875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7507" id="linearGradient3341" gradientUnits="userSpaceOnUse" x1="31.18708" y1="9.9904861" x2="25.531752" y2="18.613125" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient3227" id="radialGradient3347" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.1160948,0,1.0746735e-5,0.7873934,-21.867432,2.1771112)" cx="19.863604" cy="11.205179" fx="19.863604" fy="11.205179" r="4" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4134" id="linearGradient3384" gradientUnits="userSpaceOnUse" gradientTransform="translate(2,0)" x1="26.472569" y1="10.985043" x2="19.082977" y2="10.985043" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3290" id="linearGradient3398" gradientUnits="userSpaceOnUse" x1="13.96536" y1="10.495919" x2="20.682875" y2="31.382992" gradientTransform="translate(2,0)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient3254" id="linearGradient3401" gradientUnits="userSpaceOnUse" gradientTransform="translate(2,0)" x1="12.25" y1="20.230709" x2="17.125" y2="34.173542" /> <linearGradient id="linearGradient4134"> <stop id="stop4136" offset="0" style="stop-color:#d6d7d5;stop-opacity:1;" /> <stop style="stop-color:#d1d2d0;stop-opacity:1;" offset="0.25" id="stop4148" /> <stop style="stop-color:#a5a6a3;stop-opacity:1.0000000;" offset="0.50000000" id="stop4142" /> <stop id="stop4138" offset="1" style="stop-color:#dddedc;stop-opacity:1;" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient4134" id="linearGradient6477" x1="11.492082" y1="24.875" x2="37.640503" y2="24.875" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7489" id="linearGradient7461" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.952381,0,0,0.6279555,-7.9285716,13.115091)" x1="16.375" y1="32.71875" x2="44" y2="32.71875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7483" id="linearGradient7463" gradientUnits="userSpaceOnUse" x1="15.191748" y1="42.98222" x2="15.191748" y2="35.085632" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7477" id="linearGradient7465" gradientUnits="userSpaceOnUse" x1="16.760378" y1="35.750408" x2="16.175068" y2="41.719719" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7499" id="linearGradient7505" x1="22" y1="11.375" x2="21.1875" y2="13.25" gradientUnits="userSpaceOnUse" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="27.074618" inkscape:cy="31.813642" inkscape:document-units="px" inkscape:current-layer="layer5" showgrid="false" gridempspacing="2" gridspacingx="0.5px" gridspacingy="0.5px" inkscape:window-width="872" inkscape:window-height="771" inkscape:window-x="392" inkscape:window-y="55" stroke="#c4a000" inkscape:grid-points="false" inkscape:grid-bbox="true" fill="#555753" showborder="false" inkscape:showpageshadow="false" /> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> <dc:title>Battery</dc:title> <dc:subject> <rdf:Bag> <rdf:li>battery</rdf:li> <rdf:li>recharge</rdf:li> <rdf:li>power</rdf:li> <rdf:li>acpi</rdf:li> <rdf:li>apm</rdf:li> </rdf:Bag> </dc:subject> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer6" inkscape:label="Shadow" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.36567164;color:#000000;fill:url(#radialGradient3286);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3278" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.389034,0,0,1.337644,-6.147196,18.98077)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="Battery" style="display:inline" /> <g inkscape:groupmode="layer" id="layer4" inkscape:label="inner stroke" style="display:inline" /> <g inkscape:groupmode="layer" id="layer5" inkscape:label="tip" style="display:inline"> <path style="color:#000000;fill:url(#linearGradient6477);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 22,10.5 C 16.084021,10.71652 11.5,12.21646 11.5,14 L 11.5,37 C 11.5,38.932 16.876,40.5 23.5,40.5 C 30.124,40.5 35.5,38.932 35.5,37 L 35.5,14 C 35.5,12.068 30.124001,10.5 23.5,10.5 C 23.13775,10.5 22.79161,10.49082 22.4375,10.5 C 22.294038,10.50372 22.141983,10.4948 22,10.5 z " id="path2217" sodipodi:nodetypes="cccsccssc" /> <path sodipodi:type="arc" style="opacity:0.63921569;color:#000000;fill:url(#linearGradient3341);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3263" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.002611,0,0,0.965518,2.100522,0.362061)" /> <g id="g7467"> <path style="opacity:1;color:#000000;fill:url(#linearGradient7461);fill-opacity:1;fill-rule:nonzero;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" d="M 13.5,29.000001 L 13.5,36.349444 C 13.5,37.537657 17.98,38.508042 23.5,38.508042 C 29.02,38.508042 33.5,37.537657 33.5,36.349444 L 33.5,29.000001 L 13.5,29.000001 z " id="path7457" sodipodi:nodetypes="ccsccc" /> <path sodipodi:type="arc" style="opacity:1;color:#000000;fill:url(#linearGradient7463);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient7465);stroke-width:1.23438954;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="path7459" sodipodi:cx="16.175068" sodipodi:cy="38.542446" sodipodi:rx="7.8665628" sodipodi:ry="4.8613591" d="M 24.041631 38.542446 A 7.8665628 4.8613591 0 1 1 8.3085051,38.542446 A 7.8665628 4.8613591 0 1 1 24.041631 38.542446 z" transform="matrix(1.2761832,0,0,0.5142598,2.8968254,9.1791722)" /> </g> <path style="opacity:0.52238805;color:#000000;fill:url(#linearGradient3398);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 22,10.5 C 16.084021,10.716519 11.5,12.21646 11.5,14 L 11.5,37 C 11.5,38.932002 16.876,40.500001 23.5,40.5 C 30.124,40.5 35.5,38.932003 35.5,37 L 35.5,14 C 35.5,12.067998 30.124001,10.5 23.5,10.5 C 23.13775,10.5 22.79161,10.490818 22.4375,10.5 C 22.294038,10.50372 22.141983,10.494804 22,10.5 z " id="path3288" sodipodi:nodetypes="csssssssc" /> <path style="opacity:0.49019608;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 21.84375,11.5 C 16.548895,11.680925 12.5,12.74668 12.5,14 C 12.5,15.142813 12.5,35.855219 12.5,37 C 12.5,38.38 17.427994,39.5 23.5,39.5 C 29.572006,39.5 34.5,38.38 34.5,37 C 34.5,35.940784 34.499999,15.059216 34.5,14 C 34.5,12.62 29.572007,11.5 23.5,11.5 C 23.1205,11.5 22.744639,11.49146 22.375,11.5 C 22.201732,11.504003 22.014552,11.494164 21.84375,11.5 z " id="path2206" sodipodi:nodetypes="csssssssc" /> <path sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient3337);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient3339);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3164" sodipodi:cx="21.34375" sodipodi:cy="14.125" sodipodi:rx="11.96875" sodipodi:ry="3.625" d="M 33.3125 14.125 A 11.96875 3.625 0 1 1 9.375,14.125 A 11.96875 3.625 0 1 1 33.3125 14.125 z" transform="matrix(1.002611,0,0,0.965518,2.100522,0.362061)" /> <path style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 22,10.5 C 16.084021,10.71652 11.5,12.21646 11.5,14 L 11.5,37 C 11.5,38.932 16.876,40.5 23.5,40.5 C 30.124,40.5 35.5,38.932 35.5,37 L 35.5,14 C 35.5,12.068 30.124001,10.5 23.5,10.5 C 23.13775,10.5 22.79161,10.49082 22.4375,10.5 C 22.294038,10.50372 22.141983,10.4948 22,10.5 z " id="path7448" sodipodi:nodetypes="cccsccssc" /> <path style="opacity:0.58208955;color:#000000;fill:url(#linearGradient3401);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 15,16.375 L 20,17.3125 L 20,40.3125 L 15,39.5 L 15,16.375 z " id="rect3244" sodipodi:nodetypes="ccccc" /> <path style="color:#000000;fill:url(#linearGradient3384);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 23,9.5 C 21.315666,9.5803665 19.950192,10.074035 19.59375,10.6875 C 19.587086,10.699702 19.568368,10.737692 19.5625,10.75 C 19.559767,10.75618 19.533781,10.775045 19.53125,10.78125 C 19.528923,10.78748 19.533372,10.806246 19.53125,10.8125 C 19.521672,10.843887 19.504323,10.905557 19.5,10.9375 C 19.49935,10.943909 19.500435,10.96232 19.5,10.96875 C 19.499782,10.975199 19.5,12.993531 19.5,13 C 19.5,13.006469 19.499782,13.024801 19.5,13.03125 C 19.500435,13.03768 19.49935,13.056091 19.5,13.0625 C 19.504323,13.094443 19.521672,13.156113 19.53125,13.1875 C 19.533372,13.193754 19.528923,13.21252 19.53125,13.21875 C 19.533781,13.224955 19.559767,13.24382 19.5625,13.25 C 19.568368,13.262308 19.587086,13.300298 19.59375,13.3125 C 19.985483,13.986704 21.58525,14.5 23.5,14.5 C 25.41475,14.5 27.014517,13.986704 27.40625,13.3125 C 27.412914,13.300298 27.431632,13.262308 27.4375,13.25 C 27.440233,13.24382 27.466219,13.224955 27.46875,13.21875 C 27.471077,13.21252 27.466628,13.193754 27.46875,13.1875 C 27.478328,13.156113 27.495677,13.094443 27.5,13.0625 C 27.50065,13.056091 27.499565,13.03768 27.5,13.03125 C 27.500218,13.024801 27.5,13.006469 27.5,13 C 27.5,12.993531 27.500218,10.975199 27.5,10.96875 C 27.499565,10.96232 27.50065,10.943909 27.5,10.9375 C 27.495677,10.905557 27.478328,10.843887 27.46875,10.8125 C 27.466628,10.806246 27.471077,10.78748 27.46875,10.78125 C 27.466219,10.775045 27.440233,10.75618 27.4375,10.75 C 27.431632,10.737692 27.412914,10.699702 27.40625,10.6875 C 27.014517,10.013296 25.41475,9.5 23.5,9.5 C 23.3275,9.5 23.166766,9.4920429 23,9.5 z " id="path3198" sodipodi:nodetypes="cssssssssssssssssssssssssssssc" /> <path sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient3347);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" id="path3225" sodipodi:cx="21.5" sodipodi:cy="11" sodipodi:rx="4" sodipodi:ry="1.5" d="M 25.5 11 A 4 1.5 0 1 1 17.5,11 A 4 1.5 0 1 1 25.5 11 z" transform="matrix(0.867417,0,0,0.666667,4.820203,3.666665)" /> <path style="color:#000000;fill:none;fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient7505);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 23,9.5 C 21.315666,9.5803665 19.950192,10.074035 19.59375,10.6875 C 19.587086,10.699702 19.568368,10.737692 19.5625,10.75 C 19.559767,10.75618 19.533781,10.775045 19.53125,10.78125 C 19.528923,10.78748 19.533372,10.806246 19.53125,10.8125 C 19.521672,10.843887 19.504323,10.905557 19.5,10.9375 C 19.49935,10.943909 19.500435,10.96232 19.5,10.96875 C 19.499782,10.975199 19.5,12.993531 19.5,13 C 19.5,13.006469 19.499782,13.024801 19.5,13.03125 C 19.500435,13.03768 19.49935,13.056091 19.5,13.0625 C 19.504323,13.094443 19.521672,13.156113 19.53125,13.1875 C 19.533372,13.193754 19.528923,13.21252 19.53125,13.21875 C 19.533781,13.224955 19.559767,13.24382 19.5625,13.25 C 19.568368,13.262308 19.587086,13.300298 19.59375,13.3125 C 19.985483,13.986704 21.58525,14.5 23.5,14.5 C 25.41475,14.5 27.014517,13.986704 27.40625,13.3125 C 27.412914,13.300298 27.431632,13.262308 27.4375,13.25 C 27.440233,13.24382 27.466219,13.224955 27.46875,13.21875 C 27.471077,13.21252 27.466628,13.193754 27.46875,13.1875 C 27.478328,13.156113 27.495677,13.094443 27.5,13.0625 C 27.50065,13.056091 27.499565,13.03768 27.5,13.03125 C 27.500218,13.024801 27.5,13.006469 27.5,13 C 27.5,12.993531 27.500218,10.975199 27.5,10.96875 C 27.499565,10.96232 27.50065,10.943909 27.5,10.9375 C 27.495677,10.905557 27.478328,10.843887 27.46875,10.8125 C 27.466628,10.806246 27.471077,10.78748 27.46875,10.78125 C 27.466219,10.775045 27.440233,10.75618 27.4375,10.75 C 27.431632,10.737692 27.412914,10.699702 27.40625,10.6875 C 27.014517,10.013296 25.41475,9.5 23.5,9.5 C 23.3275,9.5 23.166766,9.4920429 23,9.5 z " id="path3205" sodipodi:nodetypes="cssssssssssssssssssssssssssssc" /> </g> </svg> �������������������������./data/icons/scalable/notification-network-ethernet-diconnected.svg���������������������������������0000644�0000041�0000041�00000101663�13570225707�026043� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" width="48" height="48" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/devices" sodipodi:docname="network-wired.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> </cc:Work> </rdf:RDF> </metadata> <defs id="defs5"> <linearGradient inkscape:collect="always" id="linearGradient7822"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7824" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7826" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7812"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7814" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7816" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7688"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7690" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7692" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7660"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7662" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7664" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7652"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop7654" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop7656" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7576"> <stop style="stop-color:#3465a4;stop-opacity:1" offset="0" id="stop7578" /> <stop style="stop-color:#3465a4;stop-opacity:0" offset="1" id="stop7580" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7438"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7440" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7442" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7430"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7432" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7434" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7422"> <stop style="stop-color:#edd400;stop-opacity:1;" offset="0" id="stop7424" /> <stop style="stop-color:#edd400;stop-opacity:0;" offset="1" id="stop7426" /> </linearGradient> <linearGradient id="linearGradient7340"> <stop style="stop-color:#2e3436;stop-opacity:1;" offset="0" id="stop7342" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop7344" /> </linearGradient> <linearGradient id="linearGradient7277"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop7279" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop7281" /> </linearGradient> <linearGradient id="linearGradient7269"> <stop id="stop7271" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop7273" offset="1" style="stop-color:#d3d7cf;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7263"> <stop id="stop7265" offset="0" style="stop-color:#adb0a8;stop-opacity:1;" /> <stop id="stop7267" offset="1" style="stop-color:#ffffff;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7257"> <stop id="stop7259" offset="0" style="stop-color:#000000;stop-opacity:1" /> <stop id="stop7261" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient7245"> <stop style="stop-color:#eeeeec;stop-opacity:1;" offset="0" id="stop7247" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop7249" /> </linearGradient> <linearGradient id="linearGradient7237"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop7239" /> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="1" id="stop7241" /> </linearGradient> <linearGradient id="linearGradient7186"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop7188" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop7190" /> </linearGradient> <linearGradient id="linearGradient6991"> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="0" id="stop6993" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop6995" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6991" id="linearGradient6047" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.0000002,0,0,1.9333333,43.500004,0.533333)" x1="-7.975069" y1="25.357235" x2="-11.005972" y2="-6.5683565" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7340" id="linearGradient7346" x1="32.8125" y1="21" x2="32.8125" y2="26.204767" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0874899,0,0,1.086371,-1.5809531,-8.9433469)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7428" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7430" id="linearGradient7436" x1="28.875" y1="29" x2="29" y2="16" gradientUnits="userSpaceOnUse" gradientTransform="translate(1,-7)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7438" id="linearGradient7444" x1="-7.8516631" y1="3.7545938" x2="-5.5098634" y2="18.937717" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7446" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7448" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7450" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7452" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7263" id="linearGradient7555" gradientUnits="userSpaceOnUse" x1="1.6256078" y1="55.219357" x2="0.82206726" y2="54.415817" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7269" id="linearGradient7557" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9642856,0,0,0.9722222,-0.2500008,1.6944444)" x1="-4.2208939" y1="59.878922" x2="-4.2208939" y2="54.707691" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7257" id="linearGradient7559" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-1.9887378" y1="51.137787" x2="-3.3587573" y2="54" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7237" id="linearGradient7561" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-4.6845822" y1="52.640388" x2="0.88388348" y2="50.563263" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7245" id="linearGradient7563" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-5.0823302" y1="50.51907" x2="0.26516503" y2="49.458408" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7186" id="linearGradient7565" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-5.96875" y1="52.875" x2="-5.96875" y2="51.812416" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7277" id="linearGradient7567" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.0285717,-4,-25.142872)" x1="-3.5355339" y1="55.866562" x2="-3.5355339" y2="59.444622" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7269" id="linearGradient7574" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1249999,0,0,1.1666666,15.874999,-34.135417)" x1="-4.1097827" y1="58.807774" x2="-4.1097827" y2="55.000004" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7576" id="linearGradient7582" x1="38.75" y1="40.625" x2="40.125" y2="46.5625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7652" id="linearGradient7658" x1="37.625" y1="40.3125" x2="38.875" y2="45.0625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7660" id="linearGradient7666" x1="41.1875" y1="38.3125" x2="42.123722" y2="42.9375" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7688" id="linearGradient7694" x1="28.625" y1="41.125" x2="30.5" y2="47.8125" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7812" id="linearGradient7818" x1="-6.40625" y1="32.4375" x2="-7.78125" y2="34.5625" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7822" id="radialGradient7828" cx="14.363107" cy="34.785942" fx="14.363107" fy="34.785942" r="8.7946405" gradientTransform="matrix(1,0,0,0.6884422,0,10.837832)" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter5386"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.26293105" id="feGaussianBlur5388" /> </filter> <filter inkscape:collect="always" id="filter5406"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.78208031" id="feGaussianBlur5408" /> </filter> </defs> <sodipodi:namedview inkscape:window-height="792" inkscape:window-width="770" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1" bordercolor="#e8e8e8" pagecolor="#ffffff" id="base" showgrid="false" inkscape:showpageshadow="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" showborder="true" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:zoom="1" inkscape:cx="39.213614" inkscape:cy="4.7574714" inkscape:window-x="369" inkscape:window-y="135" inkscape:current-layer="svg2" width="48px" height="48px" inkscape:guide-points="false" inkscape:object-nodes="false" inkscape:object-points="false" inkscape:object-paths="true" inkscape:grid-bbox="true"> <inkscape:grid type="xygrid" id="grid4751" /> </sodipodi:namedview> <path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M 5,12 L 8,12 L 10,12 L 7,12 L 5,12 z " id="path7013" sodipodi:nodetypes="ccccc" /> <path sodipodi:type="arc" style="opacity:0.45895523;fill:url(#radialGradient7828);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="path7820" sodipodi:cx="14.363107" sodipodi:cy="34.785942" sodipodi:rx="8.7946405" sodipodi:ry="6.0546017" d="M 23.157747 34.785942 A 8.7946405 6.0546017 0 1 1 5.5684662,34.785942 A 8.7946405 6.0546017 0 1 1 23.157747 34.785942 z" transform="matrix(1.1559927,0,0,1.1167882,-1.4892394,-5.8125919)" /> <rect style="opacity:0.1204819;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642;filter:url(#filter5386)" id="rect7696" width="32.000004" height="29" x="15.375001" y="2.875" rx="3.7225697" ry="3.7225697" transform="matrix(1.015625,0,0,1.015625,-0.4902344,-0.2714844)" /> <rect style="fill:url(#linearGradient6047);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" id="rect5925" width="32.000004" height="29" x="14.500001" y="1.5" rx="2.8766227" ry="2.780735" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.99866015" inkscape:original="M -12.5 0.5 C -13.608449 0.5 -14.5 1.3915505 -14.5 2.5 L -14.5 13.5 C -14.5 14.608449 -13.60845 15.5 -12.5 15.5 L -0.5 15.5 C 0.60844948 15.5 1.5 14.60845 1.5 13.5 L 1.5 2.5 C 1.5 1.3915505 0.60844948 0.5 -0.5 0.5 L -12.5 0.5 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7444);stroke-width:0.47289537999999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992000000000;stroke-opacity:0.99236641999999997" id="path6964" d="M -12.5,1.5 C -13.072952,1.5 -13.5,1.9270471 -13.5,2.5 L -13.5,13.5 C -13.5,14.072953 -13.072954,14.5 -12.5,14.5 L -0.5,14.5 C 0.072953444,14.5 0.5,14.072954 0.5,13.5 L 0.5,2.5 C 0.5,1.9270468 0.072953144,1.5 -0.5,1.5 L -12.5,1.5 z " transform="matrix(2.1428572,0,0,2.0867798,44.428572,-0.6301697)" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50945717" inkscape:original="M 14.8125 31.5 C 14.8125 31.5 10.498126 34.830189 6.59375 38.0625 C 4.6415622 39.678655 2.8956918 41.28355 1.875 42.84375 C 1.3646541 43.62385 0.8878846 44.466971 1.21875 45.625 C 1.3841827 46.204014 1.8301355 46.746216 2.3125 47.03125 C 2.7948645 47.316284 3.2706533 47.437479 3.8125 47.5 C 5.9363798 47.745063 8.5434834 47.106406 11.65625 46.21875 C 14.769017 45.331094 18.325496 44.136387 21.90625 42.96875 C 25.487004 41.801113 29.102635 40.662687 32.25 39.96875 C 35.397365 39.274813 38.085104 39.083776 39.625 39.46875 C 40.353931 39.650983 40.370552 39.769574 40.375 39.78125 C 40.379448 39.792926 40.439577 40.11668 40.15625 40.71875 C 39.589596 41.92289 37.911115 43.835283 35.96875 45.65625 C 32.08402 49.298184 27.125 52.78125 27.125 52.78125 L 28.875 55.21875 C 28.875 55.21875 33.91598 51.701816 38.03125 47.84375 C 40.088885 45.914717 41.910404 43.95211 42.84375 41.96875 C 43.310423 40.97707 43.620552 39.855512 43.1875 38.71875 C 42.754448 37.581988 41.646069 36.849017 40.375 36.53125 C 37.914896 35.916224 34.93076 36.32675 31.59375 37.0625 C 28.25674 37.79825 24.575496 38.917637 20.96875 40.09375 C 17.362004 41.269863 13.840358 42.489218 10.84375 43.34375 C 7.9314529 44.174239 5.5458184 44.563842 4.375 44.46875 C 4.9949332 43.521138 6.6709378 41.915095 8.53125 40.375 C 12.251874 37.294811 16.5 34 16.5 34 L 14.8125 31.5 z " style="opacity:0.31927712;fill:url(#linearGradient7694);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5406)" id="path7678" d="M 14.6875,31 C 14.619177,31.017916 14.555326,31.049841 14.5,31.09375 C 14.5,31.09375 10.195229,34.415989 6.28125,37.65625 C 4.316376,39.282908 2.5162731,40.913519 1.4375,42.5625 C 0.91466802,43.361686 0.33442463,44.404861 0.71875,45.75 C 0.9275427,46.480774 1.4549221,47.109726 2.0625,47.46875 C 2.6167319,47.796251 3.1674141,47.932778 3.75,48 C 6.0211642,48.262057 8.6583138,47.609306 11.78125,46.71875 C 14.911534,45.826099 18.484598,44.604207 22.0625,43.4375 C 25.639946,42.270942 29.261929,41.155126 32.375,40.46875 C 35.48201,39.783711 38.133895,39.627224 39.5,39.96875 C 39.718805,40.023451 39.763413,40.030877 39.84375,40.0625 C 39.824168,40.168535 39.78709,40.288372 39.6875,40.5 C 39.197395,41.541473 37.544362,43.481849 35.625,45.28125 C 31.779852,48.886076 26.84375,52.375 26.84375,52.375 C 26.730444,52.452627 26.653276,52.57271 26.629743,52.708026 C 26.60621,52.843342 26.638304,52.982428 26.71875,53.09375 L 28.46875,55.53125 C 28.637946,55.737822 28.937922,55.778728 29.15625,55.625 C 29.15625,55.625 34.220988,52.113137 38.375,48.21875 C 40.448974,46.2744 42.325551,44.284766 43.3125,42.1875 C 43.80516,41.140598 44.157793,39.847802 43.65625,38.53125 C 43.146184,37.192325 41.882294,36.376823 40.5,36.03125 C 37.894103,35.379776 34.829212,35.821579 31.46875,36.5625 C 28.102571,37.304681 24.425802,38.446749 20.8125,39.625 C 17.200009,40.802986 13.693676,41.995401 10.71875,42.84375 C 8.5379899,43.465629 6.8269173,43.771279 5.59375,43.875 C 6.3789191,42.999609 7.4710187,41.917692 8.84375,40.78125 C 12.555108,37.708732 16.8125,34.40625 16.8125,34.40625 C 17.029502,34.246251 17.084294,33.944894 16.9375,33.71875 L 15.25,31.21875 C 15.130504,31.030679 14.902661,30.942074 14.6875,31 z" transform="translate(0.25,-0.625)" /> <g id="g7542" transform="translate(20,0)"> <g transform="matrix(1.1666667,0,0,1.2,-3.833333,-36.2)" id="g7162"> <path style="fill:url(#linearGradient7555);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -2.34375,51 C -2.5485199,51 -2.7249072,51.101237 -2.84375,51.25 L -6.859375,55.25 C -6.8943841,55.381797 -6.9584881,55.521336 -7,55.65625 L -7,61.177083 C -7,61.540646 -6.7034811,61.833333 -6.34375,61.833333 L 0.34375,61.833333 C 0.52361547,61.833333 0.6951329,61.76445 0.8125,61.645833 L 4.8125,57.645833 C 4.9298671,57.527216 5,57.358864 5,57.177083 L 5,51.65625 C 5,51.474469 4.9298671,51.306117 4.8125,51.1875 C 4.6934039,51.068883 4.5236156,51 4.34375,51 L -2.34375,51 z " id="rect6100" sodipodi:nodetypes="cccccccccccscc" /> <path sodipodi:nodetypes="ccccccccc" style="fill:url(#linearGradient7557);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -6.3738568,55.166667 L 0.088142442,55.166667 C 0.43502581,55.166667 0.71428575,55.451224 0.71428575,55.804688 L 0.71428575,61.195312 C 0.71428575,61.548776 0.43502581,61.833333 0.088142442,61.833333 L -6.3738568,61.833333 C -6.7207401,61.833333 -7,61.548776 -7,61.195312 L -7,55.804688 C -7,55.451224 -6.7207401,55.166667 -6.3738568,55.166667 z " id="path6105" /> </g> <path sodipodi:nodetypes="ccccc" id="path7253" d="M -5,25 L -10,30 L -6,30 L -1,25 L -5,25" style="opacity:0.12313433;fill:url(#linearGradient7559);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6126" d="M -1,25 L -10.5,29 L -7,29 L -2,26 L -1,25" style="fill:#babdb6;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="csssccccccssssccsccsccsccccscc" id="path7235" d="M -6.5625,25.5 C -6.586332,25.5 -6.617114,25.506448 -6.71875,25.625 C -6.748761,25.647634 -6.780064,25.668503 -6.8125,25.6875 C -6.832372,25.709273 -6.853227,25.730128 -6.875,25.75 C -6.894872,25.771773 -6.915727,25.792628 -6.9375,25.8125 L -6.96875,25.8125 C -6.988622,25.834273 -7.009477,25.855128 -7.03125,25.875 L -7.21875,26.0625 C -7.325593,26.162845 -7.453812,26.237639 -7.59375,26.28125 L -11.84375,27.5 C -12.244246,27.708356 -12.377785,27.84932 -12.4375,27.96875 C -12.438388,27.970526 -12.403483,28.103321 -12.4375,28.0625 C -12.355653,28.160716 -12.077127,28.314744 -11.59375,28.40625 C -11.253853,28.475121 -10.976692,28.720417 -10.867022,29.049424 C -10.757353,29.378432 -10.831905,29.740965 -11.0625,30 L -11.40625,30.375 C -11.426065,30.462564 -11.460093,30.545084 -11.5,30.6875 C -11.507455,30.714105 -11.491841,30.722726 -11.5,30.75 L -11.5,37.25 C -11.5,37.304188 -11.499624,37.365539 -11.4375,37.4375 C -11.40601,37.473977 -11.334247,37.5 -11.28125,37.5 L -3.4375,37.5 C -3.344928,37.5 -3.269061,37.4898 -3.21875,37.4375 C -3.218918,37.427084 -3.218918,37.416666 -3.21875,37.40625 L 1.4375,32.59375 C 1.489686,32.539502 1.5,32.514607 1.5,32.40625 L 1.5,25.78125 C 1.5,25.6729 1.489688,25.616751 1.4375,25.5625 C 1.400675,25.524775 1.282521,25.5 1.25,25.5 L -6.5625,25.5 z " style="opacity:0.53358208;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccccsssccssccsccccccscc" id="path7229" d="M -6.5625,24.53125 C -6.950241,24.53125 -7.254192,24.749731 -7.46875,25 L -7.5,24.96875 L -7.53125,25.03125 L -7.875,25.34375 L -12.125,26.5625 C -12.157264,26.569585 -12.188688,26.58006 -12.21875,26.59375 C -12.767664,26.868207 -13.120777,27.147804 -13.3125,27.53125 C -13.504223,27.914696 -13.429021,28.397675 -13.1875,28.6875 C -12.859423,29.081192 -12.329894,29.239888 -11.78125,29.34375 L -12.1875,29.78125 C -12.243792,29.832657 -12.286698,29.897016 -12.3125,29.96875 C -12.343846,30.090131 -12.382395,30.284537 -12.4375,30.46875 C -12.45362,30.50878 -12.464136,30.550844 -12.46875,30.59375 L -12.46875,37.25 C -12.46875,37.54887 -12.355519,37.831675 -12.15625,38.0625 C -11.956981,38.293325 -11.645384,38.46875 -11.28125,38.46875 L -3.4375,38.46875 C -3.113867,38.46875 -2.780607,38.352963 -2.53125,38.09375 L 2.125,33.28125 C 2.35088,33.046445 2.46875,32.741604 2.46875,32.40625 L 2.46875,25.78125 C 2.46875,25.445897 2.350877,25.141055 2.125,24.90625 C 1.901344,24.677132 1.573636,24.53125 1.25,24.53125 L -6.5625,24.53125 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:nodetypes="cccccc" id="path7184" d="M -1,25 L -12,27.5 L -10,29 L -7,29 L -2,26 L -1,25" style="fill:url(#linearGradient7561);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path7171" d="M -5,25 L -12,27 L -8,27 L -1,25 L -5,25" style="fill:url(#linearGradient7563);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cccccc" id="rect7173" d="M -12,27 L -8.2868349,27 L -8,27 C -10,28 -8.5,29 -7,29 L -11,29 C -12.5,29 -14,28 -12,27 z " style="fill:url(#linearGradient7565);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path style="fill:url(#linearGradient7567);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -9.5941664,32 L -5.405834,32 C -5.181002,32 -5,32.195125 -5,32.4375 L -5,35.5625 C -5,35.804876 -5.181002,36 -5.405834,36 L -9.5941664,36 C -9.8189979,36 -10,35.804876 -10,35.5625 L -10,32.4375 C -10,32.195125 -9.8189979,32 -9.5941664,32 z " id="path7275" /> </g> <path style="opacity:1;fill:url(#linearGradient7346);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" d="M 29.480478,10.068145 C 28.841463,10.068145 28.32502,10.584057 28.32502,11.222414 L 28.32502,11.510202 C 28.32502,11.803424 28.095708,12.053387 27.781275,12.053387 L 26.218008,12.053387 C 25.578993,12.053387 25.06255,12.756799 25.06255,13.395156 L 25.06255,19.840086 C 25.06255,20.478444 25.578994,20.994355 26.218008,20.994355 L 34.781992,20.994355 C 35.421007,20.994355 35.93745,20.478443 35.93745,19.840086 L 35.93745,13.395156 C 35.93745,12.756798 35.421008,12.053387 34.781992,12.053387 L 33.218725,12.053387 C 32.956948,12.071055 32.67498,11.867091 32.67498,11.527176 L 32.67498,11.222414 C 32.67498,10.584056 32.158536,10.068145 31.519522,10.068145 L 29.480478,10.068145 z" id="rect7327" sodipodi:nodetypes="ccccccccccccccccc" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7436);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992000000000;stroke-opacity:1" d="M 29.5625,9.4375 C 28.453144,9.4375 27.577814,10.345513 27.5,11.4375 L 26.5625,11.4375 C 25.40342,11.4375 24.4375,12.403421 24.4375,13.5625 L 24.4375,19.4375 C 24.4375,20.59658 25.403421,21.5625 26.5625,21.5625 L 34.4375,21.5625 C 35.59658,21.5625 36.5625,20.596579 36.5625,19.4375 L 36.5625,13.5625 C 36.5625,12.403423 35.596579,11.4375 34.4375,11.4375 L 33.5,11.4375 C 33.422186,10.345512 32.546855,9.4375 31.4375,9.4375 L 29.5625,9.4375 z " id="path7350" sodipodi:nodetypes="ccccccccccccc" /> <g id="g7393" style="fill-opacity:1;stroke:url(#linearGradient7428)" transform="translate(1,-8)"> <path sodipodi:nodetypes="cc" id="path7352" d="M 26.5,26.5 L 26.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7446);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7362" d="M 28.5,26.5 L 28.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7448);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7364" d="M 30.5,26.5 L 30.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7450);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7366" d="M 32.5,26.5 L 32.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7452);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> </g> <path style="fill:url(#linearGradient7658);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient7582);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 14.6875,30.5625 C 14.6875,30.5625 10.498126,33.830189 6.59375,37.0625 C 4.6415622,38.678655 2.8956918,40.28355 1.875,41.84375 C 1.3646541,42.62385 0.8878846,43.466971 1.21875,44.625 C 1.3841827,45.204014 1.8301355,45.746216 2.3125,46.03125 C 2.7948645,46.316284 3.2706533,46.437479 3.8125,46.5 C 5.9363798,46.745063 8.5434834,46.106406 11.65625,45.21875 C 14.769017,44.331094 18.325496,43.136387 21.90625,41.96875 C 25.487004,40.801113 29.102635,39.662687 32.25,38.96875 C 35.397365,38.274813 38.085104,38.083776 39.625,38.46875 C 40.353931,38.650983 40.370552,38.769574 40.375,38.78125 C 40.379448,38.792926 40.439577,39.11668 40.15625,39.71875 C 39.589596,40.92289 37.911115,42.835283 35.96875,44.65625 C 32.08402,48.298184 27.125,51.78125 27.125,51.78125 L 28.875,54.21875 C 28.875,54.21875 33.91598,50.701816 38.03125,46.84375 C 40.088885,44.914717 41.910404,42.95211 42.84375,40.96875 C 43.310423,39.97707 43.620552,38.855512 43.1875,37.71875 C 42.754448,36.581988 41.646069,35.849017 40.375,35.53125 C 37.914896,34.916224 34.93076,35.32675 31.59375,36.0625 C 28.25674,36.79825 24.575496,37.917637 20.96875,39.09375 C 17.362004,40.269863 13.840358,41.489218 10.84375,42.34375 C 7.9314529,43.174239 5.5458184,43.563842 4.375,43.46875 C 4.9949332,42.521138 6.6709378,40.915095 8.53125,39.375 C 12.251874,36.294811 16.5,33 16.5,33 L 14.6875,30.5625 z " id="path7506" sodipodi:nodetypes="cssssssssssssccssssssscscc" /> <path style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient7666);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.19029851;fill-opacity:1.0" d="M 15.672335,31.269607 C 15.672335,31.269607 -2.765165,43.957107 3.734835,44.707107 C 10.234835,45.457107 31.734835,34.707107 39.734835,36.707107 C 47.734835,38.707107 27.734835,52.707107 27.734835,52.707107" id="path7502" sodipodi:nodetypes="cssc" /> <path style="fill:url(#linearGradient7574);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M 10.088769,30.03125 L 10.40625,32.03125 L 14.59375,32.03125 C 14.818582,32.03125 15,32.226375 15,32.46875 L 15,35.59375 L 17,35.28125 L 17,30.8125 C 17,30.388343 16.685946,30.03125 16.28125,30.03125 L 10.088769,30.03125 z " id="path7512" sodipodi:nodetypes="ccccccccc" /> <path style="fill:url(#linearGradient7818);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642;opacity:0.35447761" d="M -9.5941664,32 L -5.405834,32 C -5.181002,32 -5,32.195125 -5,32.4375 L -5,35.5625 C -5,35.804876 -5.181002,36 -5.405834,36 L -9.5941664,36 C -9.8189979,36 -10,35.804876 -10,35.5625 L -10,32.4375 C -10,32.195125 -9.8189979,32 -9.5941664,32 z " id="path7810" transform="translate(20,0)" /> </svg> �����������������������������������������������������������������������������./data/icons/scalable/notification-network-ethernet-connected.svg�����������������������������������0000644�0000041�0000041�00000101663�13570225707�025526� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" width="48" height="48" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/devices" sodipodi:docname="network-wired.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:creator> </cc:Work> </rdf:RDF> </metadata> <defs id="defs5"> <linearGradient inkscape:collect="always" id="linearGradient7822"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7824" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7826" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7812"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7814" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7816" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7688"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7690" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7692" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7660"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7662" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7664" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7652"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop7654" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop7656" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7576"> <stop style="stop-color:#3465a4;stop-opacity:1" offset="0" id="stop7578" /> <stop style="stop-color:#3465a4;stop-opacity:0" offset="1" id="stop7580" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7438"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7440" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7442" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7430"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop7432" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop7434" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient7422"> <stop style="stop-color:#edd400;stop-opacity:1;" offset="0" id="stop7424" /> <stop style="stop-color:#edd400;stop-opacity:0;" offset="1" id="stop7426" /> </linearGradient> <linearGradient id="linearGradient7340"> <stop style="stop-color:#2e3436;stop-opacity:1;" offset="0" id="stop7342" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop7344" /> </linearGradient> <linearGradient id="linearGradient7277"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop7279" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop7281" /> </linearGradient> <linearGradient id="linearGradient7269"> <stop id="stop7271" offset="0" style="stop-color:#ffffff;stop-opacity:1;" /> <stop id="stop7273" offset="1" style="stop-color:#d3d7cf;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7263"> <stop id="stop7265" offset="0" style="stop-color:#adb0a8;stop-opacity:1;" /> <stop id="stop7267" offset="1" style="stop-color:#ffffff;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient7257"> <stop id="stop7259" offset="0" style="stop-color:#000000;stop-opacity:1" /> <stop id="stop7261" offset="1" style="stop-color:#000000;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient7245"> <stop style="stop-color:#eeeeec;stop-opacity:1;" offset="0" id="stop7247" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop7249" /> </linearGradient> <linearGradient id="linearGradient7237"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop7239" /> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="1" id="stop7241" /> </linearGradient> <linearGradient id="linearGradient7186"> <stop style="stop-color:#888a85;stop-opacity:1;" offset="0" id="stop7188" /> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="1" id="stop7190" /> </linearGradient> <linearGradient id="linearGradient6991"> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="0" id="stop6993" /> <stop style="stop-color:#ffffff;stop-opacity:1" offset="1" id="stop6995" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6991" id="linearGradient6047" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.0000002,0,0,1.9333333,43.500004,0.533333)" x1="-7.975069" y1="25.357235" x2="-11.005972" y2="-6.5683565" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7340" id="linearGradient7346" x1="32.8125" y1="21" x2="32.8125" y2="26.204767" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0874899,0,0,1.086371,-1.5809531,-8.9433469)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7428" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7430" id="linearGradient7436" x1="28.875" y1="29" x2="29" y2="16" gradientUnits="userSpaceOnUse" gradientTransform="translate(1,-7)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7438" id="linearGradient7444" x1="-7.8516631" y1="3.7545938" x2="-5.5098634" y2="18.937717" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7446" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7448" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7450" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7422" id="linearGradient7452" gradientUnits="userSpaceOnUse" x1="30.3125" y1="27.313059" x2="30.3125" y2="24.6875" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7263" id="linearGradient7555" gradientUnits="userSpaceOnUse" x1="1.6256078" y1="55.219357" x2="0.82206726" y2="54.415817" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7269" id="linearGradient7557" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9642856,0,0,0.9722222,-0.2500008,1.6944444)" x1="-4.2208939" y1="59.878922" x2="-4.2208939" y2="54.707691" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7257" id="linearGradient7559" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-1.9887378" y1="51.137787" x2="-3.3587573" y2="54" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7237" id="linearGradient7561" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-4.6845822" y1="52.640388" x2="0.88388348" y2="50.563263" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7245" id="linearGradient7563" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-5.0823302" y1="50.51907" x2="0.26516503" y2="49.458408" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7186" id="linearGradient7565" gradientUnits="userSpaceOnUse" gradientTransform="translate(-4,-24)" x1="-5.96875" y1="52.875" x2="-5.96875" y2="51.812416" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7277" id="linearGradient7567" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.0285717,-4,-25.142872)" x1="-3.5355339" y1="55.866562" x2="-3.5355339" y2="59.444622" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7269" id="linearGradient7574" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.1249999,0,0,1.1666666,15.874999,-34.135417)" x1="-4.1097827" y1="58.807774" x2="-4.1097827" y2="55.000004" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7576" id="linearGradient7582" x1="38.75" y1="40.625" x2="40.125" y2="46.5625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7652" id="linearGradient7658" x1="37.625" y1="40.3125" x2="38.875" y2="45.0625" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7660" id="linearGradient7666" x1="41.1875" y1="38.3125" x2="42.123722" y2="42.9375" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7688" id="linearGradient7694" x1="28.625" y1="41.125" x2="30.5" y2="47.8125" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient7812" id="linearGradient7818" x1="-6.40625" y1="32.4375" x2="-7.78125" y2="34.5625" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient7822" id="radialGradient7828" cx="14.363107" cy="34.785942" fx="14.363107" fy="34.785942" r="8.7946405" gradientTransform="matrix(1,0,0,0.6884422,0,10.837832)" gradientUnits="userSpaceOnUse" /> <filter inkscape:collect="always" id="filter5386"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.26293105" id="feGaussianBlur5388" /> </filter> <filter inkscape:collect="always" id="filter5406"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.78208031" id="feGaussianBlur5408" /> </filter> </defs> <sodipodi:namedview inkscape:window-height="792" inkscape:window-width="770" inkscape:pageshadow="2" inkscape:pageopacity="0.0" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1" bordercolor="#e8e8e8" pagecolor="#ffffff" id="base" showgrid="false" inkscape:showpageshadow="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" showborder="true" inkscape:grid-points="true" showguides="true" inkscape:guide-bbox="true" inkscape:zoom="1" inkscape:cx="39.213614" inkscape:cy="4.7574714" inkscape:window-x="369" inkscape:window-y="135" inkscape:current-layer="svg2" width="48px" height="48px" inkscape:guide-points="false" inkscape:object-nodes="false" inkscape:object-points="false" inkscape:object-paths="true" inkscape:grid-bbox="true"> <inkscape:grid type="xygrid" id="grid4751" /> </sodipodi:namedview> <path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M 5,12 L 8,12 L 10,12 L 7,12 L 5,12 z " id="path7013" sodipodi:nodetypes="ccccc" /> <path sodipodi:type="arc" style="opacity:0.45895523;fill:url(#radialGradient7828);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" id="path7820" sodipodi:cx="14.363107" sodipodi:cy="34.785942" sodipodi:rx="8.7946405" sodipodi:ry="6.0546017" d="M 23.157747 34.785942 A 8.7946405 6.0546017 0 1 1 5.5684662,34.785942 A 8.7946405 6.0546017 0 1 1 23.157747 34.785942 z" transform="matrix(1.1559927,0,0,1.1167882,-1.4892394,-5.8125919)" /> <rect style="opacity:0.1204819;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642;filter:url(#filter5386)" id="rect7696" width="32.000004" height="29" x="15.375001" y="2.875" rx="3.7225697" ry="3.7225697" transform="matrix(1.015625,0,0,1.015625,-0.4902344,-0.2714844)" /> <rect style="fill:url(#linearGradient6047);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" id="rect5925" width="32.000004" height="29" x="14.500001" y="1.5" rx="2.8766227" ry="2.780735" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.99866015" inkscape:original="M -12.5 0.5 C -13.608449 0.5 -14.5 1.3915505 -14.5 2.5 L -14.5 13.5 C -14.5 14.608449 -13.60845 15.5 -12.5 15.5 L -0.5 15.5 C 0.60844948 15.5 1.5 14.60845 1.5 13.5 L 1.5 2.5 C 1.5 1.3915505 0.60844948 0.5 -0.5 0.5 L -12.5 0.5 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7444);stroke-width:0.47289537999999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992000000000;stroke-opacity:0.99236641999999997" id="path6964" d="M -12.5,1.5 C -13.072952,1.5 -13.5,1.9270471 -13.5,2.5 L -13.5,13.5 C -13.5,14.072953 -13.072954,14.5 -12.5,14.5 L -0.5,14.5 C 0.072953444,14.5 0.5,14.072954 0.5,13.5 L 0.5,2.5 C 0.5,1.9270468 0.072953144,1.5 -0.5,1.5 L -12.5,1.5 z " transform="matrix(2.1428572,0,0,2.0867798,44.428572,-0.6301697)" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50945717" inkscape:original="M 14.8125 31.5 C 14.8125 31.5 10.498126 34.830189 6.59375 38.0625 C 4.6415622 39.678655 2.8956918 41.28355 1.875 42.84375 C 1.3646541 43.62385 0.8878846 44.466971 1.21875 45.625 C 1.3841827 46.204014 1.8301355 46.746216 2.3125 47.03125 C 2.7948645 47.316284 3.2706533 47.437479 3.8125 47.5 C 5.9363798 47.745063 8.5434834 47.106406 11.65625 46.21875 C 14.769017 45.331094 18.325496 44.136387 21.90625 42.96875 C 25.487004 41.801113 29.102635 40.662687 32.25 39.96875 C 35.397365 39.274813 38.085104 39.083776 39.625 39.46875 C 40.353931 39.650983 40.370552 39.769574 40.375 39.78125 C 40.379448 39.792926 40.439577 40.11668 40.15625 40.71875 C 39.589596 41.92289 37.911115 43.835283 35.96875 45.65625 C 32.08402 49.298184 27.125 52.78125 27.125 52.78125 L 28.875 55.21875 C 28.875 55.21875 33.91598 51.701816 38.03125 47.84375 C 40.088885 45.914717 41.910404 43.95211 42.84375 41.96875 C 43.310423 40.97707 43.620552 39.855512 43.1875 38.71875 C 42.754448 37.581988 41.646069 36.849017 40.375 36.53125 C 37.914896 35.916224 34.93076 36.32675 31.59375 37.0625 C 28.25674 37.79825 24.575496 38.917637 20.96875 40.09375 C 17.362004 41.269863 13.840358 42.489218 10.84375 43.34375 C 7.9314529 44.174239 5.5458184 44.563842 4.375 44.46875 C 4.9949332 43.521138 6.6709378 41.915095 8.53125 40.375 C 12.251874 37.294811 16.5 34 16.5 34 L 14.8125 31.5 z " style="opacity:0.31927712;fill:url(#linearGradient7694);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter5406)" id="path7678" d="M 14.6875,31 C 14.619177,31.017916 14.555326,31.049841 14.5,31.09375 C 14.5,31.09375 10.195229,34.415989 6.28125,37.65625 C 4.316376,39.282908 2.5162731,40.913519 1.4375,42.5625 C 0.91466802,43.361686 0.33442463,44.404861 0.71875,45.75 C 0.9275427,46.480774 1.4549221,47.109726 2.0625,47.46875 C 2.6167319,47.796251 3.1674141,47.932778 3.75,48 C 6.0211642,48.262057 8.6583138,47.609306 11.78125,46.71875 C 14.911534,45.826099 18.484598,44.604207 22.0625,43.4375 C 25.639946,42.270942 29.261929,41.155126 32.375,40.46875 C 35.48201,39.783711 38.133895,39.627224 39.5,39.96875 C 39.718805,40.023451 39.763413,40.030877 39.84375,40.0625 C 39.824168,40.168535 39.78709,40.288372 39.6875,40.5 C 39.197395,41.541473 37.544362,43.481849 35.625,45.28125 C 31.779852,48.886076 26.84375,52.375 26.84375,52.375 C 26.730444,52.452627 26.653276,52.57271 26.629743,52.708026 C 26.60621,52.843342 26.638304,52.982428 26.71875,53.09375 L 28.46875,55.53125 C 28.637946,55.737822 28.937922,55.778728 29.15625,55.625 C 29.15625,55.625 34.220988,52.113137 38.375,48.21875 C 40.448974,46.2744 42.325551,44.284766 43.3125,42.1875 C 43.80516,41.140598 44.157793,39.847802 43.65625,38.53125 C 43.146184,37.192325 41.882294,36.376823 40.5,36.03125 C 37.894103,35.379776 34.829212,35.821579 31.46875,36.5625 C 28.102571,37.304681 24.425802,38.446749 20.8125,39.625 C 17.200009,40.802986 13.693676,41.995401 10.71875,42.84375 C 8.5379899,43.465629 6.8269173,43.771279 5.59375,43.875 C 6.3789191,42.999609 7.4710187,41.917692 8.84375,40.78125 C 12.555108,37.708732 16.8125,34.40625 16.8125,34.40625 C 17.029502,34.246251 17.084294,33.944894 16.9375,33.71875 L 15.25,31.21875 C 15.130504,31.030679 14.902661,30.942074 14.6875,31 z" transform="translate(0.25,-0.625)" /> <g id="g7542" transform="translate(20,0)"> <g transform="matrix(1.1666667,0,0,1.2,-3.833333,-36.2)" id="g7162"> <path style="fill:url(#linearGradient7555);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -2.34375,51 C -2.5485199,51 -2.7249072,51.101237 -2.84375,51.25 L -6.859375,55.25 C -6.8943841,55.381797 -6.9584881,55.521336 -7,55.65625 L -7,61.177083 C -7,61.540646 -6.7034811,61.833333 -6.34375,61.833333 L 0.34375,61.833333 C 0.52361547,61.833333 0.6951329,61.76445 0.8125,61.645833 L 4.8125,57.645833 C 4.9298671,57.527216 5,57.358864 5,57.177083 L 5,51.65625 C 5,51.474469 4.9298671,51.306117 4.8125,51.1875 C 4.6934039,51.068883 4.5236156,51 4.34375,51 L -2.34375,51 z " id="rect6100" sodipodi:nodetypes="cccccccccccscc" /> <path sodipodi:nodetypes="ccccccccc" style="fill:url(#linearGradient7557);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -6.3738568,55.166667 L 0.088142442,55.166667 C 0.43502581,55.166667 0.71428575,55.451224 0.71428575,55.804688 L 0.71428575,61.195312 C 0.71428575,61.548776 0.43502581,61.833333 0.088142442,61.833333 L -6.3738568,61.833333 C -6.7207401,61.833333 -7,61.548776 -7,61.195312 L -7,55.804688 C -7,55.451224 -6.7207401,55.166667 -6.3738568,55.166667 z " id="path6105" /> </g> <path sodipodi:nodetypes="ccccc" id="path7253" d="M -5,25 L -10,30 L -6,30 L -1,25 L -5,25" style="opacity:0.12313433;fill:url(#linearGradient7559);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path6126" d="M -1,25 L -10.5,29 L -7,29 L -2,26 L -1,25" style="fill:#babdb6;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="csssccccccssssccsccsccsccccscc" id="path7235" d="M -6.5625,25.5 C -6.586332,25.5 -6.617114,25.506448 -6.71875,25.625 C -6.748761,25.647634 -6.780064,25.668503 -6.8125,25.6875 C -6.832372,25.709273 -6.853227,25.730128 -6.875,25.75 C -6.894872,25.771773 -6.915727,25.792628 -6.9375,25.8125 L -6.96875,25.8125 C -6.988622,25.834273 -7.009477,25.855128 -7.03125,25.875 L -7.21875,26.0625 C -7.325593,26.162845 -7.453812,26.237639 -7.59375,26.28125 L -11.84375,27.5 C -12.244246,27.708356 -12.377785,27.84932 -12.4375,27.96875 C -12.438388,27.970526 -12.403483,28.103321 -12.4375,28.0625 C -12.355653,28.160716 -12.077127,28.314744 -11.59375,28.40625 C -11.253853,28.475121 -10.976692,28.720417 -10.867022,29.049424 C -10.757353,29.378432 -10.831905,29.740965 -11.0625,30 L -11.40625,30.375 C -11.426065,30.462564 -11.460093,30.545084 -11.5,30.6875 C -11.507455,30.714105 -11.491841,30.722726 -11.5,30.75 L -11.5,37.25 C -11.5,37.304188 -11.499624,37.365539 -11.4375,37.4375 C -11.40601,37.473977 -11.334247,37.5 -11.28125,37.5 L -3.4375,37.5 C -3.344928,37.5 -3.269061,37.4898 -3.21875,37.4375 C -3.218918,37.427084 -3.218918,37.416666 -3.21875,37.40625 L 1.4375,32.59375 C 1.489686,32.539502 1.5,32.514607 1.5,32.40625 L 1.5,25.78125 C 1.5,25.6729 1.489688,25.616751 1.4375,25.5625 C 1.400675,25.524775 1.282521,25.5 1.25,25.5 L -6.5625,25.5 z " style="opacity:0.53358208;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccccsssccssccsccccccscc" id="path7229" d="M -6.5625,24.53125 C -6.950241,24.53125 -7.254192,24.749731 -7.46875,25 L -7.5,24.96875 L -7.53125,25.03125 L -7.875,25.34375 L -12.125,26.5625 C -12.157264,26.569585 -12.188688,26.58006 -12.21875,26.59375 C -12.767664,26.868207 -13.120777,27.147804 -13.3125,27.53125 C -13.504223,27.914696 -13.429021,28.397675 -13.1875,28.6875 C -12.859423,29.081192 -12.329894,29.239888 -11.78125,29.34375 L -12.1875,29.78125 C -12.243792,29.832657 -12.286698,29.897016 -12.3125,29.96875 C -12.343846,30.090131 -12.382395,30.284537 -12.4375,30.46875 C -12.45362,30.50878 -12.464136,30.550844 -12.46875,30.59375 L -12.46875,37.25 C -12.46875,37.54887 -12.355519,37.831675 -12.15625,38.0625 C -11.956981,38.293325 -11.645384,38.46875 -11.28125,38.46875 L -3.4375,38.46875 C -3.113867,38.46875 -2.780607,38.352963 -2.53125,38.09375 L 2.125,33.28125 C 2.35088,33.046445 2.46875,32.741604 2.46875,32.40625 L 2.46875,25.78125 C 2.46875,25.445897 2.350877,25.141055 2.125,24.90625 C 1.901344,24.677132 1.573636,24.53125 1.25,24.53125 L -6.5625,24.53125 z " style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#555753;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path sodipodi:nodetypes="cccccc" id="path7184" d="M -1,25 L -12,27.5 L -10,29 L -7,29 L -2,26 L -1,25" style="fill:url(#linearGradient7561);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="ccccc" id="path7171" d="M -5,25 L -12,27 L -8,27 L -1,25 L -5,25" style="fill:url(#linearGradient7563);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cccccc" id="rect7173" d="M -12,27 L -8.2868349,27 L -8,27 C -10,28 -8.5,29 -7,29 L -11,29 C -12.5,29 -14,28 -12,27 z " style="fill:url(#linearGradient7565);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:1" /> <path style="fill:url(#linearGradient7567);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M -9.5941664,32 L -5.405834,32 C -5.181002,32 -5,32.195125 -5,32.4375 L -5,35.5625 C -5,35.804876 -5.181002,36 -5.405834,36 L -9.5941664,36 C -9.8189979,36 -10,35.804876 -10,35.5625 L -10,32.4375 C -10,32.195125 -9.8189979,32 -9.5941664,32 z " id="path7275" /> </g> <path style="opacity:1;fill:url(#linearGradient7346);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.69999992;stroke-opacity:1" d="M 29.480478,10.068145 C 28.841463,10.068145 28.32502,10.584057 28.32502,11.222414 L 28.32502,11.510202 C 28.32502,11.803424 28.095708,12.053387 27.781275,12.053387 L 26.218008,12.053387 C 25.578993,12.053387 25.06255,12.756799 25.06255,13.395156 L 25.06255,19.840086 C 25.06255,20.478444 25.578994,20.994355 26.218008,20.994355 L 34.781992,20.994355 C 35.421007,20.994355 35.93745,20.478443 35.93745,19.840086 L 35.93745,13.395156 C 35.93745,12.756798 35.421008,12.053387 34.781992,12.053387 L 33.218725,12.053387 C 32.956948,12.071055 32.67498,11.867091 32.67498,11.527176 L 32.67498,11.222414 C 32.67498,10.584056 32.158536,10.068145 31.519522,10.068145 L 29.480478,10.068145 z" id="rect7327" sodipodi:nodetypes="ccccccccccccccccc" /> <path style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7436);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992000000000;stroke-opacity:1" d="M 29.5625,9.4375 C 28.453144,9.4375 27.577814,10.345513 27.5,11.4375 L 26.5625,11.4375 C 25.40342,11.4375 24.4375,12.403421 24.4375,13.5625 L 24.4375,19.4375 C 24.4375,20.59658 25.403421,21.5625 26.5625,21.5625 L 34.4375,21.5625 C 35.59658,21.5625 36.5625,20.596579 36.5625,19.4375 L 36.5625,13.5625 C 36.5625,12.403423 35.596579,11.4375 34.4375,11.4375 L 33.5,11.4375 C 33.422186,10.345512 32.546855,9.4375 31.4375,9.4375 L 29.5625,9.4375 z " id="path7350" sodipodi:nodetypes="ccccccccccccc" /> <g id="g7393" style="fill-opacity:1;stroke:url(#linearGradient7428)" transform="translate(1,-8)"> <path sodipodi:nodetypes="cc" id="path7352" d="M 26.5,26.5 L 26.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7446);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7362" d="M 28.5,26.5 L 28.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7448);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7364" d="M 30.5,26.5 L 30.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7450);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path7366" d="M 32.5,26.5 L 32.5,24.5" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7452);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> </g> <path style="fill:url(#linearGradient7658);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient7582);stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M 14.6875,30.5625 C 14.6875,30.5625 10.498126,33.830189 6.59375,37.0625 C 4.6415622,38.678655 2.8956918,40.28355 1.875,41.84375 C 1.3646541,42.62385 0.8878846,43.466971 1.21875,44.625 C 1.3841827,45.204014 1.8301355,45.746216 2.3125,46.03125 C 2.7948645,46.316284 3.2706533,46.437479 3.8125,46.5 C 5.9363798,46.745063 8.5434834,46.106406 11.65625,45.21875 C 14.769017,44.331094 18.325496,43.136387 21.90625,41.96875 C 25.487004,40.801113 29.102635,39.662687 32.25,38.96875 C 35.397365,38.274813 38.085104,38.083776 39.625,38.46875 C 40.353931,38.650983 40.370552,38.769574 40.375,38.78125 C 40.379448,38.792926 40.439577,39.11668 40.15625,39.71875 C 39.589596,40.92289 37.911115,42.835283 35.96875,44.65625 C 32.08402,48.298184 27.125,51.78125 27.125,51.78125 L 28.875,54.21875 C 28.875,54.21875 33.91598,50.701816 38.03125,46.84375 C 40.088885,44.914717 41.910404,42.95211 42.84375,40.96875 C 43.310423,39.97707 43.620552,38.855512 43.1875,37.71875 C 42.754448,36.581988 41.646069,35.849017 40.375,35.53125 C 37.914896,34.916224 34.93076,35.32675 31.59375,36.0625 C 28.25674,36.79825 24.575496,37.917637 20.96875,39.09375 C 17.362004,40.269863 13.840358,41.489218 10.84375,42.34375 C 7.9314529,43.174239 5.5458184,43.563842 4.375,43.46875 C 4.9949332,42.521138 6.6709378,40.915095 8.53125,39.375 C 12.251874,36.294811 16.5,33 16.5,33 L 14.6875,30.5625 z " id="path7506" sodipodi:nodetypes="cssssssssssssccssssssscscc" /> <path style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient7666);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.19029851;fill-opacity:1.0" d="M 15.672335,31.269607 C 15.672335,31.269607 -2.765165,43.957107 3.734835,44.707107 C 10.234835,45.457107 31.734835,34.707107 39.734835,36.707107 C 47.734835,38.707107 27.734835,52.707107 27.734835,52.707107" id="path7502" sodipodi:nodetypes="cssc" /> <path style="fill:url(#linearGradient7574);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642" d="M 10.088769,30.03125 L 10.40625,32.03125 L 14.59375,32.03125 C 14.818582,32.03125 15,32.226375 15,32.46875 L 15,35.59375 L 17,35.28125 L 17,30.8125 C 17,30.388343 16.685946,30.03125 16.28125,30.03125 L 10.088769,30.03125 z " id="path7512" sodipodi:nodetypes="ccccccccc" /> <path style="fill:url(#linearGradient7818);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.69999992;stroke-opacity:0.99236642;opacity:0.35447761" d="M -9.5941664,32 L -5.405834,32 C -5.181002,32 -5,32.195125 -5,32.4375 L -5,35.5625 C -5,35.804876 -5.181002,36 -5.405834,36 L -9.5941664,36 C -9.8189979,36 -10,35.804876 -10,35.5625 L -10,32.4375 C -10,32.195125 -9.8189979,32 -9.5941664,32 z " id="path7810" transform="translate(20,0)" /> </svg> �����������������������������������������������������������������������������./data/icons/scalable/notification-audio-volume-muted.svg�������������������������������������������0000644�0000041�0000041�00000103623�13570225707�024001� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="audio-volume-muted.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient inkscape:collect="always" id="linearGradient6700"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6702" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6704" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6628"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6630" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6632" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6546"> <stop style="stop-color:#555753;stop-opacity:1;" offset="0" id="stop6548" /> <stop style="stop-color:#888a85;stop-opacity:1" offset="1" id="stop6550" /> </linearGradient> <linearGradient id="linearGradient6667" inkscape:collect="always"> <stop id="stop6669" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop6671" offset="1" style="stop-color:#555753;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6651"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6653" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6655" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6645" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop6647" /> </linearGradient> <linearGradient id="linearGradient6633" inkscape:collect="always"> <stop id="stop6635" offset="0" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop id="stop6637" offset="1" style="stop-color:#61635f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient6627"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6629" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6631" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6607"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop6609" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6611" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6589"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6591" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6593" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6573"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6575" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6577" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6531"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6533" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6535" /> </linearGradient> <linearGradient id="linearGradient5533"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop5535" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop5537" /> </linearGradient> <linearGradient id="linearGradient21662"> <stop id="stop21664" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.81927711" id="stop21666" /> <stop id="stop21668" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21644"> <stop id="stop21646" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.73493975" id="stop21648" /> <stop id="stop21650" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21622"> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0" id="stop21624" /> <stop id="stop21630" offset="0.85542166" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:1" offset="1" id="stop21626" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient17123"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop17125" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop17127" /> </linearGradient> <linearGradient id="linearGradient9086"> <stop id="stop9088" offset="0" style="stop-color:black;stop-opacity:1;" /> <stop id="stop9090" offset="1" style="stop-color:black;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6387"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop6389" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6391" /> </linearGradient> <linearGradient id="linearGradient6379"> <stop style="stop-color:white;stop-opacity:0;" offset="0" id="stop6381" /> <stop id="stop21606" offset="0.5" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6383" /> </linearGradient> <linearGradient id="linearGradient2793"> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="0" id="stop2795" /> <stop id="stop2801" offset="0.25301206" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop2797" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6387" id="linearGradient6393" x1="17.25" y1="18.81151" x2="16.1875" y2="32.629498" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient9086" id="radialGradient8199" cx="7.1396246" cy="22.5" fx="7.1396246" fy="22.5" r="6" gradientTransform="matrix(1.914836,-0.506192,0.654838,2.477012,-48.62381,-29.61876)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21622" id="radialGradient21684" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21662" id="radialGradient21686" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21644" id="radialGradient21688" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2793" id="linearGradient5545" gradientUnits="userSpaceOnUse" x1="78.5" y1="-4.0065207" x2="78.5" y2="14.00099" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5533" id="linearGradient5547" gradientUnits="userSpaceOnUse" x1="80.0625" y1="14" x2="80.0625" y2="-4.0087729" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6531" id="linearGradient6537" x1="3.8448932" y1="15.561477" x2="3.8448932" y2="39.884338" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6627" id="linearGradient6545" x1="7.75" y1="33.046577" x2="4.6431866" y2="12.063652" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9114584,0,0,0.8787879,2.7005208,4.6666545)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6633" id="radialGradient6553" cx="9.3203983" cy="18.817093" fx="9.3203983" fy="18.817093" r="12.5" gradientTransform="matrix(0.7132478,0.5221478,-0.9280778,1.1784895,22.517143,-6.7083001)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6573" id="linearGradient6579" x1="12.197592" y1="9.2597418" x2="12.197592" y2="47.496857" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6667" id="radialGradient6595" cx="23.164974" cy="30.23279" fx="23.164974" fy="30.23279" r="8.1890125" gradientTransform="matrix(1.7346265,-0.1698771,0.327755,3.6175226,-27.429343,-73.69679)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6589" id="radialGradient6603" cx="20.8839" cy="20.434256" fx="20.8839" fy="20.434256" r="3.9999843" gradientTransform="matrix(1.3093938,0,0,1.5604932,-8.3886376,-9.784483)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6379" id="linearGradient6641" gradientUnits="userSpaceOnUse" x1="20.226221" y1="20.33363" x2="11.4375" y2="21.75" gradientTransform="matrix(0.6666667,0,0,1,2,-1)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6651" id="radialGradient6657" cx="23.986883" cy="27.053167" fx="23.986883" fy="27.053167" r="7.75" gradientTransform="matrix(-0.2432942,0,0,-1.2543129,25.221399,61.870636)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6546" id="linearGradient6558" gradientUnits="userSpaceOnUse" x1="80.693359" y1="31.561478" x2="77.125" y2="14" gradientTransform="translate(-70,2)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6607" id="radialGradient6625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.9866298,0.1169977,0,-2.530036,-104.62676,112.74341)" cx="30.685316" cy="42.261425" fx="30.685316" fy="42.261425" r="8.22791" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6628" id="linearGradient6634" x1="23.238182" y1="12.158657" x2="29.892563" y2="26.354361" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6700" id="linearGradient6706" x1="17.5" y1="25.587416" x2="28.555141" y2="25.699326" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6643" id="linearGradient6801" gradientUnits="userSpaceOnUse" x1="33.430557" y1="45.052155" x2="33.430557" y2="0.31037101" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient17123" id="radialGradient7118" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.330579,0,24.67693)" cx="11.402097" cy="36.863068" fx="11.402097" fy="36.863068" r="10.69499" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="38.009443" inkscape:cy="20.307512" inkscape:document-units="px" inkscape:current-layer="layer2" width="48px" height="48px" inkscape:showpageshadow="false" borderlayer="true" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:window-width="1051" inkscape:window-height="936" inkscape:window-x="14" inkscape:window-y="43" inkscape:guide-points="false" inkscape:grid-points="true" showguides="false" inkscape:guide-bbox="true" showborder="false" inkscape:grid-bbox="true" units="px"> <sodipodi:guide orientation="vertical" position="22" id="guide21670" /> <sodipodi:guide orientation="horizontal" position="24" id="guide21672" /> <sodipodi:guide orientation="vertical" position="32" id="guide6673" /> <inkscape:grid type="xygrid" id="grid6385" /> <sodipodi:guide orientation="horizontal" position="2.5" id="guide6925" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Ulisse Perusin</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Audio Volume High</dc:title> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="constr" style="display:none"> <path style="opacity:0.83011588;fill:url(#radialGradient8199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -8.21875,10.5 L -20.21875,22.5 L -8.21875,34.5 L -8.21875,10.5 z " id="path7288" sodipodi:nodetypes="cccc" /> <path style="opacity:0.76833975;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6393);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -7,10.5 L -19,22.5 L -7,34.5 L -7,10.5 z " id="path2791" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50000006" inkscape:original="M 19.5 9.5 C 18 15 12 14 7.5 22.5 C 12 31 18 30 19.5 35.5 L 19.5 9.5 z " style="opacity:0.63320462;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" id="path21580" d="M 19.375,9 C 19.200644,9.0530225 19.06894,9.1967002 19.03125,9.375 C 18.327802,11.954311 16.604417,12.961638 14.34375,14.46875 C 12.083083,15.975862 9.3592888,17.942871 7.0625,22.28125 C 6.9953198,22.419346 6.9953198,22.580654 7.0625,22.71875 C 9.3592888,27.057129 12.083083,29.024138 14.34375,30.53125 C 16.604417,32.038362 18.327802,33.045689 19.03125,35.625 C 19.110592,35.845992 19.333006,35.982016 19.565879,35.951968 C 19.798752,35.92192 19.979353,35.733894 20,35.5 L 20,9.5 C 20.005,9.3425939 19.935556,9.1920293 19.812581,9.0936489 C 19.689605,8.9952685 19.527469,8.9605689 19.375,9 z " transform="translate(-42,0)" /> <path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -47.5,22.5 L -20,-8 L -20,56 L -47.5,22.5 z " id="path21676" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21684);fill-opacity:1;stroke:#204a87;stroke-width:0.12515022;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21678" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(7.990397,0,0,7.990397,-220.7725,-152.0403)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21686);fill-opacity:1;stroke:#204a87;stroke-width:0.18086948;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21680" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(5.528848,0,0,5.528848,-169.4646,-98.27085)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21688);fill-opacity:1;stroke:#204a87;stroke-width:0.29248634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21682" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(3.418962,0,0,3.418962,-125.4867,-52.18304)" /> </g> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.2;fill:url(#radialGradient7118);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" id="path16236" sodipodi:cx="11.402097" sodipodi:cy="36.863068" sodipodi:rx="10.69499" sodipodi:ry="3.5355339" d="M 22.097087 36.863068 A 10.69499 3.5355339 0 1 1 0.70710659,36.863068 A 10.69499 3.5355339 0 1 1 22.097087 36.863068 z" transform="matrix(1.5365906,0,0,2.4199734,-1.1723206,-56.384863)" /> <path sodipodi:type="arc" style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:1.30267787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path5330" sodipodi:cx="4" sodipodi:cy="25" sodipodi:rx="4" sodipodi:ry="7" d="M 8 25 A 4 7 0 1 1 0,25 A 4 7 0 1 1 8 25 z" transform="matrix(0.75,0,0,0.7857143,1.5,4.357156)" /> <path sodipodi:type="arc" style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6659" sodipodi:cx="3.75" sodipodi:cy="20.75" sodipodi:rx="0.75" sodipodi:ry="0.75" d="M 4.5 20.75 A 0.75 0.75 0 1 1 3,20.75 A 0.75 0.75 0 1 1 4.5 20.75 z" transform="translate(-1.53125,0.65625)" /> <path style="fill:url(#linearGradient5545);fill-opacity:1;stroke:url(#linearGradient5547);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 6.125,15.500014 C 4.1240036,15.500014 2.5000009,19.308036 2.5,24.000014 C 2.5,28.691991 4.1240036,32.500015 6.125,32.500014 L 9.75,32.500014 C 11.750996,32.500014 13.375,28.69199 13.375,24.000014 C 13.375,19.308037 11.750996,15.500014 9.75,15.500014 L 6.125,15.500014 z " id="path2766" sodipodi:nodetypes="csccscc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0054175" inkscape:original="M 5.5 13.5 C 3.292004 13.5 1.500001 17.308022 1.5 22 C 1.5 26.691978 3.292004 30.500001 5.5 30.5 L 9.5 30.5 C 11.707996 30.500001 13.5 26.691976 13.5 22 C 13.5 17.308024 11.707996 13.5 9.5 13.5 L 5.5 13.5 z " style="opacity:0.6;fill:none;fill-opacity:1;stroke:url(#linearGradient6537);stroke-width:1.0577718;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path5556" d="M 5.5,14.5 C 4.974,14.5 4.2339165,15.045895 3.59375,16.40625 C 2.9535835,17.766605 2.5000005,19.78201 2.5,22 C 2.5,24.21799 2.9535834,26.233394 3.59375,27.59375 C 4.2339166,28.954106 4.9740003,29.5 5.5,29.5 L 9.5,29.5 C 10.025999,29.5 10.766083,28.954106 11.40625,27.59375 C 12.046417,26.233394 12.5,24.217988 12.5,22 C 12.5,19.782012 12.046417,17.766606 11.40625,16.40625 C 10.766083,15.045894 10.026,14.5 9.5,14.5 L 5.5,14.5 z " transform="matrix(0.89375,0,0,1,1.265625,2)" /> <path style="opacity:1;fill:url(#linearGradient6558);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 9.696925,16 C 7.656226,16 6.000001,19.57702 6,23.984375 C 6,28.391729 7.656226,31.968751 9.696925,31.96875 L 10.334325,31.96875 C 12.375024,31.96875 14.03125,28.391728 14.03125,23.984375 C 14.03125,19.577021 12.375024,16 10.334325,16 L 9.696925,16 z " id="path6556" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#radialGradient6553);fill-opacity:1;stroke:url(#linearGradient6545);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 8.6250003,24 C 8.6250003,33.227273 17.811975,38.499999 23.500002,38.499999 C 27.437502,38.499999 30.500002,32.003996 30.500002,24 C 30.500002,15.996003 27.437502,9.5000001 23.500002,9.5000001 C 17.811975,9.5000001 8.6250003,14.772728 8.6250003,24 z " id="path1871" sodipodi:nodetypes="cssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6657);fill-opacity:1;stroke:none;stroke-width:0.87802505;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6649" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.3225807,0,0,1.026415,-12.145162,-4.6754711)" /> <path style="opacity:0.7335907;fill:url(#linearGradient6641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M 16,13.375 C 13.416667,14.769678 10.541667,17.570921 8,21.5 C 10.69956,20.373913 13.491292,19.539527 16,19.75 L 16,13.375 z " id="path6639" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0125009" inkscape:original="M 22.8125 5.5 C 16.571923 5.5000002 6.5 11.5 6.5 22 C 6.5 32.500001 16.571923 38.5 22.8125 38.5 C 27.1325 38.499999 30.5 31.107996 30.5 22 C 30.5 12.892005 27.1325 5.5 22.8125 5.5 z " style="opacity:0.58620689;fill:none;fill-opacity:1;stroke:url(#linearGradient6579);stroke-width:1.12734473;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6567" d="M 22.8125,6.5 C 20.016701,6.5000001 16.088488,7.9333131 12.96875,10.59375 C 9.8490125,13.254187 7.5,17.073741 7.5,22 C 7.5,26.92626 9.8490125,30.745813 12.96875,33.40625 C 16.088487,36.066687 20.016701,37.5 22.8125,37.5 C 24.394999,37.5 26.045271,36.056265 27.34375,33.25 C 28.642229,30.443735 29.5,26.429214 29.5,22 C 29.5,17.570787 28.642229,13.556265 27.34375,10.75 C 26.045271,7.943735 24.394999,6.5 22.8125,6.5 z " transform="matrix(0.9034091,0,0,0.8709678,2.8494318,4.8387095)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6595);fill-opacity:1;stroke:url(#linearGradient6801);stroke-width:0.83240509;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path1873" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.2258059,0,0,1.1773585,-8.9515943,-8.892453)" /> <path style="fill:url(#radialGradient6603);fill-opacity:1;stroke:#555753;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 21.616117,24.000008 C 21.616117,26.484005 19.233185,28.49999 17.549734,28.49999 C 15.866281,28.49999 14.500001,26.483992 14.500001,23.999995 C 14.500001,21.515998 15.866281,19.5 17.549734,19.5 C 19.233185,19.5 21.616117,21.51601 21.616117,24.000008 z " id="path3672" sodipodi:nodetypes="csssc" /> <path style="opacity:1;fill:url(#radialGradient6625);fill-opacity:1;stroke:none;stroke-width:0.90347975;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 22,5 C 19.367552,4.9999999 17.141972,7.2498264 15.5625,10.6875 C 13.983028,14.125173 13.03125,18.830125 13.03125,24 C 13.03125,29.169874 13.983028,33.874826 15.5625,37.3125 C 17.141972,40.750172 19.367552,43 22,43 C 24.632449,43 26.858028,40.750173 28.4375,37.3125 C 29.42467,35.163953 30.174611,32.501281 30.59375,29.5625 C 30.606967,29.469828 30.612431,29.374514 30.625,29.28125 C 30.701405,28.714302 30.760731,28.149758 30.8125,27.5625 C 30.863372,27.016086 30.910141,26.469464 30.9375,25.90625 C 30.938938,25.875286 30.936131,25.843507 30.9375,25.8125 C 30.964969,25.216652 30.96875,24.611754 30.96875,24 C 30.96875,23.355639 30.96794,22.720382 30.9375,22.09375 C 30.911649,21.537127 30.860238,20.979033 30.8125,20.4375 C 30.760731,19.850242 30.701405,19.285698 30.625,18.71875 C 30.611503,18.623565 30.607961,18.532009 30.59375,18.4375 C 30.174611,15.498719 29.42467,12.836046 28.4375,10.6875 C 26.858028,7.249826 24.632449,5 22,5 z M 22.5,7 C 24.422274,7.0000002 26.280368,8.7656497 27.6875,11.84375 C 28.566957,13.767562 29.264379,16.179117 29.65625,18.875 C 29.734624,19.414177 29.789845,19.97021 29.84375,20.53125 C 29.89121,21.056658 29.942834,21.584653 29.96875,22.125 C 30.000626,22.745494 30.03125,23.361156 30.03125,24 C 30.03125,24.595745 29.99653,25.170104 29.96875,25.75 C 29.966916,25.790974 29.970711,25.834105 29.96875,25.875 C 29.941175,26.411772 29.893755,26.948299 29.84375,27.46875 C 29.789845,28.029789 29.734624,28.585823 29.65625,29.125 C 29.264379,31.820883 28.566957,34.232438 27.6875,36.15625 C 26.280368,39.23435 24.422274,41 22.5,41 C 20.577727,40.999998 18.719632,39.234351 17.3125,36.15625 C 15.905367,33.078149 14.96875,28.765963 14.96875,24 C 14.96875,19.234036 15.905368,14.92185 17.3125,11.84375 C 18.719631,8.7656496 20.577727,7 22.5,7 z " id="path6605" sodipodi:nodetypes="cssssssssssssssssccssssssssssssssc" /> <path sodipodi:type="arc" style="opacity:0.36637932;fill:none;fill-opacity:1;stroke:url(#linearGradient6634);stroke-width:1.05419946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6615" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(0.9032258,0,0,0.9962264,-0.3064529,-3.8320749)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6661" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-16,5.3125)" /> <path sodipodi:type="arc" style="opacity:0.65517243;fill:none;fill-opacity:1;stroke:url(#linearGradient6706);stroke-width:0.90347946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6698" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.0967748,0,0,1.1169811,-5.6935592,-7.2056602)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path5501" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-5,-1.875)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="waves"> <g id="layer4" inkscape:label="Muted" style="display:inline" transform="matrix(1.0828519,0,0,1.0830642,1.5587564,-0.36757)"> <g id="g4694" transform="translate(-2,0)"> <rect ry="1.4868355" rx="1.4868355" y="16.498245" x="31.498245" height="12.00351" width="12.00351" id="rect2021" style="opacity:1;fill:#ef2929;fill-opacity:1;stroke:#a40000;stroke-width:0.92015547;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> <rect ry="0.49373779" rx="0.49383482" y="17.420549" x="32.420815" height="10.156369" width="10.158366" id="rect3795" style="opacity:0.3;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.92339665;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> <path sodipodi:nodetypes="cc" id="path4682" d="M 35,20 L 40,25" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.38509536;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> <path sodipodi:nodetypes="cc" id="path4684" d="M 40,20 L 35,25" style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.38509536;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" /> </g> </g> </g> </svg> �������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-volume-low.svg���������������������������������������������0000644�0000041�0000041�00000103011�13570225707�023453� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="audio-volume-low.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient id="linearGradient6958"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop6960" /> <stop id="stop6966" offset="0.60000002" style="stop-color:#729fcf;stop-opacity:1;" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop6962" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6700"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6702" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6704" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6628"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6630" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6632" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6546"> <stop style="stop-color:#555753;stop-opacity:1;" offset="0" id="stop6548" /> <stop style="stop-color:#888a85;stop-opacity:1" offset="1" id="stop6550" /> </linearGradient> <linearGradient id="linearGradient6667" inkscape:collect="always"> <stop id="stop6669" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop6671" offset="1" style="stop-color:#555753;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6651"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6653" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6655" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6645" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop6647" /> </linearGradient> <linearGradient id="linearGradient6633" inkscape:collect="always"> <stop id="stop6635" offset="0" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop id="stop6637" offset="1" style="stop-color:#61635f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient6627"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6629" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6631" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6607"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop6609" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6611" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6589"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6591" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6593" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6573"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6575" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6577" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6531"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6533" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6535" /> </linearGradient> <linearGradient id="linearGradient5533"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop5535" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop5537" /> </linearGradient> <linearGradient id="linearGradient21662"> <stop id="stop21664" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.81927711" id="stop21666" /> <stop id="stop21668" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21644"> <stop id="stop21646" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.73493975" id="stop21648" /> <stop id="stop21650" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21622"> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0" id="stop21624" /> <stop id="stop21630" offset="0.85542166" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:1" offset="1" id="stop21626" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient17123"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop17125" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop17127" /> </linearGradient> <linearGradient id="linearGradient9086"> <stop id="stop9088" offset="0" style="stop-color:black;stop-opacity:1;" /> <stop id="stop9090" offset="1" style="stop-color:black;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6387"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop6389" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6391" /> </linearGradient> <linearGradient id="linearGradient6379"> <stop style="stop-color:white;stop-opacity:0;" offset="0" id="stop6381" /> <stop id="stop21606" offset="0.5" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6383" /> </linearGradient> <linearGradient id="linearGradient2793"> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="0" id="stop2795" /> <stop id="stop2801" offset="0.25301206" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop2797" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6387" id="linearGradient6393" x1="17.25" y1="18.81151" x2="16.1875" y2="32.629498" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient9086" id="radialGradient8199" cx="7.1396246" cy="22.5" fx="7.1396246" fy="22.5" r="6" gradientTransform="matrix(1.914836,-0.506192,0.654838,2.477012,-48.62381,-29.61876)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21622" id="radialGradient21684" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21662" id="radialGradient21686" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21644" id="radialGradient21688" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2793" id="linearGradient5545" gradientUnits="userSpaceOnUse" x1="78.5" y1="-4.0065207" x2="78.5" y2="14.00099" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5533" id="linearGradient5547" gradientUnits="userSpaceOnUse" x1="80.0625" y1="14" x2="80.0625" y2="-4.0087729" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6531" id="linearGradient6537" x1="3.8448932" y1="15.561477" x2="3.8448932" y2="39.884338" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6627" id="linearGradient6545" x1="7.75" y1="33.046577" x2="4.6431866" y2="12.063652" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9114584,0,0,0.8787879,2.7005208,4.6666545)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6633" id="radialGradient6553" cx="9.3203983" cy="18.817093" fx="9.3203983" fy="18.817093" r="12.5" gradientTransform="matrix(0.7132478,0.5221478,-0.9280778,1.1784895,22.517143,-6.7083001)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6573" id="linearGradient6579" x1="12.197592" y1="9.2597418" x2="12.197592" y2="47.496857" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6667" id="radialGradient6595" cx="23.164974" cy="30.23279" fx="23.164974" fy="30.23279" r="8.1890125" gradientTransform="matrix(1.7346265,-0.1698771,0.327755,3.6175226,-27.429343,-73.69679)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6589" id="radialGradient6603" cx="20.8839" cy="20.434256" fx="20.8839" fy="20.434256" r="3.9999842" gradientTransform="matrix(1.3093938,0,0,1.5604932,-8.3886376,-9.784483)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6379" id="linearGradient6641" gradientUnits="userSpaceOnUse" x1="20.226221" y1="20.33363" x2="11.4375" y2="21.75" gradientTransform="matrix(0.6666667,0,0,1,2,-1)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6651" id="radialGradient6657" cx="23.986883" cy="27.053167" fx="23.986883" fy="27.053167" r="7.75" gradientTransform="matrix(-0.2432942,0,0,-1.2543129,25.221399,61.870636)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6546" id="linearGradient6558" gradientUnits="userSpaceOnUse" x1="80.693359" y1="31.561478" x2="77.125" y2="14" gradientTransform="translate(-70,2)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6607" id="radialGradient6625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.9866298,0.1169977,0,-2.530036,-104.62676,112.74341)" cx="30.685316" cy="42.261425" fx="30.685316" fy="42.261425" r="8.22791" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6628" id="linearGradient6634" x1="23.238182" y1="12.158657" x2="29.892563" y2="26.354361" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6700" id="linearGradient6706" x1="17.5" y1="25.587416" x2="28.555141" y2="25.699326" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6643" id="linearGradient6801" gradientUnits="userSpaceOnUse" x1="33.430557" y1="45.052155" x2="33.430557" y2="0.31037101" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6984" cx="60.640625" cy="22.65625" fx="60.640625" fy="22.65625" r="2.6194003" gradientTransform="matrix(2.1454532,0,0,3.0191635,-69.461,-45.746674)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient17123" id="radialGradient7118" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.330579,0,24.67693)" cx="11.402097" cy="36.863068" fx="11.402097" fy="36.863068" r="10.69499" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="24" inkscape:cy="42.911478" inkscape:document-units="px" inkscape:current-layer="layer2" width="48px" height="48px" inkscape:showpageshadow="false" borderlayer="true" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:window-width="1051" inkscape:window-height="936" inkscape:window-x="14" inkscape:window-y="43" inkscape:guide-points="false" inkscape:grid-points="true" showguides="false" inkscape:guide-bbox="true" showborder="false" inkscape:grid-bbox="true"> <sodipodi:guide orientation="vertical" position="22" id="guide21670" /> <sodipodi:guide orientation="horizontal" position="26" id="guide21672" /> <sodipodi:guide orientation="vertical" position="32" id="guide6673" /> <inkscape:grid type="xygrid" id="grid6385" /> <sodipodi:guide orientation="horizontal" position="2.5" id="guide6925" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Ulisse Perusin</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Audio Volume High</dc:title> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="constr" style="display:none"> <path style="opacity:0.83011588;fill:url(#radialGradient8199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -8.21875,10.5 L -20.21875,22.5 L -8.21875,34.5 L -8.21875,10.5 z " id="path7288" sodipodi:nodetypes="cccc" /> <path style="opacity:0.76833975;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6393);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -7,10.5 L -19,22.5 L -7,34.5 L -7,10.5 z " id="path2791" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50000006" inkscape:original="M 19.5 9.5 C 18 15 12 14 7.5 22.5 C 12 31 18 30 19.5 35.5 L 19.5 9.5 z " style="opacity:0.63320462;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" id="path21580" d="M 19.375,9 C 19.200644,9.0530225 19.06894,9.1967002 19.03125,9.375 C 18.327802,11.954311 16.604417,12.961638 14.34375,14.46875 C 12.083083,15.975862 9.3592888,17.942871 7.0625,22.28125 C 6.9953198,22.419346 6.9953198,22.580654 7.0625,22.71875 C 9.3592888,27.057129 12.083083,29.024138 14.34375,30.53125 C 16.604417,32.038362 18.327802,33.045689 19.03125,35.625 C 19.110592,35.845992 19.333006,35.982016 19.565879,35.951968 C 19.798752,35.92192 19.979353,35.733894 20,35.5 L 20,9.5 C 20.005,9.3425939 19.935556,9.1920293 19.812581,9.0936489 C 19.689605,8.9952685 19.527469,8.9605689 19.375,9 z " transform="translate(-42,0)" /> <path style="fill:none;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -47.5,22.5 L -20,-8 L -20,56 L -47.5,22.5 z " id="path21676" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21684);fill-opacity:1;stroke:#204a87;stroke-width:0.12515022;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21678" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(7.990397,0,0,7.990397,-220.7725,-152.0403)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21686);fill-opacity:1;stroke:#204a87;stroke-width:0.18086948;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21680" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(5.528848,0,0,5.528848,-169.4646,-98.27085)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21688);fill-opacity:1;stroke:#204a87;stroke-width:0.29248634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21682" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(3.418962,0,0,3.418962,-125.4867,-52.18304)" /> </g> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.2;fill:url(#radialGradient7118);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" id="path16236" sodipodi:cx="11.402097" sodipodi:cy="36.863068" sodipodi:rx="10.69499" sodipodi:ry="3.5355339" d="M 22.097087 36.863068 A 10.69499 3.5355339 0 1 1 0.70710659,36.863068 A 10.69499 3.5355339 0 1 1 22.097087 36.863068 z" transform="matrix(1.5365906,0,0,2.4199734,-1.1723206,-56.384863)" /> <path sodipodi:type="arc" style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:1.30267787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path5330" sodipodi:cx="4" sodipodi:cy="25" sodipodi:rx="4" sodipodi:ry="7" d="M 8 25 A 4 7 0 1 1 0,25 A 4 7 0 1 1 8 25 z" transform="matrix(0.75,0,0,0.7857143,1.5,4.357156)" /> <path sodipodi:type="arc" style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6659" sodipodi:cx="3.75" sodipodi:cy="20.75" sodipodi:rx="0.75" sodipodi:ry="0.75" d="M 4.5 20.75 A 0.75 0.75 0 1 1 3,20.75 A 0.75 0.75 0 1 1 4.5 20.75 z" transform="translate(-1.53125,0.65625)" /> <path style="fill:url(#linearGradient5545);fill-opacity:1;stroke:url(#linearGradient5547);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 6.125,15.500014 C 4.1240036,15.500014 2.5000009,19.308036 2.5,24.000014 C 2.5,28.691991 4.1240036,32.500015 6.125,32.500014 L 9.75,32.500014 C 11.750996,32.500014 13.375,28.69199 13.375,24.000014 C 13.375,19.308037 11.750996,15.500014 9.75,15.500014 L 6.125,15.500014 z " id="path2766" sodipodi:nodetypes="csccscc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0054175" inkscape:original="M 5.5 13.5 C 3.292004 13.5 1.500001 17.308022 1.5 22 C 1.5 26.691978 3.292004 30.500001 5.5 30.5 L 9.5 30.5 C 11.707996 30.500001 13.5 26.691976 13.5 22 C 13.5 17.308024 11.707996 13.5 9.5 13.5 L 5.5 13.5 z " style="opacity:0.6;fill:none;fill-opacity:1;stroke:url(#linearGradient6537);stroke-width:1.0577718;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path5556" d="M 5.5,14.5 C 4.974,14.5 4.2339165,15.045895 3.59375,16.40625 C 2.9535835,17.766605 2.5000005,19.78201 2.5,22 C 2.5,24.21799 2.9535834,26.233394 3.59375,27.59375 C 4.2339166,28.954106 4.9740003,29.5 5.5,29.5 L 9.5,29.5 C 10.025999,29.5 10.766083,28.954106 11.40625,27.59375 C 12.046417,26.233394 12.5,24.217988 12.5,22 C 12.5,19.782012 12.046417,17.766606 11.40625,16.40625 C 10.766083,15.045894 10.026,14.5 9.5,14.5 L 5.5,14.5 z " transform="matrix(0.89375,0,0,1,1.265625,2)" /> <path style="opacity:1;fill:url(#linearGradient6558);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 9.696925,16 C 7.656226,16 6.000001,19.57702 6,23.984375 C 6,28.391729 7.656226,31.968751 9.696925,31.96875 L 10.334325,31.96875 C 12.375024,31.96875 14.03125,28.391728 14.03125,23.984375 C 14.03125,19.577021 12.375024,16 10.334325,16 L 9.696925,16 z " id="path6556" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#radialGradient6553);fill-opacity:1;stroke:url(#linearGradient6545);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 8.6250003,24 C 8.6250003,33.227273 17.811975,38.499999 23.500002,38.499999 C 27.437502,38.499999 30.500002,32.003996 30.500002,24 C 30.500002,15.996003 27.437502,9.5000001 23.500002,9.5000001 C 17.811975,9.5000001 8.6250003,14.772728 8.6250003,24 z " id="path1871" sodipodi:nodetypes="cssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6657);fill-opacity:1;stroke:none;stroke-width:0.87802505;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6649" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.3225807,0,0,1.026415,-12.145162,-4.6754711)" /> <path style="opacity:0.7335907;fill:url(#linearGradient6641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M 16,13.375 C 13.416667,14.769678 10.541667,17.570921 8,21.5 C 10.69956,20.373913 13.491292,19.539527 16,19.75 L 16,13.375 z " id="path6639" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0125009" inkscape:original="M 22.8125 5.5 C 16.571923 5.5000002 6.5 11.5 6.5 22 C 6.5 32.500001 16.571923 38.5 22.8125 38.5 C 27.1325 38.499999 30.5 31.107996 30.5 22 C 30.5 12.892005 27.1325 5.5 22.8125 5.5 z " style="opacity:0.58620689;fill:none;fill-opacity:1;stroke:url(#linearGradient6579);stroke-width:1.12734473;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6567" d="M 22.8125,6.5 C 20.016701,6.5000001 16.088488,7.9333131 12.96875,10.59375 C 9.8490125,13.254187 7.5,17.073741 7.5,22 C 7.5,26.92626 9.8490125,30.745813 12.96875,33.40625 C 16.088487,36.066687 20.016701,37.5 22.8125,37.5 C 24.394999,37.5 26.045271,36.056265 27.34375,33.25 C 28.642229,30.443735 29.5,26.429214 29.5,22 C 29.5,17.570787 28.642229,13.556265 27.34375,10.75 C 26.045271,7.943735 24.394999,6.5 22.8125,6.5 z " transform="matrix(0.9034091,0,0,0.8709678,2.8494318,4.8387095)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6595);fill-opacity:1;stroke:url(#linearGradient6801);stroke-width:0.83240509;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path1873" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.2258059,0,0,1.1773585,-8.9515943,-8.892453)" /> <path style="fill:url(#radialGradient6603);fill-opacity:1;stroke:#555753;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 21.616117,24.000008 C 21.616117,26.484005 19.233185,28.49999 17.549734,28.49999 C 15.866281,28.49999 14.500001,26.483992 14.500001,23.999995 C 14.500001,21.515998 15.866281,19.5 17.549734,19.5 C 19.233185,19.5 21.616117,21.51601 21.616117,24.000008 z " id="path3672" sodipodi:nodetypes="csssc" /> <path style="opacity:1;fill:url(#radialGradient6625);fill-opacity:1;stroke:none;stroke-width:0.90347975;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 22,5 C 19.367552,4.9999999 17.141972,7.2498264 15.5625,10.6875 C 13.983028,14.125173 13.03125,18.830125 13.03125,24 C 13.03125,29.169874 13.983028,33.874826 15.5625,37.3125 C 17.141972,40.750172 19.367552,43 22,43 C 24.632449,43 26.858028,40.750173 28.4375,37.3125 C 29.42467,35.163953 30.174611,32.501281 30.59375,29.5625 C 30.606967,29.469828 30.612431,29.374514 30.625,29.28125 C 30.701405,28.714302 30.760731,28.149758 30.8125,27.5625 C 30.863372,27.016086 30.910141,26.469464 30.9375,25.90625 C 30.938938,25.875286 30.936131,25.843507 30.9375,25.8125 C 30.964969,25.216652 30.96875,24.611754 30.96875,24 C 30.96875,23.355639 30.96794,22.720382 30.9375,22.09375 C 30.911649,21.537127 30.860238,20.979033 30.8125,20.4375 C 30.760731,19.850242 30.701405,19.285698 30.625,18.71875 C 30.611503,18.623565 30.607961,18.532009 30.59375,18.4375 C 30.174611,15.498719 29.42467,12.836046 28.4375,10.6875 C 26.858028,7.249826 24.632449,5 22,5 z M 22.5,7 C 24.422274,7.0000002 26.280368,8.7656497 27.6875,11.84375 C 28.566957,13.767562 29.264379,16.179117 29.65625,18.875 C 29.734624,19.414177 29.789845,19.97021 29.84375,20.53125 C 29.89121,21.056658 29.942834,21.584653 29.96875,22.125 C 30.000626,22.745494 30.03125,23.361156 30.03125,24 C 30.03125,24.595745 29.99653,25.170104 29.96875,25.75 C 29.966916,25.790974 29.970711,25.834105 29.96875,25.875 C 29.941175,26.411772 29.893755,26.948299 29.84375,27.46875 C 29.789845,28.029789 29.734624,28.585823 29.65625,29.125 C 29.264379,31.820883 28.566957,34.232438 27.6875,36.15625 C 26.280368,39.23435 24.422274,41 22.5,41 C 20.577727,40.999998 18.719632,39.234351 17.3125,36.15625 C 15.905367,33.078149 14.96875,28.765963 14.96875,24 C 14.96875,19.234036 15.905368,14.92185 17.3125,11.84375 C 18.719631,8.7656496 20.577727,7 22.5,7 z " id="path6605" sodipodi:nodetypes="cssssssssssssssssccssssssssssssssc" /> <path sodipodi:type="arc" style="opacity:0.36637932;fill:none;fill-opacity:1;stroke:url(#linearGradient6634);stroke-width:1.05419946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6615" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(0.9032258,0,0,0.9962264,-0.3064529,-3.8320749)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6661" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-16,5.3125)" /> <path sodipodi:type="arc" style="opacity:0.65517243;fill:none;fill-opacity:1;stroke:url(#linearGradient6706);stroke-width:0.90347946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6698" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.0967748,0,0,1.1169811,-5.6935592,-7.2056602)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path5501" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-5,-1.875)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="waves"> <g style="stroke:#729fcf;display:inline" id="g28807" transform="matrix(0.3535062,0,0,1.2242975,13.43562,-3.80102)"> <path sodipodi:nodetypes="csc" id="path27920" d="M 58.78125,30.15625 C 61.050824,28.375887 62.5,25.606103 62.5,22.5 C 62.5,19.560794 61.188424,16.939552 59.125,15.15625" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6984);stroke-width:1.52005064;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> </g> </svg> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-audio-volume-high.svg��������������������������������������������0000644�0000041�0000041�00000107407�13570225707�023606� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48" height="48" id="svg2" sodipodi:version="0.32" inkscape:version="0.45" version="1.0" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/status" sodipodi:docname="audio-volume-high.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs4"> <linearGradient id="linearGradient6958"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop6960" /> <stop id="stop6966" offset="0.60000002" style="stop-color:#729fcf;stop-opacity:1;" /> <stop style="stop-color:#729fcf;stop-opacity:0;" offset="1" id="stop6962" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6700"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6702" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6704" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6628"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop6630" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop6632" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6546"> <stop style="stop-color:#555753;stop-opacity:1;" offset="0" id="stop6548" /> <stop style="stop-color:#888a85;stop-opacity:1" offset="1" id="stop6550" /> </linearGradient> <linearGradient id="linearGradient6667" inkscape:collect="always"> <stop id="stop6669" offset="0" style="stop-color:#babdb6;stop-opacity:1" /> <stop id="stop6671" offset="1" style="stop-color:#555753;stop-opacity:1" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6651"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6653" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6655" /> </linearGradient> <linearGradient id="linearGradient6643"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6645" /> <stop style="stop-color:#d3d7cf;stop-opacity:1" offset="1" id="stop6647" /> </linearGradient> <linearGradient id="linearGradient6633" inkscape:collect="always"> <stop id="stop6635" offset="0" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop id="stop6637" offset="1" style="stop-color:#61635f;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient6627"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop6629" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6631" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6607"> <stop style="stop-color:#eeeeec;stop-opacity:1" offset="0" id="stop6609" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop6611" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6589"> <stop style="stop-color:#babdb6;stop-opacity:1" offset="0" id="stop6591" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop6593" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6573"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6575" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6577" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6531"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6533" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6535" /> </linearGradient> <linearGradient id="linearGradient5533"> <stop style="stop-color:#555753;stop-opacity:1" offset="0" id="stop5535" /> <stop style="stop-color:#babdb6;stop-opacity:1" offset="1" id="stop5537" /> </linearGradient> <linearGradient id="linearGradient21662"> <stop id="stop21664" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.81927711" id="stop21666" /> <stop id="stop21668" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21644"> <stop id="stop21646" offset="0" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0.73493975" id="stop21648" /> <stop id="stop21650" offset="1" style="stop-color:#3465a4;stop-opacity:1" /> </linearGradient> <linearGradient id="linearGradient21622"> <stop style="stop-color:#3465a4;stop-opacity:0;" offset="0" id="stop21624" /> <stop id="stop21630" offset="0.85542166" style="stop-color:#3465a4;stop-opacity:0;" /> <stop style="stop-color:#3465a4;stop-opacity:1" offset="1" id="stop21626" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient17123"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop17125" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop17127" /> </linearGradient> <linearGradient id="linearGradient9086"> <stop id="stop9088" offset="0" style="stop-color:black;stop-opacity:1;" /> <stop id="stop9090" offset="1" style="stop-color:black;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient6387"> <stop style="stop-color:white;stop-opacity:1;" offset="0" id="stop6389" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6391" /> </linearGradient> <linearGradient id="linearGradient6379"> <stop style="stop-color:white;stop-opacity:0;" offset="0" id="stop6381" /> <stop id="stop21606" offset="0.5" style="stop-color:white;stop-opacity:1;" /> <stop style="stop-color:white;stop-opacity:0;" offset="1" id="stop6383" /> </linearGradient> <linearGradient id="linearGradient2793"> <stop style="stop-color:#babdb6;stop-opacity:1;" offset="0" id="stop2795" /> <stop id="stop2801" offset="0.25301206" style="stop-color:#eeeeec;stop-opacity:1;" /> <stop style="stop-color:#555753;stop-opacity:1" offset="1" id="stop2797" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6387" id="linearGradient6393" x1="17.25" y1="18.81151" x2="16.1875" y2="32.629498" gradientUnits="userSpaceOnUse" gradientTransform="translate(-28,0)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient9086" id="radialGradient8199" cx="7.1396246" cy="22.5" fx="7.1396246" fy="22.5" r="6" gradientTransform="matrix(1.914836,-0.506192,0.654838,2.477012,-48.62381,-29.61876)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21622" id="radialGradient21684" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21662" id="radialGradient21686" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient21644" id="radialGradient21688" gradientUnits="userSpaceOnUse" cx="20.84375" cy="21.84375" fx="20.84375" fy="21.84375" r="2.9063251" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient2793" id="linearGradient5545" gradientUnits="userSpaceOnUse" x1="78.5" y1="-4.0065207" x2="78.5" y2="14.00099" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5533" id="linearGradient5547" gradientUnits="userSpaceOnUse" x1="80.0625" y1="14" x2="80.0625" y2="-4.0087729" gradientTransform="matrix(0.90625,0,0,1,-65.921875,19)" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6531" id="linearGradient6537" x1="3.8448932" y1="15.561477" x2="3.8448932" y2="39.884338" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6627" id="linearGradient6545" x1="7.75" y1="33.046577" x2="4.6431866" y2="12.063652" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.9114584,0,0,0.8787879,2.7005208,4.6666545)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6633" id="radialGradient6553" cx="9.3203983" cy="18.817093" fx="9.3203983" fy="18.817093" r="12.5" gradientTransform="matrix(0.7132478,0.5221478,-0.9280778,1.1784895,22.517143,-6.7083001)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6573" id="linearGradient6579" x1="12.197592" y1="9.2597418" x2="12.197592" y2="47.496857" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6667" id="radialGradient6595" cx="23.164974" cy="30.23279" fx="23.164974" fy="30.23279" r="8.1890125" gradientTransform="matrix(1.7346265,-0.1698771,0.327755,3.6175226,-27.429343,-73.69679)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6589" id="radialGradient6603" cx="20.8839" cy="20.434256" fx="20.8839" fy="20.434256" r="3.9999842" gradientTransform="matrix(1.3093938,0,0,1.5604932,-8.3886376,-9.784483)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6379" id="linearGradient6641" gradientUnits="userSpaceOnUse" x1="20.226221" y1="20.33363" x2="11.4375" y2="21.75" gradientTransform="matrix(0.6666667,0,0,1,2,-1)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6651" id="radialGradient6657" cx="23.986883" cy="27.053167" fx="23.986883" fy="27.053167" r="7.75" gradientTransform="matrix(-0.2432942,0,0,-1.2543129,25.221399,61.870636)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6546" id="linearGradient6558" gradientUnits="userSpaceOnUse" x1="80.693359" y1="31.561478" x2="77.125" y2="14" gradientTransform="translate(-70,2)" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6607" id="radialGradient6625" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.9866298,0.1169977,0,-2.530036,-104.62676,112.74341)" cx="30.685316" cy="42.261425" fx="30.685316" fy="42.261425" r="8.22791" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6628" id="linearGradient6634" x1="23.238182" y1="12.158657" x2="29.892563" y2="26.354361" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6700" id="linearGradient6706" x1="17.5" y1="25.587416" x2="28.555141" y2="25.699326" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6643" id="linearGradient6801" gradientUnits="userSpaceOnUse" x1="33.430557" y1="45.052155" x2="33.430557" y2="0.31037101" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6964" cx="72.495682" cy="22.84375" fx="72.495682" fy="22.84375" r="4.8202302" gradientTransform="matrix(2.6999424,0,0,3.5713875,-122.46854,-58.740132)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6968" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.6999424,0,0,3.6828427,-122.46854,-61.286186)" cx="72.495682" cy="22.84375" fx="72.495682" fy="22.84375" r="4.8202302" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6976" cx="70.53125" cy="22.734375" fx="70.53125" fy="22.734375" r="3.5975378" gradientTransform="matrix(1.8087117,0,0,3.5234273,-57.039447,-57.368542)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient6958" id="radialGradient6984" cx="60.640625" cy="22.65625" fx="60.640625" fy="22.65625" r="2.6194003" gradientTransform="matrix(2.1454532,0,0,3.0191635,-69.461,-45.746674)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient17123" id="radialGradient7118" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.330579,0,24.67693)" cx="11.402097" cy="36.863068" fx="11.402097" fy="36.863068" r="10.69499" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="24" inkscape:cy="42.911478" inkscape:document-units="px" inkscape:current-layer="layer1" width="48px" height="48px" inkscape:showpageshadow="false" borderlayer="true" showgrid="false" gridspacingx="0.5px" gridspacingy="0.5px" gridempspacing="2" inkscape:window-width="1051" inkscape:window-height="936" inkscape:window-x="14" inkscape:window-y="43" inkscape:guide-points="false" inkscape:grid-points="true" showguides="false" inkscape:guide-bbox="true" showborder="false" inkscape:grid-bbox="true"> <sodipodi:guide orientation="vertical" position="22" id="guide21670" /> <sodipodi:guide orientation="horizontal" position="26" id="guide21672" /> <sodipodi:guide orientation="vertical" position="32" id="guide6673" /> <inkscape:grid type="xygrid" id="grid6385" /> <sodipodi:guide orientation="horizontal" position="2.5" id="guide6925" /> </sodipodi:namedview> <metadata id="metadata7"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:creator> <cc:Agent> <dc:title>Ulisse Perusin</dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:title>Audio Volume High</dc:title> <dc:contributor> <cc:Agent> <dc:title>Lapo Calamandrei</dc:title> </cc:Agent> </dc:contributor> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g inkscape:groupmode="layer" id="layer3" inkscape:label="constr" style="display:none"> <path style="opacity:0.83011588;fill:url(#radialGradient8199);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -8.21875,10.5 L -20.21875,22.5 L -8.21875,34.5 L -8.21875,10.5 z " id="path7288" sodipodi:nodetypes="cccc" /> <path style="opacity:0.76833975;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6393);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -7,10.5 L -19,22.5 L -7,34.5 L -7,10.5 z " id="path2791" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="0.50000006" inkscape:original="M 19.5 9.5 C 18 15 12 14 7.5 22.5 C 12 31 18 30 19.5 35.5 L 19.5 9.5 z " style="opacity:0.63320462;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" id="path21580" d="M 19.375,9 C 19.200644,9.0530225 19.06894,9.1967002 19.03125,9.375 C 18.327802,11.954311 16.604417,12.961638 14.34375,14.46875 C 12.083083,15.975862 9.3592888,17.942871 7.0625,22.28125 C 6.9953198,22.419346 6.9953198,22.580654 7.0625,22.71875 C 9.3592888,27.057129 12.083083,29.024138 14.34375,30.53125 C 16.604417,32.038362 18.327802,33.045689 19.03125,35.625 C 19.110592,35.845992 19.333006,35.982016 19.565879,35.951968 C 19.798752,35.92192 19.979353,35.733894 20,35.5 L 20,9.5 C 20.005,9.3425939 19.935556,9.1920293 19.812581,9.0936489 C 19.689605,8.9952685 19.527469,8.9605689 19.375,9 z " transform="translate(-42,0)" /> <path style="fill:none;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M -47.5,22.5 L -20,-8 L -20,56 L -47.5,22.5 z " id="path21676" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21684);fill-opacity:1;stroke:#204a87;stroke-width:0.12515022;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21678" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(7.990397,0,0,7.990397,-220.7725,-152.0403)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21686);fill-opacity:1;stroke:#204a87;stroke-width:0.18086948;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21680" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(5.528848,0,0,5.528848,-169.4646,-98.27085)" /> <path sodipodi:type="arc" style="opacity:1;fill:url(#radialGradient21688);fill-opacity:1;stroke:#204a87;stroke-width:0.29248634;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path21682" sodipodi:cx="20.84375" sodipodi:cy="21.84375" sodipodi:rx="2.84375" sodipodi:ry="2.84375" d="M 23.6875 21.84375 A 2.84375 2.84375 0 1 1 18,21.84375 A 2.84375 2.84375 0 1 1 23.6875 21.84375 z" transform="matrix(3.418962,0,0,3.418962,-125.4867,-52.18304)" /> </g> <g inkscape:label="Livello 1" inkscape:groupmode="layer" id="layer1" style="display:inline"> <path sodipodi:type="arc" style="opacity:0.2;fill:url(#radialGradient7118);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" id="path16236" sodipodi:cx="11.402097" sodipodi:cy="36.863068" sodipodi:rx="10.69499" sodipodi:ry="3.5355339" d="M 22.097087 36.863068 A 10.69499 3.5355339 0 1 1 0.70710659,36.863068 A 10.69499 3.5355339 0 1 1 22.097087 36.863068 z" transform="matrix(1.5365906,0,0,2.4199734,-1.1723206,-56.384863)" /> <path sodipodi:type="arc" style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:1.30267787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path5330" sodipodi:cx="4" sodipodi:cy="25" sodipodi:rx="4" sodipodi:ry="7" d="M 8 25 A 4 7 0 1 1 0,25 A 4 7 0 1 1 8 25 z" transform="matrix(0.75,0,0,0.7857143,1.5,4.357156)" /> <path sodipodi:type="arc" style="opacity:1;fill:#babdb6;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6659" sodipodi:cx="3.75" sodipodi:cy="20.75" sodipodi:rx="0.75" sodipodi:ry="0.75" d="M 4.5 20.75 A 0.75 0.75 0 1 1 3,20.75 A 0.75 0.75 0 1 1 4.5 20.75 z" transform="translate(-1.53125,0.65625)" /> <path style="fill:url(#linearGradient5545);fill-opacity:1;stroke:url(#linearGradient5547);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 6.125,15.500014 C 4.1240036,15.500014 2.5000009,19.308036 2.5,24.000014 C 2.5,28.691991 4.1240036,32.500015 6.125,32.500014 L 9.75,32.500014 C 11.750996,32.500014 13.375,28.69199 13.375,24.000014 C 13.375,19.308037 11.750996,15.500014 9.75,15.500014 L 6.125,15.500014 z " id="path2766" sodipodi:nodetypes="csccscc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0054175" inkscape:original="M 5.5 13.5 C 3.292004 13.5 1.500001 17.308022 1.5 22 C 1.5 26.691978 3.292004 30.500001 5.5 30.5 L 9.5 30.5 C 11.707996 30.500001 13.5 26.691976 13.5 22 C 13.5 17.308024 11.707996 13.5 9.5 13.5 L 5.5 13.5 z " style="opacity:0.6;fill:none;fill-opacity:1;stroke:url(#linearGradient6537);stroke-width:1.0577718;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path5556" d="M 5.5,14.5 C 4.974,14.5 4.2339165,15.045895 3.59375,16.40625 C 2.9535835,17.766605 2.5000005,19.78201 2.5,22 C 2.5,24.21799 2.9535834,26.233394 3.59375,27.59375 C 4.2339166,28.954106 4.9740003,29.5 5.5,29.5 L 9.5,29.5 C 10.025999,29.5 10.766083,28.954106 11.40625,27.59375 C 12.046417,26.233394 12.5,24.217988 12.5,22 C 12.5,19.782012 12.046417,17.766606 11.40625,16.40625 C 10.766083,15.045894 10.026,14.5 9.5,14.5 L 5.5,14.5 z " transform="matrix(0.89375,0,0,1,1.265625,2)" /> <path style="opacity:1;fill:url(#linearGradient6558);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 9.696925,16 C 7.656226,16 6.000001,19.57702 6,23.984375 C 6,28.391729 7.656226,31.968751 9.696925,31.96875 L 10.334325,31.96875 C 12.375024,31.96875 14.03125,28.391728 14.03125,23.984375 C 14.03125,19.577021 12.375024,16 10.334325,16 L 9.696925,16 z " id="path6556" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#radialGradient6553);fill-opacity:1;stroke:url(#linearGradient6545);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M 8.6250003,24 C 8.6250003,33.227273 17.811975,38.499999 23.500002,38.499999 C 27.437502,38.499999 30.500002,32.003996 30.500002,24 C 30.500002,15.996003 27.437502,9.5000001 23.500002,9.5000001 C 17.811975,9.5000001 8.6250003,14.772728 8.6250003,24 z " id="path1871" sodipodi:nodetypes="cssss" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6657);fill-opacity:1;stroke:none;stroke-width:0.87802505;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6649" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.3225807,0,0,1.026415,-12.145162,-4.6754711)" /> <path style="opacity:0.7335907;fill:url(#linearGradient6641);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" d="M 16,13.375 C 13.416667,14.769678 10.541667,17.570921 8,21.5 C 10.69956,20.373913 13.491292,19.539527 16,19.75 L 16,13.375 z " id="path6639" sodipodi:nodetypes="cccc" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-1.0125009" inkscape:original="M 22.8125 5.5 C 16.571923 5.5000002 6.5 11.5 6.5 22 C 6.5 32.500001 16.571923 38.5 22.8125 38.5 C 27.1325 38.499999 30.5 31.107996 30.5 22 C 30.5 12.892005 27.1325 5.5 22.8125 5.5 z " style="opacity:0.58620689;fill:none;fill-opacity:1;stroke:url(#linearGradient6579);stroke-width:1.12734473;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6567" d="M 22.8125,6.5 C 20.016701,6.5000001 16.088488,7.9333131 12.96875,10.59375 C 9.8490125,13.254187 7.5,17.073741 7.5,22 C 7.5,26.92626 9.8490125,30.745813 12.96875,33.40625 C 16.088487,36.066687 20.016701,37.5 22.8125,37.5 C 24.394999,37.5 26.045271,36.056265 27.34375,33.25 C 28.642229,30.443735 29.5,26.429214 29.5,22 C 29.5,17.570787 28.642229,13.556265 27.34375,10.75 C 26.045271,7.943735 24.394999,6.5 22.8125,6.5 z " transform="matrix(0.9034091,0,0,0.8709678,2.8494318,4.8387095)" /> <path sodipodi:type="arc" style="fill:url(#radialGradient6595);fill-opacity:1;stroke:url(#linearGradient6801);stroke-width:0.83240509;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="path1873" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.2258059,0,0,1.1773585,-8.9515943,-8.892453)" /> <path style="fill:url(#radialGradient6603);fill-opacity:1;stroke:#555753;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" d="M 21.616117,24.000008 C 21.616117,26.484005 19.233185,28.49999 17.549734,28.49999 C 15.866281,28.49999 14.500001,26.483992 14.500001,23.999995 C 14.500001,21.515998 15.866281,19.5 17.549734,19.5 C 19.233185,19.5 21.616117,21.51601 21.616117,24.000008 z " id="path3672" sodipodi:nodetypes="csssc" /> <path style="opacity:1;fill:url(#radialGradient6625);fill-opacity:1;stroke:none;stroke-width:0.90347975;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" d="M 22,5 C 19.367552,4.9999999 17.141972,7.2498264 15.5625,10.6875 C 13.983028,14.125173 13.03125,18.830125 13.03125,24 C 13.03125,29.169874 13.983028,33.874826 15.5625,37.3125 C 17.141972,40.750172 19.367552,43 22,43 C 24.632449,43 26.858028,40.750173 28.4375,37.3125 C 29.42467,35.163953 30.174611,32.501281 30.59375,29.5625 C 30.606967,29.469828 30.612431,29.374514 30.625,29.28125 C 30.701405,28.714302 30.760731,28.149758 30.8125,27.5625 C 30.863372,27.016086 30.910141,26.469464 30.9375,25.90625 C 30.938938,25.875286 30.936131,25.843507 30.9375,25.8125 C 30.964969,25.216652 30.96875,24.611754 30.96875,24 C 30.96875,23.355639 30.96794,22.720382 30.9375,22.09375 C 30.911649,21.537127 30.860238,20.979033 30.8125,20.4375 C 30.760731,19.850242 30.701405,19.285698 30.625,18.71875 C 30.611503,18.623565 30.607961,18.532009 30.59375,18.4375 C 30.174611,15.498719 29.42467,12.836046 28.4375,10.6875 C 26.858028,7.249826 24.632449,5 22,5 z M 22.5,7 C 24.422274,7.0000002 26.280368,8.7656497 27.6875,11.84375 C 28.566957,13.767562 29.264379,16.179117 29.65625,18.875 C 29.734624,19.414177 29.789845,19.97021 29.84375,20.53125 C 29.89121,21.056658 29.942834,21.584653 29.96875,22.125 C 30.000626,22.745494 30.03125,23.361156 30.03125,24 C 30.03125,24.595745 29.99653,25.170104 29.96875,25.75 C 29.966916,25.790974 29.970711,25.834105 29.96875,25.875 C 29.941175,26.411772 29.893755,26.948299 29.84375,27.46875 C 29.789845,28.029789 29.734624,28.585823 29.65625,29.125 C 29.264379,31.820883 28.566957,34.232438 27.6875,36.15625 C 26.280368,39.23435 24.422274,41 22.5,41 C 20.577727,40.999998 18.719632,39.234351 17.3125,36.15625 C 15.905367,33.078149 14.96875,28.765963 14.96875,24 C 14.96875,19.234036 15.905368,14.92185 17.3125,11.84375 C 18.719631,8.7656496 20.577727,7 22.5,7 z " id="path6605" sodipodi:nodetypes="cssssssssssssssssccssssssssssssssc" /> <path sodipodi:type="arc" style="opacity:0.36637932;fill:none;fill-opacity:1;stroke:url(#linearGradient6634);stroke-width:1.05419946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6615" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(0.9032258,0,0,0.9962264,-0.3064529,-3.8320749)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path6661" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-16,5.3125)" /> <path sodipodi:type="arc" style="opacity:0.65517243;fill:none;fill-opacity:1;stroke:url(#linearGradient6706);stroke-width:0.90347946;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" id="path6698" sodipodi:cx="25.25" sodipodi:cy="27.9375" sodipodi:rx="7.75" sodipodi:ry="16.5625" d="M 33 27.9375 A 7.75 16.5625 0 1 1 17.5,27.9375 A 7.75 16.5625 0 1 1 33 27.9375 z" transform="matrix(1.0967748,0,0,1.1169811,-5.6935592,-7.2056602)" /> <path sodipodi:type="arc" style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" id="path5501" sodipodi:cx="20.5" sodipodi:cy="13.5" sodipodi:rx="1" sodipodi:ry="1" d="M 21.5 13.5 A 1 1 0 1 1 19.5,13.5 A 1 1 0 1 1 21.5 13.5 z" transform="translate(-5,-1.875)" /> </g> <g inkscape:groupmode="layer" id="layer2" inkscape:label="waves"> <g style="stroke:url(#radialGradient6964);display:inline" id="g26136" transform="matrix(0.5949393,0,0,1.2242975,1.3739932,-4.22187)"> <path sodipodi:nodetypes="csc" id="path25249" d="M 69.03125,40.1875 C 74.190803,36.02097 77.499999,29.643289 77.5,22.5 C 77.5,15.734684 74.540259,9.6637676 69.84375,5.5" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6968);stroke-width:1.17171037;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> <g style="stroke:#729fcf;display:inline" id="g27916" transform="matrix(0.5164697,0,0,1.2242975,3.5433952,-4.22187)"> <path sodipodi:nodetypes="csc" id="path21632" d="M 67.5625,34.78125 C 71.176369,31.899733 73.499999,27.47788 73.5,22.5 C 73.5,17.793936 71.43603,13.569699 68.15625,10.6875" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6976);stroke-width:1.25757563;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> <g style="stroke:#729fcf;display:inline" id="g28807" transform="matrix(0.3535062,0,0,1.2242975,13.43562,-3.80102)"> <path sodipodi:nodetypes="csc" id="path27920" d="M 58.78125,30.15625 C 61.050824,28.375887 62.5,25.606103 62.5,22.5 C 62.5,19.560794 61.188424,16.939552 59.125,15.15625" style="opacity:1;fill:none;fill-opacity:1;stroke:url(#radialGradient6984);stroke-width:1.52005064;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;display:inline" /> </g> </g> </svg> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/Makefile.am�������������������������������������������������������������������0000644�0000041�0000041�00000001430�13570225707�017077� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������iconsdir = $(pkgdatadir)/icons/hicolor/scalable/status icons_DATA = \ README \ notification-audio-next.svg \ notification-audio-play.svg \ notification-audio-previous.svg \ notification-audio-volume-high.svg \ notification-audio-volume-low.svg \ notification-audio-volume-medium.svg \ notification-audio-volume-muted.svg \ notification-audio-volume-off.svg \ notification-battery-low.svg \ notification-device-eject.svg \ notification-device.svg \ notification-display-brightness.svg \ notification-keyboard-brightness.svg \ notification-message-email.svg \ notification-message-im.svg \ notification-network-ethernet-connected.svg \ notification-network-ethernet-diconnected.svg \ notification-network-wireless.svg \ notification-power.svg EXTRA_DIST = $(icons_DATA) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/scalable/notification-display-brightness.svg�������������������������������������������0000644�0000041�0000041�00000026477�13570225707�024105� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="48.000000px" height="48.000000px" id="svg3304" sodipodi:version="0.32" inkscape:version="0.45" sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/devices" sodipodi:docname="video-display.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"> <defs id="defs3306"> <linearGradient id="linearGradient5233"> <stop style="stop-color:#729fcf;stop-opacity:1;" offset="0" id="stop5235" /> <stop style="stop-color:#326194;stop-opacity:1;" offset="1" id="stop5237" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient5225"> <stop style="stop-color:black;stop-opacity:1;" offset="0" id="stop5227" /> <stop style="stop-color:black;stop-opacity:0;" offset="1" id="stop5229" /> </linearGradient> <linearGradient id="linearGradient5137"> <stop style="stop-color:#eeeeec;stop-opacity:1;" offset="0" id="stop5139" /> <stop style="stop-color:#e6e6e3;stop-opacity:1;" offset="1" id="stop5141" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient6240"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop6242" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop6244" /> </linearGradient> <linearGradient id="linearGradient11400"> <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop11402" /> <stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop11404" /> </linearGradient> <linearGradient inkscape:collect="always" xlink:href="#linearGradient11400" id="linearGradient11406" x1="23.154902" y1="34.572548" x2="23.529411" y2="40.219608" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient6240" id="linearGradient6246" x1="20.156862" y1="5.0996137" x2="20.156862" y2="26.039215" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5137" id="linearGradient5147" gradientUnits="userSpaceOnUse" x1="17.247635" y1="6.3760414" x2="39.904388" y2="38.876041" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient5137" id="linearGradient5223" gradientUnits="userSpaceOnUse" x1="31.743324" y1="37.842293" x2="31.86105" y2="43.82579" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5225" id="radialGradient5231" cx="23.9375" cy="42.6875" fx="23.9375" fy="42.6875" r="23.75956" gradientTransform="matrix(1,0,0,0.24763,4.590511e-16,32.1168)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient5233" id="radialGradient5239" cx="24.006104" cy="32.997028" fx="24.006104" fy="32.997028" r="19.00016" gradientTransform="matrix(1.232634,1.948681e-23,-1.1422e-23,0.778392,-5.584638,2.154377)" gradientUnits="userSpaceOnUse" /> </defs> <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#849193" borderopacity="1.0000000" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="34.423835" inkscape:cy="24.838104" inkscape:current-layer="layer1" showgrid="false" inkscape:grid-bbox="true" inkscape:document-units="px" inkscape:showpageshadow="false" showborder="true" inkscape:window-width="872" inkscape:window-height="718" inkscape:window-x="421" inkscape:window-y="196" showguides="true" inkscape:guide-bbox="true" inkscape:grid-points="true" /> <metadata id="metadata3309"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title>Video display</dc:title> <dc:creator> <cc:Agent> <dc:title>Luca Ferretti <elle.uca@libero.it></dc:title> </cc:Agent> </dc:creator> <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> <dc:subject> <rdf:Bag> <rdf:li>monitor</rdf:li> <rdf:li>display</rdf:li> <rdf:li>video</rdf:li> <rdf:li>screen</rdf:li> <rdf:li>LCD</rdf:li> <rdf:li>CRT</rdf:li> </rdf:Bag> </dc:subject> </cc:Work> <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" /> <cc:permits rdf:resource="http://web.resource.org/cc/Distribution" /> <cc:requires rdf:resource="http://web.resource.org/cc/Notice" /> <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" /> <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" /> </cc:License> </rdf:RDF> </metadata> <g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer"> <rect style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" id="rect4784" width="48.000000" height="48.000000" x="0.0000000" y="0.0000000" /> <path sodipodi:type="arc" style="opacity:0.4;fill:url(#radialGradient5231);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path13582" sodipodi:cx="23.9375" sodipodi:cy="42.6875" sodipodi:rx="23.75956" sodipodi:ry="5.8835783" d="M 47.69706 42.6875 A 23.75956 5.8835783 0 1 1 0.17794037,42.6875 A 23.75956 5.8835783 0 1 1 47.69706 42.6875 z" transform="matrix(0.968245,0,0,0.863797,1.447631,6.096332)" /> <path style="fill:url(#linearGradient5223);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:1;color:black;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;visibility:visible;display:inline;overflow:visible" d="M 14.375479,35.533351 C 14.375479,35.533351 15.592355,40.467951 10.519150,40.514275 C 8.0888743,40.536180 8.5866723,44.549426 8.5866723,44.549426 L 39.433139,44.518053 C 39.433139,44.518053 39.851577,40.622690 37.410922,40.577021 C 32.423455,40.484882 33.600393,35.470606 33.600393,35.470606 L 14.375479,35.533351 z " id="path9222" sodipodi:nodetypes="csccscc" /> <path style="fill:url(#linearGradient5147);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" d="M 4.8886262,3.4784362 L 43.01746,3.4784362 C 45.042579,3.4784362 46.518438,4.9060907 46.518438,7.104577 L 46.529388,33.308416 C 46.529388,35.000483 46.001041,35.523645 44.494732,35.523645 L 3.5320635,35.50471 C 2.3527922,35.475917 1.513468,35.010049 1.4976345,33.485407 L 1.5128113,6.9168325 C 1.5128113,5.1430066 3.0522187,3.4784362 4.8886262,3.4784362 z " id="rect5040" sodipodi:nodetypes="ccccccccc" /> <rect style="fill:url(#radialGradient5239);fill-opacity:1.0;fill-rule:evenodd;stroke:#204a87;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" id="rect9208" width="37.000320" height="22.996691" x="5.5059438" y="7.5018229" /> <path sodipodi:type="inkscape:offset" inkscape:radius="-0.875" inkscape:original="M 4.875 3.46875 C 3.0385925 3.46875 1.5 5.1324242 1.5 6.90625 L 1.5 33.5 C 1.5158335 35.024642 2.3519787 35.471206 3.53125 35.5 L 44.5 35.53125 C 46.006309 35.53125 46.53125 35.004569 46.53125 33.3125 L 46.53125 7.09375 C 46.53125 4.8952637 45.056369 3.46875 43.03125 3.46875 L 4.875 3.46875 z " xlink:href="#rect5040" style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:white;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" id="path5145" inkscape:href="#rect5040" d="M 4.875,4.34375 C 3.5670572,4.34375 2.375,5.6383996 2.375,6.90625 L 2.375,33.5 C 2.3812651,34.103278 2.5206964,34.290591 2.65625,34.40625 C 2.7918036,34.521909 3.0781685,34.613174 3.5625,34.625 L 44.5,34.65625 C 45.151173,34.65625 45.356981,34.55523 45.4375,34.46875 C 45.518019,34.38227 45.65625,34.068049 45.65625,33.3125 L 45.65625,7.09375 C 45.65625,5.2865999 44.645463,4.34375 43.03125,4.34375 L 4.875,4.34375 z " /> <path style="fill:url(#linearGradient11406);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;opacity:0.60000000" d="M 13.992156,36.039216 C 14.075817,38.211765 13.708803,38.950659 12.358532,39.714447 L 35.973934,41.011765 C 35.024915,39.843137 33.644523,38.078431 34.020993,36.02353 L 13.992156,36.039216 z " id="path10672" sodipodi:nodetypes="ccccc" /> <path style="fill:url(#linearGradient6246);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;opacity:0.75000000" d="M 6.0235294,8.0313725 L 6.0235294,26.039216 C 22.467974,24.684967 28.622222,15.926797 41.992156,15.011764 L 41.992157,8.0000000 L 6.0235294,8.0313725 z " id="path4073" sodipodi:nodetypes="ccccc" /> <path style="fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#8d8d8f;stroke-width:1.0000000px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.43902439" d="M 9.9921262,41.496063 C 16.698819,41.498032 37.788910,41.496063 37.788910,41.496063" id="path6575" sodipodi:nodetypes="cc" /> <path sodipodi:nodetypes="cc" id="path8029" d="M 9.6479280,42.503937 C 16.354621,42.505906 38.367789,42.503937 38.367789,42.503937" style="fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1.0000000" /> </g> </svg> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/icons/Makefile.am����������������������������������������������������������������������������0000644�0000041�0000041�00000000700�13570225707�015330� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = scalable # 16x16 22x22 24x24 32x32 48x48 gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor install-data-hook: update-icon-cache uninstall-hook: update-icon-cache update-icon-cache: @-if test -z "$(DESTDIR)"; then \ echo "Updating Gtk icon cache."; \ $(gtk_update_icon_cache); \ else \ echo "*** Icon cache not updated. After (un)install, run this:"; \ echo "*** $(gtk_update_icon_cache)"; \ fi ����������������������������������������������������������������./data/notify-osd.convert���������������������������������������������������������������������������0000644�0000041�0000041�00000000157�13570225707�015664� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[com.canonical.notify-osd] multihead-mode = /apps/notify-osd/multihead_mode gravity = /apps/notify-osd/gravity �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/org.freedesktop.Notifications.service.in�����������������������������������������������������0000644�0000041�0000041�00000000120�13570225707�022055� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������[D-BUS Service] Name=org.freedesktop.Notifications Exec=@LIBEXECDIR@/notify-osd ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/com.canonical.NotifyOSD.gschema.xml����������������������������������������������������������0000644�0000041�0000041�00000001242�13570225707�020634� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<schemalist> <schema id="com.canonical.notify-osd" path="/apps/notify-osd/"> <key name="multihead-mode" type="s"> <default>'focus-follow'</default> <summary>Multihead position behaviour</summary> <description>Should the notification position follow the mouse-focus or not in multi-screen environments. Use values "dont-focus-follow" or "focus-follow".</description> </key> <key name="gravity" type="i"> <default>1</default> <summary>Gravity</summary> <description>Position of notifications on screen. Supported values are 1 (top-right) and 2 (vert. centered on the right).</description> </key> </schema> </schemalist> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./data/Makefile.am����������������������������������������������������������������������������������0000644�0000041�0000041�00000001056�13570225707�014222� 0����������������������������������������������������������������������������������������������������ustar �www-data������������������������www-data��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� SUBDIRS = icons servicedir=$(datadir)/dbus-1/services service_DATA=org.freedesktop.Notifications.service gsettings_SCHEMAS=com.canonical.NotifyOSD.gschema.xml @GSETTINGS_RULES@ EXTRA_DIST=org.freedesktop.Notifications.service.in \ com.canonical.NotifyOSD.gschema.xml convertdir = $(datadir)/GConf/gsettings convert_DATA = notify-osd.convert EXTRA_DIST += $(convert_DATA) org.freedesktop.Notifications.service: org.freedesktop.Notifications.service.in sed "s,@LIBEXECDIR@,$(libexecdir)," $< > $@ CLEANFILES = org.freedesktop.Notifications.service ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������