Esempio n. 1
0
File: main.c Progetto: hiciu/ekg2
/*
 * logs_session_var_changed()
 *
 * "session-variable-changed" handler
 */
static QUERY(logs_session_var_changed) {
	char *session	= *(va_arg(ap, char**));
	char *var	= *(va_arg(ap, char**));
	int i;

	if (!logs_logs || (0 == logs_logs->len))
		return 0;

	if (!xstrcmp(var, "log_formats")) {
		session_t *s = session_find(session);
		int newformat = logs_log_format(s);

		debug_function("logs_session_var_changed() s=%s, %s=%s\n", session, var, session_get(s, var));

		for (i = logs_logs->len - 1; 0 <= i; i--) {
			logs_log_t *ll = g_ptr_array_index(logs_logs, i);
			if (LOG_FORMAT_RAW == ll->format) continue;
			if (xstrcmp(ll->session, session)) continue;
			if (ll->format != newformat)
				logs_log_reopen(ll);
		}
	}

	return 0;
}
Esempio n. 2
0
/* zwraca watcha */
static watch_t *jabber_dcc_init(int port) {
	struct sockaddr_in sin;
	int fd;

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		debug_error("jabber_dcc_init() socket() FAILED (%s)\n", strerror(errno));
		return NULL;
	}

	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_port = g_htons(port);

	while (bind(fd, (struct sockaddr *) &sin, sizeof(struct sockaddr_in))) {
		debug_error("jabber_dcc_init() bind() port: %d FAILED (%s)\n", port, strerror(errno));
		port++;
		if (port > 65535) {
			close(fd);
			return NULL;
		}

		sin.sin_port = g_htons(port);
	}
	if (listen(fd, 10)) {
		debug_error("jabber_dcc_init() listen() FAILED (%s)\n", strerror(errno));
		close(fd);
		return NULL;
	}
	debug_function("jabber_dcc_init() SUCCESSED fd:%d port:%d\n", fd, port);

	jabber_dcc_port = port;
	jabber_dcc_fd	= fd;
	return watch_add(&jabber_plugin, fd, WATCH_READ, jabber_dcc_handle_accept, NULL);
}
Esempio n. 3
0
File: main.c Progetto: hiciu/ekg2
/*
 * logs_day_changed()
 *
 * "day-changed" handler
 */
static QUERY(logs_day_changed) {
	struct tm *now	= *(va_arg(ap, struct tm**));
	struct tm *old	= *(va_arg(ap, struct tm**));
	int i;
	gboolean dfmt;

	if (!logs_logs)
		return 0;

	debug_function("logs_day_changed()\n");

	dfmt =	((now->tm_year != old->tm_year) && xstrstr(config_logs_path, "%Y")) ||
		((now->tm_mon != old->tm_mon) && xstrstr(config_logs_path, "%M")) ||
		((now->tm_mday != old->tm_mday) && xstrstr(config_logs_path, "%D"));

	for (i = logs_logs->len - 1; i >= 0; i--) {
		logs_log_t *ll = g_ptr_array_index(logs_logs, i);
		if (LOG_FORMAT_RAW == ll->format) continue;
		if (dfmt)
			logs_log_reopen(ll);
		else
			ll->daychanged = 1;
	}

	return 0;
}
Esempio n. 4
0
 void Piano_flush_map(void)
 {
     debug_function(10); //Debug debug("flush_map");
     Piano_flush_cues(); //flush dependent data also
     AllSprites.clear();
     CachedMapFilename.clear();
 }
