/* * Replace all occurrences of "needle" with a quoted "replacement", * according to the allow_markup/plain_text settings. */ char *notification_replace_format(const char *needle, const char *replacement, char *haystack, bool allow_markup, bool plain_text) { char* tmp; char* ret; if (plain_text) { tmp = strdup(replacement); tmp = string_replace_all("\\n", "\n", tmp); if (settings.ignore_newline) { tmp = string_replace_all("\n", " ", tmp); } tmp = notification_quote_markup(tmp); ret = string_replace_all(needle, tmp, haystack); free(tmp); } else if (!allow_markup) { tmp = strdup(replacement); if (!settings.ignore_newline) { tmp = string_replace_all("<br>", "\n", tmp); tmp = string_replace_all("<br/>", "\n", tmp); tmp = string_replace_all("<br />", "\n", tmp); } tmp = notification_strip_markup(tmp); tmp = notification_quote_markup(tmp); ret = string_replace_all(needle, tmp, haystack); free(tmp); } else { ret = string_replace_all(needle, replacement, haystack); } return ret; }
/* * Quote a text string for rendering with pango */ char *notification_quote_markup(char *str) { if (str == NULL) { return NULL; } str = string_replace_all("&", "&", str); str = string_replace_all("\"", """, str); str = string_replace_all("'", "'", str); str = string_replace_all("<", "<", str); str = string_replace_all(">", ">", str); return str; }
void OpenGLES_ConvertFromOpenGL(std::string& code) { // OpenGL (non-ES) compatibility const char* attributes[] = { "gl_Vertex", "gl_MultiTexCoord0", "gl_MultiTexCoord1", "gl_TexCoord", "gl_Color" }; if (const char* eofAfterVersion = get_eof_after(code, "#version")) code = eofAfterVersion; for (int i = 0; i < (int) ARRAYSIZE(attributes); i++) if (strstr(code.c_str(), attributes[i])) { insert_after_pragmas(code, string_format("attribute vec4 %s;\r\n", attributes[i])); string_replace_all(code, attributes[i], attributes[i] + 3); } string_replace_all(code, "out ", "varying "); string_replace_all(code, "in ", "varying "); code = "#define GLES 1\r\n" + code; if (!strstr(code.c_str(), "precision mediump float") && !strstr(code.c_str(), "precision highp float")) code = "precision mediump float;\r\n" + code; // HLSL compatibility string_replace_all(code, "tex2D", "texture2D"); string_replace_all(code, "float2", "vec2"); string_replace_all(code, "float3", "vec3"); string_replace_all(code, "float4", "vec4"); }
char *notification_fix_markup(char *str) { char *replace_buf, *start, *end; if (str == NULL) { return NULL; } str = string_replace_all(""", "\"", str); str = string_replace_all("'", "'", str); str = string_replace_all("&", "&", str); str = string_replace_all("<", "<", str); str = string_replace_all(">", ">", str); /* remove tags */ str = string_replace_all("<b>", "", str); str = string_replace_all("</b>", "", str); str = string_replace_all("<br>", " ", str); str = string_replace_all("<br/>", " ", str); str = string_replace_all("<br />", " ", str); str = string_replace_all("<i>", "", str); str = string_replace_all("</i>", "", str); str = string_replace_all("<u>", "", str); str = string_replace_all("</u>", "", str); str = string_replace_all("</a>", "", str); while ((start = strstr(str, "<a href")) != NULL) { end = strstr(start, ">"); if (end != NULL) { replace_buf = strndup(start, end - start + 1); str = string_replace(replace_buf, "", str); free(replace_buf); } else { break; } } while ((start = strstr(str, "<img src")) != NULL) { end = strstr(start, "/>"); if (end != NULL) { replace_buf = strndup(start, end - start + 2); str = string_replace(replace_buf, "", str); free(replace_buf); } else { break; } } return str; }
/* * Initialize the given notification and add it to * the queue. Replace notification with id if id > 0. */ int notification_init(notification * n, int id) { if (n == NULL) return -1; if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) { pause_display = true; return 0; } if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) { pause_display = false; return 0; } n->script = NULL; n->text_to_render = NULL; n->format = settings.format; rule_apply_all(n); n->urls = notification_extract_markup_urls(&(n->body)); n->msg = string_replace_all("\\n", "\n", g_strdup(n->format)); n->msg = notification_replace_format("%a", n->appname, n->msg, false, true); n->msg = notification_replace_format("%s", n->summary, n->msg, n->allow_markup, n->plain_text); n->msg = notification_replace_format("%b", n->body, n->msg, n->allow_markup, n->plain_text); if (n->icon) { n->msg = notification_replace_format("%I", basename(n->icon), n->msg, false, true); n->msg = notification_replace_format("%i", n->icon, n->msg, false, true); } if (n->progress) { char pg[10]; sprintf(pg, "[%3d%%]", n->progress - 1); n->msg = string_replace_all("%p", pg, n->msg); } else { n->msg = string_replace_all("%p", "", n->msg); } n->msg = g_strstrip(n->msg); if (id == 0) { n->id = ++next_notification_id; } else { notification_close_by_id(id, -1); n->id = id; } n->dup_count = 0; /* check if n is a duplicate */ if (settings.stack_duplicates) { for (GList * iter = g_queue_peek_head_link(queue); iter; iter = iter->next) { notification *orig = iter->data; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->summary, n->summary) == 0 && strcmp(orig->body, n->body) == 0) { /* If the progress differs this was probably intended to replace the notification * but notify-send was used. So don't increment dup_count in this case */ if (orig->progress == n->progress) { orig->dup_count++; } else { orig->progress = n->progress; } /* notifications that differ only in progress hints should be expected equal, * but we want the latest message, with the latest hint value */ free(orig->msg); orig->msg = strdup(n->msg); notification_free(n); wake_up(); return orig->id; } } for (GList * iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { notification *orig = iter->data; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->summary, n->summary) == 0 && strcmp(orig->body, n->body) == 0) { /* notifications that differ only in progress hints should be expected equal, * but we want the latest message, with the latest hint value */ free(orig->msg); orig->msg = strdup(n->msg); /* If the progress differs this was probably intended to replace the notification * but notify-send was used. So don't increment dup_count in this case */ if (orig->progress == n->progress) { orig->dup_count++; } else { orig->progress = n->progress; } orig->start = time(NULL); notification_free(n); wake_up(); return orig->id; } } } /* urgency > CRIT -> array out of range */ n->urgency = n->urgency > CRIT ? CRIT : n->urgency; if (!n->color_strings[ColFG]) { n->color_strings[ColFG] = xctx.color_strings[ColFG][n->urgency]; } if (!n->color_strings[ColBG]) { n->color_strings[ColBG] = xctx.color_strings[ColBG][n->urgency]; } n->timeout = n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout; n->start = 0; if (n->icon == NULL) { n->icon = strdup(settings.icons[n->urgency]); } else if (strlen(n->icon) <= 0) { free(n->icon); n->icon = strdup(settings.icons[n->urgency]); } if (n->category == NULL) { n->category = ""; } n->timestamp = time(NULL); n->redisplayed = false; n->first_render = true; if (strlen(n->msg) == 0) { notification_close(n, 2); printf("skipping notification: %s %s\n", n->body, n->summary); } else { g_queue_insert_sorted(queue, n, notification_cmp_data, NULL); } char *tmp = g_strconcat(n->summary, " ", n->body, NULL); char *tmp_urls = extract_urls(tmp); if (tmp_urls != NULL) { if (n->urls != NULL) { n->urls = string_append(n->urls, tmp_urls, "\n"); free(tmp_urls); } else { n->urls = tmp_urls; } } if (n->actions) { n->actions->dmenu_str = NULL; for (int i = 0; i < n->actions->count; i += 2) { char *human_readable = n->actions->actions[i + 1]; string_replace_char('[', '(', human_readable); // kill square brackets string_replace_char(']', ')', human_readable); char *act_str = g_strdup_printf("#%s [%s]", human_readable, n->appname); if (act_str) { n->actions->dmenu_str = string_append(n->actions->dmenu_str, act_str, "\n"); free(act_str); } } } free(tmp); if (settings.print_notifications) notification_print(n); return n->id; }