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

Annotation of src/usr.bin/tmux/cmd-join-pane.c, Revision 1.2

1.2     ! nicm        1: /* $OpenBSD: cmd-join-pane.c,v 1.1 2010/01/07 20:52:18 nicm Exp $ */
1.1       nicm        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 <paths.h>
                     22: #include <stdlib.h>
                     23: #include <unistd.h>
                     24:
                     25: #include "tmux.h"
                     26:
                     27: /*
                     28:  * Join a pane into another (like split/swap/kill).
                     29:  */
                     30:
                     31: int    cmd_join_pane_parse(struct cmd *, int, char **, char **);
                     32: int    cmd_join_pane_exec(struct cmd *, struct cmd_ctx *);
                     33: void   cmd_join_pane_free(struct cmd *);
                     34: void   cmd_join_pane_init(struct cmd *, int);
                     35: size_t cmd_join_pane_print(struct cmd *, char *, size_t);
                     36:
                     37: struct cmd_join_pane_data {
                     38:        char    *src;
                     39:        char    *dst;
                     40:        int      flag_detached;
                     41:        int      flag_horizontal;
                     42:        int      percentage;
                     43:        int      size;
                     44: };
                     45:
                     46: const struct cmd_entry cmd_join_pane_entry = {
                     47:        "join-pane", "joinp",
1.2     ! nicm       48:        "[-dhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane] [command]",
1.1       nicm       49:        0, "",
                     50:        cmd_join_pane_init,
                     51:        cmd_join_pane_parse,
                     52:        cmd_join_pane_exec,
                     53:        cmd_join_pane_free,
                     54:        cmd_join_pane_print
                     55: };
                     56:
                     57: void
                     58: cmd_join_pane_init(struct cmd *self, int key)
                     59: {
                     60:        struct cmd_join_pane_data        *data;
                     61:
                     62:        self->data = data = xmalloc(sizeof *data);
                     63:        data->src = NULL;
                     64:        data->dst = NULL;
                     65:        data->flag_detached = 0;
                     66:        data->flag_horizontal = 0;
                     67:        data->percentage = -1;
                     68:        data->size = -1;
                     69:
                     70:        switch (key) {
                     71:        case '%':
                     72:                data->flag_horizontal = 1;
                     73:                break;
                     74:        case '"':
                     75:                data->flag_horizontal = 0;
                     76:                break;
                     77:        }
                     78: }
                     79:
                     80: int
                     81: cmd_join_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
                     82: {
                     83:        struct cmd_join_pane_data       *data;
                     84:        int                              opt;
                     85:        const char                      *errstr;
                     86:
                     87:        self->entry->init(self, KEYC_NONE);
                     88:        data = self->data;
                     89:
                     90:        while ((opt = getopt(argc, argv, "dhl:p:s:t:v")) != -1) {
                     91:                switch (opt) {
                     92:                case 'd':
                     93:                        data->flag_detached = 1;
                     94:                        break;
                     95:                case 'h':
                     96:                        data->flag_horizontal = 1;
                     97:                        break;
                     98:                case 's':
                     99:                        if (data->src == NULL)
                    100:                                data->src = xstrdup(optarg);
                    101:                        break;
                    102:                case 't':
                    103:                        if (data->dst == NULL)
                    104:                                data->dst = xstrdup(optarg);
                    105:                        break;
                    106:                case 'l':
                    107:                        if (data->percentage != -1 || data->size != -1)
                    108:                                break;
                    109:                        data->size = strtonum(optarg, 1, INT_MAX, &errstr);
                    110:                        if (errstr != NULL) {
                    111:                                xasprintf(cause, "size %s", errstr);
                    112:                                goto error;
                    113:                        }
                    114:                        break;
                    115:                case 'p':
                    116:                        if (data->size != -1 || data->percentage != -1)
                    117:                                break;
                    118:                        data->percentage = strtonum(optarg, 1, 100, &errstr);
                    119:                        if (errstr != NULL) {
                    120:                                xasprintf(cause, "percentage %s", errstr);
                    121:                                goto error;
                    122:                        }
                    123:                        break;
                    124:                case 'v':
                    125:                        data->flag_horizontal = 0;
                    126:                        break;
                    127:                default:
                    128:                        goto usage;
                    129:                }
                    130:        }
                    131:        argc -= optind;
                    132:        argv += optind;
                    133:        if (argc != 0)
                    134:                goto usage;
                    135:
                    136:        return (0);
                    137:
                    138: usage:
                    139:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
                    140:
                    141: error:
                    142:        self->entry->free(self);
                    143:        return (-1);
                    144: }
                    145:
                    146: int
                    147: cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
                    148: {
                    149:        struct cmd_join_pane_data       *data = self->data;
                    150:        struct session                  *dst_s;
                    151:        struct winlink                  *src_wl, *dst_wl;
                    152:        struct window                   *src_w, *dst_w;
                    153:        struct window_pane              *src_wp, *dst_wp;
                    154:        int                              size;
                    155:        enum layout_type                 type;
                    156:        struct layout_cell              *lc;
                    157:
                    158:        if ((dst_wl = cmd_find_pane(ctx, data->dst, &dst_s, &dst_wp)) == NULL)
                    159:                return (-1);
                    160:        dst_w = dst_wl->window;
                    161:
                    162:        if ((src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp)) == NULL)
                    163:                return (-1);
                    164:        src_w = src_wl->window;
                    165:
                    166:        if (src_w == dst_w) {
                    167:                ctx->error(ctx, "can't join a pane to its own window");
                    168:                return (-1);
                    169:        }
                    170:
                    171:        type = LAYOUT_TOPBOTTOM;
                    172:        if (data->flag_horizontal)
                    173:                type = LAYOUT_LEFTRIGHT;
                    174:
                    175:        size = -1;
                    176:        if (data->size != -1)
                    177:                size = data->size;
                    178:        else if (data->percentage != -1) {
                    179:                if (type == LAYOUT_TOPBOTTOM)
                    180:                        size = (dst_wp->sy * data->percentage) / 100;
                    181:                else
                    182:                        size = (dst_wp->sx * data->percentage) / 100;
                    183:        }
                    184:
                    185:        if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
                    186:                ctx->error(ctx, "create pane failed: pane too small");
                    187:                return (-1);
                    188:        }
                    189:
                    190:        layout_close_pane(src_wp);
                    191:
                    192:        if (src_w->active == src_wp) {
                    193:                src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
                    194:                if (src_w->active == NULL)
                    195:                        src_w->active = TAILQ_NEXT(src_wp, entry);
                    196:        }
                    197:        TAILQ_REMOVE(&src_w->panes, src_wp, entry);
                    198:
                    199:        if (window_count_panes(src_w) == 0)
                    200:                server_kill_window(src_w);
                    201:
                    202:        src_wp->window = dst_w;
                    203:        TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
                    204:        layout_assign_pane(lc, src_wp);
                    205:
                    206:        recalculate_sizes();
                    207:
                    208:        server_redraw_window(src_w);
                    209:        server_redraw_window(dst_w);
                    210:
                    211:        if (!data->flag_detached) {
                    212:                window_set_active_pane(dst_w, src_wp);
                    213:                session_select(dst_s, dst_wl->idx);
                    214:                server_redraw_session(dst_s);
                    215:        } else
                    216:                server_status_session(dst_s);
                    217:
                    218:        return (0);
                    219: }
                    220:
                    221: void
                    222: cmd_join_pane_free(struct cmd *self)
                    223: {
                    224:        struct cmd_join_pane_data       *data = self->data;
                    225:
                    226:        if (data->src != NULL)
                    227:                xfree(data->src);
                    228:        if (data->dst != NULL)
                    229:                xfree(data->dst);
                    230:        xfree(data);
                    231: }
                    232:
                    233: size_t
                    234: cmd_join_pane_print(struct cmd *self, char *buf, size_t len)
                    235: {
                    236:        struct cmd_join_pane_data       *data = self->data;
                    237:        size_t                           off = 0;
                    238:
                    239:        off += xsnprintf(buf, len, "%s", self->entry->name);
                    240:        if (data == NULL)
                    241:                return (off);
                    242:        if (off < len && data->flag_detached)
                    243:                off += xsnprintf(buf + off, len - off, " -d");
                    244:        if (off < len && data->flag_horizontal)
                    245:                off += xsnprintf(buf + off, len - off, " -h");
                    246:        if (off < len && data->size > 0)
                    247:                off += xsnprintf(buf + off, len - off, " -l %d", data->size);
                    248:        if (off < len && data->percentage > 0) {
                    249:                off += xsnprintf(
                    250:                    buf + off, len - off, " -p %d", data->percentage);
                    251:        }
                    252:        if (off < len && data->src != NULL)
                    253:                off += cmd_prarg(buf + off, len - off, " -s ", data->src);
                    254:        if (off < len && data->dst != NULL)
                    255:                off += cmd_prarg(buf + off, len - off, " -t ", data->dst);
                    256:        return (off);
                    257: }