Esempio n. 5
0
GCancellable *ekg_connection_starter_run(
		ekg_connection_starter_t cs,
		GSocketClient *sock,
		ekg_connection_callback_t callback,
		ekg_connection_failure_callback_t failure_callback,
		gpointer priv_data)
{
	cs->callback = callback;
	cs->failure_callback = failure_callback;
	cs->priv_data = priv_data;

	cs->cancellable = g_cancellable_new();
	cs->current_server = cs->servers;

	if (cs->bind_hostname) {
		GResolver *res = g_resolver_get_default();
		GList *addrs;
		GError *err = NULL;

		addrs = g_resolver_lookup_by_name(
				res,
				cs->bind_hostname,
				NULL,
				&err);

		if (!addrs) {
				/* XXX: delay calling that */
			failed_async_connect(sock, err, cs);
			g_error_free(err);
			return cs->cancellable;
		}

		g_socket_client_set_local_address(sock,
				g_inet_socket_address_new(
					G_INET_ADDRESS(g_list_nth_data(addrs, 0)), 0));

		g_resolver_free_addresses(addrs);
		g_object_unref(res);
	}

		/* if we have the domain name, try SRV lookup first */
	if (cs->domain) {
		g_assert(cs->service);

			/* fallback to domainname lookup if 'servers' not set */
		if (!cs->servers || !cs->servers[0])
			ekg_connection_starter_set_servers(cs, cs->domain);

		debug_function("ekg_connection_start(), trying _%s._tcp.%s\n",
				cs->service, cs->domain);
		g_socket_client_connect_to_service_async(
				sock, cs->domain, cs->service,
				cs->cancellable,
				done_async_connect,
				cs);
	} else /* otherwise, just begin with servers */
		g_assert(setup_async_connect(sock, cs));

	return cs->cancellable;
}
Esempio n. 6
0
void ekg_connection_write_buf(GDataOutputStream *f, gconstpointer buf, gsize len) {
	struct ekg_connection *c = get_connection_by_outstream(f);
	GError *err = NULL;
	gssize out;
	GOutputStream *of = G_OUTPUT_STREAM(f);

	/* we can't write to buffer if it has pending ops;
	 * yes, it is stupid. */
	if (g_output_stream_has_pending(of)) {
		c->wr_buffer = g_string_append_len(c->wr_buffer, buf, len);
		return;
	}

	out = g_output_stream_write(of, buf, len, NULL, &err);
	if (out != len) {
		debug_error("ekg_connection_write_string() failed (wrote %d out of %d): %s\n",
				out, len, err ? err->message : "(no error?!)");
		failed_write(c);
		g_error_free(err);

		return;
	}

	debug_function("ekg_connection_write_buf(), wrote %d bytes\n", out);

	c->flush_handler(c);
}
Esempio n. 7
0
File: win32.c Progetto: hiciu/ekg2
int fcntl(int fd, int cmd, long arg) {
	if (cmd == F_SETFL) {
		int no_block = -1;
		if (arg & O_NONBLOCK) { no_block = 1; arg -= O_NONBLOCK; }

		debug_function("NO_POSIX_SYSTEM: fcntl() fd: %d F_SETFL  _NO_BLOCK: %d REST_args: %d\n", fd, no_block, arg);
		/* XXX */
		if (no_block != -1) ioctlsocket(fd, FIONBIO, (u_long *) &no_block);

		if (arg) { errno = ERRNO_NOT; return -1; }
		return 0;
	}
	debug_function("NO_POSIX_SYSTEM: fcntl() fd: %d cmd:%d arg:%d\n", fd, cmd, arg);

	errno = ERRNO_NOT;
	return -1;
}
Esempio n. 8
0
File: win32.c Progetto: hiciu/ekg2
int ioctl(int fd, int request, void *flags) {
	if (request == FIONBIO) {
		return fcntl(fd, F_SETFL, O_NONBLOCK);
	}
	debug_function("NO_POSIX_SYSTEM: ioctl() fd: %d req: %d flags: 0x%x", fd, request, flags);
	errno = ERRNO_NOT;
	return -1;
}
Esempio n. 9
0
//update previous bkg:
//if it's a scrolling piano, scroll previous notes up one row
//for eqbars, shorten them
void PianoRenderCache::Piano_update_bkg(RenderBuffer &buffer, int Style, wxSize& canvas, int rowh)
{
    debug_function(10);
    debug(1, "style %d", Style);
    xlColor c;
    //TODO: should use GDI+ functions on Windows
    //TODO: use GetData for better performance; probably doesn't matter since grid is fairly small (as compared to normal images or screen canvas)
    //TODO: speed
    switch (Style)
    {
        case -1: //initialize
            debug_more(5, ", init canvas %d x %d", canvas.x, canvas.y);
            //            PrevRender.clear(); //start with blank canvas
            //            PrevRender.resize(canvas.x * cnavas.y); //set all pixels off
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    buffer.SetPixel(x, y, c); //clear all (background canvas is persistent while piano effect is active)
            return;
        case PIANO_STYLE_SCROLLING: //scroll up one row
            debug_more(5, ", scroll %d x %d up by %d", canvas.x, canvas.y, rowh);
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - rowh) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, canvas.y - y - rowh - 1, x, canvas.y - y - 1);
                        buffer.CopyPixel(x, canvas.y - y - rowh - 1, x, canvas.y - y - 1);
                    } else {
                        debug_more(30, ", (%d,%d)<-0", x, canvas.y - y - 1);
                        buffer.SetPixel(x, canvas.y - y - 1, c);  //clear bottom row, scroll others
                    }
            return;
        case PIANO_STYLE_EQBARS: //scroll down one row (decaying bars)
            debug_more(5, ", scroll %d x %d down by %d", canvas.x, canvas.y, rowh);
            //            c.Set(255, 255, 255); //debug
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - rowh) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, y + rowh, x, y);
                        buffer.CopyPixel(x, y + rowh, x, y);
                    } else {
                        debug_more(30, ", (%d,%d)<-0", x, y);
                        buffer.SetPixel(x, y, c); //clear top row, scroll other rows
                    }
            return;
        case PIANO_STYLE_ICICLES: //scroll down one pixel (drip)
            debug_more(5, ", scroll %d x %d", canvas.x, canvas.y);
            for (int x = 0; x < canvas.x; ++x)
                for (int y = 0; y < canvas.y; ++y)
                    if (y < canvas.y - 1) {
                        debug_more(30, ", (%d,%d)->(%d,%d)", x, y + 1, x, y);
                        buffer.CopyPixel(x, y + 1, x, y);
                    }
            //      else { debug_more(30, ", (%d,%d)<-0", x, y); buffer.SetPixel(x, y, c); } //clear top pixel, scroll other pixels
            return;
        default:
            debug_more(5, ", no scrolling");
    }
}
Esempio n. 10
0
extern "C" void dDebug (int num, const char *msg, ...)
{
  va_list ap;
  va_start (ap,msg);
  if (debug_function) debug_function (num,msg,ap);
  else printMessage (num,"ODE INTERNAL ERROR",msg,ap);
  // *((char *)0) = 0;   ... commit SEGVicide
  abort();
}
Esempio n. 11
0
 void Piano_flush_shapes(void)
 {
     debug_function(10); //Debug debug("flush_shapes");
     Piano_flush_map(); //flush dependent data also
     //    if (Shapes.GetWidth() || Shapes.GetHeight())
     if (Shapes.IsOk()) Shapes.Clear(); //CAUTION: don't clear unless non-empty (causes access violation)
     //    ShapePalette.resize(0);
     ColorMap.clear();
     CachedShapeFilename.clear();
 }
