summaryrefslogtreecommitdiff
path: root/apps/plugins/SUBDIRS (follow)
Commit message (Expand)AuthorAge
* Build overlay plugins for all targets with PLUGIN_BUFFER <= 0x10000 bytesRafaël Carré2010-05-18
* plugins: changes for targets with small plugin buffer (Clipv1)Rafaël Carré2010-05-18
* plugins: reorder SOURCES conditions to be more readableRafaël Carré2010-05-17
* fft plugin: add touchscreen key-mapping and enable plugin for touchscreen tar...Tomer Shalev2010-02-11
* New plugin: FFT, A frequency analyzer pluginFrank Gevaerts2010-02-10
* Disable DOOM for c200v2, it won't runRafaël Carré2010-01-24
* jpeg,png: Merge user interface code and plugin entry point of the two plugins...Teruaki Kawashima2010-01-18
* New plugin: frotz, a Z-machine interpreter, for playing interactive fiction.Torne Wuff2010-01-17
* FS#10911 - Plugins: Fractals (formerly Mandelbrot) Tomer Shalev2010-01-15
* PDBox: Added iriver H100 to supported targets.Wincent Balin2009-08-05
* Insert pdbox into build system, currently only for H300.Wincent Balin2009-08-04
* Commit FS#10251. Plugins for the YH-820, YH-920, and YH-925 by Jens Erdmann ...Michael Giacomelli2009-08-04
* Add a png viewer pluginFrank Gevaerts2009-07-25
* Don't build mpegplayer on targets with 2MB of RAM or less since it won't runRafaël Carré2009-05-22
* Commit FS#9174: Lua scripting language by Dan EvertonMaurus Cuelenaere2009-05-21
* Build pictureflow using overlay on lowmem targets, support JPEG AA in PF on a...Andrew Mahone2009-05-07
* FS#9901 by Joshua Simmons for the Goban plugin: Goban overlay for the Archos ...Mustapha Senhaji2009-02-20
* Goban plugin: FS#9897 by Joshua SimmonsMustapha Senhaji2009-02-12
* Exclude the philips build too for now, to fix building.Mustapha Senhaji2009-02-11
* Attempt #2 to fix compilations, let's hope this is the last one :)Mustapha Senhaji2009-02-11
* Hopefully fix the red builds.Mustapha Senhaji2009-02-11
* Oops, missed some files in my previous commit.Mustapha Senhaji2009-02-11
* Use LCD_HEIGHT to exclude pacbox from c200 builds instead of target name so t...Marianne Arnold2009-02-01
* Move the monolithic jpeg viewer into its own subdirectory and split it into t...Dave Chapman2008-10-21
* Commit FS#9170 by Dave Hooper. Adds support for profiling on ARM, and fixes ...Michael Giacomelli2008-07-28
* Oops, revert unrelated changesNils Wallménius2008-07-27
* FS#9221 by Christopher Williams fixing a couple of bugs in keyboxNils Wallménius2008-07-27
* Make ZXBox work on the m:robe 100, and fix the linker script and loader to ma...Jens Arnold2008-05-31
* Build the remaining plugins for Gigabeat S and straigten out the fake IRAM in...Michael Sevakis2008-05-02
* m:robe - build doom pluginRobert Kukla2008-04-08
* iAudio M3: Optimised LCD driver, with more/better assembly code. Speedup is ~...Jens Arnold2008-03-25
* Revert accidental tree commit. /me needs a smaller enter key...Jens Arnold2008-03-25
* Cabbiev2 gigabeat background: reduce WPS backdrop filesize by storing it as 2...Jens Arnold2008-03-25
* D2: Enable plugin building (using initial keymaps from FS#8708 by Andreas Mue...Rob Purchase2008-03-22
* Adapted most multi-source plugins to the iAudio M3 keypad and screen. Doom an...Jens Arnold2008-03-22
* M:Robe 100: add button definition/bitmaps to plugins and enable compilationRobert Kukla2008-03-01
* Plugins now enabled and working for the Gigabeat S.Will Robertson2008-02-17
* D2 simulator build (plugins not built yet)Rob Purchase2008-01-22
* m:robe 100:Robert Kukla2008-01-11
* Build some more plugins for M:Robe most work, doom builds and runs if you use...Karl Kurbjun2007-11-02
* enable jpeg, mpegplayer and midiplay on the mr500 (only jpeg is actually usab...Jonathan Gordon2007-10-25
* add PLA keys for mrobe, and dont bother compiling any plugins yetJonathan Gordon2007-10-22
* Chessbox: ported to c200, also simplify the tile size calculation (thanks to ...Marianne Arnold2007-10-19
* Add Makefile to FILES and fix comment.Stepan Moskovchenko2007-09-27
* Some MIDI changes, and add a new musical plugin I'm working on... Not fully d...Stepan Moskovchenko2007-09-27
* Move all of midiplay into its subdir and add a Makefile for it, add header fi...Nils Wallménius2007-09-24
* A few minor cleanups for the Gigabeat SWill Robertson2007-09-22
* Merge the Gigabeat S branch back into trunk. Fingers crossed nothing breaks.Will Robertson2007-09-21
* Enable plugins on the Sansa C200. Large parts taken from patch FS#7749 by Max...Marianne Arnold2007-09-20
* Accept FS #7667 by Alexander Levin with minor fixes by me. Splits the shortcu...Peter D'Hoye2007-09-03
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

/* changes by Thomas Musil IEM KUG Graz Austria 2001 */
/* have to insert gui-objects into editor-list */
/* all changes are labeled with      iemlib      */

#ifdef ROCKBOX
#include "plugin.h"
#include "ctype.h"
#include "../../pdbox.h"
#include "m_pd.h"
#include "g_canvas.h"
#define snprintf rb->snprintf
#else /* ROCKBOX */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "m_pd.h"
#include "s_stuff.h"
#include "g_canvas.h"
#include "t_tk.h"
#endif /* ROCKBOX */

#define LMARGIN 1
#define RMARGIN 1
#define TMARGIN 2
#define BMARGIN 2

#define SEND_FIRST 1
#define SEND_UPDATE 2
#define SEND_CHECK 0

struct _rtext
{
    char *x_buf;
    int x_bufsize;
    int x_selstart;
    int x_selend;
    int x_active;
    int x_dragfrom;
    int x_height;
    int x_drawnwidth;
    int x_drawnheight;
    t_text *x_text;
    t_glist *x_glist;
    char x_tag[50];
    struct _rtext *x_next;
};

t_rtext *rtext_new(t_glist *glist, t_text *who)
{
    t_rtext *x = (t_rtext *)getbytes(sizeof *x);
#ifndef ROCKBOX
    int w = 0, h = 0, indx;
#endif
    x->x_height = -1;
    x->x_text = who;
    x->x_glist = glist;
    x->x_next = glist->gl_editor->e_rtext;
    x->x_selstart = x->x_selend = x->x_active =
    	x->x_drawnwidth = x->x_drawnheight = 0;
    binbuf_gettext(who->te_binbuf, &x->x_buf, &x->x_bufsize);
    glist->gl_editor->e_rtext = x;
#ifdef ROCKBOX
    snprintf(x->x_tag, strlen(x->x_tag),
        ".x%lx.t%lx", (unsigned long) (t_int) glist_getcanvas(x->x_glist),
                      (unsigned long) (t_int) x);
#else /* ROCKBOX */
    sprintf(x->x_tag, ".x%x.t%x", (t_int)glist_getcanvas(x->x_glist),
    	(t_int)x);
#endif /* ROCKBOX */
    return (x);
}

static t_rtext *rtext_entered;

void rtext_free(t_rtext *x)
{
    if (x->x_glist->gl_editor->e_textedfor == x)
    	x->x_glist->gl_editor->e_textedfor = 0;
    if (x->x_glist->gl_editor->e_rtext == x)
    	x->x_glist->gl_editor->e_rtext = x->x_next;
    else
    {
    	t_rtext *e2;
    	for (e2 = x->x_glist->gl_editor->e_rtext; e2; e2 = e2->x_next)
    	    if (e2->x_next == x)
    	{
    	    e2->x_next = x->x_next;
    	    break;
    	}
    }
    if (rtext_entered == x) rtext_entered = 0;
    freebytes(x->x_buf, x->x_bufsize);
    freebytes(x, sizeof *x);
}

char *rtext_gettag(t_rtext *x)
{
    return (x->x_tag);
}

void rtext_gettext(t_rtext *x, char **buf, int *bufsize)
{
    *buf = x->x_buf;
    *bufsize = x->x_bufsize;
}


/* LATER deal with tcl-significant characters */

static int firstone(char *s, int c, int n)
{
    char *s2 = s + n;
    int i = 0;
    while (s != s2)
    {
    	if (*s == c) return (i);
    	i++;
    	s++;
    }
    return (-1);
}

static int lastone(char *s, int c, int n)
{
    char *s2 = s + n;
    while (s2 != s)
    {
    	s2--;
    	n--;
    	if (*s2 == c) return (n);
    }
    return (-1);
}

    /* the following routine computes line breaks and carries out
    some action which could be:
    	SEND_FIRST - draw the box  for the first time
	SEND_UPDATE - redraw the updated box
	otherwise - don't draw, just calculate.
    Called with *widthp and *heightpas coordinates of
    a test point, the routine reports the index of the character found
    there in *indexp.  *widthp and *heightp are set to the width and height
    of the entire text in pixels.
    */

    /* LATER get this and sys_vgui to work together properly,
    	breaking up messages as needed.  As of now, there's
    	a limit of 1950 characters, imposed by sys_vgui(). */
#define UPBUFSIZE 4000
#define BOXWIDTH 60

/* Older (pre-8.3.4) TCL versions handle text selection differently; this
flag is set from the GUI if this happens.  LATER take this out: early 2006? */

extern int sys_oldtclversion;	    	

static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
    int *indexp)
{
#ifndef ROCKBOX
    float dispx, dispy;
#endif
    char tempbuf[UPBUFSIZE], *tp = tempbuf, *bp = x->x_buf;
    int outchars, inchars = x->x_bufsize, nlines = 0, ncolumns = 0,
    	pixwide, pixhigh;
#ifdef ROCKBOX
    int fontwidth = 8, fontheight = 10;
#else
    int font = glist_getfont(x->x_glist);
    int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font);
#endif
    int findx = (*widthp + (fontwidth/2)) / fontwidth,
    	findy = *heightp / fontheight;
    int reportedindex = 0;
#ifndef ROCKBOX
    t_canvas *canvas = glist_getcanvas(x->x_glist);
#endif
    int widthspec = x->x_text->te_width;
    int widthlimit = (widthspec ? widthspec : BOXWIDTH);
    while (inchars)
    {
    	int maxindex = (inchars > widthlimit ? widthlimit : inchars);
    	int eatchar = 1;
    	int foundit = firstone(bp, '\n', maxindex);
    	if (foundit < 0)
    	{
    	    if (inchars > widthlimit)
    	    {
    		foundit = lastone(bp, ' ', maxindex);
    		if (foundit < 0)
    		{
    	    	    foundit = maxindex;
    	    	    eatchar = 0;
    		}
   	    }
   	    else
   	    {
   	    	foundit = inchars;
   	    	eatchar = 0;
   	    }
   	}
	if (nlines == findy)
	{
	    int actualx = (findx < 0 ? 0 :
	    	(findx > foundit ? foundit : findx));
	    *indexp = (bp - x->x_buf) + actualx;
	    reportedindex = 1;
	}
   	strncpy(tp, bp, foundit);
    	tp += foundit;
    	bp += (foundit + eatchar);
    	inchars -= (foundit + eatchar);
    	if (inchars) *tp++ = '\n';
    	if (foundit > ncolumns) ncolumns = foundit;
    	nlines++;
    }
    outchars = tp - tempbuf;
    if (outchars > 1950) outchars = 1950;
    if (!reportedindex)
    	*indexp = outchars;
#ifndef ROCKBOX
    dispx = text_xpix(x->x_text, x->x_glist);
    dispy = text_ypix(x->x_text, x->x_glist);
#endif
    if (nlines < 1) nlines = 1;
    if (!widthspec)
    {
    	while (ncolumns < 3)
    	{
    	    tempbuf[outchars++] = ' ';
    	    ncolumns++;
    	}
    }
    else ncolumns = widthspec;
    pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN);
    pixhigh = nlines * fontheight + (TMARGIN + BMARGIN);

    if (action == SEND_FIRST)
#ifdef ROCKBOX
        ;
#else /* ROCKBOX */
    	sys_vgui("pdtk_text_new .x%x.c %s %f %f {%.*s} %d %s\n",
	    canvas, x->x_tag,
	    dispx + LMARGIN, dispy + TMARGIN,
	    outchars, tempbuf, sys_hostfontsize(font),
	    (glist_isselected(x->x_glist,
	    	&x->x_glist->gl_gobj)? "blue" : "black"));
#endif /* ROCKBOX */
    else if (action == SEND_UPDATE)
    {
#ifndef ROCKBOX
    	sys_vgui("pdtk_text_set .x%x.c %s {%.*s}\n",
    	    canvas, x->x_tag, outchars, tempbuf);
#endif
    	if (pixwide != x->x_drawnwidth || pixhigh != x->x_drawnheight) 
	    text_drawborder(x->x_text, x->x_glist, x->x_tag,
	    	pixwide, pixhigh, 0);
    	if (x->x_active)
	{
    	    if (x->x_selend > x->x_selstart)
	    {
#ifndef ROCKBOX
    		sys_vgui(".x%x.c select from %s %d\n", canvas, 
    	    	    x->x_tag, x->x_selstart);
    		sys_vgui(".x%x.c select to %s %d\n", canvas, 
    	    	    x->x_tag, x->x_selend + (sys_oldtclversion ? 0 : -1));
	    	sys_vgui(".x%x.c focus \"\"\n", canvas);	
#endif
    	    }
	    else
	    {
#ifndef ROCKBOX
    		sys_vgui(".x%x.c select clear\n", canvas);
	    	sys_vgui(".x%x.c icursor %s %d\n", canvas, x->x_tag,
		    x->x_selstart);
	    	sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag);	
#endif
	    }
	}
    }
    x->x_drawnwidth = pixwide;
    x->x_drawnheight = pixhigh;
    
    *widthp = pixwide;
    *heightp = pixhigh;
}

