Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (2)
  • Deucе's avatar
    Implement disabled text for RIP. · b9d43a4c
    Deucе authored
    We still need to pass ANSI through to the parser though because
    Synchronet goes apeshit if it doesn't get a response to a location
    request... it tries twice and eats any data it receives that isn't
    a valid position report, which obviously breaks menus.
    
    It's also very weird that on Booch's BBS at least it's sent during
    the main menu display rather than just on answering.  Not sure why
    this is, but it means we can't implement the RIP requirement of
    "ignoring all non-RIPscrip bytes" with a zero window without digging
    deep into Synchronet guts.
    b9d43a4c
  • Deucе's avatar
    More improvements for Black Flag... · 901cef17
    Deucе authored
    Pretend we are RipTel v3.
    Implement $PCB$
    Implement click actions
    Fix M areas.
    901cef17
...@@ -1194,8 +1194,8 @@ void bitmap_clrscr(void) ...@@ -1194,8 +1194,8 @@ void bitmap_clrscr(void)
pthread_mutex_lock(&blinker_lock); pthread_mutex_lock(&blinker_lock);
pthread_mutex_lock(&vstatlock); pthread_mutex_lock(&vstatlock);
vmem_ptr = get_vmem(&vstat); vmem_ptr = get_vmem(&vstat);
for(y=cio_textinfo.wintop-1; y<cio_textinfo.winbottom; y++) { for(y = cio_textinfo.wintop-1; y < cio_textinfo.winbottom && y < vstat.rows; y++) {
for(x=cio_textinfo.winleft-1; x<cio_textinfo.winright; x++) { for(x=cio_textinfo.winleft-1; x<cio_textinfo.winright && x < vstat.cols; x++) {
set_vmem_cell(vmem_ptr, y*cio_textinfo.screenwidth+x, fill, ciolib_fg, ciolib_bg); set_vmem_cell(vmem_ptr, y*cio_textinfo.screenwidth+x, fill, ciolib_fg, ciolib_bg);
bitmap_draw_one_char(x+1, y+1); bitmap_draw_one_char(x+1, y+1);
} }
......
...@@ -69,6 +69,17 @@ enum rip_state { ...@@ -69,6 +69,17 @@ enum rip_state {
,RIP_STATE_FLUSHING // Magical state ,RIP_STATE_FLUSHING // Magical state
}; };
enum ansi_state {
ANSI_STATE_NONE,
ANSI_STATE_GOT_ESC,
ANSI_STATE_GOT_CSI,
ANSI_STATE_GOT_STRING,
ANSI_STATE_GOT_LIMITED_STRING,
ANSI_STATE_GOT_ESC_IN_STRING,
ANSI_STATE_GOT_ESC_IN_LIMITED_STRING,
ANSI_STATE_GOT_IB,
};
enum rip_line_thickness { enum rip_line_thickness {
RIP_LINE_THICK_THIN = 1 RIP_LINE_THICK_THIN = 1
,RIP_LINE_THICK_THICK = 3 ,RIP_LINE_THICK_THICK = 3
...@@ -251,6 +262,10 @@ static struct { ...@@ -251,6 +262,10 @@ static struct {
int *ymap; int *ymap;
int *xunmap; int *xunmap;
int *yunmap; int *yunmap;
bool text_disabled;
enum ansi_state ansi_state;
int clipx;
int clipy;
} rip = { } rip = {
RIP_STATE_BOL, RIP_STATE_BOL,
RIP_STATE_FLUSHING, RIP_STATE_FLUSHING,
...@@ -279,6 +294,10 @@ static struct { ...@@ -279,6 +294,10 @@ static struct {
350, 350,
true, true,
NULL, NULL, NULL, NULL,
NULL, NULL,
false,
ANSI_STATE_NONE,
0, 0,
}; };
static const uint16_t rip_line_patterns[4] = { static const uint16_t rip_line_patterns[4] = {
...@@ -7181,7 +7200,20 @@ static void draw_line(int x1, int y1, int x2, int y2); ...@@ -7181,7 +7200,20 @@ static void draw_line(int x1, int y1, int x2, int y2);
static void reinit_screen(enum text_modes mode, uint8_t *font, int fontx, int fonty); static void reinit_screen(enum text_modes mode, uint8_t *font, int fontx, int fonty);
static bool no_viewport(void); static bool no_viewport(void);
static const char ripver[] = "RIPSCRIP015410"; //static const char ripver[] = "RIPSCRIP015410";
static const char ripver[] = "RIPSCRIP030001";
#define RIP_MOUSE_EVENT_NONE 0
#define RIP_MOUSE_EVENT_TEXT 1
#define RIP_MOUSE_EVENT_GRAPHICS 2
struct rip_mouse_event {
int x;
int y;
uint8_t buttons;
uint8_t type;
};
static struct rip_mouse_event rip_mouse_event;
static const struct builtin_rip_variable builtins[] = { static const struct builtin_rip_variable builtins[] = {
{"ADOW", rv_date, NULL}, // Abbreviated Day of Week {"ADOW", rv_date, NULL}, // Abbreviated Day of Week
...@@ -7319,7 +7351,7 @@ get_text_variable(const char * const var) ...@@ -7319,7 +7351,7 @@ get_text_variable(const char * const var)
} }
vardef = bsearch(var, builtins, sizeof(builtins) / sizeof(builtins[0]), sizeof(builtins[0]), bicmp); vardef = bsearch(var, builtins, sizeof(builtins) / sizeof(builtins[0]), sizeof(builtins[0]), bicmp);
if (vardef == NULL) { if (vardef == NULL) {
puts("TODO: User variables"); printf("TODO: User variables (%s)\n", var);
return(calloc(1, 1)); return(calloc(1, 1));
} }
return vardef->func(var, vardef->data); return vardef->func(var, vardef->data);
...@@ -7453,7 +7485,7 @@ rv_time(const char * const var, const void * const data) ...@@ -7453,7 +7485,7 @@ rv_time(const char * const var, const void * const data)
return strdup(str); return strdup(str);
} }
} }
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
...@@ -7504,54 +7536,57 @@ rv_sound(const char * const var, const void * const data) ...@@ -7504,54 +7536,57 @@ rv_sound(const char * const var, const void * const data)
xptone(i, 2, WAVE_SHAPE_SINE); xptone(i, 2, WAVE_SHAPE_SINE);
return NULL; return NULL;
} }
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
static char * static char *
rv_mouse(const char * const var, const void * const data) rv_mouse(const char * const var, const void * const data)
{ {
int x,y;
uint8_t but;
char str[128]; char str[128];
int fwidth = 4;
switch (rip_mouse_event.type) {
case RIP_MOUSE_EVENT_NONE:
mousestate_res(&rip_mouse_event.x, &rip_mouse_event.y, &rip_mouse_event.buttons);
break;
case RIP_MOUSE_EVENT_TEXT:
fwidth = 2;
break;
}
switch (var[0]) { switch (var[0]) {
case 'X': case 'X':
switch(var[1]) { switch(var[1]) {
case 0: case 0:
mousestate_res(&x, NULL, NULL); snprintf(str, sizeof(str), "%0*d", fwidth, rip_mouse_event.x);
snprintf(str, sizeof(str), "%04d", x);
return strdup(str); return strdup(str);
case 'Y': case 'Y':
switch(var[2]) { switch(var[2]) {
case 0: case 0:
mousestate_res(&x, &y, NULL); snprintf(str, sizeof(str), "%0*x:%0*x", fwidth, rip_mouse_event.x, fwidth, rip_mouse_event.y);
snprintf(str, sizeof(str), "%04x:%04x", x, y);
return strdup(str); return strdup(str);
case 'M': case 'M':
mousestate_res(&x, &y, &but); snprintf(str, sizeof(str), "%0*x:%0*x:%d%d%d", fwidth, rip_mouse_event.x, fwidth, rip_mouse_event.y, rip_mouse_event.buttons & 1, rip_mouse_event.buttons >> 1 & 1, rip_mouse_event.buttons >> 2 & 1);
snprintf(str, sizeof(str), "%04x:%04x:%d%d%d", x, y, but & 1, but >> 1 & 1, but >> 2 & 1);
return strdup(str); return strdup(str);
} }
break; break;
} }
break; break;
case 'Y': case 'Y':
mousestate_res(NULL, &y, NULL); snprintf(str, sizeof(str), "%0*d", fwidth, rip_mouse_event.y);
snprintf(str, sizeof(str), "%04d", y);
return strdup(str); return strdup(str);
case 'M': case 'M':
switch(var[1]) { switch(var[1]) {
case 0: case 0:
mousestate_res(NULL, NULL, &but); snprintf(str, sizeof(str), "%d%d%d", rip_mouse_event.buttons & 1, rip_mouse_event.buttons >> 1 & 1, rip_mouse_event.buttons >> 2 & 1);
snprintf(str, sizeof(str), "%d%d%d", but & 1, but >> 1 & 1, but >> 2 & 1);
return strdup(str); return strdup(str);
case 'S': case 'S':
return strdup("YES"); return strdup("YES");
} }
break; break;
} }
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
...@@ -7576,6 +7611,8 @@ rv_reset(const char * const var, const void * const data) ...@@ -7576,6 +7611,8 @@ rv_reset(const char * const var, const void * const data)
rip.line_width = 0; rip.line_width = 0;
rip.curstype = _NORMALCURSOR; rip.curstype = _NORMALCURSOR;
rip.borders = true; rip.borders = true;
rip.text_disabled = false;
rip.ansi_state = ANSI_STATE_NONE;
_setcursortype(rip.curstype); _setcursortype(rip.curstype);
reinit_screen(C80X43, NULL, 8, 8); reinit_screen(C80X43, NULL, 8, 8);
memcpy(&curr_ega_palette, &default_ega_palette, sizeof(curr_ega_palette)); memcpy(&curr_ega_palette, &default_ega_palette, sizeof(curr_ega_palette));
...@@ -7601,14 +7638,20 @@ rv_reset(const char * const var, const void * const data) ...@@ -7601,14 +7638,20 @@ rv_reset(const char * const var, const void * const data)
static char * static char *
rv_save(const char * const var, const void * const data) rv_save(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); if (strcmp(var, "SMF")) {
// Save mouse fields...
}
printf("TODO: Save RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
static char * static char *
rv_restore(const char * const var, const void * const data) rv_restore(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); if (strcmp(var, "RMF")) {
// Restore mouse fields...
}
printf("TODO: Restore RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
...@@ -7751,7 +7794,7 @@ rv_erase(const char * const var, const void * const data) ...@@ -7751,7 +7794,7 @@ rv_erase(const char * const var, const void * const data)
cterm_gotoxy(cterm, 1, 1); cterm_gotoxy(cterm, 1, 1);
return NULL; return NULL;
} }
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
...@@ -7765,14 +7808,14 @@ rv_mouse_kill(const char * const var, const void * const data) ...@@ -7765,14 +7808,14 @@ rv_mouse_kill(const char * const var, const void * const data)
static char * static char *
rv_disable(const char * const var, const void * const data) rv_disable(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
static char * static char *
rv_termstat(const char * const var, const void * const data) rv_termstat(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
...@@ -7858,21 +7901,22 @@ rv_termset(const char * const var, const void * const data) ...@@ -7858,21 +7901,22 @@ rv_termset(const char * const var, const void * const data)
static char * static char *
rv_hotkey(const char * const var, const void * const data) rv_hotkey(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
static char * static char *
rv_exploit(const char * const var, const void * const data) rv_exploit(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); printf("TODO: RIP Variables (%s)\n", var);
return NULL; return NULL;
} }
static char * static char *
rv_paste(const char * const var, const void * const data) rv_paste(const char * const var, const void * const data)
{ {
puts("TODO: RIP Variables"); if (rip.clipboard)
setpixels(rip.clipx, rip.clipy, rip.clipx + rip.clipboard->width - 1, rip.clipy + rip.clipboard->height - 1, 0, 0, rip.clipboard, NULL);
return NULL; return NULL;
} }
...@@ -10749,9 +10793,12 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs) ...@@ -10749,9 +10793,12 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
handled = true; handled = true;
GET_XY2(); GET_XY2();
if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) { if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) {
puts("TODO: Disable text output"); rip.text_disabled = true;
rip.ansi_state = ANSI_STATE_NONE;
break; break;
} }
rip.text_disabled = false;
arg1 = parse_mega(&args[8], 1); arg1 = parse_mega(&args[8], 1);
if (arg1 < 0 || arg1 > 1) if (arg1 < 0 || arg1 > 1)
break; break;
...@@ -10907,12 +10954,17 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs) ...@@ -10907,12 +10954,17 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
handle_command_str(&args[4]); handle_command_str(&args[4]);
break; break;
case 1: case 1:
free(rip.graphics_click); FREE_AND_NULL(rip.graphics_click);
rip.graphics_click = strdup(&args[4]); if (strcmp(&args[4], "$OFF$"))
rip.graphics_click = strdup(&args[4]);
break; break;
case 2: case 2:
free(rip.text_click); FREE_AND_NULL(rip.text_click);
rip.text_click = strdup(&args[4]); if (strcmp(&args[4], "$OFF$"))
rip.text_click = strdup(&args[4]);
break;
default:
printf("Unhandled QUERY type %d\n", arg1);
break; break;
} }
break; break;
...@@ -11543,6 +11595,8 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs) ...@@ -11543,6 +11595,8 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
freepixels(rip.clipboard); freepixels(rip.clipboard);
gettextinfo(&ti); gettextinfo(&ti);
rip.clipboard = getpixels(x1 + rip.viewport.sx, y1 + rip.viewport.sy, x2 + rip.viewport.sx, y2 + rip.viewport.sy, false); rip.clipboard = getpixels(x1 + rip.viewport.sx, y1 + rip.viewport.sy, x2 + rip.viewport.sx, y2 + rip.viewport.sy, false);
rip.clipx = x1 + rip.viewport.sx;
rip.clipy = y1 + rip.viewport.sy;
break; break;
case 'D': // RIP_DEFINE !|1D <flags> <res> <text> case 'D': // RIP_DEFINE !|1D <flags> <res> <text>
/* This command is used to create a text variable on the Client system /* This command is used to create a text variable on the Client system
...@@ -11938,14 +11992,14 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs) ...@@ -11938,14 +11992,14 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
x1 = parse_mega(&args[2], 2); x1 = parse_mega(&args[2], 2);
if (x1 < 0) if (x1 < 0)
break; break;
x2 = parse_mega(&args[4], 2); y1 = parse_mega(&args[4], 2);
if (y1 < 0)
break;
x2 = parse_mega(&args[6], 2);
if (x2 < 0) if (x2 < 0)
break; break;
if (x2 > rip.viewport.ex - rip.viewport.sx) if (x2 > rip.viewport.ex - rip.viewport.sx)
break; break;
y1 = parse_mega(&args[6], 2);
if (y1 < 0)
break;
y2 = parse_mega(&args[8], 2); y2 = parse_mega(&args[8], 2);
if (y2 < 0) if (y2 < 0)
break; break;
...@@ -13073,6 +13127,92 @@ pendingcmp(const char *str, const BYTE *buf) ...@@ -13073,6 +13127,92 @@ pendingcmp(const char *str, const BYTE *buf)
return 0; return 0;
} }
/*
* This strips out everything except valid ANSI and returns the
* new size.
*/
size_t
ansi_only(BYTE* buf, unsigned count)
{
BYTE* out = buf;
unsigned i;
for (i = 0; i < count; i++) {
switch (rip.ansi_state) {
case ANSI_STATE_NONE:
if (buf[i] == '\x1b') {
*(out++) = buf[i];
rip.ansi_state = ANSI_STATE_GOT_ESC;
}
break;
case ANSI_STATE_GOT_ESC:
*(out++) = buf[i];
if (buf[i] < '0' || buf[i] > '~') {
rip.ansi_state = ANSI_STATE_NONE;
break;
}
switch (buf[i]) {
case 'X':
rip.ansi_state = ANSI_STATE_GOT_STRING;
break;
case 'P':
case ']':
case '^':
case '_':
rip.ansi_state = ANSI_STATE_GOT_LIMITED_STRING;
break;
case '[':
rip.ansi_state = ANSI_STATE_GOT_CSI;
break;
default:
rip.ansi_state = ANSI_STATE_NONE;
break;
}
break;
case ANSI_STATE_GOT_LIMITED_STRING:
*(out++) = buf[i];
if (buf[i] == '\x1b') {
rip.ansi_state = ANSI_STATE_GOT_ESC_IN_STRING;
break;
}
if (buf[i] < 0x08 || (buf[i] > 0x0d && buf[i] < 0x20) || (buf[i] > 0x7e)) {
rip.ansi_state = ANSI_STATE_NONE;
break;
}
case ANSI_STATE_GOT_ESC_IN_LIMITED_STRING:
*(out++) = buf[i];
rip.ansi_state = ANSI_STATE_NONE;
break;
case ANSI_STATE_GOT_ESC_IN_STRING:
*(out++) = buf[i];
if (buf[i] == 'X' || buf[i] == '\\')
rip.ansi_state = ANSI_STATE_NONE;
break;
case ANSI_STATE_GOT_STRING:
*(out++) = buf[i];
if (buf[i] == '\x1b')
rip.ansi_state = ANSI_STATE_GOT_ESC_IN_STRING;
break;
case ANSI_STATE_GOT_CSI:
*(out++) = buf[i];
if (buf[i] >= '@' && buf[i] <= '~')
rip.ansi_state = ANSI_STATE_NONE;
else if(buf[i] >= ' ' && buf[i] <= '/')
rip.ansi_state = ANSI_STATE_GOT_IB;
else if(buf[i] < '0' || buf[i] > '?')
rip.ansi_state = ANSI_STATE_NONE;
break;
case ANSI_STATE_GOT_IB:
if(buf[i] < '0' || buf[i] > '?')
rip.ansi_state = ANSI_STATE_NONE;
else if(buf[i] < ' ' || buf[i] > '/')
rip.ansi_state = ANSI_STATE_NONE;
break;
}
}
return out - buf;
}
// This may end up stuffing up to three bytes into the buffer... // This may end up stuffing up to three bytes into the buffer...
size_t size_t
parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen) parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen)
...@@ -13350,6 +13490,8 @@ parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen) ...@@ -13350,6 +13490,8 @@ parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen)
memcpy(origbuf, buf, rip_start); memcpy(origbuf, buf, rip_start);
free(buf); free(buf);
} }
if (rip.text_disabled)
return ansi_only(origbuf, rip_start);
return rip_start; return rip_start;
} }
// Everything is fine... // Everything is fine...
...@@ -13357,12 +13499,18 @@ parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen) ...@@ -13357,12 +13499,18 @@ parse_rip(BYTE *origbuf, unsigned blen, unsigned maxlen)
memcpy(origbuf, buf, blen); memcpy(origbuf, buf, blen);
free(buf); free(buf);
} }
if (rip.text_disabled)
return ansi_only(origbuf, blen);
return blen; return blen;
} }
void void
init_rip(int enabled) init_rip(int enabled)
{ {
FREE_AND_NULL(rip.xmap);
FREE_AND_NULL(rip.ymap);
FREE_AND_NULL(rip.xunmap);
FREE_AND_NULL(rip.yunmap);
memset(&rip, 0, sizeof(rip)); memset(&rip, 0, sizeof(rip));
rip.state = RIP_STATE_BOL; rip.state = RIP_STATE_BOL;
rip.newstate = RIP_STATE_FLUSHING; rip.newstate = RIP_STATE_FLUSHING;
...@@ -13386,10 +13534,6 @@ init_rip(int enabled) ...@@ -13386,10 +13534,6 @@ init_rip(int enabled)
rip.x_max = 640; rip.x_max = 640;
rip.y_dim = 350; rip.y_dim = 350;
rip.y_max = 350; rip.y_max = 350;
FREE_AND_NULL(rip.xmap);
FREE_AND_NULL(rip.ymap);
FREE_AND_NULL(rip.xunmap);
FREE_AND_NULL(rip.yunmap);
pending_len = 0; pending_len = 0;
if (pending) if (pending)
...@@ -13460,15 +13604,9 @@ rip_getch(void) ...@@ -13460,15 +13604,9 @@ rip_getch(void)
hold_update = false; hold_update = false;
struct mouse_field *pressed; struct mouse_field *pressed;
if (rip.enabled == false) {
ch = getch();
if(ch==0 || ch==0xe0)
ch |= getch() << 8;
return ch;
}
if (ripbuf) { if (ripbuf) {
ch = ripbuf[ripbufpos++]; ch = ripbuf[ripbufpos++];
if (ripbuf[ripbufpos] == 0) { if (ripbufpos == ripbuf_pos) {
free(ripbuf); free(ripbuf);
ripbuf = NULL; ripbuf = NULL;
ripbuf_size = 0; ripbuf_size = 0;
...@@ -13477,6 +13615,12 @@ rip_getch(void) ...@@ -13477,6 +13615,12 @@ rip_getch(void)
} }
return ch; return ch;
} }
if (rip.enabled == false) {
ch = getch();
if(ch==0 || ch==0xe0)
ch |= getch() << 8;
return ch;
}
gotoxy(wherex(), wherey()); gotoxy(wherex(), wherey());
ch = getch(); ch = getch();
...@@ -13557,7 +13701,30 @@ rip_getch(void) ...@@ -13557,7 +13701,30 @@ rip_getch(void)
} }
} }
else { else {
puts("TODO: Check graphics/text clicks"); if (rip.text_click) {
if (mevent.endx >= cterm->left_margin - 1 && mevent.endx <= cterm->right_margin - 1
&& mevent.endy >= cterm->top_margin - 1 && mevent.endy <= cterm->bottom_margin - 1) {
rip_mouse_event.x = mevent.endx;
rip_mouse_event.y = mevent.endy;
rip_mouse_event.buttons = mevent.bstate | 1;
mousestate(&rip_mouse_event.x, &rip_mouse_event.y, &rip_mouse_event.buttons);
rip_mouse_event.type = RIP_MOUSE_EVENT_TEXT;
handle_command_str(rip.text_click);
rip_mouse_event.type = RIP_MOUSE_EVENT_NONE;
}
}
if (rip.graphics_click) {
if (mevent.endx_res >= rip.viewport.sx && mevent.endx_res <= rip.viewport.ex
&& mevent.endy_res >= rip.viewport.sy && mevent.endy_res <= rip.viewport.ey) {
rip_mouse_event.x = mevent.endx_res;
rip_mouse_event.y = mevent.endy_res;
rip_mouse_event.buttons = mevent.bstate | 1;
mousestate_res(&rip_mouse_event.x, &rip_mouse_event.y, &rip_mouse_event.buttons);
rip_mouse_event.type = RIP_MOUSE_EVENT_GRAPHICS;
handle_command_str(rip.graphics_click);
rip_mouse_event.type = RIP_MOUSE_EVENT_NONE;
}
}
} }
} }
} }
......
...@@ -756,7 +756,8 @@ BOOL xptone_close_locked(void) ...@@ -756,7 +756,8 @@ BOOL xptone_close_locked(void)
#ifdef WITH_PULSEAUDIO #ifdef WITH_PULSEAUDIO
if(handle_type==SOUND_DEVICE_PULSEAUDIO) { if(handle_type==SOUND_DEVICE_PULSEAUDIO) {
pu_api->simple_free(pu_handle); if (pu_handle)
pu_api->simple_free(pu_handle);
pu_handle = NULL; pu_handle = NULL;
} }
#endif #endif
......