Esempio n. 12
0
static void icq_get_description(session_t *s, const char *uin, int status) {
    icq_private_t *j = s->priv;
    string_t pkt, tlv5, rdv;
    uint32_t cookie1=rand(), cookie2=rand();
    uint32_t mtype, cookie = (j->cookie_seq-- && 0x7fff);

    debug_function("icq_get_description() for: %s\n", uin);

    switch (status) {
    case EKG_STATUS_AWAY:
        mtype = MTYPE_AUTOAWAY;
        break;
    case EKG_STATUS_GONE:
        mtype = MTYPE_AUTONA;
        break;
    case EKG_STATUS_XA:
        mtype = MTYPE_AUTOBUSY;
        break;
    case EKG_STATUS_DND:
        mtype = MTYPE_AUTODND;
        break;
    case EKG_STATUS_FFC:
        mtype = MTYPE_AUTOFFC;
        break;
    default:
        return;
    }

    pkt = string_init(NULL);
    icq_pack_append(pkt, "II", cookie1, cookie2);		// cookie
    icq_pack_append(pkt, "W", (uint32_t) 2);		// message type
    icq_pack_append(pkt, "s", uin);

    tlv5 = string_init(NULL);
    icq_pack_append(tlv5, "W", (uint32_t) 0);
    icq_pack_append(tlv5, "II", cookie1, cookie2);		// cookie
    icq_pack_append_cap(tlv5, CAP_SRV_RELAY);		// AIM_CAPS_ICQSERVERRELAY - Client supports channel 2 extended, TLV(0x2711) based messages.
    icq_pack_append(tlv5, "tW", icq_pack_tlv_word(0xA, 1));	// TLV 0x0A: acktype (1 = normal message)
    icq_pack_append(tlv5, "T", icq_pack_tlv(0x0F, NULL, 0));	// TLV 0x0F: unknown

    // RendezvousMessageData
    rdv = string_init(NULL);
    icq_pack_append_rendezvous(rdv, 9, cookie, mtype, MFLAG_AUTO, 1, 1);
    icq_pack_append_nullterm_msg(rdv, "");
    icq_pack_append(tlv5, "T", icq_pack_tlv(0x2711, rdv->str, rdv->len));
    string_free(rdv, 1);

    icq_pack_append(pkt, "T", icq_pack_tlv(0x05, tlv5->str, tlv5->len));
    string_free(tlv5, 1);

    icq_pack_append(pkt, "T", icq_pack_tlv(0x03, NULL, 0));		// empty TLV 3 to get an ack from the server

    icq_makesnac(s, pkt, 0x04, 0x06, 0, 0);
    icq_send_pkt(s, pkt);
}
Esempio n. 13
0
File: win32.c Progetto: hiciu/ekg2
int pipe(int filedes[2]) {
	HANDLE pread, pwrite;
	int res = CreatePipe(&pread, &pwrite, NULL, 0);

	debug_function("NO_POSIX_SYSTEM: pipe() read=%d write=%d result=%d\n", pread, pwrite, res);
	if (res == 0) { /* fails, XXX, errno && GetLastError? */
		return -1;
	}
	filedes[0] = (int) pread;
	filedes[1] = (int) pwrite;
	return 0;
}
Esempio n. 14
0
File: win32.c Progetto: hiciu/ekg2
HANDLE win32_fork(thread_func_t addr, void *data) {
	HANDLE ret	= (HANDLE) -1;
	DWORD thread_id = 0;

	ret = CreateThread(NULL, 0, (void *) addr, data, 0, &thread_id);
	debug_function("NO_POSIX_SYSTEM: win32_fork() ADDR=0x%x data=0x%x; thread_id = %d result = %d\n", addr, data, thread_id, ret);

	if (!ret) {	/* fails */
		return NULL; /* -1 ? */
	}
	return ret;
}
static int icq_offline_message(session_t *s, unsigned char *buf, int len, private_data_t **info) {
	/*
	 * SNAC(15,03)/0041 SRV_OFFLINE_MESSAGE Offline message response
	 *
	 * This is the server response to CLI_OFFLINE_MSGS_REQ SNAC(15,02)/003C.
	 * This snac contain single offline message that was sent by another user
	 * and buffered by server when client was offline.
	 */
	struct {
		uint32_t uin;		/* message sender uin */

		uint16_t y;		/* year when message was sent (LE) */
		uint8_t M;		/* month when message was sent */
		uint8_t d;		/* day when message was sent */
		uint8_t h;		/* hour (GMT) when message was sent */
		uint8_t m;		/* minute when message was sent */

		uint8_t type;		/* message type */
		uint8_t flags;		/* message flags */

		uint16_t len;		/* message string length (LE) */
		char *msg;		/* message string (null-terminated) */
	} pkt;
	char *recode = NULL;
	char *uid;

	debug_function("icq_offline_message()\n");

	if (ICQ_UNPACK(&buf, "i wcccc cc w", &pkt.uin, &pkt.y, &pkt.M, &pkt.d, &pkt.h, &pkt.m, &pkt.type, &pkt.flags, &pkt.len)) {
		struct tm lt;
		lt.tm_sec	= 0;
		lt.tm_min	= pkt.m;
		lt.tm_hour	= pkt.h;
		lt.tm_mday	= pkt.d;
		lt.tm_mon	= pkt.M - 1;
		lt.tm_year	= pkt.y - 1900;
		lt.tm_isdst	= -1;

		recode = icq_convert_from_ucs2be((char *) buf, pkt.len - 1);
		if (!recode)
			recode = xstrdup((const char*)buf);

		uid = saprintf("icq:%u", pkt.uin);

		if (recode && *recode)
			protocol_message_emit(s, uid, NULL, recode, NULL, mktime(&lt), EKG_MSGCLASS_CHAT, NULL, EKG_TRY_BEEP, 0);

		xfree(uid);
		xfree(recode);
	}

	return 0;
}
Esempio n. 16
0
void ekg_disconnect_by_outstream(GDataOutputStream *f) {
	struct ekg_connection *c = get_connection_by_outstream(f);

	if (!c) {
		debug_warn("ekg_disconnect_by_outstream() - connection not found\n");
		return;
	}

	debug_function("ekg_disconnect_by_outstream(%x)\n",c);

	ekg_connection_remove(c);
}
Esempio n. 17
0
//load start/stop times fort sprites:
//cues can overlap
void PianoRenderCache::Piano_load_cues(const wxString& filename)
{
    debug_function(10);
    debug(1, "load file %s", (const char*)filename.c_str());
    wxTextFile f;
    
    if (!CachedCueFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change
    if (!wxFileExists(filename)) return;
    if (!f.Open(filename.c_str())) return;
    Piano_flush_cues(); //invalidate cached data
    debug(3, "read file");
    for (wxString linebuf = f.GetFirstLine(); !f.Eof(); linebuf = f.GetNextLine())
    {
        std::string::size_type ofs;
        if ((ofs = linebuf.find("#")) != std::string::npos) linebuf.erase(ofs); //remove comments
        while (!linebuf.empty() && (linebuf.Last() == '\\')) //line continuation
        {
            linebuf.RemoveLast(); //remove trailing "\"
            /*std::*/wxString morebuf = f.GetNextLine();
            if (f.Eof()) break;
            linebuf += morebuf;
        }
        while (!linebuf.empty() && isspace(linebuf.Last())) linebuf.RemoveLast(); //trim trailing spaces
        if (linebuf.empty()) continue; //skip blank lines
        
        //start-time    end-time    shape-name
        debug(20, "got line '%s'", (const char*)linebuf.c_str());
        //        linebuf += "\teol"; //end-of-line check for missing params
        wxStringTokenizer tkz(linebuf, "\t");
        Cue cue;
        cue.start_frame = Cue::Time2Frame(tkz.GetNextToken(), -1); //first column = start time (round down)
        cue.stop_frame = Cue::Time2Frame(tkz.GetNextToken(), +1); //second column = stop time (round up)
        //        wxString junk = tkz.GetNextToken();
        //        if (/* !junk.empty()*/ junk.Cmp("eol")) { debug.Append(": junk at end '%s'", (const char*)junk.c_str()).Flush(true); continue; } //TODO: show error messages?
        debug_more(10, " => start %d, stop %d, ok? %d", cue.start_frame, cue.stop_frame, cue.stop_frame >= cue.start_frame);
        if (cue.stop_frame < cue.start_frame) continue; //ignore null cues
        for (;;) //use remaining tokens as sprite names
        {
            wxString name = tkz.GetNextToken();
            if (name.empty()) break;
            if (name.find(".") == -1) name += ".000"; //kludge: change name to match Audacity Polyphonic nodes
            //            debug.Append("add cue for sprite '%s'? %d", /*(const char*)name.c_str()*/ (const char*)name.ToStdString().c_str(), AllSprites.find(name.ToStdString()) != AllSprites.end()).Flush(true);
            if (AllSprites.find(name.ToStdString()) == AllSprites.end()) continue; //ignore missing sprites
            cue.sprite = &AllSprites[name.ToStdString()];
            CuesByStart.push_back(cue);
        }
    }
    /*std::*/sort(CuesByStart.begin(), CuesByStart.end(), Cue::SortByStart);
    debug(3, "%d cues loaded, first '%s' starts/ends %d/%d, last '%s' starts/ends %d/%d", CuesByStart.size(), CuesByStart.size()? CuesByStart.front().sprite->name.ToStdString().c_str(): "", CuesByStart.size()? CuesByStart.front().start_frame: -1, CuesByStart.size()? CuesByStart.front().stop_frame: -1, CuesByStart.size()? CuesByStart.back().sprite->name.ToStdString().c_str(): "", CuesByStart.size()? CuesByStart.back().start_frame: -1, CuesByStart.size()? CuesByStart.back().stop_frame: -1);
    CachedCueFilename = filename; //don't load same file again
}
Esempio n. 18
0
extern "C" void dDebug (int num, const char *msg, ...)
{
  va_list ap;
  va_start (ap,msg);
  if (debug_function) debug_function (num,msg,ap);
  else {
    char s[1000],title[100];
    snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num);
    vsnprintf (s,sizeof(s),msg,ap);
    s[sizeof(s)-1] = 0;
    MessageBox(0,s,title,MB_OK | MB_ICONSTOP);
  }
  abort();
}
Esempio n. 19
0
static gboolean setup_async_connect(GSocketClient *sock, struct ekg_connection_starter *cs) {
	if (*(cs->current_server)) {
		debug_function("setup_async_connect(), trying %s (defport: %d)\n",
				*(cs->current_server), cs->defport);
		g_socket_client_connect_to_host_async(
				sock, *(cs->current_server), cs->defport,
				cs->cancellable,
				done_async_connect,
				cs);
		cs->current_server++;
		return TRUE;
	} else
		return FALSE;
}
Esempio n. 20
0
static void done_async_read(GObject *obj, GAsyncResult *res, gpointer user_data) {
	struct ekg_connection *c = user_data;
	GError *err = NULL;
	gssize rsize;
	GBufferedInputStream *instr = G_BUFFERED_INPUT_STREAM(obj);

	rsize = g_buffered_input_stream_fill_finish(instr, res, &err);

	if (rsize <= 0) {
		if (rsize == -1) /* error */
			debug_error("done_async_read(), read failed: %s\n", err ? err->message : NULL);
		else { /* EOF */
#if NEED_SLAVERY
			if (c->master) /* let the master handle it */
				return;
#endif
			debug_function("done_async_read(), EOF\n");
			if (g_buffered_input_stream_get_available(instr) > 0)
				c->callback(c->instream, c->priv_data);

			err = g_error_new_literal(
					EKG_CONNECTION_ERROR,
					EKG_CONNECTION_ERROR_EOF,
					"Connection terminated");
		}

		c->failure_callback(c->instream, err, c->priv_data);
		ekg_connection_remove(c);
		g_error_free(err);
		return;
	}

	debug_function("done_async_read(): read %d bytes\n", rsize);

	c->callback(c->instream, c->priv_data);
	setup_async_read(c);
}
Esempio n. 21
0
File: main.c Progetto: hiciu/ekg2
static void logs_log_reopen(logs_log_t *ll) {
	char *session = g_strdup(ll->session);
	char *uid = g_strdup(ll->uid);
	char *oldfn = g_strdup(ll->fname);

	g_ptr_array_remove(logs_logs, ll);

	ll = logs_log_new(session, uid, FALSE);

	debug_function("logs_log_reopen() %s => %s\n", oldfn, ll?ll->fname:"");

	g_free(session);
	g_free(uid);
	g_free(oldfn);
}
Esempio n. 22
0
dcc_t *jabber_dcc_find(const char *uin, /* without xmpp: */ const char *id, const char *sid) {
#define DCC_RULE(x) (!xstrncmp(x->uid, "xmpp:", 5) && !xstrcmp(x->uid+5, uin))
	dcc_t *d;
	if (!id && !sid) { debug_error("jabber_dcc_find() neither id nor sid passed.. Returning NULL\n"); return NULL; }

	for (d = dccs; d; d = d->next) {
		jabber_dcc_t *p = d->priv;

		if (DCC_RULE(d) && (!sid || !xstrcmp(p->sid, sid)) && (!id || !xstrcmp(p->req, id))) {
			debug_function("jabber_dcc_find() %s sid: %s id: %s founded: 0x%x\n", __(uin), __(sid), __(id), d);
			return d;
		}
	}
	debug_error("jabber_dcc_find() %s %s not founded. Possible abuse attempt?!\n", __(uin), __(sid));
	return NULL;
}
Esempio n. 23
0
static void ekg_gnutls_handle_data(GDataInputStream *s, gpointer data) {
	struct ekg_gnutls_connection *gc = data;
	ssize_t ret;
	char buf[4096];

	g_assert(gc->connection->slave);

	do {
		ret = gnutls_record_recv(gc->session, buf, sizeof(buf));

		if (ret > 0)
			g_memory_input_stream_add_data(
					gc->instream,
					g_memdup(buf, ret),
					ret,
					g_free);
		else if (ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN) {
			GError *err;
			
			if (ret != 0)
				err = g_error_new_literal(EKG_GNUTLS_ERROR,
						ret, gnutls_strerror(ret));
			else {
				debug_function("ekg_gnutls_handle_data(), got EOF from gnutls\n");
				err = g_error_new_literal(
						EKG_CONNECTION_ERROR,
						EKG_CONNECTION_ERROR_EOF,
						"Connection terminated");
			}

			gc->connection->slave->failure_callback(
					gc->connection->slave->instream,
					err,
					gc->connection->slave->priv_data);
			g_error_free(err);
			ekg_connection_remove(gc->connection->slave);
			ekg_connection_remove(gc->connection);
			return;
		}
	} while (ret > 0 || ret == GNUTLS_E_INTERRUPTED);

		/* not necessarily async but be lazy */
	if (!g_input_stream_has_pending(G_INPUT_STREAM(gc->connection->slave->instream)))
		setup_async_read(gc->connection->slave);
}
Esempio n. 24
0
static inline void sniff_loop_ether(u_char *data, const struct pcap_pkthdr *header, const u_char *packet) {
	const struct ethhdr *ethernet;
	guint16 ethtype;		/* g_ntohs(ethernet->ether_type) */

	if (header->caplen < sizeof(struct ethhdr)) {
		debug_error("sniff_loop_ether() %x %x\n", header->caplen, sizeof(struct ethhdr));
		return;
	}

	ethernet = (const struct ethhdr *) packet;
	ethtype = g_ntohs(ethernet->ether_type);

	if (ethtype == ETHERTYPE_ARP)
		debug_function("sniff_loop_ether() ARP\n");
	else if (ethtype == ETHERTYPE_IP) 
		sniff_loop_ip((session_t *) data, header->caplen - sizeof(struct ethhdr), packet + SIZE_ETHERNET);
	else
		debug_error("sniff_loop_ether() ethtype [0x%x] != ETHERTYPE_IP, CUL\n", ethtype);
}
Esempio n. 25
0
File: main.c Progetto: hiciu/ekg2
static void logs_log_destroy(gpointer data) {
	logs_log_t *log = data;

	g_return_if_fail(log != NULL);

	if ((LOG_FORMAT_IRSSI == log->format) && xstrlen(IRSSI_LOG_EKG2_CLOSED)) {
		logs_open_file(log);
		log->daychanged = 0;
		logs_irssi_sysmsg(log, prepare_timestamp_format(IRSSI_LOG_EKG2_CLOSED, time(NULL)));
	}

	logs_log_close(log);

	debug_function("logs_log_destroy(%d) %s\n", logs_logs->len, log->fname);

	g_free(log->fname);
	g_free(log->session);
	g_free(log->uid);

	g_free(log);
}
static int icq_offline_message_end(session_t *s, unsigned char *buf, int len, private_data_t **info) {
	/*
	 * SNAC(15,03)/0042 SRV_END_OF_OFFLINE_MSGS End-of-offline messages reply
	 *
	 * This is the last SNAC in server response to CLI_OFFLINE_MSGS_REQ SNAC(15,02)/003C.
	 * It doesn't contain message - it is only end_of_sequence marker.
	 */
	debug_function("icq_offline_message_end()\n");

	/* SNAC(15,02)/003E CLI_DELETE_OFFLINE_MSGS_REQ Delete offline messages request
	 *
	 * Client sends this SNAC when wants to delete offline messages from
	 * server. But first you should request them from server using
	 * SNAC(15,02)/003C. If you doesn't delete messages server will send them
	 * again after client request.
	 */
	string_t pkt = string_init(NULL);
	icq_makemetasnac(s, pkt, CLI_DELETE_OFFLINE_MSGS_REQ, 0, NULL, NULL);
	icq_send_pkt(s, pkt);

	return 0;
}
Esempio n. 27
0
static inline void sniff_loop_ip(session_t *s, int len, const u_char *packet) {
	const struct iphdr *ip;
	int size_ip;

	CHECK_LEN(sizeof(struct iphdr))			ip = (struct iphdr *) (packet);
	size_ip = ip->ip_hl*4;
	
	if (size_ip < 20) {
		debug_error("sniff_loop_ip()   * Invalid IP header length: %u bytes\n", size_ip);
		return;
	}
	
	if (ip->ip_p == IPPROTO_TCP)
		sniff_loop_tcp(s, len - size_ip, packet + size_ip, ip, size_ip);
	else if (ip->ip_p == IPPROTO_UDP) 
		sniff_loop_udp(s, len - size_ip, packet + size_ip, ip);
	else if (ip->ip_p == IPPROTO_ICMP) {	/* ICMP, stub only */
		const struct icmphdr *icmp;

		CHECK_LEN(size_ip + sizeof(struct icmphdr));	icmp = (struct icmphdr *) (packet + size_ip);

		debug_function("sniff_loop_ip() IP/ICMP %15s <==> %15s TYPE: %d CODE: %d CHKSUM: %d\n",
				_inet_ntoa(ip->ip_src),		/* src ip */
				_inet_ntoa(ip->ip_dst),		/* dest ip */
				icmp->icmp_type,
				icmp->icmp_code,
				icmp->icmp_cksum);
		/* XXX */
	} else {
		/* other, implement if u want to || die. */
		debug_error("sniff_loop_ip() IP/0x%x %15s <==> %15s\n",
				ip->ip_p,			/* protocol */
				_inet_ntoa(ip->ip_src),		/* src ip */
				_inet_ntoa(ip->ip_dst));	/* dest ip */

	}
}
Esempio n. 28
0
//all shapes are loaded from same image file to reduce file I/O and caching
//thiss also allows animated images to be self-contained
void PianoRenderCache::Piano_load_shapes(RenderBuffer &buffer, const wxString& filename)
{
    debug_function(10); //Debug debug("load_shapes('%s')", (const char*)filename.c_str());
    debug(1, "load shapes file '%s'", (const char*)filename.c_str());
    //reload shapes even if file name hasn't changed; color map might be different now
    //    if (!CachedShapeFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change
    if (!wxFileExists(filename)) return;
    Piano_flush_shapes(); //invalidate cached data
    if (!Shapes.LoadFile(filename, wxBITMAP_TYPE_ANY, 0) || !Shapes.IsOk())
    {
        //wxMessageBox("Error loading image file: "+NewPictureName);
        Shapes.Clear();
        return;
    }
    
    if (buffer.GetColorCount() < 2) return; //use colors from shapes file if no user-selected colors
    //    int imgwidth=image.GetWidth();
    //    int imght   =image.GetHeight();
    //    std::hash_map<WXCOLORREF, int> palcounts;
    //TODO: use wxImage.GetData for better performance?
    //TODO: use multiple images within same file?
    for (int y = Shapes.GetHeight() - 1; y >= 0; --y) //bottom->top
        for (int x = 0; x < Shapes.GetWidth(); ++x) //left->right
            if (!Shapes.IsTransparent(x, y))
            {
                xlColor color, mapped;
                color.Set(Shapes.GetRed(x, y), Shapes.GetGreen(x, y), Shapes.GetBlue(x, y));
                if (ColorMap.find(color.GetRGB()) != ColorMap.end()) continue; //already saw this color
                buffer.palette.GetColor(ColorMap.size() % buffer.GetColorCount(), mapped); //assign user-selected colors to shape palette sequentially, loop if run out of colors
                debug(10, "shape color[%d] 0x%x => user-selected color [%d] 0x%x", ColorMap.size(), color.GetRGB(), ColorMap.size() % GetColorCount(), mapped.GetRGB());
                ColorMap[color.GetRGB()] = mapped; //.GetRGB();
                //                ShapePalette.push_back(c.GetRGB()); //keep a list of unique colors in order of occurrence from origin L-R, B-T
            }
    debug(2, "w %d, h %d, #colors %d", Shapes.GetWidth(), Shapes.GetHeight(), ColorMap.size());
    CachedShapeFilename = filename; //don't load same file again
}
Esempio n. 29
0
bool PianoRenderCache::Piano_RenderKey(RenderBuffer &buffer, Sprite* sprite, std::hash_map<wxPoint_, int>& drawn,
                                 int style, wxSize& canvas, wxSize& keywh, const wxString &placement, bool clip)