void rtext_retext(t_rtext *x)
{
    int w = 0, h = 0, indx;
    t_text *text = x->x_text;
    t_freebytes(x->x_buf, x->x_bufsize);
    binbuf_gettext(text->te_binbuf, &x->x_buf, &x->x_bufsize);
    	/* special case: for number boxes, try to pare the number down
	to the specified width of the box. */
    if (text->te_width > 0 && text->te_type == T_ATOM &&
    	x->x_bufsize > text->te_width)
    {
    	t_atom *atomp = binbuf_getvec(text->te_binbuf);
	int natom = binbuf_getnatom(text->te_binbuf);
	int bufsize = x->x_bufsize;
	if (natom == 1 && atomp->a_type == A_FLOAT)
	{
	    	/* try to reduce size by dropping decimal digits */
	    int wantreduce = bufsize - text->te_width;
	    char *decimal = 0, *nextchar, *ebuf = x->x_buf + bufsize,
		*s1, *s2;
#ifndef ROCKBOX
	    int ndecimals;
#endif
	    for (decimal = x->x_buf; decimal < ebuf; decimal++)
	    	if (*decimal == '.')
		    break;
	    if (decimal >= ebuf)
	    	goto giveup;
	    for (nextchar = decimal + 1; nextchar < ebuf; nextchar++)
	    	if (*nextchar < '0' || *nextchar > '9')
		    break;
	    if (nextchar - decimal - 1 < wantreduce)
	    	goto giveup;
	    for (s1 = nextchar - wantreduce, s2 = s1 + wantreduce;
	    	s2 < ebuf; s1++, s2++)
		    *s1 = *s2;
	    t_resizebytes(x->x_buf, bufsize, text->te_width);
	    bufsize = text->te_width;
	    goto done;
	giveup:
		/* give up and bash it to "+" or "-" */
	    x->x_buf[0] = (atomp->a_w.w_float < 0 ? '-' : '+');
	    t_resizebytes(x->x_buf, bufsize, 1);
	    bufsize = 1;
	}
	else if (bufsize > text->te_width)
	{
	    x->x_buf[text->te_width - 1] = '>';
	    t_resizebytes(x->x_buf, bufsize, text->te_width);
	    bufsize = text->te_width;
	}
    done:
	x->x_bufsize = bufsize;
    }
    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}

