mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-01-19 06:53:36 +08:00
Updating viewer code to latest
git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@337 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
parent
821b151267
commit
208f24ea04
@ -44,10 +44,6 @@ const int kMaxIntPairSize = 45; // Holds %d,%d, for upto 64 bit.
|
|||||||
|
|
||||||
#include "svutil.h"
|
#include "svutil.h"
|
||||||
|
|
||||||
// Include automatically generated configuration file if running autoconf.
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config_auto.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBLEPT
|
#ifdef HAVE_LIBLEPT
|
||||||
#include "allheaders.h"
|
#include "allheaders.h"
|
||||||
#endif
|
#endif
|
||||||
@ -60,10 +56,11 @@ struct SVPolyLineBuffer {
|
|||||||
|
|
||||||
// A map between the window IDs and their corresponding pointers.
|
// A map between the window IDs and their corresponding pointers.
|
||||||
static std::map<int, ScrollView*> svmap;
|
static std::map<int, ScrollView*> svmap;
|
||||||
|
static SVMutex* svmap_mu;
|
||||||
// A map of all semaphores waiting for a specific event on a specific window.
|
// A map of all semaphores waiting for a specific event on a specific window.
|
||||||
static std::map<std::pair<ScrollView*, SVEventType>,
|
static std::map<std::pair<ScrollView*, SVEventType>,
|
||||||
std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;
|
std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;
|
||||||
SVMutex* mutex_waiting;
|
static SVMutex* waiting_for_events_mu;
|
||||||
|
|
||||||
SVEvent* SVEvent::copy() {
|
SVEvent* SVEvent::copy() {
|
||||||
SVEvent* any = new SVEvent;
|
SVEvent* any = new SVEvent;
|
||||||
@ -110,6 +107,7 @@ void* ScrollView::MessageReceiver(void* a) {
|
|||||||
&cur->y, &cur->x_size, &cur->y_size, &cur->command_id, &n);
|
&cur->y, &cur->x_size, &cur->y_size, &cur->command_id, &n);
|
||||||
char* p = (message + n);
|
char* p = (message + n);
|
||||||
|
|
||||||
|
svmap_mu->Lock();
|
||||||
cur->window = svmap[window_id];
|
cur->window = svmap[window_id];
|
||||||
|
|
||||||
if (cur->window != NULL) {
|
if (cur->window != NULL) {
|
||||||
@ -139,7 +137,7 @@ void* ScrollView::MessageReceiver(void* a) {
|
|||||||
SVET_ANY);
|
SVET_ANY);
|
||||||
std::pair<ScrollView*, SVEventType> awaiting_list_any_window(NULL,
|
std::pair<ScrollView*, SVEventType> awaiting_list_any_window(NULL,
|
||||||
SVET_ANY);
|
SVET_ANY);
|
||||||
mutex_waiting->Lock();
|
waiting_for_events_mu->Lock();
|
||||||
if (waiting_for_events.count(awaiting_list) > 0) {
|
if (waiting_for_events.count(awaiting_list) > 0) {
|
||||||
waiting_for_events[awaiting_list].second = cur;
|
waiting_for_events[awaiting_list].second = cur;
|
||||||
waiting_for_events[awaiting_list].first->Signal();
|
waiting_for_events[awaiting_list].first->Signal();
|
||||||
@ -153,7 +151,7 @@ void* ScrollView::MessageReceiver(void* a) {
|
|||||||
// No one wanted it, so delete it.
|
// No one wanted it, so delete it.
|
||||||
delete cur;
|
delete cur;
|
||||||
}
|
}
|
||||||
mutex_waiting->Unlock();
|
waiting_for_events_mu->Unlock();
|
||||||
// Signal the corresponding semaphore twice (for both copies).
|
// Signal the corresponding semaphore twice (for both copies).
|
||||||
ScrollView* sv = svmap[window_id];
|
ScrollView* sv = svmap[window_id];
|
||||||
if (sv != NULL) {
|
if (sv != NULL) {
|
||||||
@ -161,6 +159,7 @@ void* ScrollView::MessageReceiver(void* a) {
|
|||||||
sv->Signal();
|
sv->Signal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
svmap_mu->Unlock();
|
||||||
|
|
||||||
// Wait until a new message appears in the input stream_.
|
// Wait until a new message appears in the input stream_.
|
||||||
do {
|
do {
|
||||||
@ -262,7 +261,8 @@ void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
|||||||
if (stream_ == NULL) {
|
if (stream_ == NULL) {
|
||||||
nr_created_windows_ = 0;
|
nr_created_windows_ = 0;
|
||||||
stream_ = new SVNetwork(server_name, kSvPort);
|
stream_ = new SVNetwork(server_name, kSvPort);
|
||||||
mutex_waiting = new SVMutex();
|
waiting_for_events_mu = new SVMutex();
|
||||||
|
svmap_mu = new SVMutex();
|
||||||
SendRawMessage(
|
SendRawMessage(
|
||||||
"svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
|
"svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
|
||||||
SVSync::StartThread(MessageReceiver, NULL);
|
SVSync::StartThread(MessageReceiver, NULL);
|
||||||
@ -271,6 +271,7 @@ void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
|||||||
// Set up the variables on the clientside.
|
// Set up the variables on the clientside.
|
||||||
nr_created_windows_++;
|
nr_created_windows_++;
|
||||||
event_handler_ = NULL;
|
event_handler_ = NULL;
|
||||||
|
event_handler_ended_ = false;
|
||||||
y_axis_is_reversed_ = y_axis_reversed;
|
y_axis_is_reversed_ = y_axis_reversed;
|
||||||
y_size_ = y_canvas_size;
|
y_size_ = y_canvas_size;
|
||||||
window_name_ = name;
|
window_name_ = name;
|
||||||
@ -279,7 +280,9 @@ void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
|||||||
points_ = new SVPolyLineBuffer;
|
points_ = new SVPolyLineBuffer;
|
||||||
points_->empty = true;
|
points_->empty = true;
|
||||||
|
|
||||||
|
svmap_mu->Lock();
|
||||||
svmap[window_id_] = this;
|
svmap[window_id_] = this;
|
||||||
|
svmap_mu->Unlock();
|
||||||
|
|
||||||
for (int i = 0; i < SVET_COUNT; i++) {
|
for (int i = 0; i < SVET_COUNT; i++) {
|
||||||
event_table_[i] = NULL;
|
event_table_[i] = NULL;
|
||||||
@ -327,7 +330,11 @@ void* ScrollView::StartEventHandler(void* a) {
|
|||||||
sv->event_table_[k] = NULL;
|
sv->event_table_[k] = NULL;
|
||||||
sv->mutex_->Unlock();
|
sv->mutex_->Unlock();
|
||||||
if (sv->event_handler_ != NULL) { sv->event_handler_->Notify(new_event); }
|
if (sv->event_handler_ != NULL) { sv->event_handler_->Notify(new_event); }
|
||||||
if (new_event->type == SVET_DESTROY) { sv = NULL; }
|
if (new_event->type == SVET_DESTROY) {
|
||||||
|
// Signal the destructor that it is safe to terminate.
|
||||||
|
sv->event_handler_ended_ = true;
|
||||||
|
sv = NULL;
|
||||||
|
}
|
||||||
delete new_event; // Delete the pointer after it has been processed.
|
delete new_event; // Delete the pointer after it has been processed.
|
||||||
} else { sv->mutex_->Unlock(); }
|
} else { sv->mutex_->Unlock(); }
|
||||||
// The thread should run as long as its associated window is alive.
|
// The thread should run as long as its associated window is alive.
|
||||||
@ -336,18 +343,28 @@ void* ScrollView::StartEventHandler(void* a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScrollView::~ScrollView() {
|
ScrollView::~ScrollView() {
|
||||||
|
svmap_mu->Lock();
|
||||||
if (svmap[window_id_] != NULL) {
|
if (svmap[window_id_] != NULL) {
|
||||||
|
svmap_mu->Unlock();
|
||||||
// So the event handling thread can quit.
|
// So the event handling thread can quit.
|
||||||
SendMsg("destroy()");
|
SendMsg("destroy()");
|
||||||
|
|
||||||
SVEvent* sve = AwaitEvent(SVET_DESTROY);
|
SVEvent* sve = AwaitEvent(SVET_DESTROY);
|
||||||
delete sve;
|
delete sve;
|
||||||
|
svmap_mu->Lock();
|
||||||
|
svmap[window_id_] = NULL;
|
||||||
|
svmap_mu->Unlock();
|
||||||
|
// The event handler thread for this window *must* receive the
|
||||||
|
// destroy event and set its pointer to this to NULL before we allow
|
||||||
|
// the destructor to exit.
|
||||||
|
while (!event_handler_ended_)
|
||||||
|
Update();
|
||||||
|
} else {
|
||||||
|
svmap_mu->Unlock();
|
||||||
}
|
}
|
||||||
delete mutex_;
|
delete mutex_;
|
||||||
delete semaphore_;
|
delete semaphore_;
|
||||||
delete points_;
|
delete points_;
|
||||||
|
|
||||||
svmap.erase(window_id_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a message to the server, attaching the window id.
|
// Send a message to the server, attaching the window id.
|
||||||
@ -409,17 +426,18 @@ SVEvent* ScrollView::AwaitEvent(SVEventType type) {
|
|||||||
// Initialize the waiting semaphore.
|
// Initialize the waiting semaphore.
|
||||||
SVSemaphore* sem = new SVSemaphore();
|
SVSemaphore* sem = new SVSemaphore();
|
||||||
std::pair<ScrollView*, SVEventType> ea(this, type);
|
std::pair<ScrollView*, SVEventType> ea(this, type);
|
||||||
mutex_waiting->Lock();
|
waiting_for_events_mu->Lock();
|
||||||
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
||||||
mutex_waiting->Unlock();
|
waiting_for_events_mu->Unlock();
|
||||||
// Wait on it, but first flush.
|
// Wait on it, but first flush.
|
||||||
stream_->Flush();
|
stream_->Flush();
|
||||||
sem->Wait();
|
sem->Wait();
|
||||||
// Process the event we got woken up for (its in waiting_for_events pair).
|
// Process the event we got woken up for (its in waiting_for_events pair).
|
||||||
mutex_waiting->Lock();
|
waiting_for_events_mu->Lock();
|
||||||
SVEvent* ret = waiting_for_events[ea].second;
|
SVEvent* ret = waiting_for_events[ea].second;
|
||||||
waiting_for_events.erase(ea);
|
waiting_for_events.erase(ea);
|
||||||
mutex_waiting->Unlock();
|
delete sem;
|
||||||
|
waiting_for_events_mu->Unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,17 +447,17 @@ SVEvent* ScrollView::AwaitEventAnyWindow() {
|
|||||||
// Initialize the waiting semaphore.
|
// Initialize the waiting semaphore.
|
||||||
SVSemaphore* sem = new SVSemaphore();
|
SVSemaphore* sem = new SVSemaphore();
|
||||||
std::pair<ScrollView*, SVEventType> ea(NULL, SVET_ANY);
|
std::pair<ScrollView*, SVEventType> ea(NULL, SVET_ANY);
|
||||||
mutex_waiting->Lock();
|
waiting_for_events_mu->Lock();
|
||||||
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
||||||
mutex_waiting->Unlock();
|
waiting_for_events_mu->Unlock();
|
||||||
// Wait on it.
|
// Wait on it.
|
||||||
stream_->Flush();
|
stream_->Flush();
|
||||||
sem->Wait();
|
sem->Wait();
|
||||||
// Process the event we got woken up for (its in waiting_for_events pair).
|
// Process the event we got woken up for (its in waiting_for_events pair).
|
||||||
mutex_waiting->Lock();
|
waiting_for_events_mu->Lock();
|
||||||
SVEvent* ret = waiting_for_events[ea].second;
|
SVEvent* ret = waiting_for_events[ea].second;
|
||||||
waiting_for_events.erase(ea);
|
waiting_for_events.erase(ea);
|
||||||
mutex_waiting->Unlock();
|
waiting_for_events_mu->Unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,6 +580,8 @@ void ScrollView::Stroke(float width) {
|
|||||||
// Draw a rectangle using the current pen color.
|
// Draw a rectangle using the current pen color.
|
||||||
// The rectangle is filled with the current brush color.
|
// The rectangle is filled with the current brush color.
|
||||||
void ScrollView::Rectangle(int x1, int y1, int x2, int y2) {
|
void ScrollView::Rectangle(int x1, int y1, int x2, int y2) {
|
||||||
|
if (x1 == x2 && y1 == y2)
|
||||||
|
return; // Scrollviewer locks up.
|
||||||
SendMsg("drawRectangle(%d,%d,%d,%d)",
|
SendMsg("drawRectangle(%d,%d,%d,%d)",
|
||||||
x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2));
|
x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2));
|
||||||
}
|
}
|
||||||
@ -669,11 +689,13 @@ void ScrollView::UpdateWindow() {
|
|||||||
|
|
||||||
// Note: this is an update to all windows
|
// Note: this is an update to all windows
|
||||||
void ScrollView::Update() {
|
void ScrollView::Update() {
|
||||||
|
svmap_mu->Lock();
|
||||||
for (std::map<int, ScrollView*>::iterator iter = svmap.begin();
|
for (std::map<int, ScrollView*>::iterator iter = svmap.begin();
|
||||||
iter != svmap.end(); ++iter) {
|
iter != svmap.end(); ++iter) {
|
||||||
if (iter->second != NULL)
|
if (iter->second != NULL)
|
||||||
iter->second->UpdateWindow();
|
iter->second->UpdateWindow();
|
||||||
}
|
}
|
||||||
|
svmap_mu->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the pen color, using an enum value (e.g. ScrollView::ORANGE)
|
// Set the pen color, using an enum value (e.g. ScrollView::ORANGE)
|
||||||
@ -723,9 +745,9 @@ void ScrollView::ZoomToRectangle(int x1, int y1, int x2, int y2) {
|
|||||||
MIN(x1, x2), MIN(y1, y2), MAX(x1, x2), MAX(y1, y2));
|
MIN(x1, x2), MIN(y1, y2), MAX(x1, x2), MAX(y1, y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send an image of type PIX.
|
|
||||||
void ScrollView::Image(Pix* image, int x_pos, int y_pos) {
|
|
||||||
#ifdef HAVE_LIBLEPT
|
#ifdef HAVE_LIBLEPT
|
||||||
|
// Send an image of type PIX.
|
||||||
|
void ScrollView::Image(PIX* image, int x_pos, int y_pos) {
|
||||||
int width = image->w;
|
int width = image->w;
|
||||||
int height = image->h;
|
int height = image->h;
|
||||||
l_uint32 bpp = image->d;
|
l_uint32 bpp = image->d;
|
||||||
@ -741,12 +763,10 @@ void ScrollView::Image(Pix* image, int x_pos, int y_pos) {
|
|||||||
}
|
}
|
||||||
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
||||||
SendMsg("drawImage('%s',%d,%d)", "lept", x_pos, y_pos);
|
SendMsg("drawImage('%s',%d,%d)", "lept", x_pos, y_pos);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends each pixel as hex value like html, e.g. #00FF00 for green.
|
// Sends each pixel as hex value like html, e.g. #00FF00 for green.
|
||||||
void ScrollView::Transfer32bppImage(Pix* image) {
|
void ScrollView::Transfer32bppImage(PIX* image) {
|
||||||
#ifdef HAVE_LIBLEPT
|
|
||||||
int ppL = pixGetWidth(image);
|
int ppL = pixGetWidth(image);
|
||||||
int h = pixGetHeight(image);
|
int h = pixGetHeight(image);
|
||||||
int wpl = pixGetWpl(image);
|
int wpl = pixGetWpl(image);
|
||||||
@ -765,12 +785,10 @@ void ScrollView::Transfer32bppImage(Pix* image) {
|
|||||||
SendRawMessage(pixel_data);
|
SendRawMessage(pixel_data);
|
||||||
}
|
}
|
||||||
delete[] pixel_data;
|
delete[] pixel_data;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends for each pixel either '1' or '0'.
|
// Sends for each pixel either '1' or '0'.
|
||||||
void ScrollView::TransferGrayImage(Pix* image) {
|
void ScrollView::TransferGrayImage(PIX* image) {
|
||||||
#ifdef HAVE_LIBLEPT
|
|
||||||
char* pixel_data = new char[image->w * 2 + 2];
|
char* pixel_data = new char[image->w * 2 + 2];
|
||||||
for (int y = 0; y < image->h; y++) {
|
for (int y = 0; y < image->h; y++) {
|
||||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||||
@ -782,12 +800,10 @@ void ScrollView::TransferGrayImage(Pix* image) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] pixel_data;
|
delete [] pixel_data;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends for each pixel either '1' or '0'.
|
// Sends for each pixel either '1' or '0'.
|
||||||
void ScrollView::TransferBinaryImage(Pix* image) {
|
void ScrollView::TransferBinaryImage(PIX* image) {
|
||||||
#ifdef HAVE_LIBLEPT
|
|
||||||
char* pixel_data = new char[image->w + 2];
|
char* pixel_data = new char[image->w + 2];
|
||||||
for (int y = 0; y < image->h; y++) {
|
for (int y = 0; y < image->h; y++) {
|
||||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||||
@ -802,8 +818,8 @@ void ScrollView::TransferBinaryImage(Pix* image) {
|
|||||||
SendRawMessage(pixel_data);
|
SendRawMessage(pixel_data);
|
||||||
}
|
}
|
||||||
delete [] pixel_data;
|
delete [] pixel_data;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Escapes the ' character with a \, so it can be processed by LUA.
|
// Escapes the ' character with a \, so it can be processed by LUA.
|
||||||
// Note: The caller will have to make sure he deletes the newly allocated item.
|
// Note: The caller will have to make sure he deletes the newly allocated item.
|
||||||
|
@ -201,8 +201,10 @@ class ScrollView {
|
|||||||
* constructor, so this is not listed here)
|
* constructor, so this is not listed here)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBLEPT
|
||||||
// Draw a Pix on (x,y).
|
// Draw a Pix on (x,y).
|
||||||
void Image(struct Pix* image, int x_pos, int y_pos);
|
void Image(struct Pix* image, int x_pos, int y_pos);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Flush buffers and update display.
|
// Flush buffers and update display.
|
||||||
static void Update();
|
static void Update();
|
||||||
@ -345,12 +347,14 @@ class ScrollView {
|
|||||||
int TranslateYCoordinate(int y);
|
int TranslateYCoordinate(int y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef HAVE_LIBLEPT
|
||||||
// Transfers a binary Image.
|
// Transfers a binary Image.
|
||||||
void TransferBinaryImage(struct Pix* image);
|
void TransferBinaryImage(struct Pix* image);
|
||||||
// Transfers a gray scale Image.
|
// Transfers a gray scale Image.
|
||||||
void TransferGrayImage(struct Pix* image);
|
void TransferGrayImage(struct Pix* image);
|
||||||
// Transfers a 32-Bit Image.
|
// Transfers a 32-Bit Image.
|
||||||
void Transfer32bppImage(struct Pix* image);
|
void Transfer32bppImage(struct Pix* image);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Sets up ScrollView, depending on the variables from the constructor.
|
// Sets up ScrollView, depending on the variables from the constructor.
|
||||||
void Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
void Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
||||||
@ -388,6 +392,8 @@ class ScrollView {
|
|||||||
SVPolyLineBuffer* points_;
|
SVPolyLineBuffer* points_;
|
||||||
// Whether the axis is reversed.
|
// Whether the axis is reversed.
|
||||||
bool y_axis_is_reversed_;
|
bool y_axis_is_reversed_;
|
||||||
|
// Set to true only after the event handler has terminated.
|
||||||
|
bool event_handler_ended_;
|
||||||
// If the y axis is reversed, flip all y values by ySize.
|
// If the y axis is reversed, flip all y values by ySize.
|
||||||
int y_size_;
|
int y_size_;
|
||||||
// # of created windows (used to assign an id to each ScrollView* for svmap).
|
// # of created windows (used to assign an id to each ScrollView* for svmap).
|
||||||
|
@ -24,9 +24,17 @@
|
|||||||
|
|
||||||
#include "svutil.h"
|
#include "svutil.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
|
struct addrinfo {
|
||||||
|
struct sockaddr* ai_addr;
|
||||||
|
int ai_addrlen;
|
||||||
|
int ai_family;
|
||||||
|
int ai_socktype;
|
||||||
|
int ai_protocol;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -39,13 +47,11 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
const int kBufferSize = 65536;
|
const int kBufferSize = 65536;
|
||||||
const int kMaxMsgSize = 4096;
|
const int kMaxMsgSize = 4096;
|
||||||
@ -252,44 +258,133 @@ void SVNetwork::Close() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up a connection to hostname on port.
|
|
||||||
SVNetwork::SVNetwork(const char* hostname, int port) {
|
|
||||||
mutex_send_ = new SVMutex();
|
|
||||||
struct sockaddr_in address;
|
|
||||||
struct hostent *name;
|
|
||||||
|
|
||||||
msg_buffer_in_ = new char[kMaxMsgSize + 1];
|
// The program to invoke to start ScrollView
|
||||||
msg_buffer_in_[0] = '\0';
|
static const char* ScrollViewProg() {
|
||||||
|
#ifdef WIN32
|
||||||
|
const char* prog = "java -Xms512m -Xmx1024m";
|
||||||
|
#else
|
||||||
|
const char* prog = "sh";
|
||||||
|
#endif
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
has_content = false;
|
|
||||||
|
|
||||||
buffer_ptr_ = NULL;
|
// The arguments to the program to invoke to start ScrollView
|
||||||
|
static std::string ScrollViewCommand(std::string scrollview_path) {
|
||||||
|
// The following ugly ifdef is to enable the output of the java runtime
|
||||||
|
// to be sent down a black hole on non-windows to ignore all the
|
||||||
|
// exceptions in piccolo. Ideally piccolo would be debugged to make
|
||||||
|
// this unnecessary.
|
||||||
|
// Also the path has to be separated by ; on windows and : otherwise.
|
||||||
|
#ifdef WIN32
|
||||||
|
const char* cmd_template = "-Djava.library.path=%s -cp %s/ScrollView.jar;"
|
||||||
|
"%s/piccolo-1.2.jar;%s/piccolox-1.2.jar"
|
||||||
|
" com.google.scrollview.ScrollView";
|
||||||
|
#else
|
||||||
|
const char* cmd_template = "-c \"trap 'kill %1' 0 1 2 ; java "
|
||||||
|
"-Xms1024m -Xmx2048m -Djava.library.path=%s -cp %s/ScrollView.jar:"
|
||||||
|
"%s/piccolo-1.2.jar:%s/piccolox-1.2.jar"
|
||||||
|
" com.google.scrollview.ScrollView"
|
||||||
|
" >/dev/null 2>&1 & wait\"";
|
||||||
|
#endif
|
||||||
|
int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path.c_str()) + 1;
|
||||||
|
char* cmd = new char[cmdlen];
|
||||||
|
const char* sv_path = scrollview_path.c_str();
|
||||||
|
snprintf(cmd, cmdlen, cmd_template, sv_path, sv_path, sv_path, sv_path);
|
||||||
|
std::string command(cmd);
|
||||||
|
delete [] cmd;
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Platform-independent freeaddrinfo()
|
||||||
|
static void FreeAddrInfo(struct addrinfo* addr_info) {
|
||||||
|
#if defined(__linux__)
|
||||||
|
freeaddrinfo(addr_info);
|
||||||
|
#else
|
||||||
|
delete addr_info->ai_addr;
|
||||||
|
delete addr_info;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Non-linux version of getaddrinfo()
|
||||||
|
#if !defined(__linux__)
|
||||||
|
static int GetAddrInfoNonLinux(const char* hostname, int port,
|
||||||
|
struct addrinfo** addr_info) {
|
||||||
// Get the host data depending on the OS.
|
// Get the host data depending on the OS.
|
||||||
|
struct sockaddr_in* address;
|
||||||
|
*addr_info = new struct addrinfo;
|
||||||
|
memset(*addr_info, 0, sizeof(struct addrinfo));
|
||||||
|
address = new struct sockaddr_in;
|
||||||
|
memset(address, 0, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
(*addr_info)->ai_addr = (struct sockaddr*) address;
|
||||||
|
(*addr_info)->ai_addrlen = sizeof(struct sockaddr);
|
||||||
|
(*addr_info)->ai_family = AF_INET;
|
||||||
|
(*addr_info)->ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
struct hostent *name;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
||||||
name = gethostbyname(hostname);
|
name = gethostbyname(hostname);
|
||||||
#elif defined(__linux__)
|
|
||||||
struct hostent hp;
|
|
||||||
int herr;
|
|
||||||
char *buffer = new char[kBufferSize];
|
|
||||||
gethostbyname_r(hostname, &hp, buffer, kBufferSize, &name, &herr);
|
|
||||||
delete[] buffer;
|
|
||||||
#else
|
#else
|
||||||
name = gethostbyname(hostname);
|
name = gethostbyname(hostname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fill in the appropriate variables to be able to connect to the server.
|
if (name == NULL) {
|
||||||
address.sin_family = name->h_addrtype;
|
FreeAddrInfo(*addr_info);
|
||||||
memcpy((char *) &address.sin_addr.s_addr,
|
*addr_info = NULL;
|
||||||
name->h_addr_list[0], name->h_length);
|
return -1;
|
||||||
address.sin_port = htons(port);
|
}
|
||||||
|
|
||||||
stream_ = socket(AF_INET, SOCK_STREAM, 0);
|
// Fill in the appropriate variables to be able to connect to the server.
|
||||||
|
address->sin_family = name->h_addrtype;
|
||||||
|
memcpy((char *) &address->sin_addr.s_addr,
|
||||||
|
name->h_addr_list[0], name->h_length);
|
||||||
|
address->sin_port = htons(port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Platform independent version of getaddrinfo()
|
||||||
|
// Given a hostname:port, produce an addrinfo struct
|
||||||
|
static int GetAddrInfo(const char* hostname, int port,
|
||||||
|
struct addrinfo** address) {
|
||||||
|
#if defined(__linux__)
|
||||||
|
char port_str[40];
|
||||||
|
snprintf(port_str, 40, "%d", port);
|
||||||
|
return getaddrinfo(hostname, port_str, NULL, address);
|
||||||
|
#else
|
||||||
|
return GetAddrInfoNonLinux(hostname, port, address);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set up a connection to a ScrollView on hostname:port.
|
||||||
|
SVNetwork::SVNetwork(const char* hostname, int port) {
|
||||||
|
mutex_send_ = new SVMutex();
|
||||||
|
msg_buffer_in_ = new char[kMaxMsgSize + 1];
|
||||||
|
msg_buffer_in_[0] = '\0';
|
||||||
|
|
||||||
|
has_content = false;
|
||||||
|
buffer_ptr_ = NULL;
|
||||||
|
|
||||||
|
struct addrinfo *addr_info = NULL;
|
||||||
|
|
||||||
|
if (GetAddrInfo(hostname, port, &addr_info) != 0) {
|
||||||
|
std::cerr << "Error resolving name for ScrollView host "
|
||||||
|
<< std::string(hostname) << ":" << port << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
|
||||||
|
addr_info->ai_protocol);
|
||||||
|
|
||||||
// If server is not there, we will start a new server as local child process.
|
// If server is not there, we will start a new server as local child process.
|
||||||
if (connect(stream_, (struct sockaddr *) &address, sizeof(address)) < 0) {
|
if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
|
||||||
const char* scrollview_path = getenv("SCROLLVIEW_PATH");
|
const char* scrollview_path = getenv("SCROLLVIEW_PATH");
|
||||||
if (scrollview_path == NULL) {
|
if (scrollview_path == NULL) {
|
||||||
#ifdef SCROLLVIEW_PATH
|
#ifdef SCROLLVIEW_PATH
|
||||||
@ -302,36 +397,14 @@ SVNetwork::SVNetwork(const char* hostname, int port) {
|
|||||||
scrollview_path = ".";
|
scrollview_path = ".";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// The following ugly ifdef is to enable the output of the java runtime
|
const char *prog = ScrollViewProg();
|
||||||
// to be sent down a black hole on non-windows to ignore all the
|
std::string command = ScrollViewCommand(scrollview_path);
|
||||||
// exceptions in piccolo. Ideally piccolo would be debugged to make
|
SVSync::StartProcess(prog, command.c_str());
|
||||||
// this unnecessary.
|
|
||||||
// Also the path has to be separated by ; on windows and : otherwise.
|
|
||||||
#ifdef WIN32
|
|
||||||
const char* prog = "java -Xms512m -Xmx1024m";
|
|
||||||
const char* cmd_template = "-Djava.library.path=%s -cp %s/ScrollView.jar;"
|
|
||||||
"%s/piccolo-1.2.jar;%s/piccolox-1.2.jar"
|
|
||||||
" com.google.scrollview.ScrollView";
|
|
||||||
#else
|
|
||||||
const char* prog = "sh";
|
|
||||||
const char* cmd_template = "-c \"trap 'kill %1' 0 1 2 ; java "
|
|
||||||
"-Xms1024m -Xmx2048m -Djava.library.path=%s -cp %s/ScrollView.jar:"
|
|
||||||
"%s/piccolo-1.2.jar:%s/piccolox-1.2.jar"
|
|
||||||
" com.google.scrollview.ScrollView"
|
|
||||||
" >/dev/null 2>&1 & wait\"";
|
|
||||||
#endif
|
|
||||||
int cmdlen = strlen(cmd_template) + 4*strlen(scrollview_path) + 1;
|
|
||||||
char* cmd = new char[cmdlen];
|
|
||||||
snprintf(cmd, cmdlen, cmd_template, scrollview_path, scrollview_path,
|
|
||||||
scrollview_path, scrollview_path);
|
|
||||||
|
|
||||||
SVSync::StartProcess(prog, cmd);
|
|
||||||
delete [] cmd;
|
|
||||||
|
|
||||||
// Wait for server to show up.
|
// Wait for server to show up.
|
||||||
// Note: There is no exception handling in case the server never turns up.
|
// Note: There is no exception handling in case the server never turns up.
|
||||||
while (connect(stream_, (struct sockaddr *) &address,
|
while (connect(stream_, (struct sockaddr *) addr_info->ai_addr,
|
||||||
sizeof(address)) < 0) {
|
addr_info->ai_addrlen) < 0) {
|
||||||
std::cout << "ScrollView: Waiting for server...\n";
|
std::cout << "ScrollView: Waiting for server...\n";
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
@ -340,6 +413,7 @@ SVNetwork::SVNetwork(const char* hostname, int port) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FreeAddrInfo(addr_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
SVNetwork::~SVNetwork() {
|
SVNetwork::~SVNetwork() {
|
||||||
|
@ -105,13 +105,17 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
Optimization="2"
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
|
WholeProgramOptimization="false"
|
||||||
AdditionalIncludeDirectories="..\include"
|
AdditionalIncludeDirectories="..\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;__MSW32__;_CRT_SECURE_NO_WARNINGS;HAVE_LIBLEPT;LEPTONLIB_IMPORTS"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;__MSW32__;_CRT_SECURE_NO_WARNINGS;HAVE_LIBLEPT;LEPTONLIB_IMPORTS"
|
||||||
|
StringPooling="true"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
DebugInformationFormat="3"
|
DebugInformationFormat="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
Loading…
Reference in New Issue
Block a user