[BACK]Return to screen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/screen.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD$ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
        !            15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
        !            16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include <sys/types.h>
        !            20:
        !            21: #include <string.h>
        !            22:
        !            23: #include "tmux.h"
        !            24:
        !            25: void   screen_resize_x(struct screen *, u_int);
        !            26: void   screen_resize_y(struct screen *, u_int);
        !            27:
        !            28: /* Create a new screen. */
        !            29: void
        !            30: screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
        !            31: {
        !            32:        s->grid = grid_create(sx, sy, hlimit);
        !            33:
        !            34:        s->title = xstrdup("");
        !            35:
        !            36:        screen_reinit(s);
        !            37: }
        !            38:
        !            39: /* Reinitialise screen. */
        !            40: void
        !            41: screen_reinit(struct screen *s)
        !            42: {
        !            43:        s->cx = 0;
        !            44:        s->cy = 0;
        !            45:
        !            46:        s->rupper = 0;
        !            47:        s->rlower = screen_size_y(s) - 1;
        !            48:
        !            49:        s->mode = MODE_CURSOR;
        !            50:
        !            51:        grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy - 1);
        !            52:
        !            53:        screen_clear_selection(s);
        !            54: }
        !            55:
        !            56: /* Destroy a screen. */
        !            57: void
        !            58: screen_free(struct screen *s)
        !            59: {
        !            60:        xfree(s->title);
        !            61:        grid_destroy(s->grid);
        !            62: }
        !            63:
        !            64: /* Set screen title. */
        !            65: void
        !            66: screen_set_title(struct screen *s, const char *title)
        !            67: {
        !            68:        xfree(s->title);
        !            69:        s->title = xstrdup(title);
        !            70: }
        !            71:
        !            72: /* Resize screen. */
        !            73: void
        !            74: screen_resize(struct screen *s, u_int sx, u_int sy)
        !            75: {
        !            76:        if (sx < 1)
        !            77:                sx = 1;
        !            78:        if (sy < 1)
        !            79:                sy = 1;
        !            80:
        !            81:        if (sx != screen_size_x(s))
        !            82:                screen_resize_x(s, sx);
        !            83:        if (sy != screen_size_y(s))
        !            84:                screen_resize_y(s, sy);
        !            85: }
        !            86:
        !            87: void
        !            88: screen_resize_x(struct screen *s, u_int sx)
        !            89: {
        !            90:        struct grid             *gd = s->grid;
        !            91:        const struct grid_cell  *gc;
        !            92:        const struct grid_utf8  *gu;
        !            93:        u_int                    xx, yy;
        !            94:
        !            95:        if (sx == 0)
        !            96:                fatalx("zero size");
        !            97:
        !            98:        /* If getting larger, not much to do. */
        !            99:        if (sx > screen_size_x(s)) {
        !           100:                gd->sx = sx;
        !           101:                return;
        !           102:        }
        !           103:
        !           104:        /* If getting smaller, nuke any data in lines over the new size. */
        !           105:        for (yy = gd->hsize; yy < gd->hsize + screen_size_y(s); yy++) {
        !           106:                /*
        !           107:                 * If the character after the last is wide or padding, remove
        !           108:                 * it and any leading padding.
        !           109:                 */
        !           110:                gc = &grid_default_cell;
        !           111:                for (xx = sx; xx > 0; xx--) {
        !           112:                        gc = grid_peek_cell(gd, xx - 1, yy);
        !           113:                        if (!(gc->flags & GRID_FLAG_PADDING))
        !           114:                                break;
        !           115:                        grid_set_cell(gd, xx - 1, yy, &grid_default_cell);
        !           116:                }
        !           117:                if (xx > 0 && xx != sx && gc->flags & GRID_FLAG_UTF8) {
        !           118:                        gu = grid_peek_utf8(gd, xx - 1, yy);
        !           119:                        if (gu->width > 1) {
        !           120:                                grid_set_cell(
        !           121:                                    gd, xx - 1, yy, &grid_default_cell);
        !           122:                        }
        !           123:                }
        !           124:
        !           125:                /* Reduce the line size. */
        !           126:                grid_reduce_line(gd, yy, sx);
        !           127:        }
        !           128:
        !           129:        if (s->cx >= sx)
        !           130:                s->cx = sx - 1;
        !           131:        gd->sx = sx;
        !           132: }
        !           133:
        !           134: void
        !           135: screen_resize_y(struct screen *s, u_int sy)
        !           136: {
        !           137:        struct grid     *gd = s->grid;
        !           138:        u_int            oy, yy, ny;
        !           139:
        !           140:        if (sy == 0)
        !           141:                fatalx("zero size");
        !           142:
        !           143:        /* Size decreasing. */
        !           144:        if (sy < screen_size_y(s)) {
        !           145:                oy = screen_size_y(s);
        !           146:
        !           147:                if (s->cy != 0) {
        !           148:                        /*
        !           149:                         * The cursor is not at the start. Try to remove as
        !           150:                         * many lines as possible from the top. (Up to the
        !           151:                         * cursor line.)
        !           152:                         */
        !           153:                        ny = s->cy;
        !           154:                        if (ny > oy - sy)
        !           155:                                ny = oy - sy;
        !           156:
        !           157:                        grid_view_delete_lines(gd, 0, ny);
        !           158:
        !           159:                        s->cy -= ny;
        !           160:                        oy -= ny;
        !           161:                }
        !           162:
        !           163:                if (sy < oy) {
        !           164:                        /* Remove any remaining lines from the bottom. */
        !           165:                        grid_view_delete_lines(gd, sy, oy - sy);
        !           166:                        if (s->cy >= sy)
        !           167:                                s->cy = sy - 1;
        !           168:                }
        !           169:        }
        !           170:
        !           171:        /* Resize line arrays. */
        !           172:        gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size);
        !           173:        gd->data = xrealloc(gd->data, gd->hsize + sy, sizeof *gd->data);
        !           174:        gd->usize = xrealloc(gd->usize, gd->hsize + sy, sizeof *gd->usize);
        !           175:        gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata);
        !           176:
        !           177:        /* Size increasing. */
        !           178:        if (sy > screen_size_y(s)) {
        !           179:                oy = screen_size_y(s);
        !           180:                for (yy = gd->hsize + oy; yy < gd->hsize + sy; yy++) {
        !           181:                        gd->size[yy] = 0;
        !           182:                        gd->data[yy] = NULL;
        !           183:                        gd->usize[yy] = 0;
        !           184:                        gd->udata[yy] = NULL;
        !           185:                }
        !           186:        }
        !           187:
        !           188:        gd->sy = sy;
        !           189:
        !           190:        s->rupper = 0;
        !           191:        s->rlower = screen_size_y(s) - 1;
        !           192: }
        !           193:
        !           194: /* Set selection. */
        !           195: void
        !           196: screen_set_selection(struct screen *s,
        !           197:     u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc)
        !           198: {
        !           199:        struct screen_sel       *sel = &s->sel;
        !           200:
        !           201:        memcpy(&sel->cell, gc, sizeof sel->cell);
        !           202:
        !           203:        sel->flag = 1;
        !           204:        if (ey < sy || (sy == ey && ex < sx)) {
        !           205:                sel->sx = ex; sel->sy = ey;
        !           206:                sel->ex = sx; sel->ey = sy;
        !           207:        } else {
        !           208:                sel->sx = sx; sel->sy = sy;
        !           209:                sel->ex = ex; sel->ey = ey;
        !           210:        }
        !           211: }
        !           212:
        !           213: /* Clear selection. */
        !           214: void
        !           215: screen_clear_selection(struct screen *s)
        !           216: {
        !           217:        struct screen_sel       *sel = &s->sel;
        !           218:
        !           219:        sel->flag = 0;
        !           220: }
        !           221:
        !           222: /* Check if cell in selection. */
        !           223: int
        !           224: screen_check_selection(struct screen *s, u_int px, u_int py)
        !           225: {
        !           226:        struct screen_sel       *sel = &s->sel;
        !           227:
        !           228:        if (!sel->flag || py < sel->sy || py > sel->ey)
        !           229:                return (0);
        !           230:
        !           231:        if (py == sel->sy && py == sel->ey) {
        !           232:                if (px < sel->sx || px > sel->ex)
        !           233:                        return (0);
        !           234:                return (1);
        !           235:        }
        !           236:
        !           237:        if ((py == sel->sy && px < sel->sx) || (py == sel->ey && px > sel->ex))
        !           238:                return (0);
        !           239:        return (1);
        !           240: }