/* find the rtext that goes with a text item */
t_rtext *glist_findrtext(t_glist *gl, t_text *who)
{
    t_rtext *x = gl->gl_editor->e_rtext;
    while (x && x->x_text != who) x = x->x_next;
    if (!x) bug("glist_findrtext");
    return (x);
}

int rtext_width(t_rtext *x)
{
    int w = 0, h = 0, indx;
    rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
    return (w);
}

int rtext_height(t_rtext *x)
{
    int w = 0, h = 0, indx;
    rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
    return (h);
}

void rtext_draw(t_rtext *x)
{
    int w = 0, h = 0, indx;
    rtext_senditup(x, SEND_FIRST, &w, &h, &indx);
}

void rtext_erase(t_rtext *x)
{
#ifdef ROCKBOX
    (void) x;
#else
    sys_vgui(".x%x.c delete %s\n", glist_getcanvas(x->x_glist), x->x_tag);
#endif
}

void rtext_displace(t_rtext *x, int dx, int dy)
{
#ifdef ROCKBOX
    (void) x;
    (void) dx;
    (void) dy;
#else /* ROCKBOX */
    sys_vgui(".x%x.c move %s %d %d\n", glist_getcanvas(x->x_glist), 
    	x->x_tag, dx, dy);
#endif /* ROCKBOX */
}

