40 #pragma warning(disable : 4786) // Don't give irrelevant warnings for stl 41 #pragma warning(disable : 4018) // signed/unsigned warnings 42 #pragma warning(disable : 4530) // exception warnings 51 #include "allheaders.h" 60 static std::map<int, ScrollView*> svmap;
63 static std::map<std::pair<ScrollView*, SVEventType>,
64 std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;
65 static SVMutex* waiting_for_events_mu;
83 #ifndef GRAPHICS_DISABLED 84 void* ScrollView::MessageReceiver(
void* a) {
89 int counter_event_id = 0;
93 message = ScrollView::GetStream()->
Receive();
94 }
while (message == NULL);
109 sscanf(message,
"%d,%d,%d,%d,%d,%d,%d,%n", &window_id, &ev_type, &cur->
x,
111 char* p = (message + n);
114 cur->
window = svmap[window_id];
116 if (cur->
window != NULL) {
117 cur->
parameter =
new char[strlen(p) + 1];
118 strncpy(cur->
parameter, p, strlen(p) + 1);
133 if (cur->
window->y_axis_is_reversed_)
135 cur->
counter = counter_event_id;
139 counter_event_id += 2;
145 cur->
window->SetEvent(cur);
148 std::pair<ScrollView*, SVEventType> awaiting_list(cur->
window,
150 std::pair<ScrollView*, SVEventType> awaiting_list_any(cur->
window,
152 std::pair<ScrollView*, SVEventType> awaiting_list_any_window((
ScrollView*)0,
154 waiting_for_events_mu->
Lock();
155 if (waiting_for_events.count(awaiting_list) > 0) {
156 waiting_for_events[awaiting_list].second = cur;
157 waiting_for_events[awaiting_list].first->Signal();
158 }
else if (waiting_for_events.count(awaiting_list_any) > 0) {
159 waiting_for_events[awaiting_list_any].second = cur;
160 waiting_for_events[awaiting_list_any].first->Signal();
161 }
else if (waiting_for_events.count(awaiting_list_any_window) > 0) {
162 waiting_for_events[awaiting_list_any_window].second = cur;
163 waiting_for_events[awaiting_list_any_window].first->Signal();
168 waiting_for_events_mu->
Unlock();
182 message = ScrollView::GetStream()->
Receive();
183 }
while (message == NULL);
192 {255, 255, 255, 255},
201 {128, 128, 255, 255},
205 {192, 192, 255, 255},
208 {255, 128, 128, 255},
212 {192, 192, 128, 255},
217 {192, 255, 192, 255},
219 {192, 192, 192, 255},
222 {128, 128, 128, 255},
227 {255, 192, 192, 255},
232 {255, 192, 128, 255},
247 int ScrollView::nr_created_windows_ = 0;
248 int ScrollView::image_index_ = 0;
252 int y_size,
int x_canvas_size,
int y_canvas_size,
253 bool y_axis_reversed,
const char* server_name) {
254 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
255 y_axis_reversed, server_name);}
259 int y_size,
int x_canvas_size,
int y_canvas_size,
260 bool y_axis_reversed) {
261 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
262 y_axis_reversed,
"localhost");
267 int y_size,
int x_canvas_size,
int y_canvas_size) {
268 Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
273 void ScrollView::Initialize(
const char* name,
int x_pos,
int y_pos,
int x_size,
274 int y_size,
int x_canvas_size,
int y_canvas_size,
275 bool y_axis_reversed,
const char* server_name) {
278 if (stream_ == NULL) {
279 nr_created_windows_ = 0;
281 waiting_for_events_mu =
new SVMutex();
284 "svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
289 nr_created_windows_++;
290 event_handler_ = NULL;
291 event_handler_ended_ =
false;
292 y_axis_is_reversed_ = y_axis_reversed;
293 y_size_ = y_canvas_size;
295 window_id_ = nr_created_windows_;
298 points_->
empty =
true;
301 svmap[window_id_] =
this;
305 event_table_[i] = NULL;
313 snprintf(message,
sizeof(message),
314 "w%u = luajava.newInstance('com.google.scrollview.ui" 315 ".SVWindow','%s',%u,%u,%u,%u,%u,%u,%u)\n",
316 window_id_, window_name_, window_id_,
317 x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size);
324 void* ScrollView::StartEventHandler(
void* a) {
330 sv->semaphore_->
Wait();
338 if (sv->event_table_[i] != NULL &&
339 (serial < 0 || sv->event_table_[i]->counter < serial)) {
340 new_event = sv->event_table_[i];
341 serial = sv->event_table_[i]->
counter;
346 if (new_event != NULL) {
347 sv->event_table_[k] = NULL;
349 if (sv->event_handler_ != NULL) { sv->event_handler_->
Notify(new_event); }
352 sv->event_handler_ended_ =
true;
356 }
else { sv->mutex_->
Unlock(); }
358 }
while (sv != NULL);
361 #endif // GRAPHICS_DISABLED 364 #ifndef GRAPHICS_DISABLED 366 if (svmap[window_id_] != NULL) {
374 svmap[window_id_] = NULL;
379 while (!event_handler_ended_)
388 delete event_table_[i];
390 #endif // GRAPHICS_DISABLED 393 #ifndef GRAPHICS_DISABLED 401 va_start(args, format);
406 snprintf(form,
kMaxMsgSize,
"w%u:%s\n", window_id_, message);
419 event_handler_ = listener;
422 void ScrollView::Signal() {
426 void ScrollView::SetEvent(
SVEvent* svevent) {
435 if (event_table_[specific->
type] != NULL) {
436 delete event_table_[specific->
type]; }
437 if (event_table_[
SVET_ANY] != NULL) {
440 event_table_[specific->
type] = specific;
452 std::pair<ScrollView*, SVEventType> ea(
this, type);
453 waiting_for_events_mu->
Lock();
454 waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, (
SVEvent*)0);
455 waiting_for_events_mu->
Unlock();
460 waiting_for_events_mu->
Lock();
461 SVEvent* ret = waiting_for_events[ea].second;
462 waiting_for_events.erase(ea);
464 waiting_for_events_mu->
Unlock();
474 waiting_for_events_mu->
Lock();
475 waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, (
SVEvent*)0);
476 waiting_for_events_mu->
Unlock();
481 waiting_for_events_mu->
Lock();
482 SVEvent* ret = waiting_for_events[ea].second;
483 waiting_for_events.erase(ea);
484 waiting_for_events_mu->
Unlock();
489 void ScrollView::SendPolygon() {
490 if (!points_->
empty) {
491 points_->
empty =
true;
492 int length = points_->
xcoords.size();
497 SendMsg(
"drawLine(%d,%d,%d,%d)",
500 }
else if (length > 2) {
502 SendMsg(
"createPolyline(%d)", length);
504 std::string decimal_coords;
505 for (
int i = 0; i < length; ++i) {
508 decimal_coords += coordpair;
510 decimal_coords +=
'\n';
534 points_->
empty =
false;
543 }
else if (!points_->
xcoords.empty() && x2 == points_->
xcoords.back() &&
556 if (visible) {
SendMsg(
"setVisible(true)");
557 }
else {
SendMsg(
"setVisible(false)"); }
562 if (b) {
SendMsg(
"setAlwaysOnTop(true)");
563 }
else {
SendMsg(
"setAlwaysOnTop(false)"); }
572 va_start(args, format);
576 snprintf(form,
kMaxMsgSize,
"w%u:%s", window_id_, message);
578 char* esc = AddEscapeChars(form);
579 SendMsg(
"addMessage(\"%s\")", esc);
601 SendMsg(
"setStrokeWidth(%f)", width);
607 if (x1 == x2 && y1 == y2)
609 SendMsg(
"drawRectangle(%d,%d,%d,%d)",
616 SendMsg(
"drawEllipse(%d,%d,%u,%u)",
622 SendMsg(
"pen(%d,%d,%d)", red, green, blue);
627 SendMsg(
"pen(%d,%d,%d,%d)", red, green, blue, alpha);
632 SendMsg(
"brush(%d,%d,%d)", red, green, blue);
637 SendMsg(
"brush(%d,%d,%d,%d)", red, green, blue, alpha);
642 bool bold,
bool italic,
bool underlined) {
647 if (bold) { b =
"true";
648 }
else { b =
"false"; }
649 if (italic) { i =
"true";
650 }
else { i =
"false"; }
651 if (underlined) { u =
"true";
652 }
else { u =
"false"; }
653 SendMsg(
"textAttributes('%s',%u,%s,%s,%s)", font, pixel_size,
664 SendMsg(
"openImage('%s')", image);
665 SendMsg(
"drawImage('%s',%d,%d)",
671 int cmdEvent,
bool flag) {
672 if (parent == NULL) { parent =
""; }
673 if (flag) {
SendMsg(
"addMenuBarItem('%s','%s',%d,true)",
674 parent, name, cmdEvent);
675 }
else {
SendMsg(
"addMenuBarItem('%s','%s',%d,false)",
676 parent, name, cmdEvent); }
681 if (parent == NULL) { parent =
""; }
682 SendMsg(
"addMenuBarItem('%s','%s',%d)", parent, name, cmdEvent);
687 if (parent == NULL) { parent =
""; }
688 SendMsg(
"addMenuBarItem('%s','%s')", parent, name);
693 if (parent == NULL) { parent =
""; }
694 SendMsg(
"addPopupMenuItem('%s','%s')", parent, name);
699 int cmdEvent,
const char* value,
const char* desc) {
700 if (parent == NULL) { parent =
""; }
701 char* esc = AddEscapeChars(value);
702 char* esc2 = AddEscapeChars(desc);
703 SendMsg(
"addPopupMenuItem('%s','%s',%d,'%s','%s')", parent, name,
704 cmdEvent, esc, esc2);
717 for (std::map<int, ScrollView*>::iterator iter = svmap.begin();
718 iter != svmap.end(); ++iter) {
719 if (iter->second != NULL)
720 iter->second->UpdateWindow();
741 SendMsg(
"showInputDialog(\"%s\")", msg);
745 char* p =
new char[strlen(ev->
parameter) + 1];
754 SendMsg(
"showYesNoDialog(\"%s\")", msg);
768 SendMsg(
"zoomRectangle(%d,%d,%d,%d)",
776 pixWriteMem(&data, &size, image, IFF_PNG);
777 int base64_len = (size + 2) / 3 * 4;
779 SendMsg(
"readImage(%d,%d,%d)", x_pos, y_pos, base64_len);
781 const char kBase64Table[64] = {
782 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
783 'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
784 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
785 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
786 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
787 'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
788 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
789 '4',
'5',
'6',
'7',
'8',
'9',
'+',
'/',
791 char* base64 =
new char[base64_len + 1];
792 memset(base64,
'=', base64_len);
793 base64[base64_len] =
'\0';
797 for (
size_t i = 0; i < size; ++i) {
798 int code = (data[i] >> (bits_left + 2)) | remainder;
799 base64[code_len++] = kBase64Table[code & 63];
801 remainder = data[i] << (6 - bits_left);
802 if (bits_left == 6) {
803 base64[code_len++] = kBase64Table[remainder & 63];
809 base64[code_len++] = kBase64Table[remainder & 63];
817 char* ScrollView::AddEscapeChars(
const char* input) {
818 const char* nextptr = strchr(input,
'\'');
819 const char* lastptr = input;
822 while (nextptr != NULL) {
823 strncpy(message+pos, lastptr, nextptr-lastptr);
824 pos += nextptr - lastptr;
828 nextptr = strchr(nextptr+1,
'\'');
830 strncpy(message+pos, lastptr, strlen(lastptr));
831 message[pos+strlen(lastptr)] =
'\0';
837 if (!y_axis_is_reversed_) {
return y;
838 }
else {
return y_size_ - y; }
841 #endif // GRAPHICS_DISABLED
void DrawTo(int x, int y)
void Image(struct Pix *image, int x_pos, int y_pos)
void MenuItem(const char *parent, const char *name)
virtual void Notify(const SVEvent *sve)
void SetCursor(int x, int y)
int TranslateYCoordinate(int y)
void Line(int x1, int y1, int x2, int y2)
void SendMsg(const char *msg,...)
Send a message to the server, attaching the window id.
std::vector< int > ycoords
void Wait()
Wait on a semaphore.
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
char * ShowInputDialog(const char *msg)
void Ellipse(int x, int y, int width, int height)
static void SendRawMessage(const char *msg)
SVEvent * AwaitEventAnyWindow()
void Text(int x, int y, const char *mystring)
int table_colors[ScrollView::GREEN_YELLOW+1][4]
int ShowYesNoDialog(const char *msg)
void Send(const char *msg)
Put a message in the messagebuffer to the server and try to send it.
SVEvent * AwaitEvent(SVEventType type)
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
ScrollView(const char *name, int x_pos, int y_pos, int x_size, int y_size, int x_canvas_size, int y_canvas_size)
Calls Initialize with default argument for server_name_ & y_axis_reversed.
void Lock()
Locks on a mutex.
void Rectangle(int x1, int y1, int x2, int y2)
const int kMaxIntPairSize
void Flush()
Flush the buffer.
void Unlock()
Unlocks on a mutex.
void SetVisible(bool visible)
std::vector< int > xcoords
void PopupItem(const char *parent, const char *name)
void Signal()
Signal a semaphore.
static void StartThread(void *(*func)(void *), void *arg)
Create new thread.
void AddMessage(const char *format,...)
void ZoomToRectangle(int x1, int y1, int x2, int y2)