# Testable primitives for writing to screen. # # Mu mostly uses the screen for text, but it builds it out of pixel graphics # and a bitmap font. There is no support for a blinking cursor, scrolling and # so on. # # Fake screens are primarily for testing text-mode prints. However, they do # support some rudimentary pixel operations as well. Caveats: # # - Drawing pixels atop text or vice versa is not supported. Results in a fake # screen will not mimic real screens in these situations. # - Fake screens currently also assume a fixed-width 8x16 font. # - Combining characters don't render like in a real screen (which itself # isn't ideal). type screen { # text mode width: int height: int data: (handle array screen-cell) cursor-x: int # [0..width) cursor-y: int # [0..height) # pixel graphics pixels: (handle array byte) } type screen-cell { data: code-point color: int background-color: int unused?: boolean } fn initialize-screen _screen: (addr screen), width: int, height: int, pixel-graphics?: boolean { var screen/esi: (addr screen) <- copy _screen var tmp/eax: int <- copy 0 var dest/edi: (addr int) <- copy 0 # screen->width = width dest <- get screen, width tmp <- copy width copy-to *dest, tmp # screen->height = height dest <- get screen, height tmp <- copy height copy-to *dest, tmp # populate screen->data { var data-ah/edi: (addr handle array screen-cell) <- get screen, data var capacity/eax: int <- copy width capacity <- multiply height # populate data-ah, capacity } # if necessary, populate screen->pixels { compare pixel-graphics?, 0/false break-if-= var pixels-ah/edi: (addr handle array byte) <- get screen, pixels var capacity/eax: int <- copy width capacity <- shift-left 3/log2-font-width capacity <- multiply height capacity <- shift-left 4/log2-font-height # populate pixels-ah, capacity } # screen->cursor-x = 0 dest <- get screen, cursor-x copy-to *dest, 0 # screen->cursor-y = 0 dest <- get screen, cursor-y copy-to *dest, 0 } # in code-point-utf8s fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int { var screen/esi: (addr screen) <- copy _screen var width/eax: int <- copy 0 var height/ecx: int <- copy 0 compare screen, 0 { break-if-!= return 0x80/128, 0x30/48 } # fake screen var tmp/edx: (addr int) <- get screen, width width <- copy *tmp tmp <- get screen, height height <- copy *tmp return width, height } # testable screen primitive # return number of 8x16 units drawn fn draw-code-point _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int { var screen/esi: (addr screen) <- copy _screen { compare screen, 0 break-if-!= var result/eax: int <- draw-code-point-on-real-screen c, x, y, color, background-color return result } # fake screen var wide?/eax: boolean <- wide-code-point? c compare wide?, 0/false { break-if-= draw-wide-code-point-on-fake-screen screen, c, x, y, color, background-color return 2 } draw-narrow-code-point-on-fake-screen screen, c, x, y, color, background-color return 1 } fn overlay-code-point _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int { var screen/esi: (addr screen) <- copy _screen { compare screen, 0 break-if-!= var result/eax: int <- overlay-code-point-on-real-screen c, x, y, color, background-color return result } # fake screen # TODO: support overlays in fake screen var wide?/eax: boolean <- wide-code-point? c compare wide?, 0/false { break-if-= draw-wide-code-point-on-fake-screen screen, c, x, y, color, background-color return 2 } draw-narrow-code-point-on-fake-screen screen, c, x, y, color, background-color return 1 } fn draw-narrow-code-point-on-fake-screen _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int { var screen/esi: (addr screen) <- copy _screen # ignore if out of bounds { compare x, 0 break-if->= return } { var xmax-addr/eax: (addr int) <- get screen, width var xmax/eax: int <- copy *xmax-addr compare x, xmax break-if-< { loop } return } { compare y, 0 break-if->= return } { var ymax-addr/eax: (addr int) <- get screen, height var ymax/eax: int <- copy *ymax-addr compare y, ymax break-if-< return } # var index/ecx: int <- screen-cell-index screen, x, y var data-ah/eax: (addr handle array screen-cell) <- get screen, data var data/eax: (addr array screen-cell) <- lookup *data-ah var offset/ecx: (offset screen-cell) <- compute-offset data, index var dest-cell/ecx: (addr screen-cell) <- index data, offset var dest-code-point/eax: (addr code-point) <- get dest-cell, data var c2/edx: code-point <- copy c copy-to *dest-code-point, c2 var dest-color/eax: (addr int) <- get dest-cell, color var src-color/edx: int <- copy color copy-to *dest-color, src-color dest-color <- get dest-cell, background-color src-color <- copy background-color copy-to *dest-color, src-color var dest/eax: (addr boolean) <- get dest-cell, unused? copy-to *dest, 0/false } fn draw-wide-code-point-on-fake-screen _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int { var screen/esi: (addr screen) <- copy _screen # ignore if out of bounds { compare x, 0 break-if->= return } { var xmax-addr/eax: (addr int) <- get screen, width var xmax/eax: int <- copy *xmax-addr xmax <- decrement # wide code-points need an extra unit compare x, xmax break-if-< return } { compare y, 0 break-if->= return } { var ymax-addr/eax: (addr int) <- get screen, height var ymax/eax: int <- copy *ymax-addr compare y, ymax break-if-< return } # var index/ecx: int <- screen-cell-index screen, x, y { var data-ah/eax: (addr handle array screen-cell) <- get screen, data var data/eax: (addr array screen-cell) <- lookup *data-ah var offset/ecx: (offset screen-cell) <- compute-offset data, index var dest-cell/ecx: (addr screen-cell) <- index data, offset var dest-code-point/eax: (addr code-point) <- get dest-cell, data var c2/edx: code-point <- copy c copy-to *dest-code-point, c2 var dest-color/eax: (addr int) <- get dest-cell, color var src-color/edx: int <- copy color copy-to *dest-color, src-color dest-color <- get dest-cell, background-color src-color <- copy background-color copy-to *dest-color, src-color var dest/eax: (addr boolean) <- get dest-cell, unused? copy-to *dest, 0/false } # set next screen-cell to unused index <- increment { var data-ah/eax: (addr handle array screen-cell) <- get screen, data var data/eax: (addr array screen-cell) <- lookup *data-ah var offset/ecx: (offset screen-cell) <- compute-offset data, index var dest-cell/ecx: (addr screen-cell) <- index data, offset var dest/eax: (addr boolean) <- get dest-cell, unused? copy-to *dest, 1/true } } # fake screens only fn screen-cell-index _screen: (addr screen), x: int, y: int -> _/ecx: int { var screen/esi: (addr screen) <- copy _screen var width-addr/eax: (addr int) <- get screen, width var result/ecx: int <- copy y result <- multiply *width-addr result <- add x return result } fn cursor-position _screen: (addr screen) -> _/eax: int, _/ecx: int { var screen/esi: (addr screen) <- copy _screen { compare screen, 0 break-if-!= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 x, y <- cursor-position-on-real-screen return x, y } # fake screen var cursor-x-addr/eax: (addr int) <- get screen, cursor-x var cursor-y-addr/ecx: (addr int) <- get screen, cursor-y return *cursor-x-addr, *cursor-y-addr } fn set-cursor-position _screen: (addr screen), x: int, y: int { var screen/esi: (addr screen) <- copy _screen { compare screen, 0 break-if-!= set-cursor-position-on-real-screen x, y return } # fake screen # ignore x < 0 { compare x, 0 break-if->= return } # ignore x >= width { var width-addr/eax
/*
 * resource.c
 * 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.
 *
 */

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "common.h"
#include "xmpp/resource.h"

Resource*
resource_new(const char* const name, resource_presence_t presence, const char* const status, const int priority)
{
    assert(name != NULL);
    Resource* new_resource = malloc(sizeof(struct resource_t));
    new_resource->name = strdup(name);
    new_resource->presence = presence;
    if (status) {
        new_resource->status = strdup(status);
    } else {
        new_resource->status = NULL;
    }
    new_resource->priority = priority;

    return new_resource;
}

int
resource_compare_availability(Resource* first, Resource* second)
{
    if (first->priority > second->priority) {
        return -1;
    }<