void rtext_select(t_rtext *x, int state)
{
    t_glist *glist = x->x_glist;
    t_canvas *canvas = glist_getcanvas(glist);
#ifdef ROCKBOX
    (void) state;
#else /* ROCKBOX */
    sys_vgui(".x%x.c itemconfigure %s -fill %s\n", canvas, 
    	x->x_tag, (state? "blue" : "black"));
#endif /* ROCKBOX */
    canvas_editing = canvas;
}

void rtext_activate(t_rtext *x, int state)
{
    int w = 0, h = 0, indx;
    t_glist *glist = x->x_glist;
#ifndef ROCKBOX
    t_canvas *canvas = glist_getcanvas(glist);
#endif
    if (state)
    {
#ifndef ROCKBOX
	sys_vgui(".x%x.c focus %s\n", canvas, x->x_tag);
#endif
    	glist->gl_editor->e_textedfor = x;
    	glist->gl_editor->e_textdirty = 0;
	x->x_dragfrom = x->x_selstart = 0;
	x->x_selend = x->x_bufsize;
	x->x_active = 1;
    }
    else
    {
#ifndef ROCKBOX
    	sys_vgui("selection clear .x%x.c\n", canvas);
	sys_vgui(".x%x.c focus \"\"\n", canvas);
#endif
    	if (glist->gl_editor->e_textedfor == x)
    	    glist->gl_editor->e_textedfor = 0;
	x->x_active = 0;
    }
    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}

