[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs archive.c dired.c image.c shell.c bufed....
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs archive.c dired.c image.c shell.c bufed.... |
Date: |
Thu, 27 Aug 2015 15:32:29 +0000 |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 15/08/27 15:32:29
Modified files:
. : archive.c dired.c image.c shell.c bufed.c
docbook.c qe.c video.c buffer.c html.c qe.h
Log message:
modes: upgrade mode selection and handling
- separate buffer and window specific mode data management, new API:
QEModeData *qe_create_buffer_mode_data(EditBuffer *b, ModeDef *m);
void *qe_get_buffer_mode_data(EditBuffer *b, ModeDef *m, EditState
*e);
QEModeData *qe_create_window_mode_data(EditState *s, ModeDef *m);
void *qe_get_window_mode_data(EditState *e, ModeDef *m, int status);
int qe_free_mode_data(QEModeData *md);
- make a list of buffer specific mode data areas so multiple major
modes
can co-exist in different windows for the same buffer
- add mode.mode_free callback to release buffer specific resources
- remove buffer.close callback
- shell state is now buffer specific shell_mode data
- clean up compress and archive mode
- show more buffer modes in buffer-list
- simplify edit_set_mode(), display error message on failure
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/archive.c?cvsroot=qemacs&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.58&r2=1.59
http://cvs.savannah.gnu.org/viewcvs/qemacs/image.c?cvsroot=qemacs&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.100&r2=1.101
http://cvs.savannah.gnu.org/viewcvs/qemacs/bufed.c?cvsroot=qemacs&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/qemacs/docbook.c?cvsroot=qemacs&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.209&r2=1.210
http://cvs.savannah.gnu.org/viewcvs/qemacs/video.c?cvsroot=qemacs&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.92&r2=1.93
http://cvs.savannah.gnu.org/viewcvs/qemacs/html.c?cvsroot=qemacs&r1=1.34&r2=1.35
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.206&r2=1.207
Patches:
Index: archive.c
===================================================================
RCS file: /sources/qemacs/qemacs/archive.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- archive.c 25 Aug 2015 16:19:42 -0000 1.21
+++ archive.c 27 Aug 2015 15:31:59 -0000 1.22
@@ -20,8 +20,11 @@
#include "qe.h"
-/* Archivers */
-typedef struct ArchiveType {
+/*---------------- Archivers ----------------*/
+
+typedef struct ArchiveType ArchiveType;
+
+struct ArchiveType {
const char *name; /* name of archive format */
const char *magic; /* magic signature */
int magic_size;
@@ -29,7 +32,7 @@
const char *list_cmd; /* list archive contents to stdout */
const char *extract_cmd; /* extract archive element to stdout */
struct ArchiveType *next;
-} ArchiveType;
+};
static ArchiveType archive_type_array[] = {
{ "tar", NULL, 0, "tar|tar.Z|tgz|tar.gz|tbz|tbz2|tar.bz2|tar.bzip2|"
@@ -48,34 +51,6 @@
static ArchiveType *archive_types;
-/* Compressors */
-typedef struct CompressType {
- const char *name; /* name of compressed format */
- const char *magic; /* magic signature */
- int magic_size;
- const char *extensions;
- const char *load_cmd; /* uncompress file to stdout */
- const char *save_cmd; /* compress to file from stdin */
- struct CompressType *next;
-} CompressType;
-
-static CompressType compress_type_array[] = {
- { "gzip", NULL, 0, "gz", "gunzip -c $1", "gzip > $1" },
- { "bzip2", NULL, 0, "bz2|bzip2", "bunzip2 -c $1", "bzip2 > $1" },
- { "compress", NULL, 0, "Z", "uncompress -c $1", "compress > $1" },
- { "LZMA", NULL, 0, "lzma", "unlzma -c $1", "lzma > $1" },
- { "XZ", NULL, 0, "xz", "unxz -c $1", "xz > $1" },
- { "BinHex", NULL, 0, "hqx", "binhex decode -o /tmp/qe-$$ $1 && "
- "cat /tmp/qe-$$ ; rm -f /tmp/qe-$$", NULL },
- { "sqlite", "SQLite format 3\0", 16, NULL, "sqlite3 $1 .dump", NULL },
- { "bplist", "bplist00", 8, "plist", "plutil -p $1", NULL },
-// { "bplist", "bplist00", 8, "plist", "plutil -convert xml1 -o - $1", NULL
},
-};
-
-static CompressType *compress_types;
-
-/*---------------- Archivers ----------------*/
-
static ArchiveType *find_archive_type(const char *filename,
const u8 *buf, int buf_size)
{
@@ -99,9 +74,9 @@
ArchiveType *atp = find_archive_type(p->filename, p->buf, p->buf_size);
if (atp) {
- if (p->b && p->b->priv_data) {
+ if (p->b && p->b->data_type == mode->data_type) {
/* buffer loaded, re-selecting mode causes buffer reload */
- return 9;
+ return 0;//9
} else {
/* buffer not yet loaded */
return 85;//70
@@ -139,8 +114,6 @@
return out->len;
}
-static ModeDef archive_mode;
-
static int file_read_block(EditBuffer *b, FILE *f1, u8 *buf, int buf_size)
{
FILE *f = f1;
@@ -205,6 +178,12 @@
NULL, /* next */
};
+static ModeDef archive_mode = {
+ .name = "archive",
+ .mode_probe = archive_mode_probe,
+ .data_type = &archive_data_type,
+};
+
static int archive_init(void)
{
int i;
@@ -229,6 +208,33 @@
/*---------------- Compressors ----------------*/
+typedef struct CompressType CompressType;
+
+struct CompressType {
+ const char *name; /* name of compressed format */
+ const char *magic; /* magic signature */
+ int magic_size;
+ const char *extensions;
+ const char *load_cmd; /* uncompress file to stdout */
+ const char *save_cmd; /* compress to file from stdin */
+ struct CompressType *next;
+};
+
+static CompressType compress_type_array[] = {
+ { "gzip", NULL, 0, "gz", "gunzip -c $1", "gzip > $1" },
+ { "bzip2", NULL, 0, "bz2|bzip2", "bunzip2 -c $1", "bzip2 > $1" },
+ { "compress", NULL, 0, "Z", "uncompress -c $1", "compress > $1" },
+ { "LZMA", NULL, 0, "lzma", "unlzma -c $1", "lzma > $1" },
+ { "XZ", NULL, 0, "xz", "unxz -c $1", "xz > $1" },
+ { "BinHex", NULL, 0, "hqx", "binhex decode -o /tmp/qe-$$ $1 && "
+ "cat /tmp/qe-$$ ; rm -f /tmp/qe-$$", NULL },
+ { "sqlite", "SQLite format 3\0", 16, NULL, "sqlite3 $1 .dump", NULL },
+ { "bplist", "bplist00", 8, "plist", "plutil -p $1", NULL },
+// { "bplist", "bplist00", 8, "plist", "plutil -convert xml1 -o - $1", NULL
},
+};
+
+static CompressType *compress_types;
+
static CompressType *find_compress_type(const char *filename,
const u8 *buf, int buf_size)
{
@@ -252,9 +258,9 @@
CompressType *ctp = find_compress_type(p->filename, p->buf, p->buf_size);
if (ctp) {
- if (p->b && p->b->priv_data) {
+ if (p->b && p->b->data_type == mode->data_type) {
/* buffer loaded, re-selecting mode causes buffer reload */
- return 9;
+ return 0;//9;
} else {
/* buffer not yet loaded */
return 82;
@@ -264,8 +270,6 @@
return 0;
}
-static ModeDef compress_mode;
-
static int compress_buffer_load(EditBuffer *b, FILE *f)
{
/* Launch subprocess to expand compressed contents */
@@ -313,6 +317,12 @@
NULL, /* next */
};
+static ModeDef compress_mode = {
+ .name = "compress",
+ .mode_probe = compress_mode_probe,
+ .data_type = &compress_data_type,
+};
+
static int compress_init(void)
{
int i;
@@ -344,7 +354,7 @@
if (strstart(p->real_filename, "http:", NULL)
|| strstart(p->real_filename, "https:", NULL)
|| strstart(p->real_filename, "ftp:", NULL)) {
- if (p->b && p->b->priv_data) {
+ if (p->b && p->b->data_type == mode->data_type) {
/* buffer loaded, re-selecting mode causes buffer reload */
return 9;
} else {
@@ -430,7 +440,7 @@
!memcmp(p->buf, "'''", 3) ||
!memcmp(p->buf, "\\\"", 2))) {
has_man:
- if (p->b && p->b->priv_data) {
+ if (p->b && p->b->data_type == mode->data_type) {
/* buffer loaded, re-selecting mode causes buffer reload */
return 9;
} else {
Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- dired.c 26 Aug 2015 01:12:21 -0000 1.58
+++ dired.c 27 Aug 2015 15:32:06 -0000 1.59
@@ -67,7 +67,7 @@
#endif
typedef struct DiredState {
- ModeDef *signature;
+ QEModeData base; /* derived from QEModeData */
StringArray items;
int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */
int last_index;
@@ -96,17 +96,9 @@
char name[1];
} DiredItem;
-static DiredState *dired_get_state(EditState *s, int status)
+static inline DiredState *dired_get_state(EditState *e, int status)
{
- DiredState *ds = s->b->priv_data;
-
- if (ds && ds->signature == &dired_mode)
- return ds;
-
- if (status)
- put_status(s, "Not a dired buffer");
-
- return NULL;
+ return qe_get_buffer_mode_data(e->b, &dired_mode, status ? e : NULL);
}
static inline int dired_get_index(EditState *s) {
@@ -976,7 +968,7 @@
char filename[MAX_FILENAME_SIZE];
int index;
- if (!(ds = dired_get_state(s, 1)))
+ if (!(ds = dired_get_state(s, 0)))
return;
/* Prevent point from going beyond list */
@@ -1006,71 +998,49 @@
}
}
-static void dired_close(EditBuffer *b)
-{
- DiredState *ds = b->priv_data;
-
- if (ds && ds->signature == &dired_mode) {
- dired_free(ds);
- }
-
- qe_free(&b->priv_data);
- if (b->close == dired_close)
- b->close = NULL;
-}
-
static int dired_mode_init(EditState *s, EditBuffer *b, int flags)
{
- DiredState *ds;
+ DiredState *ds = qe_get_buffer_mode_data(b, &dired_mode, NULL);
- list_mode.mode_init(s, b, flags);
-
- if (s) {
- if (s->b->priv_data) {
- ds = s->b->priv_data;
- if (ds->signature != &dired_mode)
- return -1;
- } else {
- /* XXX: should be allocated by buffer_load API */
- ds = qe_mallocz(DiredState);
if (!ds)
return -1;
- ds->signature = &dired_mode;
+ list_mode.mode_init(s, b, flags);
+
+ if (flags & MODEF_NEWINSTANCE) {
/* XXX: Should use last sort mode, a global variable */
ds->sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME;
ds->last_index = -1;
- s->b->priv_data = ds;
- s->b->close = dired_close;
-
eb_create_style_buffer(b, BF_STYLE1);
/* XXX: should be built by buffer_load API */
- dired_build_list(ds, s->b->filename, NULL, s->b, s);
+ dired_build_list(ds, b->filename, NULL, b, s);
/* XXX: File system charset should be detected automatically */
/* XXX: If file system charset is not utf8, eb_printf will fail */
- eb_set_charset(s->b, &charset_utf8, s->b->eol_type);
- }
+ eb_set_charset(b, &charset_utf8, b->eol_type);
}
return 0;
}
+static void dired_mode_free(EditBuffer *b, void *state)
+{
+ DiredState *ds = state;
+
+ dired_free(ds);
+}
+
/* can only apply dired mode on directories */
static int dired_mode_probe(ModeDef *mode, ModeProbeData *p)
{
- if (p->b->priv_data) {
- DiredState *ds = p->b->priv_data;
- if (ds->signature != &dired_mode)
- return 0;
- else
+ if (qe_get_buffer_mode_data(p->b, &dired_mode, NULL))
return 100;
- }
+
if (S_ISDIR(p->st_mode))
return 95;
- else
+
if (strchr(p->real_filename, '*') || strchr(p->real_filename, '?'))
return 90;
- else
+
return 0;
}
@@ -1196,7 +1166,9 @@
memcpy(&dired_mode, &list_mode, sizeof(ModeDef));
dired_mode.name = "dired";
dired_mode.mode_probe = dired_mode_probe;
+ dired_mode.buffer_instance_size = sizeof(DiredState);
dired_mode.mode_init = dired_mode_init;
+ dired_mode.mode_free = dired_mode_free;
/* CG: not a good idea, display hook has side effect on layout */
dired_mode.display_hook = dired_display_hook;
Index: image.c
===================================================================
RCS file: /sources/qemacs/qemacs/image.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- image.c 1 Jun 2014 13:54:59 -0000 1.28
+++ image.c 27 Aug 2015 15:32:09 -0000 1.29
@@ -23,25 +23,35 @@
#define SCROLL_MHEIGHT 10
-typedef struct ImageBuffer {
+typedef struct ImageBuffer ImageBuffer;
+typedef struct ImageState ImageState;
+typedef struct ImageBufferState ImageBufferState;
+
+struct ImageBufferState {
+ QEModeData base;
+ ImageBuffer *ib;
+};
+
+struct ImageBuffer {
int pix_fmt;
int width;
int height;
int interleaved; /* just an info to tell if the image is interleaved */
int alpha_info; /* see FF_ALPHA_xxx constants */
AVPicture pict; /* NOTE: data[] fields are temporary */
-} ImageBuffer;
+};
-typedef struct ImageState {
+struct ImageState {
+ QEModeData base;
+ ImageBufferState *ibs;
QEBitmap *disp_bmp;
int x, y; /* position of the center of the image in window */
int w, h; /* displayed size */
int xfactor_num, xfactor_den;
int yfactor_num, yfactor_den;
+ /* XXX: should also have a current zone with mark(x/y) and cur(x/y) */
QEColor background_color; /* transparent to display tiles */
-} ImageState;
-
-static EditBufferDataType image_data_type;
+};
int qe_bitmap_format_to_pix_fmt(int format)
{
@@ -89,6 +99,7 @@
h2 = s->height - (y + h);
if (h2 < 0)
h2 = 0;
+
fill_rectangle(s->screen,
s->xleft, s->ytop,
w1, s->height,
@@ -125,13 +136,21 @@
}
}
+static ImageState *image_get_state(EditState *e, int status)
+{
+ return qe_get_window_mode_data(e, &image_mode, status);
+}
+
/* transp: 0x94 and 0x64, 16x16 grid */
static void image_display(EditState *s)
{
- ImageState *is = s->mode_data;
+ ImageState *is = image_get_state(s, 0);
int x, y;
+ if (!is)
+ return;
+
if (s->display_invalid) {
if (is->disp_bmp) {
x = is->x + (s->width - is->w) / 2;
@@ -166,10 +185,15 @@
/* resize current image using the current factors */
static void image_resize(EditState *s)
{
- ImageState *is = s->mode_data;
- ImageBuffer *ib = s->b->data;
+ ImageState *is = image_get_state(s, 1);
+ ImageBuffer *ib;
int d, w, h;
+ if (!is)
+ return;
+
+ ib = is->ibs->ib;
+
/* simplify factors */
d = gcd(is->xfactor_num, is->xfactor_den);
is->xfactor_num /= d;
@@ -190,8 +214,7 @@
h = 1;
/* if no resize needed, exit */
- if (w == is->w &&
- h == is->h)
+ if (w == is->w && h == is->h)
return;
edit_invalidate(s);
@@ -200,7 +223,10 @@
static void image_normal_size(EditState *s)
{
- ImageState *is = s->mode_data;
+ ImageState *is = image_get_state(s, 1);
+
+ if (!is)
+ return;
is->xfactor_num = 1;
is->xfactor_den = 1;
@@ -214,7 +240,10 @@
/* increase or decrease image size by percent */
static void image_mult_size(EditState *s, int percent)
{
- ImageState *is = s->mode_data;
+ ImageState *is = image_get_state(s, 1);
+
+ if (!is)
+ return;
is->xfactor_num *= (100 + percent);
is->xfactor_den *= 100;
@@ -226,8 +255,13 @@
static void image_set_size(EditState *s, int w, int h)
{
- ImageState *is = s->mode_data;
- ImageBuffer *ib = s->b->data;
+ ImageState *is = image_get_state(s, 1);
+ ImageBuffer *ib;
+
+ if (!is)
+ return;
+
+ ib = is->ibs->ib;
if (w < 1 || h < 1) {
put_status(s, "Invalid image size");
@@ -258,6 +292,13 @@
return 100;
}
+static void image_mode_free(EditBuffer *b, void *state)
+{
+ ImageBufferState *ibs = state;
+
+ image_free(&ibs->ib);
+}
+
/* allocate a new image at the end of the buffer */
static ImageBuffer *image_allocate(int pix_fmt, int width, int height)
{
@@ -286,24 +327,26 @@
return ib;
}
-static void image_free(ImageBuffer *ib)
+static void image_free(ImageBuffer **ibp)
{
- qe_free(&ib->pict.data[0]);
- qe_free(&ib);
+ if (*ibp) {
+ qe_free(&(*ibp)->pict.data[0]);
+ qe_free(ibp);
+ }
}
-
static int read_image_cb(void *opaque, AVImageInfo *info)
{
- EditBuffer *b = opaque;
+ ImageBufferState *ibs = opaque;
ImageBuffer *ib;
int i;
ib = image_allocate(info->pix_fmt, info->width, info->height);
if (!ib)
return AVERROR_NOMEM;
+
+ ibs->ib = ib;
ib->interleaved = info->interleaved;
- b->data = ib;
for (i = 0; i < 4; i++) {
info->pict.linesize[i] = ib->pict.linesize[i];
info->pict.data[i] = ib->pict.data[i];
@@ -314,42 +357,61 @@
static int image_buffer_load(EditBuffer *b, FILE *f)
{
ByteIOContext pb1, *pb = &pb1;
+ ImageBufferState *ibs;
int ret;
+ ibs = qe_get_buffer_mode_data(b, &image_mode, NULL);
+ if (!ibs)
+ return;
+
/* start loading the image */
ret = url_fopen(pb, b->filename, URL_RDONLY);
if (ret < 0)
return -1;
- ret = av_read_image(pb, b->filename, NULL, read_image_cb, b);
+ ret = av_read_image(pb, b->filename, NULL, read_image_cb, ibs);
url_fclose(pb);
if (ret) {
return -1;
} else {
- ImageBuffer *ib = b->data;
+ ImageBuffer *ib = ibs->ib;
ib->alpha_info = img_get_alpha_info(&ib->pict, ib->pix_fmt,
ib->width, ib->height);
return 0;
}
}
-static void set_new_image(EditBuffer *b, ImageBuffer *ib)
+static int set_new_image(EditBuffer *b, ImageBuffer *ib)
{
- b->data = ib;
+ ImageBufferState *ibs = qe_get_buffer_mode_data(b, &image_mode, NULL);
+
+ if (!ibs)
+ return -1;
+
+ image_free(&ibs->ib);
+ ibs->ib = ib;
+ /* XXX: should signal all windows that image changed? */
eb_invalidate_raw_data(b);
- b->modified = 1;
+ b->modified = 1; /* not really */
+ return 0;
}
static int image_buffer_save(EditBuffer *b, int start, int end,
const char *filename)
{
ByteIOContext pb1, *pb = &pb1;
- ImageBuffer *ib = b->data;
+ ImageBufferState *ibs = qe_get_buffer_mode_data(b, &image_mode, NULL);
+ ImageBuffer *ib;
ImageBuffer *ib1 = NULL;
int ret, dst_pix_fmt, loss;
AVImageFormat *fmt;
AVImageInfo info;
+ if (!ibs || !ibs->ib)
+ return -1;
+
+ ib = ibs->ib;
+
/* find image format */
fmt = guess_image_format(filename);
if (!fmt)
@@ -360,17 +422,18 @@
ib->pix_fmt, ib->alpha_info,
&loss);
if (dst_pix_fmt < 0)
return -1;
+
/* convert to new format if needed */
if (dst_pix_fmt != ib->pix_fmt) {
ib1 = image_allocate(dst_pix_fmt, ib->width, ib->height);
if (!ib1)
return -1;
if (img_convert(&ib1->pict, ib1->pix_fmt,
- &ib->pict, ib->pix_fmt, ib->width, ib->height) < 0)
+ &ib->pict, ib->pix_fmt, ib->width, ib->height) < 0) {
+ image_free(&ib1);
return -1;
-
+ }
set_new_image(b, ib1);
- image_free(ib);
ib = ib1;
}
@@ -392,23 +455,28 @@
static void image_buffer_close(EditBuffer *b)
{
- ImageBuffer *ib = b->data;
+ ImageBufferState *ibs = qe_get_buffer_mode_data(b, &image_mode, NULL);
- image_free(ib);
- b->data = NULL;
+ if (ibs) {
+ image_free(&ibs->ib);
+ }
}
-
static void update_bmp(EditState *s)
{
- ImageState *is = s->mode_data;
- ImageBuffer *ib = s->b->data;
+ ImageState *is = image_get_state(s, 1);
+ ImageBuffer *ib;
QEPicture pict;
AVPicture avpict;
ImageBuffer *ib1;
int dst_pix_fmt;
int i;
+ if (!is)
+ return;
+
+ ib = is->ibs->ib;
+
bmp_free(s->screen, &is->disp_bmp);
/* combine with the appropriate background if alpha is present */
@@ -487,9 +555,20 @@
static int image_mode_init(EditState *s, EditBuffer *b, int flags)
{
if (s) {
- ImageState *is = s->mode_data;
- ImageBuffer *ib = s->b->data;
+ if (flags & MODEF_NEWINSTANCE) {
+ ImageState *is = qe_get_window_mode_data(s, &image_mode, 0);
+ ImageBufferState *ibs = qe_get_buffer_mode_data(b, &image_mode,
NULL);
+ ImageBuffer *ib;
+
+ if (!ibs || !is)
+ return -1;
+
+ ib = qe_mallocz(ImageBuffer);
+ if (!ib)
+ return -1;
+ is->ibs = ibs;
+ ibs->ib = ib;
is->w = ib->width;
is->h = ib->height;
is->xfactor_num = 1;
@@ -497,7 +576,7 @@
is->yfactor_num = 1;
is->yfactor_den = 1;
is->background_color = 0; /* display tiles */
-
+ }
update_bmp(s);
eb_add_callback(s->b, image_callback, s, 1);
@@ -507,9 +586,12 @@
static void update_pos(EditState *s, int dx, int dy)
{
- ImageState *is = s->mode_data;
+ ImageState *is = image_get_state(s, 1);
int delta;
+ if (!is)
+ return;
+
is->x += dx;
delta = (s->width - is->w) / 2;
if (delta < 0) {
@@ -573,7 +655,10 @@
static void image_mode_close(EditState *s)
{
- ImageState *is = s->mode_data;
+ ImageState *is = image_get_state(s, 0);
+
+ if (!is)
+ return;
bmp_free(s->screen, &is->disp_bmp);
eb_free_callback(s->b, image_callback, s);
@@ -663,12 +748,16 @@
static void image_rotate(EditState *e)
{
- ImageState *is = e->mode_data;
- EditBuffer *b = e->b;
- ImageBuffer *ib = b->data;
+ ImageState *is = image_get_state(e, 1);
+ ImageBuffer *ib;
int ret, w, h, pix_fmt;
ImageBuffer *ib1;
+ if (!is)
+ return;
+
+ ib = is->ibs->ib;
+
pix_fmt = ib->pix_fmt;
w = ib->width;
h = ib->height;
@@ -686,8 +775,7 @@
return;
}
ib1->alpha_info = ib->alpha_info;
- set_new_image(b, ib1);
- image_free(ib);
+ set_new_image(e->b, ib1);
/* temporary */
is->w = h;
is->h = w;
@@ -697,7 +785,10 @@
static void image_set_background_color(EditState *e, const char *color_str)
{
- ImageState *is = e->mode_data;
+ ImageState *is = image_get_state(s, 0);
+
+ if (!is)
+ return;
css_get_color(&is->background_color, color_str);
update_bmp(e);
@@ -705,12 +796,17 @@
static void image_convert(EditState *e, const char *pix_fmt_str)
{
- EditBuffer *b = e->b;
- ImageBuffer *ib = b->data;
+ ImageState *is = image_get_state(s, 0);
+ ImageBuffer *ib;
int ret, new_pix_fmt, i, loss;
ImageBuffer *ib1;
const char *name;
+ if (!is)
+ return;
+
+ ib = is->ibs->ib;
+
for (i = 0; i < PIX_FMT_NB; i++) {
name = avcodec_get_pix_fmt_name(i);
if (strequal(name, pix_fmt_str))
@@ -754,8 +850,7 @@
}
ib1->alpha_info = img_get_alpha_info(&ib1->pict, ib1->pix_fmt,
ib1->width, ib1->height);
- set_new_image(b, ib1);
- image_free(ib);
+ set_new_image(e->b, ib1);
/* suppress that and use callback */
update_bmp(e);
}
@@ -763,9 +858,15 @@
void image_mode_line(EditState *s, buf_t *out)
{
EditBuffer *b = s->b;
- ImageBuffer *ib = b->data;
+ ImageState *is = image_get_state(s, 0);
+ ImageBuffer *ib;
char alpha_mode;
+ if (!is)
+ return;
+
+ ib = is->ib;
+
basic_mode_line(s, out, '-');
if (ib->alpha_info & FF_ALPHA_SEMI_TRANSP)
@@ -822,12 +923,21 @@
CMD_DEF_END,
};
+static EditBufferDataType image_data_type = {
+ "image",
+ image_buffer_load,
+ image_buffer_save,
+ image_buffer_close,
+};
+
ModeDef image_mode = {
.name = "image",
- .instance_size = sizeof(ImageState),
+ .buffer_instance_size = sizeof(ImageBufferState),
+ .window_instance_size = sizeof(ImageState),
.mode_probe = image_mode_probe,
.mode_init = image_mode_init,
.mode_close = image_mode_close,
+ .mode_free = image_mode_free,
.display = image_display,
.move_up_down = image_move_up_down,
.move_left_right = image_move_left_right,
@@ -836,13 +946,6 @@
.get_mode_line = image_mode_line,
};
-static EditBufferDataType image_data_type = {
- "image",
- image_buffer_load,
- image_buffer_save,
- image_buffer_close,
-};
-
static int image_init(void)
{
av_register_all();
Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -b -r1.100 -r1.101
--- shell.c 26 Aug 2015 22:51:25 -0000 1.100
+++ shell.c 27 Aug 2015 15:32:11 -0000 1.101
@@ -53,7 +53,7 @@
};
typedef struct ShellState {
- ModeDef *signature;
+ QEModeData base;
/* buffer state */
int pty_fd;
int pid; /* -1 if not launched */
@@ -653,17 +653,9 @@
#endif
}
-static ShellState *shell_get_state(EditState *e, int status)
+static inline ShellState *shell_get_state(EditState *e, int status)
{
- ShellState *s = e->b->priv_data;
-
- if (s && s->signature == &shell_mode)
- return s;
-
- if (status)
- put_status(e, "Not a shell buffer");
-
- return NULL;
+ return qe_get_buffer_mode_data(e->b, &shell_mode, status ? e : NULL);
}
/* CG: much cleaner way! */
@@ -685,7 +677,7 @@
const char *p;
int len;
- if (!s || s->signature != &shell_mode)
+ if (!s || s->base.mode != &shell_mode)
return;
if (key == KEY_CTRL('o')) {
@@ -1242,7 +1234,7 @@
unsigned char buf[16 * 1024];
int len, i;
- if (!s || s->signature != &shell_mode)
+ if (!s || s->base.mode != &shell_mode)
return;
qs = s->qe_state;
@@ -1259,6 +1251,12 @@
s->b->flags &= ~BF_READONLY;
s->b->last_log = 0;
+#if 0
+ /* XXX: tty emulation should be optional */
+ if (!emulate) {
+ eb_write(s->b, s->b->total_size, buf, len);
+ } else
+#endif
for (i = 0; i < len; i++)
tty_emulate(s, buf[i]);
@@ -1272,14 +1270,11 @@
dpy_flush(qs->screen);
}
-static void shell_close(EditBuffer *b)
+static void shell_mode_free(EditBuffer *b, void *state)
{
- ShellState *s = b->priv_data;
+ ShellState *s = state;
int status;
- if (!s || s->signature != &shell_mode)
- return;
-
eb_free_callback(b, eb_offset_callback, &s->cur_offset);
if (s->pid != -1) {
@@ -1302,9 +1297,6 @@
close(s->pty_fd);
s->pty_fd = -1;
}
- qe_free(&b->priv_data);
- if (b->close == shell_close)
- b->close = NULL;
}
static void shell_pid_cb(void *opaque, int status)
@@ -1315,7 +1307,7 @@
EditState *e;
char buf[1024];
- if (!s || s->signature != &shell_mode)
+ if (!s || s->base.mode != &shell_mode)
return;
b = s->b;
@@ -1374,7 +1366,7 @@
qe_set_next_mode(e, 0, 0);
}
if (!(s->shell_flags & SF_INTERACTIVE)) {
- shell_close(b);
+ qe_free_mode_data(&s->base);
}
edit_display(qs);
dpy_flush(qs->screen);
@@ -1391,22 +1383,15 @@
int rows, cols;
b = b0;
- if (b) {
- s = b->priv_data;
- if (s && s->signature != &shell_mode)
- return NULL;
- if (shell_flags & SF_COLOR)
- eb_create_style_buffer(b, BF_STYLE2);
- } else {
- int bf_flags = BF_SAVELOG;
- if (shell_flags & SF_COLOR)
- bf_flags |= BF_STYLE2;
- b = eb_new(bufname, bf_flags);
+ if (!b) {
+ b = eb_new(bufname, BF_SAVELOG);
if (!b)
return NULL;
}
eb_set_buffer_name(b, bufname); /* ensure that the name is unique */
+ if (shell_flags & SF_COLOR)
+ eb_create_style_buffer(b, BF_STYLE2);
/* Select shell output buffer encoding from LANG setting */
if (((lang = getenv("LANG")) != NULL && strstr(lang, "UTF-8")) ||
@@ -1416,17 +1401,14 @@
eb_set_charset(b, &charset_vt100, b->eol_type);
}
- s = b->priv_data;
+ s = qe_get_buffer_mode_data(b, &shell_mode, NULL);
if (!s) {
- s = qe_mallocz(ShellState);
+ s = (ShellState*)qe_create_buffer_mode_data(b, &shell_mode);
if (!s) {
if (!b0)
eb_free(&b);
return NULL;
}
- s->signature = &shell_mode;
- b->priv_data = s;
- b->close = shell_close;
/* Track cursor with edge effect */
eb_add_callback(b, eb_offset_callback, &s->cur_offset, 1);
}
@@ -1493,25 +1475,19 @@
* restart shell process in it.
*/
b = s->b;
- shs = b->priv_data;
- if (strstart(b->name, "*shell*", NULL)
- && shs && shs->signature == &shell_mode) {
+ shs = shell_get_state(s, 0);
+ if (shs && strstart(b->name, "*shell", NULL)) {
if (shs->pid >= 0)
return;
} else {
/* XXX: should find the last used shell buffer */
b = try_show_buffer(s, "*shell*");
if (b) {
- shs = b->priv_data;
- if (shs) {
- if (shs->signature != &shell_mode) {
- b = NULL;
- } else
- if (shs->pid >= 0)
+ shs = qe_get_buffer_mode_data(b, &shell_mode, NULL);
+ if (shs && shs->pid >= 0)
return;
}
}
- }
if (b) {
/* restart shell in *shell* buffer */
s->offset = b->total_size;
@@ -1573,7 +1549,6 @@
b->data_type_name = "ssh";
b->default_mode = &shell_mode;
switch_to_buffer(s, b);
- //edit_set_mode(s, &shell_mode);
put_status(s, "Press C-o to toggle between shell/edit mode");
}
@@ -1966,13 +1941,11 @@
static int shell_mode_probe(ModeDef *mode, ModeProbeData *p)
{
- if (p->b && p->b->priv_data) {
- ShellState *s = p->b->priv_data;
- if (s->signature == &shell_mode) {
- if (s->shell_flags & SF_INTERACTIVE)
+ ShellState *s = qe_get_buffer_mode_data(p->b, &shell_mode, NULL);
+
+ if (s && s->shell_flags & SF_INTERACTIVE)
return 100;
- }
- }
+
return 0;
}
@@ -2008,7 +1981,9 @@
shell_mode.name = "shell";
shell_mode.mode_name = NULL;
shell_mode.mode_probe = shell_mode_probe;
+ shell_mode.buffer_instance_size = sizeof(ShellState);
shell_mode.mode_init = shell_mode_init;
+ shell_mode.mode_free = shell_mode_free;
shell_mode.display_hook = shell_display_hook;
shell_mode.move_left_right = shell_move_left_right;
shell_mode.move_word_left_right = shell_move_word_left_right;
Index: bufed.c
===================================================================
RCS file: /sources/qemacs/qemacs/bufed.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- bufed.c 26 Aug 2015 01:07:29 -0000 1.39
+++ bufed.c 27 Aug 2015 15:32:12 -0000 1.40
@@ -36,7 +36,7 @@
};
typedef struct BufedState {
- ModeDef *signature;
+ QEModeData base;
int flags;
int last_index;
EditState *cur_window;
@@ -47,31 +47,19 @@
static ModeDef bufed_mode;
-static BufedState *bufed_get_state(EditState *s, int status)
+static inline BufedState *bufed_get_state(EditState *e, int status)
{
- BufedState *bs = s->b->priv_data;
-
- if (bs && bs->signature == &bufed_mode)
- return bs;
-
- if (status)
- put_status(s, "Not a bufed buffer");
-
- return NULL;
+ return qe_get_buffer_mode_data(e->b, &bufed_mode, status ? e : NULL);
}
-static void build_bufed_list(EditState *s)
+static void build_bufed_list(BufedState *bs, EditState *s)
{
QEmacsState *qs = s->qe_state;
EditBuffer *b;
- BufedState *bs;
StringItem *item;
int last_index = list_get_pos(s);
int i;
- if (!(bs = bufed_get_state(s, 1)))
- return;
-
free_strings(&bs->items);
for (b = qs->first_buffer; b != NULL; b = b->next) {
if (!(b->flags & BF_SYSTEM) || (bs->flags & BUFED_ALL_VISIBLE)) {
@@ -127,6 +115,7 @@
char mode_buf[64];
const char *mode_name;
buf_t outbuf, *out;
+ QEModeData *md;
if (b1->flags & BF_IS_LOG) {
mode_name = "log";
@@ -150,6 +139,10 @@
buf_printf(out, "%s+", b1->data_type_name);
}
buf_puts(out, mode_name);
+ for (md = b1->mode_data_list; md; md = md->next) {
+ if (md->mode && md->mode != b1->saved_mode)
+ buf_printf(out, ",%s", md->mode->name);
+ }
b->cur_style = style0;
eb_printf(b, " %10d %1.0d %-8.8s %-11s ",
@@ -169,14 +162,10 @@
b->flags |= BF_READONLY;
}
-static EditBuffer *bufed_get_buffer(EditState *s)
+static EditBuffer *bufed_get_buffer(BufedState *bs, EditState *s)
{
- BufedState *bs;
int index;
- if (!(bs = bufed_get_state(s, 1)))
- return NULL;
-
index = list_get_pos(s);
if (index < 0 || index >= bs->items.nb_items)
return NULL;
@@ -272,7 +261,7 @@
string_selection_iterate(&bs->items, list_get_pos(s),
bufed_kill_item, s);
- build_bufed_list(s);
+ build_bufed_list(bs, s);
}
/* show a list of buffers */
@@ -316,7 +305,7 @@
} else {
bs->flags |= BUFED_ALL_VISIBLE;
}
- build_bufed_list(e);
+ build_bufed_list(bs, e);
/* if active buffer is found, go directly on it */
for (i = 0; i < bs->items.nb_items; i++) {
@@ -329,26 +318,34 @@
static void bufed_clear_modified(EditState *s)
{
+ BufedState *bs;
EditBuffer *b;
- b = bufed_get_buffer(s);
+ if (!(bs = bufed_get_state(s, 1)))
+ return;
+
+ b = bufed_get_buffer(bs, s);
if (!b)
return;
b->modified = 0;
- build_bufed_list(s);
+ build_bufed_list(bs, s);
}
static void bufed_toggle_read_only(EditState *s)
{
+ BufedState *bs;
EditBuffer *b;
- b = bufed_get_buffer(s);
+ if (!(bs = bufed_get_state(s, 1)))
+ return;
+
+ b = bufed_get_buffer(bs, s);
if (!b)
return;
b->flags ^= BF_READONLY;
- build_bufed_list(s);
+ build_bufed_list(bs, s);
}
static void bufed_refresh(EditState *s, int toggle)
@@ -361,7 +358,7 @@
if (toggle)
bs->flags ^= BUFED_ALL_VISIBLE;
- build_bufed_list(s);
+ build_bufed_list(bs, s);
}
static void bufed_display_hook(EditState *s)
@@ -376,52 +373,27 @@
static int bufed_mode_probe(ModeDef *mode, ModeProbeData *p)
{
- if (p->b->priv_data) {
- BufedState *bs = p->b->priv_data;
- if (bs->signature == &bufed_mode)
+ if (qe_get_buffer_mode_data(p->b, &bufed_mode, NULL))
return 95;
- else
- return 0;
- }
+
return 0;
}
-static void bufed_close(EditBuffer *b)
+static int bufed_mode_init(EditState *s, EditBuffer *b, int flags)
{
- BufedState *bs = b->priv_data;
+ BufedState *bs = qe_get_buffer_mode_data(b, &bufed_mode, NULL);
- if (bs && bs->signature == &bufed_mode) {
- free_strings(&bs->items);
- }
+ if (!bs)
+ return -1;
- qe_free(&b->priv_data);
- if (b->close == bufed_close)
- b->close = NULL;
+ return list_mode.mode_init(s, b, flags);
}
-static int bufed_mode_init(EditState *s, EditBuffer *b, int flags)
+static void bufed_mode_free(EditBuffer *b, void *state)
{
- BufedState *bs;
+ BufedState *bs = state;
- list_mode.mode_init(s, b, flags);
-
- if (s) {
- if (s->b->priv_data) {
- bs = s->b->priv_data;
- if (bs->signature != &bufed_mode)
- return -1;
- } else {
- /* XXX: should be allocated by buffer_load API */
- bs = qe_mallocz(BufedState);
- if (!bs)
- return -1;
-
- bs->signature = &bufed_mode;
- s->b->priv_data = bs;
- s->b->close = bufed_close;
- }
- }
- return 0;
+ free_strings(&bs->items);
}
/* specific bufed commands */
@@ -466,7 +438,9 @@
memcpy(&bufed_mode, &list_mode, sizeof(ModeDef));
bufed_mode.name = "bufed";
bufed_mode.mode_probe = bufed_mode_probe;
+ bufed_mode.buffer_instance_size = sizeof(BufedState);
bufed_mode.mode_init = bufed_mode_init;
+ bufed_mode.mode_free = bufed_mode_free;
bufed_mode.display_hook = bufed_display_hook;
/* first register mode */
Index: docbook.c
===================================================================
RCS file: /sources/qemacs/qemacs/docbook.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- docbook.c 1 Jun 2014 13:54:59 -0000 1.12
+++ docbook.c 27 Aug 2015 15:32:13 -0000 1.13
@@ -34,7 +34,12 @@
static int docbook_mode_init(EditState *s, EditBuffer *b, int flags)
{
- return gxml_mode_init(s, XML_IGNORE_CASE | XML_DOCBOOK, docbook_style);
+ if (flags & MODEF_NEWINSTANCE) {
+ /* Implement mode inheritance manually */
+ qe_create_buffer_mode_data(b, &html_mode);
+ return gxml_mode_init(b, XML_IGNORE_CASE | XML_DOCBOOK, docbook_style);
+ }
+ return 0;
}
static ModeDef docbook_mode;
@@ -44,6 +49,7 @@
/* inherit from html mode */
memcpy(&docbook_mode, &html_mode, sizeof(ModeDef));
docbook_mode.name = "docbook";
+ docbook_mode.buffer_instance_size = sizeof(QEModeData);
docbook_mode.extensions = NULL;
docbook_mode.mode_probe = docbook_mode_probe;
docbook_mode.mode_init = docbook_mode_init;
Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.209
retrieving revision 1.210
diff -u -b -r1.209 -r1.210
--- qe.c 26 Aug 2015 22:51:24 -0000 1.209
+++ qe.c 27 Aug 2015 15:32:14 -0000 1.210
@@ -1846,7 +1846,7 @@
if (b->filename[0] == '\0')
return 0;
- if (b->data_type == &raw_data_type) {
+ if (!f1 && b->data_type == &raw_data_type) {
struct stat st;
if (stat(b->filename, &st) < 0 || !S_ISREG(st.st_mode))
@@ -1859,6 +1859,11 @@
} else {
f = f1;
}
+ /* XXX: the log buffer is inappropriate if the file was modified on
+ * disk. If this is a reload operation, should create a log for
+ * clearing the buffer and another one for loading it. So the
+ * operation can be undone.
+ */
saved = b->save_log;
b->save_log = 0;
if (b->data_type->buffer_load)
@@ -1884,13 +1889,104 @@
}
}
-void edit_set_mode(EditState *s, ModeDef *m)
+QEModeData *qe_create_buffer_mode_data(EditBuffer *b, ModeDef *m)
{
- int data_count;
- EditState *e;
- EditBuffer *b;
+ QEModeData *md = NULL;
+ int size = m->buffer_instance_size - sizeof(QEModeData);
- b = s->b;
+ if (size >= 0) {
+ md = qe_mallocz_hack(QEModeData, size);
+ if (md) {
+ md->mode = m;
+ md->b = b;
+ md->next = b->mode_data_list;
+ b->mode_data_list = md;
+ }
+ }
+ return md;
+}
+
+void *qe_get_buffer_mode_data(EditBuffer *b, ModeDef *m, EditState *e)
+{
+ if (b) {
+ QEModeData *md;
+ for (md = b->mode_data_list; md; md = md->next) {
+ if (md->mode == m)
+ return md;
+ }
+ }
+ if (e)
+ put_status(e, "Not a %s buffer", m->name);
+
+ return NULL;
+}
+
+QEModeData *qe_create_window_mode_data(EditState *s, ModeDef *m)
+{
+ QEModeData *md = NULL;
+ int size = m->window_instance_size - sizeof(QEModeData);
+
+ if (!s->mode_data && size >= 0) {
+ md = qe_mallocz_hack(QEModeData, size);
+ if (md) {
+ md->mode = m;
+ md->s = s;
+ s->mode_data = md;
+ }
+ }
+ return md;
+}
+
+void *qe_get_window_mode_data(EditState *e, ModeDef *m, int status)
+{
+ if (e) {
+ QEModeData *md = e->mode_data;
+ if (md && md->mode == m)
+ return md;
+ }
+ if (status)
+ put_status(e, "Not a %s buffer", m->name);
+
+ return NULL;
+}
+
+int qe_free_mode_data(QEModeData *md)
+{
+ int rc = -1;
+
+ if (!md)
+ return 0;
+
+ if (check_buffer(&md->b)) {
+ EditBuffer *b = md->b;
+ QEModeData **mdp;
+ for (mdp = &b->mode_data_list; *mdp; mdp = &(*mdp)->next) {
+ if (*mdp == md) {
+ /* unlink before calling destructor */
+ *mdp = md->next;
+ if (md->mode->mode_free)
+ md->mode->mode_free(b, md);
+ rc = 0;
+ break;
+ }
+ }
+ }
+ if (check_window(&md->s)) {
+ if (md->s->mode_data == md) {
+ md->s->mode_data = NULL;
+ rc = 0;
+ }
+ }
+ qe_free(&md);
+ return rc;
+}
+
+int edit_set_mode(EditState *s, ModeDef *m)
+{
+ int mode_flags = 0;
+ EditBuffer *b = s->b;
+ const char *errstr = NULL;
+ int rc = 0;
/* if a mode is already defined, try to close it */
if (s->mode) {
@@ -1899,16 +1995,21 @@
if (s->mode->mode_close)
s->mode->mode_close(s);
generic_mode_close(s);
- qe_free(&s->mode_data);
- s->mode = NULL;
+ qe_free_mode_data(s->mode_data);
+ s->mode = NULL; /* XXX: should instead use fundamental_mode */
set_colorize_func(s, NULL);
+ /* XXX: this code makes no sense, if must be reworked! */
+#if 0
+ int data_count;
+ EditState *e;
+
/* try to remove the raw or mode specific data if it is no
longer used. */
data_count = 0;
for (e = s->qe_state->first_window; e != NULL; e = e->next_window) {
if (e != s && e->b == b) {
- if (e->mode->data_type != &raw_data_type)
+ if (e->mode && e->mode->data_type != &raw_data_type)
data_count++;
}
}
@@ -1917,6 +2018,8 @@
if (data_count == 0 && !b->modified) {
/* close mode specific buffer representation because it is
always redundant if it was not modified */
+ /* XXX: move this to reset buffer data: eb_free or changing
+ * data_type */
if (b->data_type != &raw_data_type) {
b->data_type->buffer_close(b);
b->data_data = NULL;
@@ -1925,36 +2028,46 @@
b->modified = 0;
}
}
+#endif
}
/* if a new mode is wanted, open it */
if (m) {
s->mode_data = NULL;
- if (m->instance_size > 0) {
- s->mode_data = qe_mallocz_array(u8, m->instance_size);
+ if (m->buffer_instance_size > 0) {
+ if (!qe_get_buffer_mode_data(b, m, NULL)) {
+ if (qe_create_buffer_mode_data(b, m)) {
+ mode_flags = MODEF_NEWINSTANCE;
+ } else {
+ errstr = "Cannot allocate buffer mode data";
+ }
+ }
+ }
+ if (m->window_instance_size > 0) {
+ if (!qe_create_window_mode_data(s, m)) {
/* safe fall back: use text mode */
- if (!s->mode_data)
- m = &text_mode;
+ errstr = "Cannot allocate window mode data";
+ }
}
if (m->data_type != &raw_data_type) {
/* if a non raw data type is requested, we see if we can use it */
if (b->data_type == &raw_data_type) {
/* non raw data type: we must call a mode specific
load method */
+ s->mode = m;
b->data_type = m->data_type;
b->data_type_name = m->data_type->name;
if (reload_buffer(s, b) < 0) {
- /* error: reset to text mode */
- m = &text_mode;
b->data_type = &raw_data_type;
b->data_type_name = NULL;
+ errstr = "Cannot reload buffer";
}
} else
if (b->data_type != m->data_type) {
/* non raw data type requested, but the the buffer has
a different type: we cannot switch mode, so we fall
back to text */
- m = &text_mode;
+ errstr = "incompatible data type";
} else {
/* same data type: nothing more to do */
}
@@ -1963,11 +2076,17 @@
if (b->total_size == 0 && !b->modified)
reload_buffer(s, b);
}
+ if (errstr) {
+ put_status(s, "Cannot set mode %s: %s", m->name, errstr);
+ m = &text_mode;
+ rc = -1;
+ }
+
s->mode = m;
/* init mode */
generic_mode_init(s);
- m->mode_init(s, s->b, MODEF_VIEW);
+ m->mode_init(s, s->b, MODEF_VIEW | mode_flags);
if (m->colorize_func)
set_colorize_func(s, m->colorize_func);
/* modify offset_top so that its value is correct */
@@ -1976,6 +2095,7 @@
/* keep saved data in sync with last mode used for buffer */
generic_save_window_data(s);
}
+ return rc;
}
void do_set_mode(EditState *s, const char *name)
@@ -5071,9 +5191,10 @@
}
}
-/* close the edit window. If it is active, find another active
- window. If the buffer is only referenced by this window, then save
- in the buffer all the window state so that it can be recovered. */
+/* Close the edit window.
+ * Save the window state to the buffer for later retrieval.
+ * If it is active, find another window to activate.
+ */
void edit_close(EditState **sp)
{
if (*sp) {
@@ -5082,7 +5203,7 @@
/* save current state for later window reattachment */
switch_to_buffer(s, NULL);
edit_detach(s);
- qe_free(&s->mode_data);
+ qe_free_mode_data(s->mode_data);
qe_free(&s->prompt);
qe_free(&s->line_shadow);
qe_free(sp);
@@ -5713,6 +5834,7 @@
e_new = edit_new(b, 0, 0, width, qs->height - qs->status_height,
flags | WF_POPLEFT | WF_RSEPARATOR);
+ e_new->wrap = WRAP_TRUNCATE;
do_refresh(e_new);
return e_new;
}
@@ -6164,10 +6286,15 @@
f = NULL;
}
- /* Attach buffer to window, will set default_mode
- * XXX: this will also load the file, incorrect for non raw modes
- */
b->default_mode = selected_mode;
+ /* attaching the buffer to the window will set the default_mode
+ * which in turn will load the data.
+ * XXX: This is an ugly side effect, ineffective for
+ * asynchronous shell buffers.
+ * XXX: should instead instantiate the mode on the buffer and
+ * test the resulting data_mode, loading the file if raw_mode
+ * selected.
+ */
switch_to_buffer(s, b);
if (access(b->filename, W_OK)) {
b->flags |= BF_READONLY;
Index: video.c
===================================================================
RCS file: /sources/qemacs/qemacs/video.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- video.c 1 Jun 2014 13:55:00 -0000 1.20
+++ video.c 27 Aug 2015 15:32:24 -0000 1.21
@@ -51,6 +51,7 @@
} VideoPicture;
typedef struct VideoState {
+ QEModeData base;
EditState *edit_state;
pthread_t parse_tid;
pthread_t audio_tid;
@@ -207,14 +208,22 @@
return ret;
}
+static inline VideoState *video_get_state(EditState *e, int status)
+{
+ return qe_get_window_mode_data(e, &video_mode, status);
+}
+
/* called to display each frame */
static void video_refresh_timer(void *opaque)
{
EditState *s = opaque;
QEmacsState *qs = &qe_state;
- VideoState *is = s->mode_data;
+ VideoState *is;
VideoPicture *vp;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
if (is->video_st) {
if (is->pictq_size == 0) {
/* if no picture, need to wait */
@@ -263,11 +272,14 @@
static void video_image_display(EditState *s)
{
- VideoState *is = s->mode_data;
+ VideoState *is;
VideoPicture *vp;
float aspect_ratio;
int width, height, x, y;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
vp = &is->pictq[is->pictq_rindex];
if (vp->bmp) {
/* XXX: use variable in the frame */
@@ -301,9 +313,12 @@
static void video_audio_display(EditState *s)
{
- VideoState *is = s->mode_data;
+ VideoState *is;
int i, x, y1, y, h, ys;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
fill_rectangle(s->screen,
s->xleft, s->ytop, s->width, s->height,
QERGB(0x00, 0x00, 0x00));
@@ -333,7 +348,10 @@
/* display the current picture, if any */
static void video_display(EditState *s)
{
- VideoState *is = s->mode_data;
+ VideoState *is;
+
+ if (!(is = video_get_state(s, 1)))
+ return;
if (s->display_invalid) {
if (is->video_st)
@@ -583,16 +601,20 @@
/* open a given stream. Return 0 if OK */
static int stream_open(EditState *s, int stream_index)
{
- VideoState *is = s->mode_data;
- AVFormatContext *ic = is->ic;
+ VideoState *is;
+ AVFormatContext *ic;
AVCodecContext *enc;
AVCodec *codec;
AVStream *st;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
+ ic = is->ic;
if (stream_index < 0 || stream_index >= ic->nb_streams)
return -1;
- enc = &ic->streams[stream_index]->codec;
+ enc = &ic->streams[stream_index]->codec;
/* prepare audio output */
if (enc->codec_type == CODEC_TYPE_AUDIO) {
@@ -636,10 +658,14 @@
static void stream_close(EditState *s, int stream_index)
{
- VideoState *is = s->mode_data;
- AVFormatContext *ic = is->ic;
+ VideoState *is;
+ AVFormatContext *ic;
AVCodecContext *enc;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
+ ic = is->ic;
enc = &ic->streams[stream_index]->codec;
switch (enc->codec_type) {
@@ -690,11 +716,14 @@
static void *decode_thread(void *arg)
{
EditState *s = arg;
- VideoState *is = s->mode_data;
+ VideoState *is;
AVFormatContext *ic;
int err, i, ret, video_index, audio_index;
AVPacket pkt1, *pkt = &pkt1;
+ if (!(is = video_get_state(s, 1)))
+ return NULL;
+
video_index = -1;
audio_index = -1;
is->video_stream = -1;
@@ -785,18 +814,25 @@
/* pause or resume the video */
static void video_pause(EditState *s)
{
- VideoState *is = s->mode_data;
+ VideoState *is;
+
+ if (!(is = video_get_state(s, 1)))
+ return;
+
is->paused = !is->paused;
}
static int video_mode_init(EditState *s, EditBuffer *b, int flags)
{
if (s) {
- VideoState *is = s->mode_data;
+ VideoState *is = qe_get_buffer_mode_data(b, &video_mode, NULL);
QEmacsState *qs = s->qe_state;
int err, video_playing;
EditState *e;
+ if (!is)
+ return -1;
+
/* XXX: avoid annoying Overwrite in mode line */
s->insert = 1;
@@ -811,10 +847,11 @@
/* if there is already a window with this video playing, then we
stop this new instance (C-x 2 case) */
video_playing = 0;
+ /* need window based mode data for this */
for (e = qs->first_window; e != NULL; e = e->next_window) {
if (e->mode == s->mode && e != s && e->b == s->b) {
- VideoState *is1 = e->mode_data;
- if (!is1->paused)
+ VideoState *is1 = qe_get_window_mode_data(e, &video_mode, 0);
+ if (is1 && !is1->paused)
video_playing = 1;
}
}
@@ -832,10 +869,13 @@
static void video_mode_close(EditState *s)
{
- VideoState *is = s->mode_data;
+ VideoState *is;
VideoPicture *vp;
int i;
+ if (!(is = video_get_state(s, 1)))
+ return;
+
/* XXX: use a special url_shutdown call to abort parse cleanly */
is->abort_request = 1;
pthread_join(is->parse_tid, NULL);
@@ -863,13 +903,16 @@
static void video_mode_line(EditState *s, buf_t *out)
{
const char *name;
- VideoState *is = s->mode_data;
+ VideoState *is;
AVCodec *codec;
AVCodecContext *dec;
char buf1[32];
basic_mode_line(s, out, '-');
+ if (!(is = video_get_state(s, 0)))
+ return;
+
if (is->paused)
buf_printf(out, "[paused]--");
@@ -901,16 +944,22 @@
static void av_cycle_stream(EditState *s, int codec_type)
{
- VideoState *is = s->mode_data;
- AVFormatContext *ic = is->ic;
+ VideoState *is;
+ AVFormatContext *ic;
int start_index, stream_index;
AVStream *st;
char buf[32];
+ if (!(is = video_get_state(s, 0)))
+ return;
+
+ ic = is->ic;
+
if (codec_type == CODEC_TYPE_VIDEO)
start_index = is->video_stream;
else
start_index = is->audio_stream;
+
if (start_index < 0) {
put_status(s, "No %s stream to cycle",
(codec_type == CODEC_TYPE_VIDEO) ? "video" : "audio");
@@ -950,7 +999,7 @@
ModeDef video_mode = {
.name = "av",
- .instance_size = sizeof(VideoState),
+ .window_instance_size = sizeof(VideoState),
.mode_probe = video_mode_probe,
.mode_init = video_mode_init,
.mode_close = video_mode_close,
Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -b -r1.92 -r1.93
--- buffer.c 26 Aug 2015 00:53:24 -0000 1.92
+++ buffer.c 27 Aug 2015 15:32:27 -0000 1.93
@@ -782,9 +782,15 @@
QEmacsState *qs = &qe_state;
EditBuffer **pb;
- /* call user defined close */
- if (b->close)
- b->close(b);
+ /* free b->mode_data_list by calling destructors */
+ while (b->mode_data_list) {
+ QEModeData *md = b->mode_data_list;
+ b->mode_data_list = md->next;
+ md->next = NULL;
+ if (md->mode && md->mode->mode_free)
+ md->mode->mode_free(b, md);
+ qe_free(&md);
+ }
/* free each callback */
while (b->first_callback) {
@@ -811,7 +817,6 @@
eb_free_style_buffer(b);
qe_free(&b->saved_data);
- qe_free(&b->priv_data);
qe_free(bp);
}
}
Index: html.c
===================================================================
RCS file: /sources/qemacs/qemacs/html.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -b -r1.34 -r1.35
--- html.c 1 Jun 2014 13:54:59 -0000 1.34
+++ html.c 27 Aug 2015 15:32:28 -0000 1.35
@@ -29,6 +29,7 @@
/* mode state */
typedef struct HTMLState {
+ QEModeData base;
/* default style sheet */
CSSStyleSheet *default_style_sheet;
CSSContext *css_ctx;
@@ -81,11 +82,19 @@
return 0;
}
+static inline HTMLState *html_get_state(EditState *e, int status)
+{
+ return qe_get_buffer_mode_data(e->b, &html_mode, status ? e : NULL);
+}
+
static void recompute_offset(EditState *s)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
RecomputeOffsetData data;
+ if (!(hs = html_get_state(s, 0)))
+ return;
+
data.ctx = hs->css_ctx;
data.wanted_offset = s->offset;
data.closest_offset = 0;
@@ -138,13 +147,16 @@
static void html_display(EditState *s)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
CSSRect cursor_pos;
DirType dirc;
int n, cursor_found, d, ret, sel_start, sel_end;
CSSRect rect;
EditBuffer *b;
+ if (!(hs = html_get_state(s, 0)))
+ return;
+
/* XXX: should be generic ? */
if (hs->last_width != s->width) {
hs->last_width = s->width;
@@ -379,10 +391,13 @@
static void html_scroll_up_down(EditState *s, int dir)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
ScrollContext m1, *m = &m1;
int h;
+ if (!(hs = html_get_state(s, 1)))
+ return;
+
if (!hs->up_to_date)
return;
@@ -491,11 +506,14 @@
static void html_move_up_down1(EditState *s, int dir, int xtarget)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
MoveContext m1, *m = &m1;
CSSRect cursor_pos;
int dirc, offset;
+ if (!(hs = html_get_state(s, 1)))
+ return;
+
/* get the cursor position in the current chunk */
if (!css_get_cursor_pos(hs->css_ctx, hs->top_box, NULL, NULL, NULL,
&cursor_pos, &dirc, s->offset))
@@ -538,7 +556,10 @@
static void html_move_up_down(EditState *s, int dir)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
+
+ if (!(hs = html_get_state(s, 1)))
+ return;
if (!hs->up_to_date)
return;
@@ -586,12 +607,15 @@
/* go to left or right in visual order */
static void html_move_left_right_visual(EditState *s, int dir)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
LeftRightMoveContext m1, *m = &m1;
CSSRect cursor_pos;
int dirc, offset, x0;
CSSBox *box;
+ if (!(hs = html_get_state(s, 1)))
+ return;
+
if (!hs->up_to_date)
return;
@@ -635,12 +659,15 @@
static void html_move_bol_eol(EditState *s, int dir)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
LeftRightMoveContext m1, *m = &m1;
CSSRect cursor_pos;
int dirc, offset, x0, xtarget;
CSSBox *box;
+ if (!(hs = html_get_state(s, 1)))
+ return;
+
if (!hs->up_to_date)
return;
@@ -726,10 +753,13 @@
static void html_mouse_goto(EditState *s, int x, int y)
{
- HTMLState *hs = s->mode_data;
+ HTMLState *hs;
MouseGotoContext m1, *m = &m1;
int offset;
+ if (!(hs = html_get_state(s, 1)))
+ return;
+
if (!hs->up_to_date)
return;
@@ -756,8 +786,9 @@
__unused__ int offset,
__unused__ int size)
{
- EditState *s = opaque;
- HTMLState *hs = s->mode_data;
+ HTMLState *hs = opaque;
+
+ if (hs)
hs->up_to_date = 0;
}
@@ -775,36 +806,49 @@
/* graphical XML/CSS mode init. is_html is TRUE to tell that specific HTML
quirks are needed in the parser. */
-int gxml_mode_init(EditState *s,
- int flags, const char *default_stylesheet)
+int gxml_mode_init(EditBuffer *b, int flags, const char *default_stylesheet)
{
- if (s) {
- HTMLState *hs = s->mode_data;
+ HTMLState *hs = qe_get_buffer_mode_data(b, &html_mode, NULL);
+
+ if (!hs)
+ return -1;
/* XXX: unregister callbacks for s->offset and s->top_offset ? */
- eb_add_callback(s->b, html_callback, s, 0);
+ eb_add_callback(b, html_callback, hs, 0);
hs->parse_flags = flags;
-
load_default_style_sheet(hs, default_stylesheet, flags);
-
hs->up_to_date = 0;
- }
+
return 0;
}
+/* XXX: should keep parsed data for buffer lifetime? */
static int html_mode_init(EditState *s, EditBuffer *b, int flags)
{
- return gxml_mode_init(s, XML_HTML | XML_HTML_SYNTAX | XML_IGNORE_CASE,
+ HTMLState *hs = qe_get_buffer_mode_data(b, &html_mode, NULL);
+
+ if (flags & MODEF_NEWINSTANCE) {
+ if (!hs)
+ return -1;
+ return gxml_mode_init(b, XML_HTML | XML_HTML_SYNTAX | XML_IGNORE_CASE,
html_style);
+ }
+ return 0;
}
static void html_mode_close(EditState *s)
{
- HTMLState *hs = s->mode_data;
- eb_free_callback(s->b, html_callback, s);
+ s->busy = 0; /* make it a buffer flag? */
+}
+
+static void html_mode_free(EditBuffer *b, void *state)
+{
+ HTMLState *hs = state;
- s->busy = 0;
+ eb_free_callback(b, html_callback, hs);
+
+ //s->busy = 0; /* make it a buffer flag? */
css_delete_box(&hs->top_box);
css_delete_document(&hs->css_ctx);
css_free_style_sheet(&hs->default_style_sheet);
@@ -872,10 +916,11 @@
ModeDef html_mode = {
.name = "html",
- .instance_size = sizeof(HTMLState),
+ .buffer_instance_size = sizeof(HTMLState),
.mode_probe = html_mode_probe,
.mode_init = html_mode_init,
.mode_close = html_mode_close,
+ .mode_free = html_mode_free,
.display = html_display,
.move_left_right = html_move_left_right_visual,
.move_up_down = html_move_up_down,
Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.206
retrieving revision 1.207
diff -u -b -r1.206 -r1.207
--- qe.h 26 Aug 2015 22:51:24 -0000 1.206
+++ qe.h 27 Aug 2015 15:32:28 -0000 1.207
@@ -133,6 +133,7 @@
typedef struct QEmacsState QEmacsState;
typedef struct DisplayState DisplayState;
typedef struct ModeProbeData ModeProbeData;
+typedef struct QEModeData QEModeData;
typedef struct ModeDef ModeDef;
typedef struct QETimer QETimer;
typedef struct QEColorizeContext QEColorizeContext;
@@ -883,8 +884,6 @@
const char *data_type_name;
EditBufferDataType *data_type;
void *data_data; /* associated buffer data, used if data_type !=
raw_data */
- void *priv_data; /* buffer polling & private data */
- void (*close)(EditBuffer *); /* called when deleting the buffer */
/* buffer syntax or major mode */
ModeDef *syntax_mode;
@@ -934,6 +933,9 @@
ModeDef *saved_mode;
OWNED u8 *saved_data; /* SAVED_DATA_SIZE bytes */
+ /* list of mode data associated with buffer */
+ OWNED QEModeData *mode_data_list;
+
/* default mode stuff when buffer is detached from window */
int offset;
@@ -1179,7 +1181,7 @@
/* mode specific info */
ModeDef *mode;
- OWNED void *mode_data; /* mode private window based data */
+ OWNED QEModeData *mode_data; /* mode private window based data */
/* state before line n, one short per line */
/* XXX: move this to buffer based mode_data */
@@ -1249,6 +1251,14 @@
EditBuffer *b;
};
+struct QEModeData {
+ QEModeData *next;
+ ModeDef *mode;
+ EditState *s;
+ EditBuffer *b;
+ /* Other mode specific data follows */
+};
+
struct ModeDef {
const char *name;
const char *mode_name;
@@ -1264,12 +1274,15 @@
#define MODEF_MAJOR 0x04
#define MODEF_DATATYPE 0x10
#define MODEF_SHELLPROC 0x20
- int instance_size; /* size of malloced instance */
+#define MODEF_NEWINSTANCE 0x100
+ int buffer_instance_size; /* size of malloced buffer state */
+ int window_instance_size; /* size of malloced window state */
/* return the percentage of confidence */
int (*mode_probe)(ModeDef *m, ModeProbeData *pd);
int (*mode_init)(EditState *s, EditBuffer *b, int flags);
void (*mode_close)(EditState *s);
+ void (*mode_free)(EditBuffer *b, void *state);
/* low level display functions (must be NULL to use text related
functions)*/
@@ -1321,6 +1334,12 @@
#define TTY_GET_FG(color) (((color) >> 4) & 15)
#define TTY_GET_BG(color) (((color) >> 0) & 15)
+QEModeData *qe_create_buffer_mode_data(EditBuffer *b, ModeDef *m);
+void *qe_get_buffer_mode_data(EditBuffer *b, ModeDef *m, EditState *e);
+QEModeData *qe_create_window_mode_data(EditState *s, ModeDef *m);
+void *qe_get_window_mode_data(EditState *e, ModeDef *m, int status);
+int qe_free_mode_data(QEModeData *md);
+
/* from tty.c */
extern unsigned int const *tty_bg_colors;
extern int tty_bg_colors_count;
@@ -1788,7 +1807,7 @@
void edit_display(QEmacsState *qs);
void edit_invalidate(EditState *s);
void display_mode_line(EditState *s);
-void edit_set_mode(EditState *s, ModeDef *m);
+int edit_set_mode(EditState *s, ModeDef *m);
void qe_set_next_mode(EditState *s, int dir, int status);
void do_set_next_mode(EditState *s, int dir);
@@ -2029,8 +2048,8 @@
extern ModeDef html_mode;
-int gxml_mode_init(EditState *s,
- int is_html, const char *default_stylesheet);
+/* flags from libqhtml/css.h */
+int gxml_mode_init(EditBuffer *b, int flags, const char *default_stylesheet);
/* image.c */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs archive.c dired.c image.c shell.c bufed....,
Charlie Gordon <=