//bool RgbEffects::Sprite::render(wxSize& keywh, wxSize& BufferWH_int, int yscroll, bool Clipping)
{
    debug_function(9);
    
    //hash_map<pair<wxPoint, wxSize>, int>& drawn)
    //PIANO_STYLE_KEYS sprites have 2 states: on (down) and off (up); draw all sprites; top view or edge view
    int drawstate = sprite->ani_state++; //bump to next active (animation) state
    if (!drawstate) sprite->ani_state = 0; //stay in inactive state
    else
        //    if ((xy.size() == 1) && (drawstate == -1)) return false; //inactive on/off sprite; don't need tp draw anything
        if (drawstate >= sprite->xy.size()) //end of animation
            //				if (it->repeat > 0) drawstate = 0; //loop immediately
            //				else if (it->repeat < 0) drawstate = -rnd(); //loop with delay
        /*else*/ drawstate = sprite->xy.size() - 1; //stay at last state; don't loop
    
    //    wxPoint realxy = sprite->destxy;
    //    realxy.y += yscroll; //scrolling
    debug_more(30, ", dest (%d => %d, %d), #drawn %d", sprite->destxy.x, (clip? sprite->destxy.x: sprite->destxy.x % canvas.x), sprite->destxy.y, drawn.size());
    if (clip)
        if ((sprite->destxy.x >= buffer.BufferWi) || (sprite->destxy.y >= buffer.BufferHt) || (sprite->destxy.x + keywh.x < 0) || (sprite->destxy.y + keywh.y < 0)) return false; //outside of visible rect
    //    debug_more(30, ", here1");
    wxPoint_ where = sprite->destxy.y * 65536 + (clip? sprite->destxy.x: sprite->destxy.x % canvas.x); //wrap on even key boundary
    //    debug_more(30, ", here2");
    if ((style != PIANO_STYLE_ANIMAGE) && (drawn.find(where) != drawn.end()) && (drawstate <= drawn[where])) { debug_more(30, ", already drawn[0x%x]=%d vs %d", where, drawn[where], drawstate); return false; } //do not redraw older states in same location
    drawn[where] = drawstate; //remember highest state drawn in this location
    
    //don't draw overlapping regions more than once
    
    //                    SetPixel(x-xoffset,(state % ((imght+BufferHt)*speedfactor)) / speedfactor-y,c); //moving up
    //                    SetPixel(x-xoffset,BufferHt+imght-y-(state % ((imght+BufferHt)*speedfactor)) / speedfactor,c); //moving down
    //copy sprite image to pixel buffer, scale up/down:
    //iterate thru target pixels and pull from sprite in case sizes don't match (need to set all target pixels, but okay to skip some source pixels)
    float xscale = (float)sprite->wh.x / keywh.x, yscale = (float)sprite->wh.y / keywh.y; //src -> dest scale factor
    //    debug_more(30, ", here3");
    //TODO: use wxImage.GetData for better performance?
    int xofs = !clip? (buffer.BufferWi % (7 * keywh.x)) / 2: 0; //center keys if not clipped
    if (WantHistory(style)) debug(20, "draw sprite '%s': set x/y %d/%d + %d/%d to 0x%x", (const char*)sprite->name.ToStdString().c_str(), sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, drawstate? sprite->on.GetRGB(): sprite->off.GetRGB()); //.Flush(true);
    else debug(20, "draw sprite '%s': copy from x/y[%d/%d] %d/%d + %d/%d => x/y %d/%d + %d/%d, x/y scale = %f/%f", (const char*)sprite->name.ToStdString().c_str(), drawstate, sprite->xy.size(), sprite->xy[drawstate].x, sprite->xy[drawstate].y, sprite->wh.x, sprite->wh.y, sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, 1.0 / xscale, 1.0 / yscale); //.Flush(true);
    for (int x = 0; x < keywh.x; ++x) //copying to it->w columns in dest
        for (int y = 0; y < keywh.y; ++y) //copying to it->h rows in dest; vert scaling is more likely, so make Y the inner loop for better pixel caching
        {
            //            static xlColor cached_rgb; //cached mapped pixel color
            //            static wxPoint cached_xy(-1, -1);
            wxPoint src_xy(sprite->xy[drawstate].x + x * xscale, sprite->xy[drawstate].y + y * yscale);
            //TODO: scale doesn't make sense for all cases
            src_xy.y = Shapes.GetHeight() - src_xy.y - 1; //whoops, origin is top left but wanted bottom left
            bool transparent = 0;
            if (WantHistory(style)) cached_rgb = drawstate? sprite->on: sprite->off; //kludge: fill rect with same color to avoid losing pixels due to scaling
            else if ((src_xy.x != cached_xy.x) || (src_xy.y != cached_xy.y)) //update cached pixel info
            {
                cached_xy = src_xy; //prev_xy.x = src_xy.x; prev_y = srcy; //not sure how expensive wx pixel functions are, so cache current pixel info just in case; aliasing/averaging and color mapping also makes thiss more expensive
                if (Shapes.IsTransparent(src_xy.x, src_xy.y)) transparent = 1; //-1; //-1 matches white, so use + instead
                else
                {
                    //                        xlColor c;
                    //TODO: tile, center, anti-aliasing
                    cached_rgb.Set(Shapes.GetRed(src_xy.x, src_xy.y), Shapes.GetGreen(src_xy.x, src_xy.y), Shapes.GetBlue(src_xy.x, src_xy.y)); //NOTE: need to do pixel merging if scale is not 1:1
                    if (!ColorMap.empty()) cached_rgb = ColorMap[cached_rgb.GetRGB()]; //map to user-selected colors
                }
                debug_more(20, ", LK(%d,%d)", cached_xy.x, cached_xy.y);
            }
            if (transparent == 1 /*-1*/) continue; //don't need to draw pixel
            int wrapx = sprite->destxy.x + x, scrolly = sprite->destxy.y;
            //            if (style == PIANO_STYLE_ANIMAGE) { wrapx *= xscale; scrolly *= yscale; }
            if (!clip) wrapx %= canvas.x; //wrap on even key boundary
            //            if ((style == PIANO_STYLE_ICICLES) || (style == PIANO_STYLE_EQBARS)) scrolly += canvas.y - keywh.y; //draw at top instead of bottom
            if (style == PIANO_STYLE_ICICLES) scrolly += canvas.y - keywh.y; //draw at top instead of bottom
            //            debug_more(20, ", %d+%d vs. %d-%d? %d", xofs, wrapx, BufferWi, xofs, xofs + wrapx < BufferWi - xofs);
            //            if (!clip) wrapx = (wrapx + 2 * xofs) % BufferWi - 2 * xofs; //wrap within reduced area, not expanded area
            debug_more(20, ", (%d,%d)<-0x%x", wrapx, sprite->destxy.y + y, cached_rgb.GetRGB());
            if (xofs + wrapx < buffer.BufferWi - xofs) buffer.SetPixel(xofs + wrapx, sprite->destxy.y + y, cached_rgb); //no vertical wrap, only horizontal wrap
        }
    //    debug.Flush(true);
    return true;
}
Esempio n. 30
0
//render piano fx during sequence:
void PianoEffect::RenderPiano(RenderBuffer &buffer, const std::string & StyleStr, int NumKeys, int NumRows, const std::string & Placement,
                             bool Clipping, const std::string& CueFilename, const std::string& MapFilename, const std::string& ShapeFilename)
{
    int Style = GetPianoStyle(StyleStr);
    //    wxImage::HSVValue hsv;
    //    xlColor color;
    //    int ColorIdx;
    //    int keys_mod;
    debug_function(9);
    static std::vector<Cue>::iterator cue_cursor; //cached cue ptr
    //    static /*std::*/deque</*std::*/vector<int>> history; //cached history
    static int prev_update;
    static unsigned int cached_state = -1;
    int curframe = buffer.curPeriod - buffer.curEffStartPer; //units of 50 msec
    int state = curframe;
    debug(2, "RenderPiano[%d -> %d] speed %d, frame %d, %f sec, empty? %d", cached_state, state, speed, curframe, (float)curframe*50/1000, CuesByStart.empty());
    if (Style != PIANO_STYLE_ANIMAGE) buffer.InhibitClear = true; //allow canvas to be persistent so we don't need to keep redrawing it
    
    NumKeys = buffer.BufferWi/3; //TODO: make this look better for other values
    
    //get/check/fix up rendering params:
    if (NumKeys < 2) NumKeys = 7; //default to 1 octave
    if (NumKeys > buffer.BufferWi) NumKeys = buffer.BufferWi; //give each key at least 1 pixel in order to be visible
    if (!WantHistory(Style)) NumRows = 1;
    else if (NumRows < 2) NumRows = NumKeys * buffer.BufferHt / buffer.BufferWi; //default square keys
    if (NumRows > buffer.BufferHt) NumRows = buffer.BufferHt; //each row needs at least 1 pixel in order to be visible
    if (Style == PIANO_STYLE_ANIMAGE) NumKeys = NumRows = 1; //use entire canvas
    int adjustw = Clipping? divup(NumKeys, 7): NumKeys/7; //round up vs. down
    if (adjustw < 1) adjustw = 1; //kludge: compiler bug; gcc is generating a imul instr here! gives 0 for NumKeys == 10
    wxSize keywh(buffer.BufferWi / NumKeys, buffer.BufferHt / NumRows), /*BufferWH_full(BufferWi, BufferHt),*/ BufferWH_octave(7 * adjustw * keywh.x, NumRows * keywh.y); //wrap on octave boundaries only (so notes don't move); NOTE: only count white keys (black ones overlap), so octave width is actually 7 keys, not 12
    wxSize keywh_1row(buffer.BufferWi / NumKeys, buffer.BufferHt / 5 + rand() % (buffer.BufferHt * 4/5 + 1)); //kludge: simulate varying amplitudes for eq bars
    if (Style == PIANO_STYLE_ANIMAGE) BufferWH_octave.x = keywh.x; //use entire canvas
    if (Style == PIANO_STYLE_EQBARS) BufferWH_octave.y = buffer.BufferHt; //use entire height
    //    int yscroll = 0;
    debug_more(5, ": style %d, #keys %d, keyw %d/%d(%d), #rows %d, rowh %d/%d(%d)", Style, NumKeys, keywh.x, BufferWH_octave.x, BufferWi, NumRows, keywh.y, BufferWH_octave.y, buffer.BufferHt);
    
    //NOTE: overlap needs more work
    //if 2 keys wrap to the same canvas location and one turns off, should it be redrawn?
    //if any keys are on, you want to see them; OTOH if anything changes, you also want to see that
    //since the purpose of thiss is animation, we'll take the latter option for now
    std::hash_map<wxPoint_, int> drawn; //don't draw overlapping regions more than once
    
    PianoRenderCache *cache = (PianoRenderCache*)buffer.infoCache[id];
    if (cache == nullptr) {
        cache = new PianoRenderCache();
        buffer.infoCache[id] = cache;
    }
    
    //initialize cached data:
    //NOTE: must come thru here if fx params changed
    if ((state < cached_state) || cache->CuesByStart.empty()) //start of playback or rewind/backtrack, or keep trying to load cues
    {
        cache->Piano_load_shapes(buffer, ShapeFilename);
        cache->Piano_load_sprite_map(MapFilename); //, Clipping);
        cache->Piano_load_cues(CueFilename);
        //		history.clear();
        //		resolve_visible(Buffer_Wi, Buffer_Ht, Clipping);
        //        Piano_map_colors();
        cue_cursor = cache->CuesByStart.begin(); //rewind
        //        ActiveCues = std::priority_queue<Cue*, std::vector<Cue*>, Cue /*SortByStop*/>();
        cache->ActiveCues.clear();
        cache->Piano_update_bkg(buffer, -1, BufferWH_octave, keywh.y); //initialize canvas
        for (auto it = cache->AllSprites.begin(); it != cache->AllSprites.end(); ++it) //draw all sprites in their initial state
        {
            it->second.ani_state = 0; //always restart keys in inactive state?
            if (Style != PIANO_STYLE_ANIMAGE)
                cache->Piano_RenderKey(buffer, &it->second, drawn, Style, BufferWH_octave, keywh, Placement, Clipping);
        }
        prev_update = 0;
        cache->cached_xy = wxPoint(-1, -1);
    }
    cached_state = state; //detect rewind
    if (cache->CuesByStart.empty()) return; //nothing to draw
    
    //    if (ShowHistory(Style))
    //    {
    //        history.push_back(/*std::*/vector<int>(NumKeys)); //.emplace_back(); //add new row for current frame
    //        if (history.size() > NumRows) history.pop_front(); //drop oldest row
    //    }
    
    if (WantHistory(Style) && (state - prev_update >= 1000/50)) //time to scroll; speed == #times/sec
    {
        cache->Piano_update_bkg(buffer, Style, BufferWH_octave, keywh.y); //scrolling
        prev_update = state;
    }
    //                SetPixel(x-xoffset,(state % ((imght+BufferHt)*speedfactor)) / speedfactor-y,c); //moving up
    //                    SetPixel(x-xoffset,BufferHt+imght-y-(state % ((imght+BufferHt)*speedfactor)) / speedfactor,c); //moving down
    
    //prune expired cues, update sprite state:
    //    drawn.clear(); //redraw Off sprites only once
    //#define top  front
    //#define pop  pop_front
    //#define push  push_back
    bool repaint = false;
    while (cache->ActiveCues.size() && (cache->ActiveCues.top()->stop_frame <= curframe)) //stopped during previous frame
    {
        debug(7, "prune: '%s' is first of %d stops @%d vs. %d", (const char*)ActiveCues.top()->sprite->name.c_str(), ActiveCues.size(), ActiveCues.top()->stop_frame, curframe);
        cache->ActiveCues.top()->sprite->ani_state = 0; //inactive state
        if (Style != PIANO_STYLE_ANIMAGE)
            cache->Piano_RenderKey(buffer, cache->ActiveCues.top()->sprite, drawn, Style, BufferWH_octave, keywh, Placement, Clipping);
        cache->ActiveCues.pop(); //remove first element (soonest to expire)
        if (cache->ActiveCues.size()) { debug_more(7, ", next is '%s' %d, ", (const char*)cache->ActiveCues.top()->sprite->name.c_str(), cache->ActiveCues.top()->stop_frame); }
        repaint = true;
    }
    
    //add new cues, update sprite state:
    //NOTE: do thiss after pruning so cues with short durations get at least one frame
    //	if (!state) start_cursor = ByStart.begin(); //rewind at start of playback
    //	while ((start_cursor != ByStart.end()) && (start_cursor->start_frame < now + speed)) //start during thiss frame
    //    drawn.clear(); //redraw On sprites over Off sprites only once
    debug(6, "checking %d - %d cues for activation <= frame %d, next is '%s' %d", CuesByStart.size(), cue_cursor - CuesByStart.begin(), curframe, (cue_cursor != CuesByStart.end())? (const char*)cue_cursor->sprite->name.c_str(): "", (cue_cursor != CuesByStart.end())? cue_cursor->start_frame: -1);
    //    for (cue_cursor = /*CuesByStart.begin()*/ /*std::*/ lower_bound(/*cue_cursor*/ CuesByStart.begin(), CuesByStart.end(), Cue(state), Cue::SortByStart); /*(cue_cursor != CuesByStart.end()) && (cue_cursor->start_frame <= state)*/; ++cue_cursor)
    while ((cue_cursor != cache->CuesByStart.end()) && (cue_cursor->start_frame <= curframe)) //TODO: use lower_bound for better performance
    {
        //	    debug.Append("activate check: cur@ %d, end? %d, start_frame %d <= frame %d? %d", cue_cursor - CuesByStart.begin(), cue_cursor == CuesByStart.end(), cue_cursor->start_frame, state, cue_cursor->start_frame <= state).Flush(true);
        //        if ((cue_cursor == CuesByStart.end()) || (cue_cursor->start_frame > state)) break;
        debug(7, "activate: '%s' starts/stops %d/%d, has %d states", (const char*)cue_cursor->sprite->name.c_str(), cue_cursor->start_frame, cue_cursor->stop_frame, cue_cursor->sprite->xy.size());
        cue_cursor->sprite->ani_state = 1; //first active state
        if (Style != PIANO_STYLE_ANIMAGE)
            cache->Piano_RenderKey(buffer, cue_cursor->sprite, drawn, Style, BufferWH_octave, (Style == PIANO_STYLE_EQBARS)? keywh_1row: keywh, Placement, Clipping);
        if (Style != PIANO_STYLE_EQBARS) //eq bars will age out by themselves
            cache->ActiveCues.push(&*cue_cursor);
        else if ((cache->ActiveCues.size() > 1) && (cache->ActiveCues.c[0]->stop_frame > cache->ActiveCues.c[1]->stop_frame)) //paranoid check
        {
            debug(5, "priority_queue broken! [0] %d > [1] %d", ActiveCues.c[0]->stop_frame, ActiveCues.c[1]->stop_frame);
            //        sort(ActiveCues.begin(), ActiveCues.end(), Cue::SortByStop); //kludge: priority_queue not working, so explicitly sort it
            //                std::swap(ActiveCues.c.begin(), ActiveCues.c.begin() + 1);
            cache->ActiveCues.c.erase(cache->ActiveCues.c.begin()); //remove and try again
            for (auto it = cache->ActiveCues.c.begin();; ++it)
                if ((it == cache->ActiveCues.c.end()) || (cue_cursor->stop_frame < (*it)->stop_frame))
                {
                    cache->ActiveCues.c.insert(it, &*cue_cursor);
                    debug_more(5, ", fixed @%d", it - ActiveCues.c.begin());
                    break;
                }
        }
        ++cue_cursor;
        repaint = true;
    }
    //#undef top
    //#undef pop
    //#undef push
    
    //TODO: fix repaint logic
    if (Style == PIANO_STYLE_ANIMAGE)//&& repaint) //repaint all now
        for (auto it = cache->AllSprites.begin(); it != cache->AllSprites.end(); ++it) //draw all sprites in their initial state
            if (it->second.ani_state) //redraw active sprites
                cache->Piano_RenderKey(buffer, &it->second, drawn, Style, BufferWH_octave, keywh, Placement, Clipping);
}