void rtext_key(t_rtext *x, int keynum, t_symbol *keysym)
{
    int w = 0, h = 0, indx, i, newsize, ndel;
#ifndef ROCKBOX
    char *s1, *s2;
#endif
    if (keynum)
    {
    	int n = keynum;
	if (n == '\r') n = '\n';
	if (n == '\b')	/* backspace */
	{
	    	    /* LATER delete the box if all text is selected...
		    this causes reentrancy problems now. */
    	    /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize))
    	    {
    		....
    	    } */
    	    if (x->x_selstart && (x->x_selstart == x->x_selend))
		x->x_selstart--;
	}
	else if (n == 127)	/* delete */
    	{
	    if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend))
		x->x_selend++;
	}
	
	ndel = x->x_selend - x->x_selstart;
	for (i = x->x_selend; i < x->x_bufsize; i++)
    	    x->x_buf[i- ndel] = x->x_buf[i];
	newsize = x->x_bufsize - ndel;
	x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
	x->x_bufsize = newsize;

	if (n == '\n' || isprint(n))
	{
    	    newsize = x->x_bufsize+1;
    	    x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize);
	    for (i = x->x_bufsize; i > x->x_selstart; i--)
		x->x_buf[i] = x->x_buf[i-1];
    	    x->x_buf[x->x_selstart] = n;
    	    x->x_bufsize = newsize;
	    x->x_selstart = x->x_selstart + 1;
	}
	x->x_selend = x->x_selstart;
	x->x_glist->gl_editor->e_textdirty = 1;
    }
    else if (!strcmp(keysym->s_name, "Right"))
    {
    	if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize)
	    x->x_selend = x->x_selstart = x->x_selstart + 1;
	else
	    x->x_selstart = x->x_selend;
    }
    else if (!strcmp(keysym->s_name, "Left"))
    {
    	if (x->x_selend == x->x_selstart && x->x_selstart > 0)
	    x->x_selend = x->x_selstart = x->x_selstart - 1;
	else
	    x->x_selend = x->x_selstart;
    }
    	/* this should be improved...  life's too short */
    else if (!strcmp(keysym->s_name, "Up"))
    {
	if (x->x_selstart)
	    x->x_selstart--;
    	while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
	    x->x_selstart--;
	x->x_selend = x->x_selstart;
    }
    else if (!strcmp(keysym->s_name, "Down"))
    {
    	while (x->x_selend < x->x_bufsize &&
	    x->x_buf[x->x_selend] != '\n')
	    x->x_selend++;
	if (x->x_selend < x->x_bufsize)
	    x->x_selend++;
	x->x_selstart = x->x_selend;
    }
    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}

void rtext_mouse(t_rtext *x, int xval, int yval, int flag)
{
    int w = xval, h = yval, indx;
    rtext_senditup(x, SEND_CHECK, &w, &h, &indx);
    if (flag == RTEXT_DOWN)
    {
    	x->x_dragfrom = x->x_selstart = x->x_selend = indx;
    }
    else if (flag == RTEXT_SHIFT)
    {
    	if (indx * 2 > x->x_selstart + x->x_selend)
	    x->x_dragfrom = x->x_selstart, x->x_selend = indx;
    	else
	    x->x_dragfrom = x->x_selend, x->x_selstart = indx;
    }
    else if (flag == RTEXT_DRAG)
    {
    	x->x_selstart = (x->x_dragfrom < indx ? x->x_dragfrom : indx);
    	x->x_selend = (x->x_dragfrom > indx ? x->x_dragfrom : indx);
    }
    rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
}