[BACK]Return to cmd-swap-pane.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/cmd-swap-pane.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD$ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2009 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 <stdlib.h>
        !            22:
        !            23: #include "tmux.h"
        !            24:
        !            25: /*
        !            26:  * Swap two panes.
        !            27:  */
        !            28:
        !            29: int    cmd_swap_pane_parse(struct cmd *, int, char **, char **);
        !            30: int    cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
        !            31: void   cmd_swap_pane_send(struct cmd *, struct buffer *);
        !            32: void   cmd_swap_pane_recv(struct cmd *, struct buffer *);
        !            33: void   cmd_swap_pane_free(struct cmd *);
        !            34: void   cmd_swap_pane_init(struct cmd *, int);
        !            35: size_t cmd_swap_pane_print(struct cmd *, char *, size_t);
        !            36:
        !            37: struct cmd_swap_pane_data {
        !            38:        char    *target;
        !            39:         int     src;
        !            40:        int      dst;
        !            41:        int      flag_detached;
        !            42:        int      flag_up;
        !            43:        int      flag_down;
        !            44: };
        !            45:
        !            46: const struct cmd_entry cmd_swap_pane_entry = {
        !            47:        "swap-pane", "swapp",
        !            48:        "[-dDU] [-t target-window] [-p src-index] [-q dst-index]",
        !            49:        0,
        !            50:        cmd_swap_pane_init,
        !            51:        cmd_swap_pane_parse,
        !            52:        cmd_swap_pane_exec,
        !            53:        cmd_swap_pane_send,
        !            54:        cmd_swap_pane_recv,
        !            55:        cmd_swap_pane_free,
        !            56:        cmd_swap_pane_print
        !            57: };
        !            58:
        !            59: void
        !            60: cmd_swap_pane_init(struct cmd *self, int key)
        !            61: {
        !            62:        struct cmd_swap_pane_data        *data;
        !            63:
        !            64:        self->data = data = xmalloc(sizeof *data);
        !            65:        data->target = NULL;
        !            66:        data->src = -1;
        !            67:        data->dst = -1;
        !            68:        data->flag_detached = 0;
        !            69:        data->flag_up = 0;
        !            70:        data->flag_down = 0;
        !            71:
        !            72:        switch (key) {
        !            73:        case '{':
        !            74:                data->flag_up = 1;
        !            75:                break;
        !            76:        case '}':
        !            77:                data->flag_down = 1;
        !            78:                break;
        !            79:        }
        !            80: }
        !            81:
        !            82: int
        !            83: cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
        !            84: {
        !            85:        struct cmd_swap_pane_data       *data;
        !            86:        int                              opt, n;
        !            87:        const char                      *errstr;
        !            88:
        !            89:        self->entry->init(self, 0);
        !            90:        data = self->data;
        !            91:
        !            92:        while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) {
        !            93:                switch (opt) {
        !            94:                case 'd':
        !            95:                        data->flag_detached = 1;
        !            96:                        break;
        !            97:                case 'D':
        !            98:                        data->flag_up = 0;
        !            99:                        data->flag_down = 1;
        !           100:                        data->dst = -1;
        !           101:                        break;
        !           102:                case 't':
        !           103:                        if (data->target == NULL)
        !           104:                                data->target = xstrdup(optarg);
        !           105:                        break;
        !           106:                case 'p':
        !           107:                        if (data->src == -1) {
        !           108:                                n = strtonum(optarg, 0, INT_MAX, &errstr);
        !           109:                                if (errstr != NULL) {
        !           110:                                        xasprintf(cause, "src %s", errstr);
        !           111:                                        goto error;
        !           112:                                }
        !           113:                                data->src = n;
        !           114:                        }
        !           115:                        break;
        !           116:                case 'q':
        !           117:                        if (data->dst == -1) {
        !           118:                                n = strtonum(optarg, 0, INT_MAX, &errstr);
        !           119:                                if (errstr != NULL) {
        !           120:                                        xasprintf(cause, "dst %s", errstr);
        !           121:                                        goto error;
        !           122:                                }
        !           123:                                data->dst = n;
        !           124:                        }
        !           125:                        data->flag_up = 0;
        !           126:                        data->flag_down = 0;
        !           127:                        break;
        !           128:                case 'U':
        !           129:                        data->flag_up = 1;
        !           130:                        data->flag_down = 0;
        !           131:                        data->dst = -1;
        !           132:                        break;
        !           133:
        !           134:                default:
        !           135:                        goto usage;
        !           136:                }
        !           137:        }
        !           138:        argc -= optind;
        !           139:        argv += optind;
        !           140:        if (argc != 0)
        !           141:                goto usage;
        !           142:
        !           143:        return (0);
        !           144:
        !           145: usage:
        !           146:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
        !           147:
        !           148: error:
        !           149:        self->entry->free(self);
        !           150:        return (-1);
        !           151: }
        !           152:
        !           153: int
        !           154: cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
        !           155: {
        !           156:        struct cmd_swap_pane_data       *data = self->data;
        !           157:        struct winlink                  *wl;
        !           158:        struct window                   *w;
        !           159:        struct window_pane              *tmp_wp, *src_wp, *dst_wp;
        !           160:        u_int                            xx, yy;
        !           161:
        !           162:        if (data == NULL)
        !           163:                return (0);
        !           164:
        !           165:        if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
        !           166:                return (-1);
        !           167:        w = wl->window;
        !           168:
        !           169:        if (data->src == -1)
        !           170:                src_wp = w->active;
        !           171:        else {
        !           172:                src_wp = window_pane_at_index(w, data->src);
        !           173:                if (src_wp == NULL) {
        !           174:                        ctx->error(ctx, "no pane: %d", data->src);
        !           175:                        return (-1);
        !           176:                }
        !           177:        }
        !           178:        if (data->dst == -1)
        !           179:                dst_wp = w->active;
        !           180:        else {
        !           181:                dst_wp = window_pane_at_index(w, data->dst);
        !           182:                if (dst_wp == NULL) {
        !           183:                        ctx->error(ctx, "no pane: %d", data->dst);
        !           184:                        return (-1);
        !           185:                }
        !           186:        }
        !           187:
        !           188:        if (data->dst == -1 && data->flag_up) {
        !           189:                if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
        !           190:                        dst_wp = TAILQ_LAST(&w->panes, window_panes);
        !           191:        }
        !           192:        if (data->dst == -1 && data->flag_down) {
        !           193:                if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
        !           194:                        dst_wp = TAILQ_FIRST(&w->panes);
        !           195:        }
        !           196:
        !           197:        if (src_wp == dst_wp)
        !           198:                return (0);
        !           199:
        !           200:        tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
        !           201:        TAILQ_REMOVE(&w->panes, dst_wp, entry);
        !           202:        TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
        !           203:        if (tmp_wp == src_wp)
        !           204:                tmp_wp = dst_wp;
        !           205:        if (tmp_wp == NULL)
        !           206:                TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
        !           207:        else
        !           208:                TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
        !           209:
        !           210:        xx = src_wp->xoff;
        !           211:        yy = src_wp->yoff;
        !           212:        src_wp->xoff = dst_wp->xoff;
        !           213:        src_wp->yoff = dst_wp->yoff;
        !           214:        dst_wp->xoff = xx;
        !           215:        dst_wp->yoff = yy;
        !           216:
        !           217:        xx = src_wp->sx;
        !           218:        yy = src_wp->sy;
        !           219:        window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
        !           220:        window_pane_resize(dst_wp, xx, yy);
        !           221:
        !           222:        if (!data->flag_detached) {
        !           223:                window_set_active_pane(w, dst_wp);
        !           224:                layout_refresh(w, 0);
        !           225:        }
        !           226:
        !           227:        return (0);
        !           228: }
        !           229:
        !           230: void
        !           231: cmd_swap_pane_send(struct cmd *self, struct buffer *b)
        !           232: {
        !           233:        struct cmd_swap_pane_data       *data = self->data;
        !           234:
        !           235:        buffer_write(b, data, sizeof *data);
        !           236:        cmd_send_string(b, data->target);
        !           237: }
        !           238:
        !           239: void
        !           240: cmd_swap_pane_recv(struct cmd *self, struct buffer *b)
        !           241: {
        !           242:        struct cmd_swap_pane_data       *data;
        !           243:
        !           244:        self->data = data = xmalloc(sizeof *data);
        !           245:        buffer_read(b, data, sizeof *data);
        !           246:        data->target = cmd_recv_string(b);
        !           247: }
        !           248:
        !           249: void
        !           250: cmd_swap_pane_free(struct cmd *self)
        !           251: {
        !           252:        struct cmd_swap_pane_data       *data = self->data;
        !           253:
        !           254:        if (data->target != NULL)
        !           255:                xfree(data->target);
        !           256:        xfree(data);
        !           257: }
        !           258:
        !           259: size_t
        !           260: cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
        !           261: {
        !           262:        struct cmd_swap_pane_data       *data = self->data;
        !           263:        size_t                           off = 0;
        !           264:
        !           265:        off += xsnprintf(buf, len, "%s", self->entry->name);
        !           266:        if (data == NULL)
        !           267:                return (off);
        !           268:        if (off < len &&
        !           269:            (data->flag_down || data->flag_up || data->flag_detached)) {
        !           270:                off += xsnprintf(buf + off, len - off, " -");
        !           271:                if (off < len && data->flag_detached)
        !           272:                        off += xsnprintf(buf + off, len - off, "d");
        !           273:                if (off < len && data->flag_up)
        !           274:                        off += xsnprintf(buf + off, len - off, "D");
        !           275:                if (off < len && data->flag_down)
        !           276:                        off += xsnprintf(buf + off, len - off, "U");
        !           277:        }
        !           278:        if (off < len && data->target != NULL)
        !           279:                off += cmd_prarg(buf + off, len - off, " -t ", data->target);
        !           280:        if (off < len && data->src != -1)
        !           281:                off += xsnprintf(buf + off, len - off, " -p %d", data->src);
        !           282:        if (off < len && data->dst != -1)
        !           283:                off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
        !           284:        return (off);
        !           285: }