/* * 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; }
/* 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); }
/* * 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; }
void Piano_flush_map(void) { debug_function(10); //Debug debug("flush_map"); Piano_flush_cues(); //flush dependent data also AllSprites.clear(); CachedMapFilename.clear(); }
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; }
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); }
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; }
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; }
//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"); } }
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(); }
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(); }
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); }
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; }
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(<), EKG_MSGCLASS_CHAT, NULL, EKG_TRY_BEEP, 0); xfree(uid); xfree(recode); } return 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); }
//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 }
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(); }
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; }
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); }
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); }
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; }
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); }
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); }
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; }
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 */ } }
//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 }
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; }
//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); }