// To recursively copy containers and any addresses they contain, use // 'deep-copy'. // // Invariant: After a deep-copy its ingredient and result will point to no // common addresses. // Implications: Refcounts of all data pointed to by the original ingredient // will remain unchanged. Refcounts of all data pointed to by the (newly // created) result will be 1, in the absence of cycles. // // We do handle cycles in the ingredient, however. All cycles are translated // to new cycles in the product. :(scenario deep_copy_number) def main [ local-scope x:num <- copy 34 y:num <- deep-copy x 10:bool/raw <- equal x, y ] # non-address primitives are identical +mem: storing 1 in location 10 :(scenario deep_copy_container_without_address) container foo [ x:num y:num ] def main [ local-scope a:foo <- merge 34, 35 b:foo <- deep-copy a 10:bool/raw <- equal a, b ] # containers are identical as long as they don't contain addresses +mem: storing 1 in location 10 :(scenario deep_copy_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:num <- copy 100/unsafe # pretend allocation *1:&:num <- copy 34 2:&:num <- deep-copy 1:&:num 10:bool <- equal 1:&:num, 2:&:num 11:bool <- equal *1:&:num, *2:&:num 2:&:num <- copy 0 ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 # the result of deep-copy gets a refcount of 1 # (its address 202 = 200 base + 2 for temporary space inside deep-copy) +run: {2: ("address" "number")} <- copy {0: "literal"} +mem: decrementing refcount of 202: 1 -> 0 +abandon: saving 202 in free-list of size 2 :(scenario deep_copy_address_to_container) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:point <- copy 100/unsafe # pretend allocation *1:&:point <- merge 34, 35 2:&:point <- deep-copy 1:&:point 10:bool <- equal 1:&:point, 2:&:point 11:bool <- equal *1:&:point, *2:&:point ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_address_to_address) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 1:&:&:num <- copy 100/unsafe # pretend allocation *1:&:&:num <- copy 150/unsafe **1:&:&:num <- copy 34 2:&:&:num <- deep-copy 1:&:&:num 10:bool <- equal 1:&:&:num, 2:&:&:num 11:bool <- equal *1:&:&:num, *2:&:&:num 12:bool <- equal **1:&:&:num, **2:&:&:num ] # the result of deep-copy is a new address +mem: storing 0 in location 10 # any addresses in it or pointed to it are also new +mem: storing 0 in location 11 # however, the non-address contents are identical +mem: storing 1 in location 12 :(scenario deep_copy_array) % Memory_allocated_until = 200; def main [ # avoid all memory allocations except the implicit ones inside deep-copy, so # that the result is deterministic 100:num <- copy 1 # pretend refcount 101:num <- copy 3 # pretend array length 1:&:@:num <- copy 100/unsafe # pretend allocation put-index *1:&:@:num, 0, 34 put-index *1:&:@:num, 1, 35 put-index *1:&:@:num, 2, 36 stash [old:], *1:&:@:num 2:&:@:num <- deep-copy 1:&:@:num stash 2:&:@:num stash [new:], *2:&:@:num 10:bool <- equal 1:&:@:num, 2:&:@:num 11:bool <- equal *1:&:@:num, *2:&:@:num ] +app: old: 3 34 35 36 +app: new: 3 34 35 36 # the result of deep-copy is a new address +mem: storing 0 in location 10 # however, the contents are identical +mem: storing 1 in location 11 :(scenario deep_copy_container_with_address) container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 35 a:foo <- merge 34, y0 b:foo <- deep-copy a 10:bool/raw <- equal a, b y1:&:num <- get b, y:offset 11:bool/raw <- equal y0, y1 12:num/raw <- copy *y1 ] # containers containing addresses are not identical to their deep copies +mem: storing 0 in location 10 # the addresses they contain are not identical either +mem: storing 0 in location 11 +mem: storing 35 in location 12 :(scenario deep_copy_exclusive_container_with_address) exclusive-container foo [ x:num y:&:num ] def main [ local-scope y0:&:num <- new number:type *y0 <- copy 34 a:foo <- merge 1/y, y0 b
/*
 * tray.h
 * vim: expandtab:ts=4:sts=4:sw=4
 *
 * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
 *
 * This file is part of Profanity.
 *
 * Profanity is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Profanity 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Profanity.  If not, see <https://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give permission to
 * link the code of portions of this program with the OpenSSL library under
 * certain conditions as described in each individual source file, and
 * distribute linked combinations including the two.
 *
 * You must obey the GNU General Public License in all respects for all of the
 * code used other than OpenSSL. If you modify file(s) with this exception, you
 * may extend this exception to your version of the file(s), but you are not
 * obligated to do so. If you do not wish to do so, delete this exception
 * statement from your version. If you delete this exception statement from all
 * source files in the program, then also delete it here.
 *
 */

#ifndef UI_TRAY_H
#define UI_TRAY_H

#ifdef HAVE_GTK
void tray_init(void);
void tray_update(