mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-11-27 20:59:36 +08:00
Updated graphics output for new java-based display
git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@149 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
parent
89a5284c69
commit
1a23b25eeb
@ -1,10 +1,9 @@
|
||||
SUBDIRS =
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/image -I$(top_srcdir)/ccutil
|
||||
AM_CPPFLAGS =
|
||||
|
||||
include_HEADERS = \
|
||||
evntlst.h evnts.h grphics.h grphshm.h sbgconst.h sbgdefs.h \
|
||||
sbgtypes.h showim.h
|
||||
scrollview.h svmnode.h svutil.h svpaint.cpp
|
||||
|
||||
lib_LIBRARIES = libtesseract_viewer.a
|
||||
libtesseract_viewer_a_SOURCES = \
|
||||
evntlst.cpp grphics.cpp evnts.cpp showim.cpp grphshm.cpp
|
||||
scrollview.cpp svmnode.cpp svutil.cpp
|
||||
|
@ -75,13 +75,13 @@ RANLIB = @RANLIB@
|
||||
VERSION = @VERSION@
|
||||
|
||||
SUBDIRS =
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/image -I$(top_srcdir)/ccutil
|
||||
AM_CPPFLAGS =
|
||||
|
||||
include_HEADERS = evntlst.h evnts.h grphics.h grphshm.h sbgconst.h sbgdefs.h sbgtypes.h showim.h
|
||||
include_HEADERS = scrollview.h svmnode.h svutil.h svpaint.cpp
|
||||
|
||||
|
||||
lib_LIBRARIES = libtesseract_viewer.a
|
||||
libtesseract_viewer_a_SOURCES = evntlst.cpp grphics.cpp evnts.cpp showim.cpp grphshm.cpp
|
||||
libtesseract_viewer_a_SOURCES = scrollview.cpp svmnode.cpp svutil.cpp
|
||||
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = ../config_auto.h
|
||||
@ -94,8 +94,7 @@ CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libtesseract_viewer_a_LIBADD =
|
||||
libtesseract_viewer_a_OBJECTS = evntlst.o grphics.o evnts.o showim.o \
|
||||
grphshm.o
|
||||
libtesseract_viewer_a_OBJECTS = scrollview.o svmnode.o svutil.o
|
||||
AR = ar
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
@ -110,8 +109,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DEP_FILES = .deps/evntlst.P .deps/evnts.P .deps/grphics.P \
|
||||
.deps/grphshm.P .deps/showim.P
|
||||
DEP_FILES = .deps/scrollview.P .deps/svmnode.P .deps/svutil.P
|
||||
SOURCES = $(libtesseract_viewer_a_SOURCES)
|
||||
OBJECTS = $(libtesseract_viewer_a_OBJECTS)
|
||||
|
||||
|
@ -1,344 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: evntlst.c (Formerly eventlst.c)
|
||||
* Description: Code to manipulate lists of events.
|
||||
* Author: Ray Smith
|
||||
* Created: Fri Nov 01 11:02:52 GMT 1991
|
||||
*
|
||||
* (C) Copyright 1991, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "mfcpch.h"
|
||||
#include "grphshm.h"
|
||||
#include "grphics.h"
|
||||
#ifdef __UNIX__
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
//#include "pipes.h"
|
||||
#include "fileerr.h"
|
||||
//#include "sbderrs.h"
|
||||
//#include "grpherr.h"
|
||||
#elif defined (__MSW32__)
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "evntlst.h"
|
||||
|
||||
#define EXTERN
|
||||
//anything new in queue
|
||||
EXTERN BOOL8 event_waiting = FALSE;
|
||||
|
||||
#ifdef __UNIX__
|
||||
//semaphore count
|
||||
static INT32 event_critical_section = 0;
|
||||
//true if pending
|
||||
static BOOL8 event_pending = FALSE;
|
||||
EXTERN BOOL8 handler_set; //true if signal handler on
|
||||
EXTERN STRING_VAR (events_logfile, "", "File to log events to");
|
||||
EXTERN STRING_VAR (events_playback, "", "File to read events from");
|
||||
|
||||
/**********************************************************************
|
||||
* event_handler
|
||||
*
|
||||
* Handler for signal.
|
||||
* If not critical, read events now, otherwise, set pending flag.
|
||||
**********************************************************************/
|
||||
|
||||
void event_handler( //signal handler
|
||||
int, //signal
|
||||
int, //code
|
||||
struct sigcontext *scp //info for sigvector
|
||||
) {
|
||||
// scp->sc_syscall_action=SIG_RESTART; //restart sys calls
|
||||
event_pending = TRUE;
|
||||
if (!event_critical_section) {
|
||||
lock_events();
|
||||
unlock_events();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* check_event
|
||||
*
|
||||
* See if any events are available, and if there are, return 1, else 0.
|
||||
**********************************************************************/
|
||||
|
||||
BOOL8 check_event( /*test for event */
|
||||
INT16 fd, /*window to wait on */
|
||||
BOOL8 wait /*set if waiting */
|
||||
) {
|
||||
GRAPHICS_EVENT event; /*event from daemon */
|
||||
SBD_GRAPHICS_EVENT sbd_event; //event from pipe
|
||||
BOOL8 gotone; /*repeat while do */
|
||||
INT32 time; /*time to select */
|
||||
INT32 typein; //input type
|
||||
INT32 keyin; //input key
|
||||
INT32 fdin; //input fd
|
||||
int scanresult; //of fscanf
|
||||
static FILE *eventsin = NULL; //input file
|
||||
|
||||
// && sbfds[fd].used!=1)
|
||||
if (fd < 0 || fd > maxsbfd || fd > 0) {
|
||||
// BADSBFD.error("check_event",TESSLOG,NULL); /*report error*/
|
||||
return FALSE;
|
||||
}
|
||||
time = wait ? AWAIT_TIME : CHECK_TIME;
|
||||
gotone = FALSE;
|
||||
while (!gotone
|
||||
&& (events_playback.string ()[0] != '\0' || eventsin != NULL)) {
|
||||
if (eventsin == NULL && events_playback.string ()[0] != '\0') {
|
||||
if ((eventsin = fopen (events_playback.string (), "r")) == NULL)
|
||||
CANTOPENFILE.error ("check_event", TESSLOG,
|
||||
events_playback.string ());
|
||||
//remove name
|
||||
events_playback.set_value (NULL);
|
||||
}
|
||||
if (eventsin != NULL) {
|
||||
scanresult =
|
||||
fscanf (eventsin,
|
||||
INT32FORMAT " " INT32FORMAT "(%f,%f) on " INT32FORMAT,
|
||||
&typein, &keyin, &event.x, &event.y, &fdin);
|
||||
if (scanresult != 5) {
|
||||
if (scanresult == EOF)
|
||||
fprintf (stderr, "Closing input event file\n");
|
||||
else
|
||||
fprintf (stderr, "Error on event input: copied %d values\n",
|
||||
scanresult);
|
||||
fclose(eventsin);
|
||||
eventsin = NULL;
|
||||
}
|
||||
else {
|
||||
// fprintf(stderr,"Read input on %d\n", fdin );
|
||||
event.type = (INT8) typein;
|
||||
event.key = (char) keyin;
|
||||
event.fildes = fdin;
|
||||
add_event(&event); //got one
|
||||
gotone = gotone || fd == 0 || fd == event.fildes;
|
||||
/*know if we got one */
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!gotone) { // && select_read(shminfo.fds[INFD],time)!=0) /*event available*/
|
||||
if (read (shminfo.fds[INFD], &sbd_event, sizeof (SBD_GRAPHICS_EVENT))
|
||||
!= sizeof (SBD_GRAPHICS_EVENT))
|
||||
READFAILED.error ("check_event", EXIT, "sbdaemon pipe");
|
||||
if (sbd_event.type != QUEUE_CLEAR) {
|
||||
event.fildes = sbd_event.fd;
|
||||
event.type = sbd_event.type;
|
||||
event.key = sbd_event.key;
|
||||
event.x = sbd_event.x;
|
||||
event.y = sbd_event.y;
|
||||
event.next = NULL;
|
||||
add_event(&event); /*add event to queue */
|
||||
/*know if we got one */
|
||||
gotone = gotone || fd == 0 || fd == event.fildes;
|
||||
}
|
||||
else
|
||||
kick_daemon(COUNT_READS); /*keep count accurate */
|
||||
time = CHECK_TIME;
|
||||
}
|
||||
return gotone;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
EXTERN HANDLE event_sem = NULL; //event lock
|
||||
|
||||
/**********************************************************************
|
||||
* event_reader
|
||||
*
|
||||
* A separate thread that reads the input from the pipe and places
|
||||
* events in the appropriate queue. This thread also calls any appropriate
|
||||
* event handler on receiving an event.
|
||||
**********************************************************************/
|
||||
|
||||
void event_reader( /*read events */
|
||||
void *param /*file descriptor */
|
||||
) {
|
||||
#ifndef __MAC__
|
||||
//real file descriptor
|
||||
HANDLE *fdptr = (HANDLE *) param;
|
||||
HANDLE fd = *fdptr; //real file descriptor
|
||||
unsigned long nread; //bytes read
|
||||
SBD_GRAPHICS_EVENT event; /*event from daemon */
|
||||
GRAPHICS_EVENT real_event; //converted format
|
||||
char pipe_char[2]; //from pipe
|
||||
INT32 pipe_index; //index to event queue
|
||||
|
||||
event_id = GetCurrentThreadId ();
|
||||
while (ReadFile (fd, pipe_char, 2, &nread, NULL) != 0 && nread == 2) {
|
||||
pipe_index = EVENT_HEAD;
|
||||
event = EVENT_INDEX (pipe_index);
|
||||
pipe_index++;
|
||||
if (pipe_index >= EVENTSIZE)
|
||||
pipe_index = 0;
|
||||
EVENT_HEAD = pipe_index;
|
||||
if (event.type != QUEUE_CLEAR) {
|
||||
real_event.fildes = event.fd;
|
||||
real_event.type = event.type;
|
||||
real_event.key = event.key;
|
||||
real_event.x = event.x;
|
||||
real_event.y = event.y;
|
||||
real_event.next = NULL;
|
||||
add_event(&real_event); /*add event to queue */
|
||||
}
|
||||
else
|
||||
kick_daemon(COUNT_READS); /*got acknowledge */
|
||||
}
|
||||
CloseHandle(fd);
|
||||
*fdptr = NULL;
|
||||
_endthread();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* add_event
|
||||
*
|
||||
* Adds an event from the sbdaemon to the correct event queue.
|
||||
**********************************************************************/
|
||||
|
||||
void add_event( /*add an event */
|
||||
GRAPHICS_EVENT *event /*event to add */
|
||||
) {
|
||||
GRAPHICS_EVENT *newevent; /*new event */
|
||||
EVENT_HANDLER handler; //avoid race hazards
|
||||
GRAPHICS_EVENT sel_event; //selection
|
||||
//last button down
|
||||
static GRAPHICS_EVENT last_down;
|
||||
|
||||
#ifdef __UNIX__
|
||||
static FILE *eventsout = NULL; //output file
|
||||
static STRING outname; //output name
|
||||
|
||||
//doing anything
|
||||
if (events_logfile.string ()[0] != '\0' || eventsout != NULL) {
|
||||
if (eventsout != NULL //already open
|
||||
&& outname != (STRING &) events_logfile) {
|
||||
fclose(eventsout); //finished that one
|
||||
eventsout = NULL;
|
||||
}
|
||||
//needs opening
|
||||
if (eventsout == NULL && events_logfile.string ()[0] != '\0') {
|
||||
//save name
|
||||
outname = events_logfile.string ();
|
||||
if ((eventsout = fopen (outname.string (), "w")) == NULL)
|
||||
CANTOPENFILE.error ("add_event", TESSLOG, outname.string ());
|
||||
}
|
||||
if (eventsout != NULL)
|
||||
fprintf (eventsout, "%d %d(%f,%f) on %d\n",
|
||||
event->type, event->key, event->x, event->y, event->fildes);
|
||||
}
|
||||
#endif
|
||||
// fprintf(stderr,"Received event of type %d at (%f,%f) on %d\n",
|
||||
// event->type,event->x,event->y,event->fildes);
|
||||
event->fd = &sbfds[event->fildes];
|
||||
switch (event->type) {
|
||||
case DOWN_EVENT:
|
||||
last_down = *event; //save it
|
||||
handler = sbfds[event->fildes].click_handler;
|
||||
if (handler != NULL) {
|
||||
(*handler) (event);
|
||||
return; //done it
|
||||
}
|
||||
break;
|
||||
case UP_EVENT:
|
||||
sel_event = *event;
|
||||
if (last_down.x > event->x)
|
||||
sel_event.xmax = last_down.x;
|
||||
else {
|
||||
sel_event.xmax = event->x;
|
||||
sel_event.x = last_down.x;
|
||||
}
|
||||
if (last_down.y > event->y)
|
||||
sel_event.ymax = last_down.y;
|
||||
else {
|
||||
sel_event.ymax = event->y;
|
||||
sel_event.y = last_down.y;
|
||||
}
|
||||
handler = sbfds[event->fildes].selection_handler;
|
||||
if (handler != NULL) {
|
||||
(*handler) (&sel_event);
|
||||
return; //done it
|
||||
}
|
||||
break;
|
||||
case KEYPRESS_EVENT:
|
||||
handler = sbfds[event->fildes].key_handler;
|
||||
if (handler != NULL) {
|
||||
(*handler) (event);
|
||||
return; //done it
|
||||
}
|
||||
break;
|
||||
case DESTROY_EVENT:
|
||||
handler = sbfds[event->fildes].destroy_handler;
|
||||
if (handler != NULL) {
|
||||
(*handler) (event);
|
||||
// return; //done it
|
||||
}
|
||||
break;
|
||||
}
|
||||
lock_events();
|
||||
newevent = new GRAPHICS_EVENT;
|
||||
if (newevent != NULL) {
|
||||
*newevent = *event; /*copy event */
|
||||
/*first event */
|
||||
if (sbfds[event->fildes].events == NULL)
|
||||
sbfds[event->fildes].events = newevent;
|
||||
else
|
||||
/*add to end */
|
||||
sbfds[event->fildes].lastevent->next = newevent;
|
||||
/*is new end */
|
||||
sbfds[event->fildes].lastevent = newevent;
|
||||
newevent->next = NULL;
|
||||
}
|
||||
event_waiting = TRUE; //added to queue
|
||||
unlock_events();
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* lock_events
|
||||
*
|
||||
* Lock out event handler to protect data structures.
|
||||
**********************************************************************/
|
||||
|
||||
void lock_events() { //lock
|
||||
#ifdef __UNIX__
|
||||
event_critical_section++;
|
||||
#elif defined (__MSW32__)
|
||||
WaitForSingleObject (event_sem, (unsigned long) -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* unlock_events
|
||||
*
|
||||
* Unlock. If event pending deal with it.
|
||||
**********************************************************************/
|
||||
|
||||
void unlock_events() { //lock
|
||||
#ifdef __UNIX__
|
||||
if (event_pending && event_critical_section == 1) {
|
||||
//get all events
|
||||
while (check_event (0, FALSE));
|
||||
event_pending = FALSE;
|
||||
}
|
||||
event_critical_section--;
|
||||
#elif defined (__MSW32__)
|
||||
//release it
|
||||
ReleaseSemaphore (event_sem, 1, NULL);
|
||||
#endif
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: evntlst.h (Formerly eventlst.h)
|
||||
* Description: Code to manipulate lists of events.
|
||||
* Author: Ray Smith
|
||||
* Created: Fri Nov 01 11:02:52 GMT 1991
|
||||
*
|
||||
* (C) Copyright 1991, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef EVNTLST_H
|
||||
#define EVNTLST_H
|
||||
|
||||
#include "sbgtypes.h"
|
||||
extern BOOL8 event_waiting; //anything new in queue
|
||||
#ifdef __UNIX__
|
||||
#include "varable.h"
|
||||
|
||||
extern BOOL8 handler_set; //true if signal handler on
|
||||
extern STRING_VAR_H (events_logfile, "", "File to log events to");
|
||||
extern STRING_VAR_H (events_playback, "", "File to read events from");
|
||||
void event_handler( //signal handler
|
||||
int, //signal
|
||||
int, //code
|
||||
struct sigcontext *scp //info for sigvector
|
||||
);
|
||||
BOOL8 check_event( /*test for event */
|
||||
INT16 fd, /*window to wait on */
|
||||
BOOL8 wait /*set if waiting */
|
||||
);
|
||||
#else /* */
|
||||
extern HANDLE event_sem; //event lock
|
||||
void event_reader( /*read events */
|
||||
void *param /*file descriptor */
|
||||
);
|
||||
#endif
|
||||
void add_event( /*add an event */
|
||||
GRAPHICS_EVENT *event /*event to add */
|
||||
);
|
||||
void lock_events(); //lock
|
||||
void unlock_events(); //lock
|
||||
#endif
|
349
viewer/evnts.cpp
349
viewer/evnts.cpp
@ -1,349 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: evnts.c (Formerly events.c)
|
||||
* Description: Additional functions needed to receive graphics events.
|
||||
* Author: Ray Smith
|
||||
* Created: Thu May 24 14:13:00 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "mfcpch.h"
|
||||
#ifdef __UNIX__
|
||||
#include "sbderrs.h"
|
||||
#include "fileerr.h"
|
||||
#include "grpherr.h"
|
||||
#endif
|
||||
#include "grphshm.h"
|
||||
#include "evntlst.h"
|
||||
#include "evnts.h"
|
||||
|
||||
#define EXTERN
|
||||
DLLSYM EVENT_HANDLER win_selection_handler;
|
||||
WINDOW (*await_event_func) (WINDOW, BOOL8, INT8, GRAPHICS_EVENT *) =
|
||||
def_await_event;
|
||||
|
||||
//local non-public functions
|
||||
GRAPHICS_EVENT *find_event( /*wait for event */
|
||||
INT16 &fd, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
INT8 event_type /*type to look for */
|
||||
);
|
||||
/*search for event */
|
||||
GRAPHICS_EVENT *search_event_queue(INT16 &fd, /*queue to search */
|
||||
INT8 event_type /*type to search for */
|
||||
);
|
||||
/*search for event */
|
||||
GRAPHICS_EVENT *search_single_queue(INT16 fd, /*queue to search */
|
||||
INT8 event_type /*type to search for */
|
||||
);
|
||||
|
||||
/**********************************************************************
|
||||
* await_selection
|
||||
*
|
||||
* Wait (or check) for a selection on the given (or all) fd and return it.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM WINDOW await_selection( /*wait for selection */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
float &xmin, /*coords of selection */
|
||||
float &ymin, /*coords of selection */
|
||||
float &xmax, /*coords of selection */
|
||||
float &ymax /*coords of selection */
|
||||
) {
|
||||
GRAPHICS_EVENT event; /*return event */
|
||||
|
||||
win = await_event (win, wait, SELECT_EVENT, &event);
|
||||
if (event.type == DESTROY_EVENT)
|
||||
return NULL; //was destroyed
|
||||
if (win != NULL) {
|
||||
xmin = event.x; /*get coords */
|
||||
ymin = event.y;
|
||||
xmax = event.xmax; /*get coords */
|
||||
ymax = event.ymax;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* await_click
|
||||
*
|
||||
* Wait (or check) for a click on the given (or all) fd and return it.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM WINDOW await_click( /*wait for click */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
float &x, /*coords of click */
|
||||
float &y /*coords of click */
|
||||
) {
|
||||
GRAPHICS_EVENT event; /*return event */
|
||||
|
||||
win = await_event (win, wait, DOWN_EVENT, &event);
|
||||
if (event.type == DESTROY_EVENT)
|
||||
return NULL; //was destroyed
|
||||
if (win != NULL) {
|
||||
x = event.x; /*get coords */
|
||||
y = event.y;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* await_key
|
||||
*
|
||||
* Wait (or check) for a key on the given (or all) fd and return it.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM WINDOW await_key( /*wait for key */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
char &c /*return character */
|
||||
) {
|
||||
GRAPHICS_EVENT event; /*return event */
|
||||
|
||||
win = await_event (win, wait, KEYPRESS_EVENT, &event);
|
||||
if (event.type == DESTROY_EVENT)
|
||||
return NULL; //was destroyed
|
||||
if (win != NULL)
|
||||
c = event.key; /*get keypress */
|
||||
return win;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* await_event
|
||||
*
|
||||
* Wait (or check) for a event on the given (or all) fd and return it.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM WINDOW def_await_event( /*wait for event */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
INT8 event_type, /*type to wait for */
|
||||
GRAPHICS_EVENT *out_event /*output event */
|
||||
) {
|
||||
GRAPHICS_EVENT *event; /*return event */
|
||||
INT16 fd; //file descriptor
|
||||
|
||||
if (win == NULL)
|
||||
fd = 0;
|
||||
else
|
||||
fd = win->get_fd ();
|
||||
/*look for one */
|
||||
event = find_event (fd, wait, event_type);
|
||||
if (event == NULL)
|
||||
return NULL; /*not found */
|
||||
else {
|
||||
*out_event = *event; /*copy event */
|
||||
if (event->type != DESTROY_EVENT)
|
||||
delete event; //free the element
|
||||
return out_event->fd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* find_event
|
||||
*
|
||||
* Search the queue for an event of a given type, and return it.
|
||||
* Read or wait until one turns up if there is not one already.
|
||||
**********************************************************************/
|
||||
|
||||
GRAPHICS_EVENT *find_event( /*wait for event */
|
||||
INT16 &fd, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
INT8 event_type /*type to look for */
|
||||
) {
|
||||
GRAPHICS_EVENT *event; /*return event */
|
||||
|
||||
/*look for one */
|
||||
event = search_event_queue (fd, event_type);
|
||||
if (event == NULL) {
|
||||
do {
|
||||
#ifdef __UNIX__
|
||||
if (check_event (fd, wait))
|
||||
#elif defined (__MSW32__)
|
||||
if (wait)
|
||||
Sleep (50);
|
||||
if (event_waiting)
|
||||
#endif
|
||||
{
|
||||
// fprintf(stderr,"Got an event:searching queue %d\n",fd);
|
||||
/*try after reading */
|
||||
event = search_event_queue (fd, event_type);
|
||||
}
|
||||
}
|
||||
while (wait && event == NULL);
|
||||
}
|
||||
// if (event!=NULL)
|
||||
// event->fd=&sbfds[fd];
|
||||
return event; /*event located */
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* search_event_queue
|
||||
*
|
||||
* Search the event queue(s) for events of a particular type.
|
||||
* If found, it is removed from the queue and returned.
|
||||
**********************************************************************/
|
||||
|
||||
GRAPHICS_EVENT *search_event_queue( /*search for event */
|
||||
INT16 &fd, /*queue to search */
|
||||
INT8 event_type /*type to search for */
|
||||
) {
|
||||
GRAPHICS_EVENT *event; /*event from daemon */
|
||||
INT16 testfd; /*test window */
|
||||
|
||||
if (fd < 0 || fd > maxsbfd || fd > 0 && sbfds[fd].used != 1) {
|
||||
return NULL;
|
||||
}
|
||||
if (fd > 0)
|
||||
/*just one to search */
|
||||
return search_single_queue (fd, event_type);
|
||||
else {
|
||||
for (testfd = 1; testfd < maxsbfd; testfd++) {
|
||||
if (sbfds[testfd].used) {
|
||||
event = search_single_queue (testfd, event_type);
|
||||
if (event != NULL) {
|
||||
fd = testfd; /*successful window */
|
||||
return event; /*got one */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL; /*found nothing */
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* search_single_queue
|
||||
*
|
||||
* Search the event queue for events of a particular type.
|
||||
* If found, it is removed from the queue and returned.
|
||||
**********************************************************************/
|
||||
|
||||
GRAPHICS_EVENT *search_single_queue( /*search for event */
|
||||
INT16 fd, /*queue to search */
|
||||
INT8 event_type /*type to search for */
|
||||
) {
|
||||
GRAPHICS_EVENT *event; /*event from daemon */
|
||||
GRAPHICS_EVENT *prev; /*previous event */
|
||||
GRAPHICS_EVENT *event2; /*2nd event */
|
||||
GRAPHICS_EVENT *prev2; /*2nd previous */
|
||||
GRAPHICS_EVENT *nextevent; /*next event in list */
|
||||
BOOL8 any_destroy = FALSE;
|
||||
|
||||
lock_events();
|
||||
event_waiting = FALSE; //done a scan
|
||||
prev = NULL; /*previous event */
|
||||
event2 = NULL; /*2nd event */
|
||||
if (event_type == ANY_EVENT) {
|
||||
event = sbfds[fd].events; /*start of queue */
|
||||
}
|
||||
else if (event_type == SELECT_EVENT) {
|
||||
for (prev = NULL, event = sbfds[fd].events; event != NULL
|
||||
&& event->type != DOWN_EVENT; event = nextevent) {
|
||||
//Delete up events that are in the list prior to a down event
|
||||
nextevent = event->next; /*next in list */
|
||||
if (event->type == UP_EVENT) {
|
||||
if (prev == NULL)
|
||||
/*new head */
|
||||
sbfds[fd].events = nextevent;
|
||||
else
|
||||
prev->next = nextevent;/*delete event */
|
||||
if (nextevent == NULL)
|
||||
/*new last element */
|
||||
sbfds[fd].lastevent = prev;
|
||||
delete event;
|
||||
}
|
||||
else
|
||||
prev = event;
|
||||
if (event->type == DESTROY_EVENT)
|
||||
any_destroy = TRUE;
|
||||
}
|
||||
if (event == NULL) {
|
||||
unlock_events();
|
||||
if (any_destroy)
|
||||
return search_single_queue (fd, DESTROY_EVENT);
|
||||
return NULL; /*no good */
|
||||
}
|
||||
for (prev2 = event, event2 = event->next; event2 != NULL
|
||||
&& event2->type != UP_EVENT;
|
||||
prev2 = event2, event2 = event2->next);
|
||||
if (event2 == NULL) {
|
||||
unlock_events();
|
||||
return NULL; /*no good */
|
||||
}
|
||||
if (prev2 != event) { /*got some intervening */
|
||||
for (prev2 = event->next; prev2 != event2; prev2 = nextevent) {
|
||||
nextevent = prev2->next;
|
||||
delete prev2;
|
||||
}
|
||||
}
|
||||
event->next = event2->next; /*cut out event2 */
|
||||
event2->next = NULL; /*event is new end */
|
||||
|
||||
event->xmax = event2->x; /*get coords */
|
||||
event->ymax = event2->y;
|
||||
if (event->x > event->xmax) {
|
||||
event->xmax = event->x;
|
||||
event->x = event2->x; /*get coords */
|
||||
}
|
||||
if (event->y > event->ymax) {
|
||||
event->ymax = event->y;
|
||||
event->y = event2->y;
|
||||
}
|
||||
delete event2; //free the element
|
||||
}
|
||||
else {
|
||||
for (prev = NULL, event = sbfds[fd].events; event != NULL
|
||||
&& event->type != DESTROY_EVENT
|
||||
&& event->type != event_type; event = nextevent) {
|
||||
nextevent = event->next; /*next in list */
|
||||
/*delete up in front of down */
|
||||
if (event->type == UP_EVENT && event_type == DOWN_EVENT) {
|
||||
if (prev == NULL)
|
||||
/*new head */
|
||||
sbfds[fd].events = nextevent;
|
||||
else
|
||||
prev->next = nextevent;/*delete event */
|
||||
if (nextevent == NULL)
|
||||
/*new last element */
|
||||
sbfds[fd].lastevent = prev;
|
||||
delete event;
|
||||
}
|
||||
else
|
||||
prev = event; /*trailing ptr */
|
||||
}
|
||||
}
|
||||
if (event == NULL) {
|
||||
unlock_events();
|
||||
return NULL; /*no good */
|
||||
}
|
||||
if (event->type != DESTROY_EVENT) {
|
||||
if (prev == NULL)
|
||||
/*new head */
|
||||
sbfds[fd].events = event->next;
|
||||
else
|
||||
prev->next = event->next; /*delete event */
|
||||
if (event->next == NULL)
|
||||
sbfds[fd].lastevent = prev;/*new last event */
|
||||
event->next = NULL; /*possible 2nd event */
|
||||
}
|
||||
unlock_events();
|
||||
return event; /*got one!! */
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: evnts.h (Formerly events.h)
|
||||
* Description: Header of functions and types needed for using events.
|
||||
* Author: Ray Smith
|
||||
* Created: Thu May 24 15:14:45 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef EVNTS_H
|
||||
#define EVNTS_H
|
||||
|
||||
#include "grphics.h"
|
||||
|
||||
extern DLLSYM EVENT_HANDLER win_selection_handler;
|
||||
|
||||
DLLSYM WINDOW await_selection( /*wait for selection */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
float &xmin, /*coords of selection */
|
||||
float &ymin, /*coords of selection */
|
||||
float &xmax, /*coords of selection */
|
||||
float &ymax /*coords of selection */
|
||||
);
|
||||
DLLSYM WINDOW await_click( /*wait for click */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
float &x, /*coords of click */
|
||||
float &y /*coords of click */
|
||||
);
|
||||
DLLSYM WINDOW await_key( /*wait for key */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
char &c /*return character */
|
||||
);
|
||||
DLLSYM WINDOW def_await_event( /*wait for event */
|
||||
WINDOW win, /*window to wait on */
|
||||
BOOL8 wait, /*waiting flag */
|
||||
INT8 event_type, /*type to wait for */
|
||||
GRAPHICS_EVENT *out_event /*output event */
|
||||
);
|
||||
#endif
|
1009
viewer/grphics.cpp
1009
viewer/grphics.cpp
File diff suppressed because it is too large
Load Diff
270
viewer/grphics.h
270
viewer/grphics.h
@ -1,270 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: grphics.h (Formerly graphics.h)
|
||||
* Description: Starbase stubs for connection to sbdaemon
|
||||
* Author: Ray Smith
|
||||
* Created: Wed May 16 08:34:32 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef GRPHICS_H
|
||||
#define GRPHICS_H
|
||||
|
||||
//This is the main include file needed to get sbdaemon functionality
|
||||
//TO BUILD A PROGRAM THAT USES SBDAEMON, YOU NEED:
|
||||
//GRPHICS.CPP GRPHSHM.CPP AND EVNTLST.CPP.
|
||||
//If you want to be able to wait for events, add evnts.cpp and include evnts.h.
|
||||
//If you want to be able to show images, add showim.cpp and include showim.h.
|
||||
|
||||
#include "sbgdefs.h"
|
||||
#include "sbgconst.h"
|
||||
|
||||
#define STATESIZE 13 //MUST equal EDGESTYLE+1
|
||||
|
||||
#define line_color_index(fd,index) fd->Line_color_index(index)
|
||||
#define perimeter_color_index(fd,index) fd->Perimeter_color_index(index)
|
||||
#define fill_color_index(fd,index) fd->Fill_color_index(index)
|
||||
#define fill_color(fd,r,g,b) fd->Fill_color(r,g,b)
|
||||
#define text_color_index(fd,index) fd->Text_color_index(index)
|
||||
#define text_font_index(fd,index) fd->Text_font_index(index)
|
||||
#define character_height(fd,height) fd->Character_height(height)
|
||||
#define line_type(fd,style) fd->Line_type(style)
|
||||
#define interior_style(fd,style,edged) fd->Interior_style(style,edged)
|
||||
#define move2d(fd,x,y) fd->Move2d(x,y)
|
||||
#define draw2d(fd,x,y) fd->Draw2d(x,y)
|
||||
#define rectangle(fd,x1,y1,x2,y2) fd->Rectangle(x1,y1,x2,y2)
|
||||
#define text2d(fd,x,y,string,xform,more) fd->Text2d(x,y,string,xform,more)
|
||||
#define ellipse(fd,x_radius,y_radius,x_center,y_center,rotation) fd->Ellipse(x_radius,y_radius,x_center,y_center,rotation)
|
||||
#define destroy_window(fd) fd->Destroy_window()
|
||||
#define clear_view_surface(fd) fd->Clear_view_surface()
|
||||
#define vdc_extent(fd,xmin,ymin,xmax,ymax) fd->Vdc_extent(xmin,ymin,xmax,ymax)
|
||||
#define make_picture_current(fd) fd->Make_picture_current()
|
||||
#define set_click_handler(fd,handler) fd->Set_click_handler(handler)
|
||||
#define set_selection_handler(fd,handler) fd->Set_selection_handler(handler)
|
||||
#define set_key_handler(fd,handler) fd->Set_key_handler(handler)
|
||||
#define set_destroy_handler(fd,handler) fd->Set_destroy_handler(handler)
|
||||
#define clear_event_queue(fd) fd->Clear_event_queue()
|
||||
#define create_window(name,window_type,xpos,ypos,xsize,ysize,xmin,xmax,ymin,ymax,downon,moveon,upon,keyon) (*create_func)(name,window_type,xpos,ypos,xsize,ysize,xmin,xmax,ymin,ymax,downon,moveon,upon,keyon)
|
||||
#define overlap_picture_ops(update) (*overlap_func)(update)
|
||||
#define await_event(win,wait,type,event) (*await_event_func)(win,wait,type,event)
|
||||
|
||||
typedef void (*EVENT_HANDLER) (GRAPHICS_EVENT *);
|
||||
/*name/title of window */
|
||||
typedef WINDOW (*WINCREATEFUNC) (const char *name,
|
||||
INT8 window_type, /*type of window */
|
||||
INT16 xpos, /*coords of window */
|
||||
INT16 ypos, /*coords of window */
|
||||
INT16 xsize, /*size of window */
|
||||
INT16 ysize, /*size of window */
|
||||
float xmin, /*scrolling limits */
|
||||
float xmax, /*to stop users */
|
||||
float ymin, /*getting lost in */
|
||||
float ymax, /*empty space */
|
||||
BOOL8 downon, /*Events wanted */
|
||||
BOOL8 moveon, BOOL8 upon, BOOL8 keyon);
|
||||
|
||||
extern WINCREATEFUNC create_func;
|
||||
extern void (*overlap_func) (BOOL8);
|
||||
extern WINDOW (*await_event_func) (WINDOW, BOOL8, INT8, GRAPHICS_EVENT *);
|
||||
const int kInputSize = 16;
|
||||
extern int input_unicode[kInputSize];
|
||||
|
||||
class DLLSYM WINFD
|
||||
{
|
||||
public:
|
||||
//Constructors for WINFD are host dependent to match different
|
||||
//implementations and are intended to be called only by
|
||||
//create_window. Use create_window to make a window.
|
||||
static WINDOW create( /*create a window */
|
||||
const char *name, /*name/title of window */
|
||||
INT8 window_type, /*type of window */
|
||||
INT16 xpos, /*coords of window */
|
||||
INT16 ypos, /*coords of window */
|
||||
INT16 xsize, /*size of window */
|
||||
INT16 ysize, /*size of window */
|
||||
float xmin, /*scrolling limits */
|
||||
float xmax, /*to stop users */
|
||||
float ymin, /*getting lost in */
|
||||
float ymax, /*empty space */
|
||||
BOOL8 downon, /*Events wanted */
|
||||
BOOL8 moveon,
|
||||
BOOL8 upon,
|
||||
BOOL8 keyon);
|
||||
WINFD(); //constructor
|
||||
virtual ~ WINFD ();
|
||||
|
||||
/*set line colour */
|
||||
virtual void Line_color_index(COLOUR index); /*index to use */
|
||||
/*set perimeter colour */
|
||||
virtual void Perimeter_color_index(COLOUR index); /*index to use */
|
||||
/*set fill colour */
|
||||
virtual void Fill_color_index(COLOUR index); /*index to use */
|
||||
virtual void Fill_color( /*set RGB fill colour */
|
||||
UINT8 red,
|
||||
UINT8 green,
|
||||
UINT8 blue);
|
||||
/*set marker colour */
|
||||
virtual void Marker_color_index(COLOUR index); /*index to use */
|
||||
/*set text colour */
|
||||
virtual void Text_color_index(COLOUR index); /*index to use */
|
||||
/*set text font */
|
||||
virtual void Text_font_index(INT16 index); /*index to use */
|
||||
/*set text height */
|
||||
virtual void Character_height(float height); /*height to use */
|
||||
virtual void Line_type( /*set line type */
|
||||
INT16 style); /*style to use */
|
||||
virtual void Marker_type( /*set marker type */
|
||||
INT16 type); /*type to use */
|
||||
virtual void Interior_style( /*set polygon style */
|
||||
INT16 style, /*style to use */
|
||||
INT16 edged); /*draw edge or not */
|
||||
virtual void Marker_size( /*set marker size */
|
||||
float size); /*size to use */
|
||||
virtual void Move2d( /*move the pen */
|
||||
float x, /*coords to move to */
|
||||
float y); /*coords to move to */
|
||||
virtual void Draw2d( /*draw the pen */
|
||||
float x, /*coords to draw to */
|
||||
float y); /*coords to draw to */
|
||||
virtual void Rectangle( /*draw a rectangle */
|
||||
float x1, /*coords to draw to */
|
||||
float y1, /*coords to draw to */
|
||||
float x2, /*coords to draw to */
|
||||
float y2); /*coords to draw to */
|
||||
virtual void Text_alignment( /*draw a rectangle */
|
||||
INT32 h_select, //horizontal
|
||||
INT32 v_select, //vertical
|
||||
float horiz, /*coords to draw to */
|
||||
float vert); /*coords to draw to */
|
||||
virtual void Polyline2d ( /*draw a polyline */
|
||||
float clist[], /*coordinate list */
|
||||
INT16 numpts, /*number of coords */
|
||||
INT16 flags); /*does it have move/draws */
|
||||
virtual void Polygon2d ( /*draw a polygon */
|
||||
float clist[], /*coordinate list */
|
||||
INT16 numpts, /*number of coords */
|
||||
INT16 flags); /*does it have move/draws */
|
||||
virtual void Polymarker2d ( /*draw a polymarker */
|
||||
float clist[], /*coordinate list */
|
||||
INT16 numpts, /*number of coords */
|
||||
INT16 flags); /*does it have move/draws */
|
||||
virtual void Text2d( /*draw a text */
|
||||
float x, /*coords of text */
|
||||
float y,
|
||||
const char *string, /*text to draw */
|
||||
INT16 xform, /*transform */
|
||||
INT16 more); /*more text? */
|
||||
void Append_text( /*draw a text */
|
||||
const char *string, /*text to draw */
|
||||
INT16 xform, /*transform */
|
||||
INT16 more); /*more text? */
|
||||
virtual void Ellipse( /*draw a ellipse */
|
||||
float x_radius, /*radii of ellipse */
|
||||
float y_radius, /*radii of ellipse */
|
||||
float x_center, /*centre of ellipse */
|
||||
float y_center, /*centre of ellipse */
|
||||
float rotation); /*rotation of ellipse */
|
||||
virtual void Arc( /*draw a arc */
|
||||
float x_radius, /*radii of arc */
|
||||
float y_radius, /*radii of arc */
|
||||
float x_center, /*centre of arc */
|
||||
float y_center, /*centre of arc */
|
||||
float start, /*ends of arc */
|
||||
float stop, /*ends of arc */
|
||||
float rotation, /*rotation of arc */
|
||||
INT16 close_type); /*type of closure */
|
||||
/*destroy a window */
|
||||
virtual void Destroy_window();
|
||||
/*clear window */
|
||||
virtual void Clear_view_surface();
|
||||
/*Mark need to recalc */
|
||||
virtual void Re_compute_colourmap();
|
||||
virtual void Vdc_extent( /*set window focus */
|
||||
float xmin, /*min values */
|
||||
float ymin, /*min values */
|
||||
float xmax, /*max values */
|
||||
float ymax); /*max values */
|
||||
void Set_echo( /*set window echo */
|
||||
ECHO_TYPE echo_type, //type of echo
|
||||
float xorig, /*min values */
|
||||
float yorig); /*min values */
|
||||
/*update window */
|
||||
virtual void Make_picture_current();
|
||||
/*flush output */
|
||||
friend void def_overlap_picture_ops(BOOL8 update); /*send make_ */
|
||||
/*set line colour */
|
||||
virtual void Synchronize_windows(WINDOW fd2); //other window
|
||||
/* void Show_sub_image( //show rectangle
|
||||
IMAGE* source, //source image
|
||||
INT32 xstart, //start coords
|
||||
INT32 ystart,
|
||||
INT32 xext, //extent to copy
|
||||
INT32 yext,
|
||||
INT32 xdest, //destination coords
|
||||
INT32 ydest);*/
|
||||
|
||||
INT16 get_fd() { //access
|
||||
return fd;
|
||||
}
|
||||
|
||||
void Set_selection_handler( //set callback function
|
||||
EVENT_HANDLER handler); //handler function
|
||||
void Set_key_handler( //set callback function
|
||||
EVENT_HANDLER handler); //handler function
|
||||
void Set_destroy_handler( //set callback function
|
||||
EVENT_HANDLER handler); //handler function
|
||||
void Set_click_handler( //set callback function
|
||||
EVENT_HANDLER handler); //handler function
|
||||
/*delete all events */
|
||||
virtual void Clear_event_queue();
|
||||
|
||||
//internal maintenance functions
|
||||
friend void add_event( /*add an event */
|
||||
GRAPHICS_EVENT *event); /*event to add */
|
||||
/*search for event */
|
||||
friend GRAPHICS_EVENT *search_event_queue(INT16 &fd, /*queue to search */
|
||||
INT8 event_type); /*type to search for */
|
||||
/*search for event */
|
||||
friend GRAPHICS_EVENT *search_single_queue(INT16 fd, /*queue to search */
|
||||
INT8 event_type); /*type to search for */
|
||||
|
||||
protected:
|
||||
EVENT_HANDLER click_handler; //callback function
|
||||
//callback function
|
||||
EVENT_HANDLER selection_handler;
|
||||
EVENT_HANDLER key_handler; //callback function
|
||||
//callback function
|
||||
EVENT_HANDLER destroy_handler;
|
||||
private:
|
||||
void get_lock() {
|
||||
} //wait for lock
|
||||
void get_lock_for_draw() {
|
||||
} //kill draw thread
|
||||
void release_lock() {
|
||||
} //let it go
|
||||
void get_core_lock() {
|
||||
} //wait for lock
|
||||
void release_core_lock() {
|
||||
} //let it go
|
||||
|
||||
INT16 fd; //"file descriptor"
|
||||
BOOL8 used; /*true if fd in use */
|
||||
BOOL8 downevent; /*event flags */
|
||||
BOOL8 moveevent;
|
||||
BOOL8 upevent;
|
||||
BOOL8 keyevent;
|
||||
GRAPHICS_EVENT *events; /*event queue */
|
||||
GRAPHICS_EVENT *lastevent; /*event queue */
|
||||
|
||||
};
|
||||
#endif
|
@ -1,472 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: grphshm.c (Formerly graphshm.c)
|
||||
* Description: Functions for the shared memory sbdaemon connection.
|
||||
* Author: Ray Smith
|
||||
* Created: Thu May 24 14:09:38 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "mfcpch.h"
|
||||
#include "evntlst.h"
|
||||
#ifdef __UNIX__
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
//#include <osfcn.h>
|
||||
#include <errno.h>
|
||||
//#include "pipes.h"
|
||||
#include "fileerr.h"
|
||||
//#include "grpherr.h"
|
||||
//#include "basefile.h"
|
||||
#include <unistd.h>
|
||||
#elif defined(__MSW32__)
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <process.h>
|
||||
#include <stdio.h>
|
||||
#else
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "grphics.h"
|
||||
#include "grphshm.h"
|
||||
|
||||
#define EXTERN
|
||||
|
||||
EXTERN SHMINFO shminfo; /*shared memory */
|
||||
EXTERN WINFD sbfds[MAXWINDOWS]; /*file descriptors */
|
||||
EXTERN INT16 maxsbfd = 0; /*no of fds in use */
|
||||
#ifdef __MSW32__
|
||||
//event thread id
|
||||
EXTERN DWORD event_id = (DWORD) - 1;
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* start_sbdaemon
|
||||
*
|
||||
* Creates the shared memory segment and starts up the sbdaemon telling
|
||||
* it info about the segment. This only needs to be called once.
|
||||
* It is called automatically from create_window at the first creation attempt.
|
||||
**********************************************************************/
|
||||
|
||||
void start_sbdaemon() { /*start the daemon */
|
||||
#if defined (__UNIX__) || defined(__MSW32__)
|
||||
char *shmaddr; /*address to attach */
|
||||
char *sbenv; /*SB_DISPLAY_ADDR */
|
||||
INT32 sbaddr; /*starbase address */
|
||||
INT32 wmshm; //windows shared mem
|
||||
char arg1[MAX_PATH]; /*shmid argument */
|
||||
char arg2[MAX_PATH]; /*shmstart argument */
|
||||
char arg3[MAX_PATH]; /*shmsize argument */
|
||||
const char *argv[5]; /*args of sbdaemon */
|
||||
/*for pipe usage */
|
||||
static char pipebuffer[PIPESIZE];
|
||||
|
||||
sbenv = getenv (SBADDR); /*get SB_DISPLAY_ADDR */
|
||||
if (sbenv == NULL || sscanf (sbenv, INT32FORMAT, &sbaddr) != 1)
|
||||
sbaddr = SBDEFAULT;
|
||||
shmaddr = getenv (WMSHM);
|
||||
if (shmaddr == NULL || sscanf (shmaddr, INT32FORMAT, &wmshm) != 1)
|
||||
wmshm = WMSHMDEFAULT;
|
||||
/*default address */
|
||||
shmaddr = (char *) sbaddr - (wmshm + SHMSIZE + SHMOFFSET);
|
||||
|
||||
if (!remote_display (arg1)) {
|
||||
shminfo.shmsize = SHMSIZE; /*size of segment */
|
||||
#ifdef __UNIX__
|
||||
shminfo.shmid = shmget (IPC_PRIVATE, SHMSIZE, USER_RW);
|
||||
/*get shm segment */
|
||||
// if (shminfo.shmid==-1)
|
||||
// NO_SHM_SEGMENT.error("start_sbdaemon",ABORT,"Errno=%d",errno);
|
||||
#ifdef hp9000s800
|
||||
/*attach it */
|
||||
shminfo.shmstart = shmat (shminfo.shmid, 0, 0);
|
||||
if ((int) shminfo.shmstart == -1)
|
||||
#else
|
||||
/*attach it */
|
||||
shminfo.shmstart = shmat (shminfo.shmid, shmaddr, 0);
|
||||
// if (shminfo.shmstart!=shmaddr)
|
||||
#endif
|
||||
// SHM_ATTACH_FAILED.error("start_sbdaemon",ABORT,"Errno=%d",errno);
|
||||
#else
|
||||
SECURITY_ATTRIBUTES security;//for handles
|
||||
|
||||
security.nLength = sizeof (security);
|
||||
security.lpSecurityDescriptor = NULL;
|
||||
//make it inheritable
|
||||
security.bInheritHandle = TRUE;
|
||||
//anonymous
|
||||
shminfo.shmid = CreateFileMapping ((HANDLE) 0xffffffff, &security, PAGE_READWRITE, 0, shminfo.shmsize + 3 * sizeof (INT32) + EVENTSIZE * sizeof (SBD_GRAPHICS_EVENT), NULL);
|
||||
if (shminfo.shmid == NULL) {
|
||||
shminfo.shmstart = NULL;
|
||||
return; //quietly fail
|
||||
}
|
||||
shminfo.shmstart =
|
||||
MapViewOfFile (shminfo.shmid, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (shminfo.shmstart == NULL)
|
||||
return;
|
||||
EVENT_TAIL = 0;
|
||||
EVENT_HEAD = 0;
|
||||
#endif
|
||||
/*set up args */
|
||||
sprintf (arg1, "%d", shminfo.shmid);
|
||||
sprintf (arg2, "%p", shminfo.shmstart);
|
||||
sprintf (arg3, INT32FORMAT, shminfo.shmsize);
|
||||
argv[0] = SBDAEMON; /*set up argv */
|
||||
argv[1] = arg1;
|
||||
argv[2] = arg2;
|
||||
argv[3] = arg3;
|
||||
argv[4] = NULL;
|
||||
}
|
||||
else {
|
||||
shmaddr = NULL; //remote
|
||||
fprintf (stderr, "start_sbdaemon:using %s to connect to machine %s\n",
|
||||
REMSH, arg1);
|
||||
#ifdef __UNIX__
|
||||
shminfo.shmid = -1;
|
||||
#else
|
||||
shminfo.shmid = NULL;
|
||||
#endif
|
||||
/*not using shm */
|
||||
shminfo.shmstart = pipebuffer;
|
||||
shminfo.shmsize = PIPESIZE; /*size of pipe buffer */
|
||||
#ifdef __UNIX__
|
||||
/*command on host */
|
||||
sprintf (arg2, "%s=0x%x; export %s; %s -1 0 " INT32FORMAT " %s", SBADDR, sbaddr, SBADDR, SBDAEMON, shminfo.shmsize, getenv (DISP));
|
||||
#else
|
||||
/*command on host */
|
||||
sprintf (arg2, "%s -1 0 %d %s", SBDAEMON, shminfo.shmsize, getenv (DISP));
|
||||
#endif
|
||||
argv[0] = REMSH; /*set up argv */
|
||||
argv[1] = arg1; /*host to use */
|
||||
argv[2] = arg2;
|
||||
argv[3] = NULL;
|
||||
}
|
||||
|
||||
shminfo.usedsize = 0; /*none used yet */
|
||||
|
||||
#ifdef __UNIX__
|
||||
// shminfo.pid=two_way_pipe(argv[0],argv,shminfo.fds); /*start daemon*/
|
||||
#else
|
||||
if (two_way_pipe (argv[0], argv, shminfo.fds) != 0) {
|
||||
cleanup_sbdaemon();
|
||||
}
|
||||
else {
|
||||
//anonymous
|
||||
event_sem = CreateSemaphore (NULL, 1, 1, NULL);
|
||||
//xiaofan
|
||||
_beginthread (event_reader, 0, &shminfo.fds[INFD]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* cleanup_sbdaemon
|
||||
*
|
||||
* Free system resources for when the daemon has failed or been killed.
|
||||
**********************************************************************/
|
||||
void cleanup_sbdaemon() { /*forget about the daemon */
|
||||
#ifdef __MSW32__
|
||||
if (shminfo.fds[INFD] != NULL) {
|
||||
CloseHandle (shminfo.fds[INFD]);
|
||||
shminfo.fds[INFD] = 0;
|
||||
}
|
||||
if (shminfo.fds[OUTFD] != NULL) {
|
||||
CloseHandle (shminfo.fds[OUTFD]);
|
||||
shminfo.fds[OUTFD] = 0;
|
||||
}
|
||||
if (shminfo.shmstart != NULL) {
|
||||
UnmapViewOfFile (shminfo.shmstart);
|
||||
shminfo.shmstart = NULL;
|
||||
}
|
||||
if (shminfo.shmid != NULL) {
|
||||
CloseHandle (shminfo.shmid);
|
||||
shminfo.shmid = NULL;
|
||||
}
|
||||
if (event_sem != NULL) {
|
||||
CloseHandle(event_sem);
|
||||
event_sem = NULL;
|
||||
}
|
||||
#elif defined(__UNIX__)
|
||||
if (shminfo.fds[INFD] > 0) {
|
||||
close (shminfo.fds[INFD]);
|
||||
shminfo.fds[INFD] = 0;
|
||||
}
|
||||
if (shminfo.fds[OUTFD] > 0) {
|
||||
close (shminfo.fds[OUTFD]);
|
||||
shminfo.fds[OUTFD] = 0;
|
||||
}
|
||||
shminfo.shmstart = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* remote_display
|
||||
*
|
||||
* Returns TRUE if the DISPLAY environment variable points to a
|
||||
* Remote display, and sets the name to the name of the host.
|
||||
* Otherwise, returns FALSE.
|
||||
**********************************************************************/
|
||||
|
||||
BOOL8 remote_display( //check for remote
|
||||
char *name //name of host
|
||||
) {
|
||||
#if defined (__UNIX__) || defined(__MSW32__)
|
||||
char *xenv; /*DISPLAY environ */
|
||||
char *nameend; //end of name
|
||||
#ifdef __UNIX__
|
||||
char thishost[MAX_PATH]; //current host
|
||||
#endif
|
||||
|
||||
xenv = getenv (DISP); /*get display variable */
|
||||
if (xenv != NULL) {
|
||||
strcpy(name, xenv);
|
||||
nameend = strchr (name, ':');
|
||||
if (nameend != NULL)
|
||||
*nameend = '\0'; /*chop display off */
|
||||
nameend = strchr (name, '.');
|
||||
if (nameend != NULL)
|
||||
*nameend = '\0'; /*chop resolv off */
|
||||
#ifdef __UNIX__
|
||||
if (strcmp (name, LOCAL1) && strcmp (name, LOCAL2)
|
||||
&& gethostname (thishost, MAX_PATH) >= 0) {
|
||||
nameend = strchr (thishost, '.');
|
||||
if (nameend != NULL)
|
||||
*nameend = '\0'; /*chop resolv off */
|
||||
if (strcmp (name, thishost)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* getshm
|
||||
*
|
||||
* Get the next element of the shared memory. If there is no more room
|
||||
* in the segment, kick the daemon to get it to empty it out and then
|
||||
* restart the buffer once it acknowledges the cleanout.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM void *getshm( /*get memory */
|
||||
INT32 size /*required size */
|
||||
) {
|
||||
void *segment; /*return segment */
|
||||
|
||||
if (shminfo.shmstart == NULL)
|
||||
return NULL; //no daemon connection
|
||||
size = (size + 3) & ~3;
|
||||
if (size > shminfo.shmsize)
|
||||
return NULL;
|
||||
/*too full? */
|
||||
if (shminfo.usedsize + size > shminfo.shmsize
|
||||
|| shminfo.usedsize < 0) { /*or read pending */
|
||||
kick_daemon(AWAIT_BUFFER); /*get it to read */
|
||||
}
|
||||
/*address of segment */
|
||||
segment = (char *) shminfo.shmstart + shminfo.usedsize;
|
||||
shminfo.usedsize += size; /*sum used sizes */
|
||||
return segment;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* kick_daemon
|
||||
*
|
||||
* Tell the daemon to read the shared memory and perform all the
|
||||
* operations in it. This function blocks until the daemon has
|
||||
* emptied the queue.
|
||||
**********************************************************************/
|
||||
|
||||
void kick_daemon( /*empty queue */
|
||||
INT8 mode /*control mode */
|
||||
) {
|
||||
#ifndef __MAC__
|
||||
SBD_GRAPHICS_EVENT event; /*event from daemon */
|
||||
GRAPHICS_EVENT real_event; //converted format
|
||||
#ifdef __MSW32__
|
||||
unsigned long nwrite;
|
||||
unsigned long nread; //bytes read
|
||||
char pipe_char[2]; //char from pipe
|
||||
INT32 pipe_index; //index to event queue
|
||||
#endif
|
||||
static INT16 reads_pending = 0;/*acknowledges pending */
|
||||
|
||||
if (mode == COUNT_READS) {
|
||||
lock_events();
|
||||
reads_pending--; /*got a read */
|
||||
unlock_events();
|
||||
return;
|
||||
}
|
||||
if (shminfo.shmstart == NULL)
|
||||
return; //no connection
|
||||
if (shminfo.usedsize > 0) {
|
||||
#ifdef __UNIX__
|
||||
if (write
|
||||
(shminfo.fds[OUTFD], (const char *) &shminfo.usedsize,
|
||||
sizeof (INT32)) != sizeof (INT32))
|
||||
WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
|
||||
#else
|
||||
PRIMITIVES = shminfo.usedsize;
|
||||
if (WriteFile (shminfo.fds[OUTFD], "xx", 2, &nwrite, NULL) == 0
|
||||
|| nwrite != 2) {
|
||||
cleanup_sbdaemon();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef __UNIX__
|
||||
if (shminfo.shmid < 0) {
|
||||
if (write (shminfo.fds[OUTFD], (const char *) shminfo.shmstart,
|
||||
shminfo.usedsize) != shminfo.usedsize)
|
||||
WRITEFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
|
||||
#else
|
||||
if (shminfo.shmid == NULL) {
|
||||
if (WriteFile (shminfo.fds[OUTFD], (const char *) shminfo.shmstart,
|
||||
shminfo.usedsize, &nwrite, NULL) == 0
|
||||
|| nwrite != (UINT32) shminfo.usedsize) {
|
||||
cleanup_sbdaemon();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
shminfo.usedsize = 0; /*can use it now */
|
||||
}
|
||||
else
|
||||
shminfo.usedsize = -1; /*need to wait */
|
||||
lock_events();
|
||||
reads_pending++; /*acknowledges due */
|
||||
unlock_events();
|
||||
}
|
||||
if (mode == FLUSH_IN || reads_pending > MAX_PENDING || mode == AWAIT_BUFFER
|
||||
#ifdef __UNIX__
|
||||
&& shminfo.shmid < 0)
|
||||
#else
|
||||
&& shminfo.shmid != NULL)
|
||||
#endif
|
||||
{
|
||||
while (reads_pending > 0) {
|
||||
#ifdef __MSW32__
|
||||
if (event_id == GetCurrentThreadId ()) {
|
||||
if (ReadFile (shminfo.fds[INFD], pipe_char, 2, &nread, NULL) != 0
|
||||
&& nread == 2) {
|
||||
pipe_index = EVENT_HEAD;
|
||||
event = EVENT_INDEX (pipe_index);
|
||||
pipe_index++;
|
||||
if (pipe_index >= EVENTSIZE)
|
||||
pipe_index = 0;
|
||||
EVENT_HEAD = pipe_index;
|
||||
#endif
|
||||
#ifdef __UNIX__
|
||||
if (read
|
||||
(shminfo.fds[INFD], &event,
|
||||
sizeof (SBD_GRAPHICS_EVENT)) !=
|
||||
sizeof (SBD_GRAPHICS_EVENT))
|
||||
READFAILED.error ("kick_daemon", EXIT, "sbdaemon pipe");
|
||||
#endif
|
||||
if (event.type != QUEUE_CLEAR) {
|
||||
real_event.fildes = event.fd;
|
||||
real_event.type = event.type;
|
||||
real_event.key = event.key;
|
||||
real_event.x = event.x;
|
||||
real_event.y = event.y;
|
||||
real_event.next = NULL;
|
||||
/*add event to queue */
|
||||
add_event(&real_event);
|
||||
}
|
||||
else
|
||||
reads_pending--; /*got acknowledge */
|
||||
#ifdef __MSW32__
|
||||
}
|
||||
}
|
||||
else
|
||||
Sleep (50);
|
||||
#endif
|
||||
}
|
||||
if (shminfo.usedsize < 0) //must be reentrant
|
||||
shminfo.usedsize = 0; /*none used now */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __MSW32__
|
||||
/**********************************************************************
|
||||
* two_way_pipe
|
||||
*
|
||||
* Open the process and connect a 2 way pipe to its stdin and stdout.
|
||||
**********************************************************************/
|
||||
|
||||
int
|
||||
two_way_pipe ( //do one file
|
||||
const char *file, //program to run
|
||||
const char *argv[], //args to execvp
|
||||
HANDLE fds[] //output fds
|
||||
) {
|
||||
int argind; //argument index
|
||||
HANDLE infds[2]; //input fds
|
||||
HANDLE outfds[2]; //output fds
|
||||
HANDLE sends[2]; //fds for child
|
||||
HANDLE process; //current process
|
||||
STARTUPINFO start_info; //start information
|
||||
//process info
|
||||
PROCESS_INFORMATION proc_info;
|
||||
char cmd[MAX_PATH * 2]; //final command line
|
||||
|
||||
if (CreatePipe (&infds[0], &infds[1], NULL, PIPESIZE) == 0
|
||||
|| CreatePipe (&outfds[0], &outfds[1], NULL, PIPESIZE) == 0)
|
||||
return -1;
|
||||
/* if (_pipe(infds,PIPESIZE,_O_BINARY)<0
|
||||
|| _pipe(outfds,PIPESIZE,_O_BINARY)<0)
|
||||
return -1; */
|
||||
process = GetCurrentProcess ();
|
||||
if (DuplicateHandle (process, outfds[0],
|
||||
process, &sends[0], GENERIC_READ, TRUE,
|
||||
DUPLICATE_CLOSE_SOURCE) == 0)
|
||||
return -1;
|
||||
if (DuplicateHandle (process, infds[1],
|
||||
process, &sends[1], GENERIC_WRITE, TRUE,
|
||||
DUPLICATE_CLOSE_SOURCE) == 0)
|
||||
return -1;
|
||||
|
||||
cmd[0] = '\0';
|
||||
for (argind = 0; argv[argind] != NULL; argind++) {
|
||||
if (argind != 0)
|
||||
strcat (cmd, " ");
|
||||
strcat (cmd, argv[argind]);
|
||||
}
|
||||
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.wShowWindow = FALSE;
|
||||
start_info.hStdInput = sends[0];
|
||||
start_info.hStdOutput = sends[1];
|
||||
start_info.dwFlags = STARTF_USESTDHANDLES;
|
||||
if (!CreateProcess (NULL, (char *) cmd, NULL, NULL, TRUE,
|
||||
CREATE_NO_WINDOW | CREATE_SUSPENDED, NULL, NULL,
|
||||
&start_info, &proc_info))
|
||||
return -1;
|
||||
CloseHandle (sends[0]);
|
||||
CloseHandle (sends[1]);
|
||||
CloseHandle (proc_info.hProcess);
|
||||
ResumeThread (proc_info.hThread);
|
||||
CloseHandle (proc_info.hThread);
|
||||
fds[INFD] = infds[0];
|
||||
fds[OUTFD] = outfds[1];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,74 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: grphshm.h (Formerly graphshm.h)
|
||||
* Description: Header for graphics shared memory functions.
|
||||
* Author: Ray Smith
|
||||
* Created: Thu May 24 15:29:28 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef GRPHSHM_H
|
||||
#define GRPHSHM_H
|
||||
|
||||
#include "sbgtypes.h"
|
||||
#include "grphics.h"
|
||||
|
||||
#define SHMSIZE (65536*8) /*shm segment size */
|
||||
#define PIPESIZE 8192 /*pipe bufer size */
|
||||
#define USER_RW 0600 /*permission flags */
|
||||
/*starbase environ */
|
||||
#define SBADDR "SB_DISPLAY_ADDR"
|
||||
#define WMSHM "WMSHMSPC" /*shared mem size */
|
||||
#define WMSHMDEFAULT 0x200000 /*default value */
|
||||
#define SBDEFAULT 0x0b00000 /*default ADDR */
|
||||
#define SHMOFFSET 0x200000 /*offset before sbaddr */
|
||||
#define MAXDATA 0x1000000 /*default data seg size */
|
||||
|
||||
#define SBDAEMON "sbdaemon"
|
||||
#define REMSH "remsh" /*command for remote use */
|
||||
#define DISP "DISPLAY" /*environ var */
|
||||
#define LOCAL1 "local" /*possible values */
|
||||
#define LOCAL2 "unix" /*of DISPLAY */
|
||||
|
||||
#define FLUSH_OUT 0 /*kick_daemon commands */
|
||||
#define FLUSH_IN 1
|
||||
#define AWAIT_BUFFER 2 /*wait for free buffer */
|
||||
#define COUNT_READS 3 /*count a queue clear */
|
||||
#define MAX_PENDING 255 /*max pending reads */
|
||||
|
||||
extern SHMINFO shminfo; /*shared memory */
|
||||
extern WINFD sbfds[MAXWINDOWS]; /*file descriptors */
|
||||
extern INT16 maxsbfd;
|
||||
#ifdef __MSW32__
|
||||
extern DWORD event_id; //event thread id
|
||||
#endif
|
||||
|
||||
void start_sbdaemon(); /*start the daemon */
|
||||
void cleanup_sbdaemon(); /*forget about the daemon */
|
||||
BOOL8 remote_display( //check for remote
|
||||
char *name //name of host
|
||||
);
|
||||
DLLSYM void *getshm( /*get memory */
|
||||
INT32 size /*required size */
|
||||
);
|
||||
void kick_daemon( /*empty queue */
|
||||
INT8 mode /*control mode */
|
||||
);
|
||||
#ifdef __MSW32__
|
||||
int two_way_pipe ( //do one file
|
||||
const char *file, //program to run
|
||||
const char *argv[], //args to execvp
|
||||
HANDLE fds[] //output fds
|
||||
);
|
||||
#endif
|
||||
#endif
|
@ -1,135 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: sbgconst.h (Formerly sbconst.h)
|
||||
* Description: Header file of constants needed by graphics code.
|
||||
* Author: Ray Smith
|
||||
* Created: Thu May 24 14:19:43 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SBGCONST_H
|
||||
#define SBGCONST_H
|
||||
|
||||
//This file contains all the symbols and constants that the user sees
|
||||
//that are not defined by Starbase.
|
||||
|
||||
#include "host.h"
|
||||
|
||||
#define WINDOWNAMESIZE 13 /*max size of name */
|
||||
#define MAXWINDOWS 64 /*max allowed windows */
|
||||
#define MAXWINDOWNAME 1024 /*max name length */
|
||||
|
||||
#define NO_WINDOW 0 /*no legal window */
|
||||
#define SMDWINDOW 0 /*use smd, no window */
|
||||
#define SCROLLINGWIN 1 /*scrolling window */
|
||||
#define FULLSIZEWIN 2 /*non-scrolling window */
|
||||
#define DCWIN 3 /*dc drawing only */
|
||||
|
||||
#define M_DOT 0 /*marker_types */
|
||||
#define M_PLUS 1 /*starbase markers */
|
||||
#define M_ASTERISK 2
|
||||
#define M_CIRCLE 3
|
||||
#define M_CROSS 4
|
||||
#define M_TRIANGLE 5
|
||||
#define M_SQUARE 6
|
||||
#define M_DIAMOND 7
|
||||
#define M_CROSSED_SQUARE 8
|
||||
|
||||
class WINFD;
|
||||
typedef WINFD *WINDOW; //compatible with old code
|
||||
|
||||
typedef enum {
|
||||
BLACK,
|
||||
WHITE,
|
||||
RED,
|
||||
YELLOW,
|
||||
GREEN,
|
||||
CYAN,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
AQUAMARINE,
|
||||
DARK_SLATE_BLUE,
|
||||
LIGHT_BLUE,
|
||||
MEDIUM_BLUE,
|
||||
MIDNIGHT_BLUE,
|
||||
NAVY_BLUE,
|
||||
SKY_BLUE,
|
||||
SLATE_BLUE,
|
||||
STEEL_BLUE,
|
||||
CORAL,
|
||||
BROWN,
|
||||
SANDY_BROWN,
|
||||
GOLD,
|
||||
GOLDENROD,
|
||||
DARK_GREEN,
|
||||
DARK_OLIVE_GREEN,
|
||||
FOREST_GREEN,
|
||||
LIME_GREEN,
|
||||
PALE_GREEN,
|
||||
YELLOW_GREEN,
|
||||
LIGHT_GREY,
|
||||
DARK_SLATE_GREY,
|
||||
DIM_GREY,
|
||||
GREY,
|
||||
KHAKI,
|
||||
MAROON,
|
||||
ORANGE,
|
||||
ORCHID,
|
||||
PINK,
|
||||
PLUM,
|
||||
INDIAN_RED,
|
||||
ORANGE_RED,
|
||||
VIOLET_RED,
|
||||
SALMON,
|
||||
TAN,
|
||||
TURQUOISE,
|
||||
DARK_TURQUOISE,
|
||||
VIOLET,
|
||||
WHEAT,
|
||||
GREEN_YELLOW
|
||||
} COLOUR; /*starbase colours */
|
||||
|
||||
enum ECHO_TYPE
|
||||
{
|
||||
NO_ECHO,
|
||||
BEST_ECHO,
|
||||
CROSS_HAIR_ECHO,
|
||||
SMALL_X_ECHO,
|
||||
RUBBER_LINE_ECHO,
|
||||
RUBBER_BOX_ECHO,
|
||||
ALPHA_ECHO
|
||||
};
|
||||
|
||||
/*Event types*/
|
||||
#define QUEUE_CLEAR 0 /*queue is empty */
|
||||
#define DOWN_EVENT 1 /*button press */
|
||||
#define MOVE_EVENT 2 /*pointer move */
|
||||
#define UP_EVENT 3 /*button release */
|
||||
#define KEYPRESS_EVENT 4 /*key pressed */
|
||||
#define SELECT_EVENT 5 /*press-release pair */
|
||||
#define ANY_EVENT 6 /*any type */
|
||||
#define DESTROY_EVENT 7
|
||||
|
||||
typedef struct graphicsevent
|
||||
{
|
||||
struct graphicsevent *next; /*next event */
|
||||
WINDOW fd; //structure of window
|
||||
INT16 fildes; //unix only
|
||||
INT8 type; /*event type */
|
||||
char key; /*keypress */
|
||||
float x, y; /*position of event */
|
||||
float xmax, ymax; //for selection
|
||||
} GRAPHICS_EVENT; /*event type */
|
||||
|
||||
typedef void (*EVENT_HANDLER) (GRAPHICS_EVENT *);
|
||||
#endif
|
421
viewer/sbgdefs.h
421
viewer/sbgdefs.h
@ -1,421 +0,0 @@
|
||||
/* STARBASE_ID:sb.c.h 286.1 07/06/89 22:09:56 */
|
||||
|
||||
/* (c) Copyright Hewlett-Packard Company, 1985.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
All rights are reserved. Copying or other
|
||||
reproduction of this program except for archival
|
||||
purposes is prohibited without the prior
|
||||
written consent of Hewlett-Packard Company.
|
||||
|
||||
RESTRICTED RIGHTS LEGEND
|
||||
|
||||
Use, duplication, or disclosure by the U.S. Government
|
||||
is subject to restrictions as set forth in
|
||||
subdivision (b) (3) (ii) of the Rights in Technical
|
||||
Data and Computer Software clause at
|
||||
52.227-7013.
|
||||
|
||||
HEWLETT-PACKARD COMPANY
|
||||
Fort Collins, Colorado */
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* definitions and types to be included with STARBASE application
|
||||
* programs
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef _STARBASE_INCLUDED /* allow multiple inclusions */
|
||||
#define _STARBASE_INCLUDED
|
||||
|
||||
/* kinds of graphics devices */
|
||||
#define OUTDEV 0
|
||||
#define INDEV 1
|
||||
#define OUTINDEV 2
|
||||
#define OUTMETA 3
|
||||
#define INMETA 4
|
||||
|
||||
/* clear control parameters */
|
||||
#define CLEAR_VDC_EXTENT 1
|
||||
#define CLEAR_VIEWPORT 17
|
||||
#define CLEAR_CLIP_RECTANGLE 33
|
||||
#define CLEAR_DISPLAY_SURFACE 65
|
||||
#define CLEAR_ALL_BANKS 128
|
||||
#define CLEAR_ZBUFFER 256
|
||||
|
||||
/* clip control parameters */
|
||||
#define CLIP_TO_RECT 1
|
||||
#define CLIP_TO_VDC 2
|
||||
#define CLIP_OFF 3
|
||||
#define CLIP_TO_VIEWPORT 4
|
||||
|
||||
/* gopen open_mode parameter masks */
|
||||
#define SPOOLED 0x01 /* if this bit is on, output is spooled */
|
||||
//#define INIT 0x02 /* if this bit is on, device initialization occurs */
|
||||
#define THREE_D 0x04 /* if this bit is on, all transformations are 3D */
|
||||
#define RESET_DEVICE 0x08 /* if this bit is on, hard reset including p1 & p2 */
|
||||
#define MODEL_XFORM 0x10 /* if this bit is on, matrix stack in modeling mode */
|
||||
#define INT_XFORM 0x20 /* if this bit is on, matrix stack in modeling mode */
|
||||
#define FLOAT_XFORM 0x40 /* if this bit is on, matrix stack in modeling mode */
|
||||
|
||||
/* color map modes set with shade_mode */
|
||||
#define CMAP_NORMAL 0
|
||||
#define CMAP_MONOTONIC 1
|
||||
#define CMAP_FULL 4
|
||||
|
||||
/* double_buffer mode used to draw into the same buffer that is displayed */
|
||||
#define DFRONT 4
|
||||
/* double_buffer mode used to not clear buffer when switched */
|
||||
#define SUPPRESS_CLEAR 8
|
||||
|
||||
/* light source types set with light_source */
|
||||
#define DIRECTIONAL 0
|
||||
#define POSITIONAL 1
|
||||
#define ATTEN_LIGHT 2
|
||||
#define SPOT_LIGHT 4
|
||||
#define CONE_LIGHT 8
|
||||
|
||||
/* vertex orders set with vertex_format */
|
||||
#define CLOCKWISE 0x0000
|
||||
#define COUNTER_CLOCKWISE 0x0001
|
||||
#define UNIT_NORMALS 0x0200
|
||||
|
||||
/* set p1 p2 units */
|
||||
#define FRACTIONAL 0
|
||||
#define METRIC 1
|
||||
|
||||
/* mapping modes */
|
||||
#define ISOTROPIC 0
|
||||
#define DISTORT 1
|
||||
|
||||
/* Starbase linetypes */
|
||||
#define SOLID 0
|
||||
#define DASH 1
|
||||
#define DOT 2
|
||||
#define DASH_DOT 3
|
||||
#define DASH_DOT_DOT 4
|
||||
#define LONG_DASH 5
|
||||
#define CENTER_DASH 6
|
||||
#define CENTER_DASH_DASH 7
|
||||
|
||||
/* wide endpoint types */
|
||||
#define SQUARE 0
|
||||
#define ROUNDED 1
|
||||
|
||||
/* depth cue models */
|
||||
#define DC_MIN 2
|
||||
#define DC_COLOR 4
|
||||
|
||||
/* distance modes for line_width, hatch_spacing */
|
||||
#define VDC_UNITS 0
|
||||
#define WC_UNITS 1
|
||||
#define MC_UNITS WC_UNITS
|
||||
#define DC_UNITS 2
|
||||
|
||||
/* polygon interior styles */
|
||||
#define INT_HOLLOW 0
|
||||
#define INT_SOLID 1
|
||||
#define INT_PATTERN 2
|
||||
#define INT_HATCH 3
|
||||
#define INT_OUTLINE 4
|
||||
#define INT_POINT 5
|
||||
|
||||
/* Matrix concatenation types */
|
||||
#define PRE 0
|
||||
#define POST 1
|
||||
#define REPLACE 0
|
||||
#define PUSH 1
|
||||
|
||||
/* Viewing matrix change types */
|
||||
#define REPLACE_VW 0
|
||||
#define PRE_CONCAT_VW 1
|
||||
#define POST_CONCAT_VW 2
|
||||
|
||||
/* character switching modes */
|
||||
#define ISO_7BIT 0
|
||||
#define ISO_8BIT 1
|
||||
#define HP_8BIT 2
|
||||
|
||||
/* text precision types */
|
||||
#define STRING_TEXT 0
|
||||
#define CHARACTER_TEXT 1
|
||||
#define STROKE_TEXT 2
|
||||
|
||||
/* text transformation types */
|
||||
#define VDC_TEXT 0
|
||||
#define WORLD_COORDINATE_TEXT 1
|
||||
#define TOS_TEXT 2
|
||||
#define ANNOTATION_TEXT 3
|
||||
|
||||
/* text alignment enumerated types */
|
||||
#define TA_LEFT 0
|
||||
#define SB_TA_CENTER 1
|
||||
#define TA_RIGHT 2
|
||||
#define TA_CONTINUOUS_HORIZONTAL 3
|
||||
#define TA_NORMAL_HORIZONTAL 4
|
||||
|
||||
#define TA_TOP 0
|
||||
#define TA_CAP 1
|
||||
#define TA_HALF 2
|
||||
#define TA_BASE 3
|
||||
#define SB_TA_BOTTOM 4
|
||||
#define TA_CONTINUOUS_VERTICAL 5
|
||||
#define TA_NORMAL_VERTICAL 6
|
||||
|
||||
/* character path and line path enumerated types */
|
||||
#define PATH_RIGHT 0
|
||||
#define PATH_LEFT 1
|
||||
#define PATH_UP 2
|
||||
#define PATH_DOWN 3
|
||||
|
||||
/* input device class enumerated types */
|
||||
#define ALL 0
|
||||
#define LOCATOR 1
|
||||
#define CHOICE 4
|
||||
|
||||
/* event queue states */
|
||||
#define EMPTY_NO_OVERFLOW 0
|
||||
#define EMPTY_OVERFLOW 1
|
||||
#define NOT_EMPTY_NO_OVERFLOW 2
|
||||
#define NOT_EMPTY_OVERFLOW 3
|
||||
|
||||
/* event message link enumerated types */
|
||||
#define SIMULTANEOUS_EVENT_FOLLOWS 0
|
||||
#define SINGLE_EVENT 1
|
||||
|
||||
/* gerr printing flags */
|
||||
#define NO_ERROR_PRINTING 0
|
||||
#define PRINT_ERRORS 1
|
||||
#define PRINT_WARNINGS 2
|
||||
|
||||
/* arc close_types */
|
||||
#define NO_CHORD 0
|
||||
#define PIE 1
|
||||
#define CHORD 2
|
||||
|
||||
/* spline orders and rationalities */
|
||||
#define NONRATIONAL 0
|
||||
//#define RATIONAL 1
|
||||
#define LINEAR 2
|
||||
#define QUADRATIC 3
|
||||
#define CUBIC 4
|
||||
#define QUARTIC 5
|
||||
#define QUINTIC 6
|
||||
#define DC_VALUES 0
|
||||
#define VDC_VALUES 2
|
||||
#define STEP_SIZE 3
|
||||
|
||||
/* transform_point modes */
|
||||
#define MC_TO_WC 0
|
||||
#define MC_TO_WORLD 0
|
||||
#define MC_TO_VDC 1
|
||||
#define WC_TO_VDC 2
|
||||
#define WORLD_TO_VDC 2
|
||||
#define WC_TO_MC 3
|
||||
#define WORLD_TO_MC 3
|
||||
#define VDC_TO_MC 4
|
||||
#define VDC_TO_WC 5
|
||||
#define VDC_TO_WORLD 5
|
||||
#define INTVDC_TO_DC 6
|
||||
#define DC_TO_INTVDC 7
|
||||
|
||||
/* view_camera projection types */
|
||||
#define CAM_PERSPECTIVE 0.0
|
||||
#define CAM_PARALLEL 1.0
|
||||
|
||||
/* plane printing modes */
|
||||
#define ALL_PLANES -1
|
||||
#define PIXEL_MAJOR -1
|
||||
#define PLANE_MAJOR -2
|
||||
|
||||
/* hatch types */
|
||||
#define PARALLEL_HATCH 0
|
||||
#define CROSSHATCH 1
|
||||
|
||||
/* highlight attribute types */
|
||||
#define HL_COLOR 1
|
||||
#define HL_STYLE 2
|
||||
|
||||
/* Hardware cursor control types */
|
||||
#define REQUEST_HW_CURSOR 1
|
||||
#define REQUEST_SW_CURSOR 2
|
||||
#define FORCE_HW_CURSOR 3
|
||||
#define REQUEST_HW_ECHO 1
|
||||
#define REQUEST_SW_ECHO 2
|
||||
#define FORCE_HW_ECHO 3
|
||||
|
||||
/* cgm encoding types */
|
||||
#define CGM_BINARY 1
|
||||
#define CGM_CHARACTER 2
|
||||
#define CGM_CLEAR_TEXT 3
|
||||
|
||||
/* GLOBAL gescapes */
|
||||
#define SWITCH_SEMAPHORE 0
|
||||
#define READ_COLOR_MAP 1
|
||||
#define BLINK_PLANES 2
|
||||
#define BLINK_INDEX 3
|
||||
|
||||
/* GLOBAL raster gescapes */
|
||||
#define R_GET_FRAME_BUFFER 20
|
||||
#define R_LOCK_DEVICE 21
|
||||
#define R_UNLOCK_DEVICE 22
|
||||
#define R_GET_WINDOW_INFO 23
|
||||
#define R_FULL_FRAME_BUFFER 24
|
||||
#define R_ALLOC_OFFSCREEN 25
|
||||
#define R_FREE_OFFSCREEN 26
|
||||
#define R_BIT_MODE 27
|
||||
#define R_BIT_MASK 28
|
||||
#define R_DEF_FILL_PAT 29
|
||||
#define R_OVERLAY_ECHO 30
|
||||
#define R_OV_ECHO_COLORS 31
|
||||
#define R_DEF_ECHO_TRANS 32
|
||||
#define R_TRANSPARENCY_INDEX 33
|
||||
#define R_LINE_TYPE 34
|
||||
#define R_ECHO_FG_BG_COLORS 35
|
||||
#define R_DMA_MODE 36
|
||||
#define R_ECHO_MASK 37
|
||||
#define R_ECHO_CONTROL 38
|
||||
#define R_OFFSCREEN_ALLOC 1106
|
||||
#define R_OFFSCREEN_FREE 1107
|
||||
|
||||
/* HPGL gescapes */
|
||||
#define HPGL_WRITE_BUFFER 100
|
||||
#define HPGL_SET_PEN_NUM 101
|
||||
#define HPGL_SET_PEN_SPEED 102
|
||||
#define HPGL_SET_PEN_WIDTH 103
|
||||
#define HPGL_READ_BUFFER 104
|
||||
|
||||
/* HPGL2 gescapes */
|
||||
#define HPGL2_SET_MEDIA_TYPE 105
|
||||
#define HPGL2_LOGICAL_PEN_WIDTH 106
|
||||
#define HPGL2_CUTTER_CONTROL 107
|
||||
#define HPGL2_REPLOT 108
|
||||
#define HPGL2_FONT_TYPEFACE 109
|
||||
#define HPGL2_ADAPTIVE_LINES 110
|
||||
#define HPGL2_SET_QUALITY 111
|
||||
#define HPGL2_SET_CMAP_SIZE 112
|
||||
#define HPGL2_FONT_WEIGHT 113
|
||||
#define HPGL2_FONT_POSTURE 114
|
||||
|
||||
/* HP26XX gescapes */
|
||||
#define HP26_PRINT_ESC 200
|
||||
#define HPTERM_PRINT_ESC 200
|
||||
#define HPTERM_640x400 201
|
||||
|
||||
/* 98700 gescapes */
|
||||
#define GB_NONE 300
|
||||
|
||||
/* 98710 gescapes */
|
||||
#define GA_NONE 400
|
||||
|
||||
/* 300l gescapes */
|
||||
#define TC_HALF_PIXEL 500
|
||||
|
||||
/* HIL and keyboard gescapes */
|
||||
#define ENABLE_AUTO_PROMPT 600
|
||||
#define DISABLE_AUTO_PROMPT 601
|
||||
#define PROMPT_ON 602
|
||||
#define PROMPT_OFF 603
|
||||
#define TRIGGER_ON_RELEASE 604
|
||||
#define IGNORE_RELEASE 605
|
||||
#define REPORT_PROXIMITY 606
|
||||
#define IGNORE_PROXIMITY 607
|
||||
#define ENABLE_ACKNOWLEDGE 608
|
||||
#define DISABLE_ACKNOWLEDGE 609
|
||||
#define SET_ACCELERATION 610 /* hil acceleration multiplier */
|
||||
|
||||
/* GKSM gescapes */
|
||||
#define GKSM_WRITE_ITEM 700
|
||||
#define GKSM_GET_ITEM_TYPE 701
|
||||
#define GKSM_READ_ITEM 702
|
||||
#define GKSM_SKIP_ITEM 703
|
||||
#define GKSM_INQ_COLOR_NDCES 704
|
||||
#define GKSM_INQ_PAT_REP 705
|
||||
|
||||
/* 98721 gescapes */
|
||||
#define TRANSPARENCY 800
|
||||
#define ZBUFFER_ALLOC 801
|
||||
#define LS_OVERFLOW_CONTROL 802
|
||||
#define PATTERN_FILL 803
|
||||
#define ZWRITE_ENABLE 804
|
||||
#define ZSTATE_SAVE 805
|
||||
#define ZSTATE_RESTORE 806
|
||||
|
||||
/* SMDpixel and SMDpixel3 gescapes */
|
||||
#define SMD_SUPPLY_MEM_BUFF 900
|
||||
#define SMD_GET_MEM_REQUIRED 901
|
||||
#define SMD_DEFINE_XY 902
|
||||
#define SMD_DEFINE_DEPTH 903
|
||||
#define SMD_ALLOCATE_MEMORY 904
|
||||
|
||||
/* Xn gescapes */
|
||||
#define XN_INPUT_RAW 1000
|
||||
/* raw mode (TRUE) returns LK201 keycodes
|
||||
cooked mode (FALSE) returns ASCII */
|
||||
#define XN_KEY_RELEASE 1001 /* turn on/off key release events */
|
||||
#define XN_BUTTON_RELEASE 1002 /* turn on/off button release events */
|
||||
|
||||
/* 98549/49/50/56 gescapes */
|
||||
#define GR2D_MASK_ENABLE 1100
|
||||
#define GR2D_MASK_RULE 1101
|
||||
#define GR2D_DEF_MASK 1102
|
||||
#define GR2D_FILL_PATTERN 1103
|
||||
#define GR2D_OVERLAY_TRANSPARENT 1104
|
||||
#define GR2D_REPLICATE 1105
|
||||
#define GR2D_ALLOC_OFFSCREEN 1106
|
||||
#define GR2D_FREE_OFFSCREEN 1107
|
||||
#define GR2D_PLANE_MASK 1108
|
||||
#define GR2D_INQ_CLIST_ADDR 1109
|
||||
#define GR2D_LOAD_CLIST 1110
|
||||
#define GR2D_CONVEX_POLYGONS 1112
|
||||
|
||||
/* hp98730/31 driver gescapes */
|
||||
#define PAN_AND_ZOOM 1200
|
||||
#define OVERLAY_BLEND 1201
|
||||
#define IMAGE_BLEND 1202
|
||||
#define SET_BANK_CMAP 1203
|
||||
#define GAMMA_CORRECTION 1204
|
||||
#define INQ_GAMMA_CORRECTION 1205
|
||||
#define FULL_COLOR_INDEX 1206
|
||||
#define POLYGON_TRANSPARENCY 1207
|
||||
#define CLIP_OVERFLOW 1208
|
||||
|
||||
/* hp98704/05 gescapes */
|
||||
#define SET_REPLACEMENT_RULE 1250
|
||||
|
||||
/* hpcgm driver gescapes */
|
||||
#define CGMESC_ENCODING 1300
|
||||
#define CGMESC_ESCAPE_ELT 1301
|
||||
#define CGMESC_MET_NAME 1302
|
||||
#define CGMESC_PIC_NAME 1303
|
||||
#define CGMESC_FONT_IX 1304
|
||||
#define CGMESC_MESSAGE 1305
|
||||
#define CGMESC_APPL_DATA 1306
|
||||
#define CGMESC_VDC_PREC 1307
|
||||
#define CGMESC_TOP_MODE 1308
|
||||
|
||||
typedef union
|
||||
{
|
||||
int i[64];
|
||||
float f[64];
|
||||
char c[255];
|
||||
} gescape_arg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float refx, refy, refz;
|
||||
float camx, camy, camz;
|
||||
float upx, upy, upz;
|
||||
float field_of_view;
|
||||
float front, back;
|
||||
float projection;
|
||||
} camera_arg;
|
||||
#endif /* _STARBASE_INCLUDED */
|
@ -1,248 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: sbgtypes.h (Formerly sbtypes.h)
|
||||
* Description: Structures for the Starbase/X daemon interface.
|
||||
* Author: Ray Smith
|
||||
* Created: Wed May 16 09:26:35 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SBGTYPES_H
|
||||
#define SBGTYPES_H
|
||||
|
||||
//This file contains all the symbols and types that are not of concern
|
||||
//to the user, but are common to both the client and the sbdaemon side.
|
||||
|
||||
#include "sbgconst.h"
|
||||
#ifdef __UNIX__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_TIME 1000 /*1 millisecond */
|
||||
#define AWAIT_TIME 999999 /*1 second */
|
||||
#define INFD 0 /*index to fds */
|
||||
#define OUTFD 1 /*for read/write */
|
||||
#define EVENTSIZE 16 //event buffer
|
||||
#define PRIMITIVES (*(INT32*)((char*)shminfo.shmstart+shminfo.shmsize))
|
||||
#define EVENT_TAIL (*(INT32*)((char*)shminfo.shmstart+shminfo.shmsize+sizeof(INT32)))
|
||||
#define EVENT_HEAD (*(INT32*)((char*)shminfo.shmstart+shminfo.shmsize+2*sizeof(INT32)))
|
||||
#define EVENT_INDEX(index) (((SBD_GRAPHICS_EVENT*)((char*)shminfo.shmstart+shminfo.shmsize+3*sizeof(INT32)))[index])
|
||||
|
||||
typedef enum {
|
||||
LINECOLOUR, /*line_color_index */
|
||||
PERIMETERCOLOUR, /*perimeter_color_index */
|
||||
FILLCOLOUR, /*fill_color_index */
|
||||
MARKERCOLOUR, /*marker_color_index */
|
||||
TEXTCOLOUR, /*text_color_index */
|
||||
TEXTFONT, /*text_font_index */
|
||||
CHARHEIGHT, /*character_height */
|
||||
LINETYPE, /*line_type */
|
||||
MARKERTYPE, /*marker_type */
|
||||
MARKERSIZE, /*marker_size */
|
||||
MARKERMODE, /*mode in markersize */
|
||||
INTERIORSTYLE, /*interior_style */
|
||||
EDGESTYLE, /*edge in interior_style */
|
||||
|
||||
MOVE2D, /*move2d */
|
||||
DRAW2D, /*draw2d */
|
||||
RECTANGLE, /*rectangle */
|
||||
TEXT_ALIGNMENT, //alginment
|
||||
POLYLINE2D, /*polyline2d */
|
||||
POLYGON2D, /*polygon2d */
|
||||
POLYMARKER2D, /*polymarker2d */
|
||||
TEXT2D, /*text2d */
|
||||
APPENDTEXT, /*append_text */
|
||||
ELLIPSE, /*ellipse */
|
||||
ARC, /*arc */
|
||||
|
||||
SHOWIMAGE, /*display image */
|
||||
SHOWLINE, /*send image line */
|
||||
|
||||
CREATE, /*create_window */
|
||||
DESTROY, /*destroy_window */
|
||||
CLEAR, /*clear_view_surface */
|
||||
VDCEXTENT, /*vdc_extent */
|
||||
MAKECURRENT, /*make_picture_current */
|
||||
SETSIGNALS, //add callback
|
||||
SETECHO, //change cursor
|
||||
SYNCWIN, //sychronize
|
||||
RE_COMP_COLMAP //Re-compute colourmap
|
||||
} CALL_TYPE; /*type of call */
|
||||
|
||||
typedef union
|
||||
{
|
||||
INT16 fd; /*input fd */
|
||||
void *next; /*turns to link */
|
||||
} HEADUNION; /*header of structure */
|
||||
|
||||
typedef union
|
||||
{
|
||||
float f; /*parameter union */
|
||||
INT32 i; /*to reduce structures */
|
||||
} PARAMUNION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PARAMUNION p; /*single parameter */
|
||||
} ONEPARAM;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PARAMUNION p[2]; /*two params */
|
||||
} TWOPARAMS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PARAMUNION p[4]; /*4 params */
|
||||
} FOURPARAMS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PARAMUNION p[8]; /*8 params */
|
||||
} EIGHTPARAMS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next op */
|
||||
CALL_TYPE type; /*call type */
|
||||
ONEPARAM param; /*single parameter */
|
||||
} ONEOP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next op */
|
||||
CALL_TYPE type; /*call type */
|
||||
TWOPARAMS param; /*single parameter */
|
||||
} TWOOP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next op */
|
||||
CALL_TYPE type; /*call type */
|
||||
FOURPARAMS param; /*single parameter */
|
||||
} FOUROP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next op */
|
||||
CALL_TYPE type; /*call type */
|
||||
EIGHTPARAMS param; /*single parameter */
|
||||
} EIGHTOP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float *clist; /*coord list */
|
||||
INT32 numpts; /*number of coords */
|
||||
INT32 flags; /*move/draws on/off */
|
||||
} POLYPARAM; /*polygon params */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next */
|
||||
CALL_TYPE type; /*operator type */
|
||||
POLYPARAM param; /*parameters */
|
||||
float polyxmin, polyxmax; /*bounding box */
|
||||
float polyymin, polyymax; /*of polyline */
|
||||
float clist[1]; /*place holder */
|
||||
} POLYOP; /*poly line/marker */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y; /*coords of text */
|
||||
char *string; /*string to draw */
|
||||
INT32 xform; /*coord transform */
|
||||
INT32 more; /*any more text */
|
||||
} TEXTPARAM; /*text parameters */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *string; /*string to draw */
|
||||
INT32 xform; /*coord transform */
|
||||
INT32 more; /*any more text */
|
||||
} APPENDPARAM; /*text parameters */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next */
|
||||
CALL_TYPE type; /*operator type */
|
||||
TEXTPARAM param; /*parameters */
|
||||
char chars[4]; /*place holder */
|
||||
} TEXTOP; /*poly line/marker */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next */
|
||||
CALL_TYPE type; /*operator type */
|
||||
APPENDPARAM param; /*parameters */
|
||||
char chars[4]; /*place holder */
|
||||
} APPENDOP; /*poly line/marker */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next */
|
||||
CALL_TYPE type; /*operator type */
|
||||
INT32 size; /*size of structure */
|
||||
UINT8 line[2]; /*image line */
|
||||
} IMAGEOP; /*image passing */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HEADUNION header; /*fd/next */
|
||||
CALL_TYPE type; /*operator type */
|
||||
INT16 xpos, ypos; /*initial position */
|
||||
INT16 xsize, ysize; /*initial size */
|
||||
float xmin, xmax; /*scrolling limits */
|
||||
float ymin, ymax;
|
||||
BOOL8 downon; /*events required */
|
||||
BOOL8 moveon;
|
||||
BOOL8 upon;
|
||||
BOOL8 keyon;
|
||||
INT32 window_type; /*false for SMD */
|
||||
char name[MAXWINDOWNAME]; /*name of window */
|
||||
} CREATEOP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef __UNIX__
|
||||
int fds[2]; /*I/O files */
|
||||
int shmid; /*shared memory id */
|
||||
#else
|
||||
#ifdef __PCDEMON__
|
||||
int fds[2]; /*I/O files */
|
||||
#else
|
||||
HANDLE fds[2]; /*I/O files */
|
||||
#endif
|
||||
HANDLE shmid; //handle to it
|
||||
#endif
|
||||
void *shmstart; /*addr of shm seg */
|
||||
INT32 usedsize; /*amount used */
|
||||
INT32 shmsize; /*size of shm seg */
|
||||
#ifdef __UNIX
|
||||
pid_t pid; /*child process id */
|
||||
#endif
|
||||
} SHMINFO; /*shared memory info */
|
||||
|
||||
typedef struct sbdgraphicsevent
|
||||
{
|
||||
struct sbdgraphicsevent *next; /*next event */
|
||||
INT16 fd; //unix only
|
||||
INT8 type; /*event type */
|
||||
char key; /*keypress */
|
||||
float x, y; /*position of event */
|
||||
} SBD_GRAPHICS_EVENT; /*event type */
|
||||
|
||||
//typedef void (*SBFUNC)(WINFD*,...); /*starbase function*/
|
||||
typedef void (*DELFUNC) (void *, INT32);
|
||||
/*deletion function */
|
||||
typedef INT16 SBDWINDOW;
|
||||
#endif
|
751
viewer/scrollview.cpp
Normal file
751
viewer/scrollview.cpp
Normal file
@ -0,0 +1,751 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: scrollview.cc
|
||||
// Description: ScrollView
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This class contains the main ScrollView-logic,
|
||||
// e.g. parsing & sending messages, images etc.
|
||||
|
||||
const bool kDebugMode = false;
|
||||
const int kSvPort = 8461;
|
||||
const int kMaxMsgSize = 4096;
|
||||
|
||||
#include "scrollview.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "svutil.h"
|
||||
|
||||
#ifdef HAVE_LIBLEPT
|
||||
#include "allheaders.h"
|
||||
#endif
|
||||
|
||||
// A map between the window IDs and their corresponding pointers.
|
||||
static std::map<int, ScrollView*> svmap;
|
||||
// A map of all semaphores waiting for a specific event on a specific window.
|
||||
static std::map<std::pair<ScrollView*, SVEventType>,
|
||||
std::pair<SVSemaphore*, SVEvent*> > waiting_for_events;
|
||||
SVMutex* mutex_waiting;
|
||||
|
||||
SVEvent* SVEvent::copy() {
|
||||
SVEvent* any = new SVEvent;
|
||||
any->command_id = command_id;
|
||||
any->counter = counter;
|
||||
any->parameter = new char[strlen(parameter) + 1];
|
||||
strncpy(any->parameter, parameter, strlen(parameter));
|
||||
any->parameter[strlen(parameter)] = '\0';
|
||||
any->type = type;
|
||||
any->x = x;
|
||||
any->y = y;
|
||||
any->x_size = x_size;
|
||||
any->y_size = y_size;
|
||||
any->window = window;
|
||||
return any;
|
||||
}
|
||||
|
||||
// This is the main loop which handles the ScrollView-logic from the server
|
||||
// to the client. It basically loops through messages, parses them to events
|
||||
// and distributes it to the waiting handlers.
|
||||
// It is run from a different thread and synchronizes via SVSync.
|
||||
void* ScrollView::MessageReceiver(void* a) {
|
||||
int counter_event_id = 0; //ongoing counter
|
||||
char* message = NULL;
|
||||
// Wait until a new message appears in the input stream_.
|
||||
do {
|
||||
message = ScrollView::GetStream()->Receive();
|
||||
} while (message == NULL);
|
||||
|
||||
// This is the main loop which iterates until the server is dead (strlen = -1).
|
||||
// It basically parses for 3 different messagetypes and then distributes the
|
||||
// events accordingly.
|
||||
while (strlen(message) != -1) {
|
||||
// The new event we create.
|
||||
SVEvent* cur = new SVEvent;
|
||||
// The ID of the corresponding window.
|
||||
int window_id;
|
||||
|
||||
int ev_type;
|
||||
|
||||
if (kDebugMode) { std::cout << "(s->C)" << message << "\n"; }
|
||||
|
||||
int n;
|
||||
// Fill the new SVEvent properly.
|
||||
sscanf(message, "%d,%d,%d,%d,%d,%d,%d,%n", &window_id, &ev_type, &cur->x,
|
||||
&cur->y, &cur->x_size, &cur->y_size, &cur->command_id, &n);
|
||||
char* p = (message + n);
|
||||
|
||||
cur->window = svmap[window_id];
|
||||
|
||||
if (cur->window != NULL) {
|
||||
cur->parameter = new char[strlen(p) + 1];
|
||||
strncpy(cur->parameter, p, strlen(p) + 1);
|
||||
if (strlen(p) > 0) { // remove the last \n
|
||||
cur->parameter[strlen(p)] = '\0';
|
||||
}
|
||||
cur->type = static_cast<SVEventType>(ev_type);
|
||||
cur->y = cur->window->TranslateYCoordinate(cur->y);
|
||||
cur->counter = counter_event_id;
|
||||
// Increase by 2 since we will also create an SVET_ANY event from cur, which
|
||||
// will have a counter_id of cur + 1 (and thus gets processed after cur).
|
||||
counter_event_id += 2;
|
||||
|
||||
// In case of an SVET_EXIT event, quit the whole application.
|
||||
if (ev_type == SVET_EXIT) { ScrollView::Exit(); }
|
||||
|
||||
// Place two copies of it in the table for the window.
|
||||
cur->window->SetEvent(cur);
|
||||
|
||||
// Check if any of the threads currently waiting want it.
|
||||
std::pair<ScrollView*, SVEventType> awaiting_list(cur->window,
|
||||
cur->type);
|
||||
std::pair<ScrollView*, SVEventType> awaiting_list_any(cur->window,
|
||||
SVET_ANY);
|
||||
std::pair<ScrollView*, SVEventType> awaiting_list_any_window(NULL,
|
||||
SVET_ANY);
|
||||
mutex_waiting->Lock();
|
||||
if (waiting_for_events.count(awaiting_list) > 0) {
|
||||
waiting_for_events[awaiting_list].second = cur;
|
||||
waiting_for_events[awaiting_list].first->Signal();
|
||||
} else if (waiting_for_events.count(awaiting_list_any) > 0) {
|
||||
waiting_for_events[awaiting_list_any].second = cur;
|
||||
waiting_for_events[awaiting_list_any].first->Signal();
|
||||
} else if (waiting_for_events.count(awaiting_list_any_window) > 0) {
|
||||
waiting_for_events[awaiting_list_any_window].second = cur;
|
||||
waiting_for_events[awaiting_list_any_window].first->Signal();
|
||||
} else {
|
||||
// No one wanted it, so delete it.
|
||||
delete cur;
|
||||
}
|
||||
mutex_waiting->Unlock();
|
||||
// Signal the corresponding semaphore twice (for both copies).
|
||||
ScrollView* sv = svmap[window_id];
|
||||
sv->Signal();
|
||||
sv->Signal();
|
||||
}
|
||||
|
||||
// Wait until a new message appears in the input stream_.
|
||||
do {
|
||||
message = ScrollView::GetStream()->Receive();
|
||||
} while (message == NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Table to implement the color index values in the old system.
|
||||
int table_colors[ScrollView::GREEN_YELLOW+1][4]= {
|
||||
{0, 0, 0, 0}, // NONE (transparent)
|
||||
{0, 0, 0, 255}, // BLACK.
|
||||
{255, 255, 255, 255}, // WHITE.
|
||||
{255, 0, 0, 255}, // RED.
|
||||
{255, 255, 0, 255}, // YELLOW.
|
||||
{0, 255, 0, 255}, // GREEN.
|
||||
{0, 255, 255, 255}, // CYAN.
|
||||
{0, 0, 255, 255}, // BLUE.
|
||||
{255, 0, 255, 255}, // MAGENTA.
|
||||
{0, 128, 255, 255}, // AQUAMARINE.
|
||||
{0, 0, 64, 255}, // DARK_SLATE_BLUE.
|
||||
{128, 128, 255, 255}, // LIGHT_BLUE.
|
||||
{64, 64, 255, 255}, // MEDIUM_BLUE.
|
||||
{0, 0, 32, 255}, // MIDNIGHT_BLUE.
|
||||
{0, 0, 128, 255}, // NAVY_BLUE.
|
||||
{192, 192, 255, 255}, // SKY_BLUE.
|
||||
{64, 64, 128, 255}, // SLATE_BLUE.
|
||||
{32, 32, 64, 255}, // STEEL_BLUE.
|
||||
{255, 128, 128, 255}, // CORAL.
|
||||
{128, 64, 0, 255}, // BROWN.
|
||||
{128, 128, 0, 255}, // SANDY_BROWN.
|
||||
{192, 192, 0, 255}, // GOLD.
|
||||
{192, 192, 128, 255}, // GOLDENROD.
|
||||
{0, 64, 0, 255}, // DARK_GREEN.
|
||||
{32, 64, 0, 255}, // DARK_OLIVE_GREEN.
|
||||
{64, 128, 0, 255}, // FOREST_GREEN.
|
||||
{128, 255, 0, 255}, // LIME_GREEN.
|
||||
{192, 255, 192, 255}, // PALE_GREEN.
|
||||
{192, 255, 0, 255}, // YELLOW_GREEN.
|
||||
{192, 192, 192, 255}, // LIGHT_GREY.
|
||||
{64, 64, 128, 255}, // DARK_SLATE_GREY.
|
||||
{64, 64, 64, 255}, // DIM_GREY.
|
||||
{128, 128, 128, 255}, // GREY.
|
||||
{64, 192, 0, 255}, // KHAKI.
|
||||
{255, 0, 192, 255}, // MAROON.
|
||||
{255, 128, 0, 255}, // ORANGE.
|
||||
{255, 128, 64, 255}, // ORCHID.
|
||||
{255, 192, 192, 255}, // PINK.
|
||||
{128, 0, 128, 255}, // PLUM.
|
||||
{255, 0, 64, 255}, // INDIAN_RED.
|
||||
{255, 64, 0, 255}, // ORANGE_RED.
|
||||
{255, 0, 192, 255}, // VIOLET_RED.
|
||||
{255, 192, 128, 255}, // SALMON.
|
||||
{128, 128, 0, 255}, // TAN.
|
||||
{0, 255, 255, 255}, // TURQUOISE.
|
||||
{0, 128, 128, 255}, // DARK_TURQUOISE.
|
||||
{192, 0, 255, 255}, // VIOLET.
|
||||
{128, 128, 0, 255}, // WHEAT.
|
||||
{128, 255, 0, 255} // GREEN_YELLOW
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Scrollview implementation.
|
||||
*******************************************************************************/
|
||||
|
||||
SVNetwork* ScrollView::stream_ = NULL;
|
||||
int ScrollView::nr_created_windows_ = 0;
|
||||
|
||||
// Calls Initialize with all arguments given.
|
||||
ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,
|
||||
int y_size, int x_canvas_size, int y_canvas_size,
|
||||
bool y_axis_reversed, const char* server_name) {
|
||||
Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
|
||||
y_axis_reversed, server_name);}
|
||||
|
||||
// Calls Initialize with default argument for server_name_.
|
||||
ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,
|
||||
int y_size, int x_canvas_size, int y_canvas_size,
|
||||
bool y_axis_reversed) {
|
||||
Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
|
||||
y_axis_reversed, "localhost");
|
||||
}
|
||||
|
||||
// Calls Initialize with default argument for server_name_ & y_axis_reversed.
|
||||
ScrollView::ScrollView(const char* name, int x_pos, int y_pos, int x_size,
|
||||
int y_size, int x_canvas_size, int y_canvas_size) {
|
||||
Initialize(name, x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size,
|
||||
false, "localhost");
|
||||
}
|
||||
|
||||
// Sets up a ScrollView window, depending on the constructor variables.
|
||||
void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
||||
int y_size, int x_canvas_size, int y_canvas_size,
|
||||
bool y_axis_reversed, const char* server_name) {
|
||||
// If this is the first ScrollView Window which gets created, there is no
|
||||
// network connection yet and we have to set it up in a different thread.
|
||||
if (stream_ == NULL) {
|
||||
nr_created_windows_ = 0;
|
||||
stream_ = new SVNetwork(server_name, kSvPort);
|
||||
mutex_waiting = new SVMutex();
|
||||
if (kDebugMode) {
|
||||
std::cout << "(C->s) svmain = "
|
||||
<< "luajava.bindClass('com.google.scrollview.ScrollView')\n";
|
||||
}
|
||||
SendRawMessage(
|
||||
"svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
|
||||
SVSync::StartThread(MessageReceiver, NULL);
|
||||
}
|
||||
|
||||
// Set up the variables on the clientside.
|
||||
nr_created_windows_++;
|
||||
event_handler_ = NULL;
|
||||
y_axis_is_reversed_ = y_axis_reversed;
|
||||
y_size_ = y_canvas_size;
|
||||
window_name_ = name;
|
||||
window_id_ = nr_created_windows_;
|
||||
|
||||
svmap[window_id_] = this;
|
||||
|
||||
for (int i = 0; i < SVET_COUNT; i++) {
|
||||
event_table_[i] = NULL;
|
||||
}
|
||||
|
||||
mutex_ = new SVMutex();
|
||||
semaphore_ = new SVSemaphore();
|
||||
|
||||
// Set up an actual Window on the client side.
|
||||
char message[kMaxMsgSize];
|
||||
snprintf(message, sizeof(message),
|
||||
"w%u = luajava.newInstance('com.google.scrollview.ui"
|
||||
".SVWindow','%s',%u,%u,%u,%u,%u,%u,%u)\n",
|
||||
window_id_, window_name_,
|
||||
window_id_, x_pos,
|
||||
TranslateYCoordinate(y_pos), x_size,
|
||||
y_size_, x_canvas_size, y_canvas_size);
|
||||
if (kDebugMode) {
|
||||
std::cout << "(C->s)" << message;
|
||||
}
|
||||
SendRawMessage(message);
|
||||
|
||||
SVSync::StartThread(StartEventHandler, this);
|
||||
}
|
||||
|
||||
// Sits and waits for events on this window.
|
||||
void* ScrollView::StartEventHandler(void* a) {
|
||||
ScrollView* sv = (ScrollView*) a;
|
||||
SVEvent* new_event;
|
||||
|
||||
do {
|
||||
stream_->Flush();
|
||||
sv->semaphore_->Wait();
|
||||
new_event = NULL;
|
||||
int serial = INT_MAX;
|
||||
int k = -1;
|
||||
sv->mutex_->Lock();
|
||||
// Check every table entry if he is is valid and not already processed.
|
||||
|
||||
for (int i = 0; i < SVET_COUNT; i++) {
|
||||
if ((sv->event_table_[i] != NULL) &&
|
||||
(sv->event_table_[i]->counter < serial)) {
|
||||
new_event = sv->event_table_[i];
|
||||
serial = sv->event_table_[i]->counter;
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
// If we didnt find anything we had an old alarm and just sleep again.
|
||||
if (new_event != NULL) {
|
||||
sv->event_table_[k] = NULL;
|
||||
sv->mutex_->Unlock();
|
||||
if (sv->event_handler_ != NULL) { sv->event_handler_->Notify(new_event); }
|
||||
if (new_event->type == SVET_DESTROY) { sv = NULL; }
|
||||
delete new_event; // Delete the pointer after it has been processed.
|
||||
} else { sv->mutex_->Unlock(); }
|
||||
// The thread should run as long as its associated window is alive.
|
||||
} while (sv != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ScrollView::~ScrollView() {
|
||||
// So the event handling thread can quit.
|
||||
SendMsg("destroy()");
|
||||
|
||||
SVEvent* sve = AwaitEvent(SVET_DESTROY);
|
||||
delete sve;
|
||||
delete mutex_;
|
||||
delete semaphore_;
|
||||
|
||||
svmap.erase(window_id_);
|
||||
}
|
||||
|
||||
// Send a message to the server, attaching the window id.
|
||||
void ScrollView::SendMsg(const char* format, ...) {
|
||||
va_list args;
|
||||
char message[kMaxMsgSize];
|
||||
|
||||
va_start(args, format); // variable list
|
||||
vsnprintf(message, kMaxMsgSize, format, args);
|
||||
va_end(args);
|
||||
|
||||
char form[kMaxMsgSize];
|
||||
snprintf(form, kMaxMsgSize, "w%u:%s\n", window_id_, message);
|
||||
|
||||
if (kDebugMode) { std::cout << "(C->s)" << form; }
|
||||
stream_->Send(form);
|
||||
}
|
||||
|
||||
// Send a message to the server without a
|
||||
// window id. Used for global events like exit().
|
||||
void ScrollView::SendRawMessage(const char* msg) {
|
||||
stream_->Send(msg);
|
||||
}
|
||||
|
||||
// Add an Event Listener to this ScrollView Window
|
||||
void ScrollView::AddEventHandler(SVEventHandler* listener) {
|
||||
event_handler_ = listener;
|
||||
}
|
||||
|
||||
void ScrollView::Signal() {
|
||||
semaphore_->Signal();
|
||||
}
|
||||
|
||||
void ScrollView::SetEvent(SVEvent* svevent) {
|
||||
// Copy event
|
||||
SVEvent* any = svevent->copy();
|
||||
SVEvent* specific = svevent->copy();
|
||||
any->counter = specific->counter + 1;
|
||||
|
||||
// Place both events into the queue.
|
||||
mutex_->Lock();
|
||||
// Delete the old objects..
|
||||
if (event_table_[specific->type] != NULL) {
|
||||
delete event_table_[specific->type]; }
|
||||
if (event_table_[SVET_ANY] != NULL) {
|
||||
delete event_table_[SVET_ANY]; }
|
||||
// ...and put the new ones in the table.
|
||||
event_table_[specific->type] = specific;
|
||||
event_table_[SVET_ANY] = any;
|
||||
mutex_->Unlock();
|
||||
}
|
||||
|
||||
|
||||
// Block until an event of the given type is received.
|
||||
// Note: The calling function is responsible for deleting the returned
|
||||
// SVEvent afterwards!
|
||||
SVEvent* ScrollView::AwaitEvent(SVEventType type) {
|
||||
// Initialize the waiting semaphore.
|
||||
SVSemaphore* sem = new SVSemaphore();
|
||||
std::pair<ScrollView*, SVEventType> ea(this, type);
|
||||
mutex_waiting->Lock();
|
||||
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
||||
mutex_waiting->Unlock();
|
||||
// Wait on it, but first flush.
|
||||
stream_->Flush();
|
||||
sem->Wait();
|
||||
// Process the event we got woken up for (its in waiting_for_events pair).
|
||||
mutex_waiting->Lock();
|
||||
SVEvent* ret = waiting_for_events[ea].second;
|
||||
waiting_for_events.erase(ea);
|
||||
mutex_waiting->Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Block until any event on any window is received.
|
||||
// No event is returned here!
|
||||
SVEvent* ScrollView::AwaitEventAnyWindow() {
|
||||
// Initialize the waiting semaphore.
|
||||
SVSemaphore* sem = new SVSemaphore();
|
||||
std::pair<ScrollView*, SVEventType> ea(NULL, SVET_ANY);
|
||||
mutex_waiting->Lock();
|
||||
waiting_for_events[ea] = std::pair<SVSemaphore*, SVEvent*> (sem, NULL);
|
||||
mutex_waiting->Unlock();
|
||||
// Wait on it.
|
||||
stream_->Flush();
|
||||
sem->Wait();
|
||||
// Process the event we got woken up for (its in waiting_for_events pair).
|
||||
mutex_waiting->Lock();
|
||||
SVEvent* ret = waiting_for_events[ea].second;
|
||||
waiting_for_events.erase(ea);
|
||||
mutex_waiting->Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* LUA "API" functions.
|
||||
*******************************************************************************/
|
||||
|
||||
// Sets the position from which to draw to (x,y).
|
||||
void ScrollView::SetCursor(int x, int y) {
|
||||
current_position_x_ = x;
|
||||
current_position_y_ = y;
|
||||
}
|
||||
|
||||
// Draws from the current position to (x,y) and sets the new position to it.
|
||||
void ScrollView::DrawTo(int x, int y) {
|
||||
Line(current_position_x_, current_position_y_, x, y);
|
||||
SetCursor(x, y);
|
||||
}
|
||||
|
||||
// Set the visibility of the window.
|
||||
void ScrollView::SetVisible(bool visible) {
|
||||
if (visible) { SendMsg("setVisible(true)");
|
||||
} else { SendMsg("setVisible(false)"); }
|
||||
}
|
||||
|
||||
// Set the alwaysOnTop flag.
|
||||
void ScrollView::AlwaysOnTop(bool b) {
|
||||
if (b) { SendMsg("setAlwaysOnTop(true)");
|
||||
} else { SendMsg("setAlwaysOnTop(false)"); }
|
||||
}
|
||||
|
||||
// Adds a message entry to the message box.
|
||||
void ScrollView::AddMessage(const char* format, ...) {
|
||||
va_list args;
|
||||
char message[kMaxMsgSize];
|
||||
char form[kMaxMsgSize];
|
||||
|
||||
va_start(args, format); // variable list
|
||||
vsnprintf(message, kMaxMsgSize, format, args);
|
||||
va_end(args);
|
||||
|
||||
snprintf(form, kMaxMsgSize, "w%u:%s", window_id_, message);
|
||||
|
||||
char* esc = AddEscapeChars(form);
|
||||
SendMsg("addMessage(\"%s\")", esc);
|
||||
delete[] esc;
|
||||
}
|
||||
|
||||
// Set a messagebox.
|
||||
void ScrollView::AddMessageBox() {
|
||||
SendMsg("addMessageBox()");
|
||||
}
|
||||
|
||||
// Exit the client completely (and notify the server of it).
|
||||
void ScrollView::Exit() {
|
||||
SendRawMessage("svmain:exit()");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Clear the canvas.
|
||||
void ScrollView::Clear() {
|
||||
SendMsg("clear()");
|
||||
}
|
||||
|
||||
// Draw a line using the current pen color.
|
||||
void ScrollView::Line(int x1, int y1, int x2, int y2) {
|
||||
SendMsg("drawLine(%d,%d,%d,%d)",
|
||||
x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2));
|
||||
}
|
||||
|
||||
// Set the stroke width.
|
||||
void ScrollView::Stroke(float width) {
|
||||
SendMsg("setStrokeWidth(%f)", width);
|
||||
}
|
||||
|
||||
// Draw a rectangle using the current pen color.
|
||||
// The rectangle is filled with the current brush color.
|
||||
void ScrollView::Rectangle(int x1, int y1, int x2, int y2) {
|
||||
SendMsg("drawRectangle(%d,%d,%d,%d)",
|
||||
x1, TranslateYCoordinate(y1), x2, TranslateYCoordinate(y2));
|
||||
}
|
||||
|
||||
// Draw an ellipse using the current pen color.
|
||||
// The ellipse is filled with the current brush color.
|
||||
void ScrollView::Ellipse(int x1, int y1, int width, int height) {
|
||||
SendMsg("drawEllipse(%d,%d,%u,%u)",
|
||||
x1, TranslateYCoordinate(y1), width, height);
|
||||
}
|
||||
|
||||
// Set the pen color to the given RGB values.
|
||||
void ScrollView::Pen(int red, int green, int blue) {
|
||||
SendMsg("pen(%d,%d,%d)", red, green, blue);
|
||||
}
|
||||
|
||||
// Set the pen color to the given RGB values.
|
||||
void ScrollView::Pen(int red, int green, int blue, int alpha) {
|
||||
SendMsg("pen(%d,%d,%d,%d)", red, green, blue, alpha);
|
||||
}
|
||||
|
||||
// Set the brush color to the given RGB values.
|
||||
void ScrollView::Brush(int red, int green, int blue) {
|
||||
SendMsg("brush(%d,%d,%d)", red, green, blue);
|
||||
}
|
||||
|
||||
// Set the brush color to the given RGB values.
|
||||
void ScrollView::Brush(int red, int green, int blue, int alpha) {
|
||||
SendMsg("brush(%d,%d,%d,%d)", red, green, blue, alpha);
|
||||
}
|
||||
|
||||
// Set the attributes for future Text(..) calls.
|
||||
void ScrollView::TextAttributes(const char* font, int pixel_size,
|
||||
bool bold, bool italic, bool underlined) {
|
||||
const char* b;
|
||||
const char* i;
|
||||
const char* u;
|
||||
|
||||
if (bold) { b = "true";
|
||||
} else { b = "false"; }
|
||||
if (italic) { i = "true";
|
||||
} else { i = "false"; }
|
||||
if (underlined) { u = "true";
|
||||
} else { u = "false"; }
|
||||
SendMsg("textAttributes('%s',%u,%s,%s,%s)", font, pixel_size,
|
||||
b, i, u);
|
||||
}
|
||||
|
||||
// Draw text at the given coordinates.
|
||||
void ScrollView::Text(int x, int y, const char* mystring) {
|
||||
SendMsg("drawText(%d,%d,'%s')", x, TranslateYCoordinate(y), mystring);
|
||||
}
|
||||
|
||||
// Open and draw an image given a name at (x,y).
|
||||
void ScrollView::Image(const char* image, int x_pos, int y_pos) {
|
||||
SendMsg("openImage('%s')", image);
|
||||
SendMsg("drawImage('%s',%d,%d)",
|
||||
image, x_pos, TranslateYCoordinate(y_pos));
|
||||
}
|
||||
|
||||
// Add new checkboxmenuentry to menubar.
|
||||
void ScrollView::MenuItem(const char* parent, const char* name,
|
||||
int cmdEvent, bool flag) {
|
||||
if (parent == NULL) { parent = ""; }
|
||||
if (flag) { SendMsg("addMenuBarItem('%s','%s',%d,true)",
|
||||
parent, name, cmdEvent);
|
||||
} else { SendMsg("addMenuBarItem('%s','%s',%d,false)",
|
||||
parent, name, cmdEvent); }
|
||||
}
|
||||
|
||||
// Add new menuentry to menubar.
|
||||
void ScrollView::MenuItem(const char* parent, const char* name, int cmdEvent) {
|
||||
if (parent == NULL) { parent = ""; }
|
||||
SendMsg("addMenuBarItem('%s','%s',%d)", parent, name, cmdEvent);
|
||||
}
|
||||
|
||||
// Add new submenu to menubar.
|
||||
void ScrollView::MenuItem(const char* parent, const char* name) {
|
||||
if (parent == NULL) { parent = ""; }
|
||||
SendMsg("addMenuBarItem('%s','%s')", parent, name);
|
||||
}
|
||||
|
||||
// Add new submenu to popupmenu.
|
||||
void ScrollView::PopupItem(const char* parent, const char* name) {
|
||||
if (parent == NULL) { parent = ""; }
|
||||
SendMsg("addPopupMenuItem('%s','%s')", parent, name);
|
||||
}
|
||||
|
||||
// Add new submenuentry to popupmenu.
|
||||
void ScrollView::PopupItem(const char* parent, const char* name,
|
||||
int cmdEvent, const char* value, const char* desc) {
|
||||
if (parent == NULL) { parent = ""; }
|
||||
char* esc = AddEscapeChars(value);
|
||||
char* esc2 = AddEscapeChars(desc);
|
||||
SendMsg("addPopupMenuItem('%s','%s',%d,'%s','%s')", parent, name,
|
||||
cmdEvent, esc, esc2);
|
||||
delete[] esc;
|
||||
delete[] esc2;
|
||||
}
|
||||
|
||||
// Send an update message for a single window.
|
||||
void ScrollView::UpdateWindow() {
|
||||
SendMsg("update()");
|
||||
}
|
||||
|
||||
// Note: this is an update to all windows
|
||||
void ScrollView::Update() {
|
||||
for (std::map<int, ScrollView*>::iterator iter = svmap.begin();
|
||||
iter != svmap.end(); ++iter) {
|
||||
iter->second->UpdateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pen color, using an enum value (e.g. ScrollView::ORANGE)
|
||||
void ScrollView::Pen(Color color) {
|
||||
Pen(table_colors[color][0], table_colors[color][1],
|
||||
table_colors[color][2], table_colors[color][3]);
|
||||
}
|
||||
|
||||
// Set the brush color, using an enum value (e.g. ScrollView::ORANGE)
|
||||
void ScrollView::Brush(Color color) {
|
||||
Brush(table_colors[color][0],
|
||||
table_colors[color][1],
|
||||
table_colors[color][2],
|
||||
table_colors[color][3]);
|
||||
}
|
||||
|
||||
// Shows a modal Input Dialog which can return any kind of String
|
||||
char* ScrollView::ShowInputDialog(const char* msg) {
|
||||
SendMsg("showInputDialog(\"%s\")", msg);
|
||||
SVEvent* ev;
|
||||
// wait till an input event (all others are thrown away)
|
||||
ev = AwaitEvent(SVET_INPUT);
|
||||
char* p = new char[strlen(ev->parameter) + 1];
|
||||
strncpy(p, ev->parameter, strlen(ev->parameter));
|
||||
p[strlen(ev->parameter)] = '\0';
|
||||
delete ev;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Shows a modal Yes/No Dialog which will return 'y' or 'n'
|
||||
int ScrollView::ShowYesNoDialog(const char* msg) {
|
||||
SendMsg("showYesNoDialog(\"%s\")", msg);
|
||||
SVEvent* ev;
|
||||
// Wait till an input event (all others are thrown away)
|
||||
ev = AwaitEvent(SVET_INPUT);
|
||||
int a = ev->parameter[0];
|
||||
delete ev;
|
||||
return a;
|
||||
}
|
||||
|
||||
#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 height = image->h;
|
||||
l_uint32 bpp = image->d;
|
||||
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
||||
SendMsg("createImage('%u',%u,%u,%u)", "lept", width, height, bpp);
|
||||
|
||||
if (bpp == 32) {
|
||||
Transfer32bppImage(image);
|
||||
} else if (bpp == 8) {
|
||||
TransferGrayImage(image);
|
||||
} else if (bpp == 1) {
|
||||
TransferBinaryImage(image);
|
||||
}
|
||||
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
||||
SendMsg("drawImage('%u',%d,%d)", "lept", x_pos, y_pos);
|
||||
}
|
||||
|
||||
// Sends each pixel as hex value like html, e.g. #00FF00 for green.
|
||||
void ScrollView::Transfer32bppImage(PIX* image) {
|
||||
int ppL = pixGetWidth(image);
|
||||
int h = pixGetHeight(image);
|
||||
int wpl = pixGetWpl(image);
|
||||
int transfer_size= ppL * 7 + 1;
|
||||
char* pixel_data = new char[transfer_size];
|
||||
for (int y = 0; y < h; ++y) {
|
||||
l_uint32* data = pixGetData(image) + y*wpl;
|
||||
for (int x = 0; x < ppL; ++x, ++data) {
|
||||
snprintf(&pixel_data[x*7], 7, "#%.2x%.2x%.2x",
|
||||
GET_DATA_BYTE(data, COLOR_RED),
|
||||
GET_DATA_BYTE(data, COLOR_GREEN),
|
||||
GET_DATA_BYTE(data, COLOR_BLUE));
|
||||
}
|
||||
pixel_data[transfer_size - 1] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
}
|
||||
delete[] pixel_data;
|
||||
}
|
||||
|
||||
// TODO add RunLengthEncoding to this or something similar
|
||||
// TODO testme
|
||||
// Sends for each pixel either '1' or '0'.
|
||||
void ScrollView::TransferGrayImage(PIX* image) {
|
||||
char pixel_data[image->w * 2 + 1];
|
||||
for (int y = 0; y < image->h; y++) {
|
||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||
for (int x = 0; x < image->w; x++) {
|
||||
snprintf(&pixel_data[x*2], 2, "%.2x", (GET_DATA_BYTE(data, x)));
|
||||
pixel_data[image->w * 2] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add RunLengthEncoding to this or something similar
|
||||
// Sends for each pixel either '1' or '0'.
|
||||
void ScrollView::TransferBinaryImage(PIX* image) {
|
||||
char pixel_data[image->w + 1];
|
||||
for (int y = 0; y < image->h; y++) {
|
||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||
for (int x = 0; x < image->w; x++) {
|
||||
if (GET_DATA_BIT(data, x))
|
||||
{ pixel_data[x] = '1'; }
|
||||
else
|
||||
{ pixel_data[x] = '0'; }
|
||||
}
|
||||
pixel_data[image->w] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
char* ScrollView::AddEscapeChars(const char* input) {
|
||||
const char* nextptr = strchr(input, '\'');
|
||||
const char* lastptr = input;
|
||||
char* message = new char[kMaxMsgSize];
|
||||
int pos = 0;
|
||||
while (nextptr != NULL) {
|
||||
strncpy(message+pos, lastptr, nextptr-lastptr);
|
||||
pos += nextptr - lastptr;
|
||||
message[pos] = '\\';
|
||||
pos += 1;
|
||||
lastptr = nextptr;
|
||||
nextptr = strchr(nextptr+1, '\'');
|
||||
}
|
||||
strncpy(message+pos, lastptr, strlen(lastptr));
|
||||
message[pos+strlen(lastptr)] = '\0';
|
||||
return message;
|
||||
}
|
||||
|
||||
// Inverse the Y axis if the coordinates are actually inversed.
|
||||
int ScrollView::TranslateYCoordinate(int y) {
|
||||
if (!y_axis_is_reversed_) { return y;
|
||||
} else { return y_size_ - y; }
|
||||
}
|
401
viewer/scrollview.h
Normal file
401
viewer/scrollview.h
Normal file
@ -0,0 +1,401 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: scrollview.h
|
||||
// Description: ScrollView
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ScrollView is designed as an UI which can be run remotely. This is the
|
||||
// client code for it, the server part is written in java. The client consists
|
||||
// mainly of 2 parts:
|
||||
// The "core" ScrollView which sets up the remote connection,
|
||||
// takes care of event handling etc.
|
||||
// The other part of ScrollView consists of predefined API calls through LUA,
|
||||
// which can basically be used to get a zoomable canvas in which it is possible
|
||||
// to draw lines, text etc.
|
||||
// Technically, thanks to LUA, its even possible to bypass the here defined LUA
|
||||
// API calls at all and generate a java user interface from scratch (or
|
||||
// basically generate any kind of java program, possibly even dangerous ones).
|
||||
|
||||
#ifndef THIRD_PARTY_TESSERACT_VIEWER_SCROLLVIEW_H__
|
||||
#define THIRD_PARTY_TESSERACT_VIEWER_SCROLLVIEW_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class ScrollView;
|
||||
class SVNetwork;
|
||||
class SVMutex;
|
||||
class SVSemaphore;
|
||||
|
||||
enum SVEventType {
|
||||
SVET_DESTROY, // Window has been destroyed by user.
|
||||
SVET_EXIT, // User has destroyed the last window by clicking on the 'X'.
|
||||
SVET_CLICK, // Left button pressed.
|
||||
SVET_SELECTION, // Left button selection.
|
||||
SVET_INPUT, // There is some input (single key or a whole string).
|
||||
SVET_MOUSE, // The mouse has moved with a button pressed.
|
||||
SVET_MOTION, // The mouse has moved with no button pressed.
|
||||
SVET_HOVER, // The mouse has stayed still for a second.
|
||||
SVET_POPUP, // A command selected through a popup menu.
|
||||
SVET_MENU, // A command selected through the menubar.
|
||||
SVET_ANY, // Any of the above.
|
||||
|
||||
SVET_COUNT // Array sizing.
|
||||
};
|
||||
|
||||
struct SVEvent {
|
||||
~SVEvent() { delete [] parameter; }
|
||||
SVEvent* copy();
|
||||
SVEventType type; // What kind of event.
|
||||
ScrollView* window; // Window event relates to.
|
||||
int x; // Coords of click or selection.
|
||||
int y;
|
||||
int x_size; // Size of selection.
|
||||
int y_size;
|
||||
int command_id; // The ID of the possibly associated event (e.g. MENU)
|
||||
char* parameter; // Any string that might have been passed as argument.
|
||||
int counter; // Used to detect which kind of event to process next.
|
||||
|
||||
SVEvent() {
|
||||
window = NULL;
|
||||
parameter = NULL;
|
||||
}
|
||||
|
||||
SVEvent(const SVEvent&);
|
||||
SVEvent& operator=(const SVEvent&);
|
||||
};
|
||||
|
||||
// The SVEventHandler class is used for Event handling: If you register your
|
||||
// class as SVEventHandler to a ScrollView Window, the SVEventHandler will be
|
||||
// called whenever an appropriate event occurs.
|
||||
class SVEventHandler {
|
||||
public:
|
||||
// Gets called by the SV Window. Does nothing on default, overwrite this
|
||||
// to implement the desired behaviour
|
||||
virtual void Notify(const SVEvent* sve) { }
|
||||
};
|
||||
|
||||
// The ScrollView class provides the expernal API to the scrollviewer process.
|
||||
// The scrollviewer process manages windows and displays images, graphics and
|
||||
// text while allowing the user to zoom and scroll the windows arbitrarily.
|
||||
// Each ScrollView class instance represents one window, and stuff is drawn in
|
||||
// the window through method calls on the class. The constructor is used to
|
||||
// create the class instance (and the window).
|
||||
|
||||
class ScrollView {
|
||||
public:
|
||||
// Color enum for pens and brushes.
|
||||
enum Color {
|
||||
NONE,
|
||||
BLACK,
|
||||
WHITE,
|
||||
RED,
|
||||
YELLOW,
|
||||
GREEN,
|
||||
CYAN,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
AQUAMARINE,
|
||||
DARK_SLATE_BLUE,
|
||||
LIGHT_BLUE,
|
||||
MEDIUM_BLUE,
|
||||
MIDNIGHT_BLUE,
|
||||
NAVY_BLUE,
|
||||
SKY_BLUE,
|
||||
SLATE_BLUE,
|
||||
STEEL_BLUE,
|
||||
CORAL,
|
||||
BROWN,
|
||||
SANDY_BROWN,
|
||||
GOLD,
|
||||
GOLDENROD,
|
||||
DARK_GREEN,
|
||||
DARK_OLIVE_GREEN,
|
||||
FOREST_GREEN,
|
||||
LIME_GREEN,
|
||||
PALE_GREEN,
|
||||
YELLOW_GREEN,
|
||||
LIGHT_GREY,
|
||||
DARK_SLATE_GREY,
|
||||
DIM_GREY,
|
||||
GREY,
|
||||
KHAKI,
|
||||
MAROON,
|
||||
ORANGE,
|
||||
ORCHID,
|
||||
PINK,
|
||||
PLUM,
|
||||
INDIAN_RED,
|
||||
ORANGE_RED,
|
||||
VIOLET_RED,
|
||||
SALMON,
|
||||
TAN,
|
||||
TURQUOISE,
|
||||
DARK_TURQUOISE,
|
||||
VIOLET,
|
||||
WHEAT,
|
||||
GREEN_YELLOW // Make sure this one is last.
|
||||
};
|
||||
|
||||
// Create a window. The pixel size of the window may be 0,0, in which case
|
||||
// a default size is selected based on the size of your canvas.
|
||||
// The canvas may not be 0,0 in size!
|
||||
ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size,
|
||||
int x_canvas_size, int y_canvas_size);
|
||||
// With a flag whether the x axis is reversed.
|
||||
ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size,
|
||||
int x_canvas_size, int y_canvas_size, bool y_axis_reversed);
|
||||
// Connect to a server other than localhost.
|
||||
ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size,
|
||||
int x_canvas_size, int y_canvas_size, bool y_axis_reversed,
|
||||
const char* server_name);
|
||||
~ScrollView();
|
||||
|
||||
/*******************************************************************************
|
||||
* Event handling
|
||||
* To register as listener, the class has to derive from the SVEventHandler
|
||||
* class, which consists of a notifyMe(SVEvent*) function that should be
|
||||
* overwritten to process the event the way you want.
|
||||
*******************************************************************************/
|
||||
|
||||
// Add an Event Listener to this ScrollView Window.
|
||||
void AddEventHandler(SVEventHandler* listener);
|
||||
|
||||
// Block until an event of the given type is received.
|
||||
SVEvent* AwaitEvent(SVEventType type);
|
||||
|
||||
// Block until any event on any window is received.
|
||||
SVEvent* AwaitEventAnyWindow();
|
||||
|
||||
/*******************************************************************************
|
||||
* Getters and Setters
|
||||
*******************************************************************************/
|
||||
|
||||
// Returns the title of the window.
|
||||
const char* GetName() { return window_name_; }
|
||||
|
||||
// Returns the unique ID of the window.
|
||||
int GetId() { return window_id_; }
|
||||
|
||||
/*******************************************************************************
|
||||
* API functions for LUA calls
|
||||
* the implementations for these can be found in svapi.cc
|
||||
* (keep in mind that the window is actually created through the ScrollView
|
||||
* constructor, so this is not listed here)
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef HAVE_LIBLEPT
|
||||
// Draw a Pix on (x,y).
|
||||
void Image(struct Pix* image, int x_pos, int y_pos);
|
||||
#endif
|
||||
|
||||
// Flush buffers and update display.
|
||||
static void Update();
|
||||
|
||||
// Exit the program.
|
||||
static void Exit();
|
||||
|
||||
// Update the contents of a specific window.
|
||||
void UpdateWindow();
|
||||
|
||||
// Erase all content from the window, but do not destroy it.
|
||||
void Clear();
|
||||
|
||||
// Set pen color with an enum.
|
||||
void Pen(Color color);
|
||||
|
||||
// Set pen color to RGB (0-255).
|
||||
void Pen(int red, int green, int blue);
|
||||
|
||||
// Set pen color to RGBA (0-255).
|
||||
void Pen(int red, int green, int blue, int alpha);
|
||||
|
||||
// Set brush color with an enum.
|
||||
void Brush(Color color);
|
||||
|
||||
// Set brush color to RGB (0-255).
|
||||
void Brush(int red, int green, int blue);
|
||||
|
||||
// Set brush color to RGBA (0-255).
|
||||
void Brush(int red, int green, int blue, int alpha);
|
||||
|
||||
// Set attributes for future text, like font name (e.g.
|
||||
// "Times New Roman"), font size etc..
|
||||
// Note: The underlined flag is currently not supported
|
||||
void TextAttributes(const char* font, int pixel_size,
|
||||
bool bold, bool italic, bool underlined);
|
||||
|
||||
// Draw line from (x1,y1) to (x2,y2) with the current pencolor.
|
||||
void Line(int x1, int y1, int x2, int y2);
|
||||
|
||||
// Set the stroke width of the pen.
|
||||
void Stroke(float width);
|
||||
|
||||
// Draw a rectangle given upper left corner and lower right corner.
|
||||
// The current pencolor is used as outline, the brushcolor to fill the shape.
|
||||
void Rectangle(int x1, int y1, int x2, int y2);
|
||||
|
||||
// Draw an ellipse centered on (x,y).
|
||||
// The current pencolor is used as outline, the brushcolor to fill the shape.
|
||||
void Ellipse(int x, int y, int width, int height);
|
||||
|
||||
// Draw text with the current pencolor
|
||||
void Text(int x, int y, const char* mystring);
|
||||
|
||||
// Draw an image from a local filename. This should be faster than createImage.
|
||||
// WARNING: This only works on a local machine. This also only works image
|
||||
// types supported by java (like bmp,jpeg,gif,png) since the image is opened by
|
||||
// the server.
|
||||
void Image(const char* image, int x_pos, int y_pos);
|
||||
|
||||
// Set the current position to draw from (x,y). In conjunction with...
|
||||
void SetCursor(int x, int y);
|
||||
|
||||
// ...this function, which draws a line from the current to (x,y) and then
|
||||
// sets the new position to the new (x,y), this can be used to easily draw
|
||||
// polygons using vertices
|
||||
void DrawTo(int x, int y);
|
||||
|
||||
// Set the SVWindow visible/invisible.
|
||||
void SetVisible(bool visible);
|
||||
|
||||
// Set the SVWindow always on top or not always on top.
|
||||
void AlwaysOnTop(bool b);
|
||||
|
||||
// Shows a modal dialog with "msg" as question and returns 'y' or 'n'.
|
||||
int ShowYesNoDialog(const char* msg);
|
||||
|
||||
// Shows a modal dialog with "msg" as question and returns a char* string.
|
||||
// Constraint: As return, only words (e.g. no whitespaces etc.) are allowed.
|
||||
char* ShowInputDialog(const char* msg);
|
||||
|
||||
// Adds a messagebox to the SVWindow. This way, it can show the messages...
|
||||
void AddMessageBox();
|
||||
|
||||
// ...which can be added by this command.
|
||||
// This is intended as an "debug" output window.
|
||||
void AddMessage(const char* format, ...);
|
||||
|
||||
// Custom messages (manipulating java code directly) can be send through this.
|
||||
// Send a message to the server and attach the Id of the corresponding window.
|
||||
// Note: This should only be called if you are know what you are doing, since
|
||||
// you are fiddling with the Java objects on the server directly. Calling
|
||||
// this just for fun will likely break your application!
|
||||
// It is public so you can actually take use of the LUA functionalities, but
|
||||
// be careful!
|
||||
void SendMsg(const char* msg, ...);
|
||||
|
||||
// Custom messages (manipulating java code directly) can be send through this.
|
||||
// Send a message to the server without adding the
|
||||
// window id. Used for global events like Exit().
|
||||
// Note: This should only be called if you are know what you are doing, since
|
||||
// you are fiddling with the Java objects on the server directly. Calling
|
||||
// this just for fun will likely break your application!
|
||||
// It is public so you can actually take use of the LUA functionalities, but
|
||||
// be careful!
|
||||
static void SendRawMessage(const char* msg);
|
||||
|
||||
/*******************************************************************************
|
||||
* Add new menu entries to parent. If parent is "", the entry gets added to the
|
||||
* main menubar (toplevel).
|
||||
*******************************************************************************/
|
||||
// This adds a new submenu to the menubar.
|
||||
void MenuItem(const char* parent, const char* name);
|
||||
|
||||
// This adds a new (normal) menu entry with an associated eventID, which should
|
||||
// be unique among menubar eventIDs.
|
||||
void MenuItem(const char* parent, const char* name, int cmdEvent);
|
||||
|
||||
// This adds a new checkbox entry, which might initally be flagged.
|
||||
void MenuItem(const char* parent, const char* name,
|
||||
int cmdEvent, bool flagged);
|
||||
|
||||
// This adds a new popup submenu to the popup menu. If parent is "", the entry
|
||||
// gets added at "toplevel" popupmenu.
|
||||
void PopupItem(const char* parent, const char* name);
|
||||
|
||||
// This adds a new popup entry with the associated eventID, which should be
|
||||
// unique among popup eventIDs.
|
||||
// If value and desc are given, on a click the server will ask you to modify
|
||||
// the value and return the new value.
|
||||
void PopupItem(const char* parent, const char* name,
|
||||
int cmdEvent, const char* value, const char* desc);
|
||||
|
||||
// Returns the correct Y coordinate for a window, depending on whether it might
|
||||
// have to be flipped (by ySize).
|
||||
int TranslateYCoordinate(int y);
|
||||
|
||||
private:
|
||||
#ifdef HAVE_LIBLEPT
|
||||
// Transfers a binary Image.
|
||||
void TransferBinaryImage(struct Pix* image);
|
||||
// Transfers a gray scale Image.
|
||||
void TransferGrayImage(struct Pix* image);
|
||||
// Transfers a 32-Bit Image.
|
||||
void Transfer32bppImage(struct Pix* image);
|
||||
#endif
|
||||
|
||||
// Sets up ScrollView, depending on the variables from the constructor.
|
||||
void Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
||||
int y_size, int x_canvas_size, int y_canvas_size,
|
||||
bool y_axis_reversed, const char* server_name);
|
||||
|
||||
// Start the message receiving thread.
|
||||
static void* MessageReceiver(void* a);
|
||||
|
||||
// Place an event into the event_table (synchronized).
|
||||
void SetEvent(SVEvent* svevent);
|
||||
|
||||
// Wake up the semaphore.
|
||||
void Signal();
|
||||
|
||||
// Returns the unique, shared network stream.
|
||||
static SVNetwork* GetStream() { return stream_; }
|
||||
|
||||
// Starts a new event handler. Called whenever a new window is created.
|
||||
static void* StartEventHandler(void* sv);
|
||||
|
||||
// Escapes the ' character with a \, so it can be processed by LUA.
|
||||
char* AddEscapeChars(const char* input);
|
||||
|
||||
// The event handler for this window.
|
||||
SVEventHandler* event_handler_;
|
||||
// The name of the window.
|
||||
const char* window_name_;
|
||||
// The id of the window.
|
||||
int window_id_;
|
||||
// The points last set by setCursor(x,y) or then updated by drawTo(x,y).
|
||||
int current_position_x_, current_position_y_;
|
||||
// Whether the axis is reversed.
|
||||
bool y_axis_is_reversed_;
|
||||
// If the y axis is reversed, flip all y values by ySize.
|
||||
int y_size_;
|
||||
// # of created windows (used to assign an id to each ScrollView* for svmap).
|
||||
static int nr_created_windows_;
|
||||
|
||||
// The stream through which the c++ client is connected to the server.
|
||||
static SVNetwork* stream_;
|
||||
|
||||
// Table of all the currently queued events.
|
||||
SVEvent* event_table_[SVET_COUNT];
|
||||
|
||||
// Mutex to access the event_table_ in a synchronized fashion.
|
||||
SVMutex* mutex_;
|
||||
|
||||
// Semaphore to the thread belonging to this window.
|
||||
SVSemaphore* semaphore_;
|
||||
};
|
||||
|
||||
#endif // THIRD_PARTY_TESSERACT_VIEWER_SCROLLVIEW_H__
|
@ -1,84 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: showimg.c (Formerly showim.c)
|
||||
* Description: Interface to sbdaemon for displaying images.
|
||||
* Author: Ray Smith
|
||||
* Created: Mon Jun 11 16:20:34 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "mfcpch.h"
|
||||
#include "grphshm.h"
|
||||
#include "showim.h"
|
||||
|
||||
void (*show_func) (IMAGE *, INT32, INT32, INT32, INT32, WINDOW, INT32,
|
||||
INT32) = def_show_sub_image;
|
||||
|
||||
/**********************************************************************
|
||||
* show_sub_image
|
||||
*
|
||||
* Send the given image to the daemon and insert it in the display list.
|
||||
**********************************************************************/
|
||||
|
||||
DLLSYM void def_show_sub_image( //show this image
|
||||
IMAGE *source, //image to show
|
||||
INT32 xstart, //start coords
|
||||
INT32 ystart,
|
||||
INT32 xext, //extent to show
|
||||
INT32 yext,
|
||||
WINDOW win, //window to draw in
|
||||
INT32 xpos, //position to show at
|
||||
INT32 ypos //y position
|
||||
) {
|
||||
EIGHTOP *newop; //message structure
|
||||
INT32 y; //y coord
|
||||
INT32 linelength; //bytes per line
|
||||
IMAGE dummyimage; //used for copying to
|
||||
IMAGEOP *sendline; //transmitted line
|
||||
INT32 structsize; //size of structure
|
||||
INT32 destbpp; //destination bits per pixel
|
||||
|
||||
destbpp = source->get_bpp (); //send all images unchanged
|
||||
|
||||
newop = (EIGHTOP *) getshm (sizeof (EIGHTOP));
|
||||
if (newop != NULL) {
|
||||
//send the fd
|
||||
newop->header.fd = win->get_fd ();
|
||||
newop->type = SHOWIMAGE; //send the operator
|
||||
newop->param.p[0].i = xext; //send parameters
|
||||
newop->param.p[1].i = yext;
|
||||
newop->param.p[2].i = destbpp;
|
||||
newop->param.p[3].i = xpos;
|
||||
newop->param.p[4].i = ypos;
|
||||
|
||||
//bytes required
|
||||
linelength = COMPUTE_IMAGE_XDIM (xext, destbpp);
|
||||
linelength++; //round up to next
|
||||
linelength &= ~1; //multiple of 2
|
||||
//size of structure
|
||||
structsize = (INT32) (sizeof (IMAGEOP) + linelength - 2);
|
||||
for (y = yext - 1; y >= 0; --y) {
|
||||
//get space
|
||||
sendline = (IMAGEOP *) getshm (structsize);
|
||||
if (sendline != NULL) {
|
||||
sendline->header.fd = win->get_fd ();
|
||||
sendline->type = SHOWLINE;
|
||||
sendline->size = structsize;
|
||||
dummyimage.capture (sendline->line, xext, 1, (INT8) destbpp);
|
||||
//ready for copy
|
||||
//copy to shm
|
||||
copy_sub_image (source, xstart, ystart + y, xext, 1, &dummyimage, 0, 0, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/**********************************************************************
|
||||
* File: showimg.c (Formerly showim.c)
|
||||
* Description: Interface to sbdaemon for displaying images.
|
||||
* Author: Ray Smith
|
||||
* Created: Mon Jun 11 16:20:34 BST 1990
|
||||
*
|
||||
* (C) Copyright 1990, Hewlett-Packard Ltd.
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef SHOWIM_H
|
||||
#define SHOWIM_H
|
||||
|
||||
#include "grphics.h"
|
||||
#include "img.h"
|
||||
|
||||
#define show_sub_image(im,xstart,ystart,xext,yext,win,xpos,ypos) (*show_func)(im,xstart,ystart,xext,yext,win,xpos,ypos)
|
||||
|
||||
extern void (*show_func) (IMAGE *, INT32, INT32, INT32, INT32, WINDOW, INT32,
|
||||
INT32);
|
||||
|
||||
DLLSYM void def_show_sub_image( //show this image
|
||||
IMAGE *source, //image to show
|
||||
INT32 xstart, //start coords
|
||||
INT32 ystart,
|
||||
INT32 xext, //extent to show
|
||||
INT32 yext,
|
||||
WINDOW win, //window to draw in
|
||||
INT32 xpos, //position to show at
|
||||
INT32 ypos //y position
|
||||
);
|
||||
#endif
|
134
viewer/svmnode.cpp
Normal file
134
viewer/svmnode.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: svmnode.cpp
|
||||
// description_: ScrollView Menu Node
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A SVMenuNode is an entity which contains the mapping from a menu entry on
|
||||
// the server side to the corresponding associated commands on the client.
|
||||
// It is designed to be a tree structure with a root node, which can then be
|
||||
// used to generate the appropriate messages to the server to display the
|
||||
// menu structure there.
|
||||
// A SVMenuNode can both be used in the context_ of popup menus as well as
|
||||
// menu bars.
|
||||
#include "svmnode.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "scrollview.h"
|
||||
|
||||
// Create the empty root menu node. with just a caption. All other nodes should
|
||||
// be added to this or one of the submenus.
|
||||
SVMenuNode::SVMenuNode() {
|
||||
cmd_event_ = -1;
|
||||
text_ = NULL;
|
||||
child_ = NULL;
|
||||
next_ = NULL;
|
||||
parent_ = NULL;
|
||||
toggle_value_ = false;
|
||||
is_check_box_entry_ = false;
|
||||
value_ = NULL;
|
||||
description_ = NULL;
|
||||
}
|
||||
|
||||
SVMenuNode::~SVMenuNode() {
|
||||
delete[] text_;
|
||||
// delete[] description_;
|
||||
}
|
||||
|
||||
// Create a new sub menu node with just a caption. This is used to create
|
||||
// nodes which act as parent nodes to other nodes (e.g. submenus).
|
||||
SVMenuNode* SVMenuNode::AddChild(const char* txt) {
|
||||
SVMenuNode* s = new SVMenuNode(-1, txt, false, false, NULL, NULL);
|
||||
this->AddChild(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Create a "normal" menu node which is associated with a command event.
|
||||
void SVMenuNode::AddChild(const char* txt, int command_event) {
|
||||
this->AddChild(new SVMenuNode(command_event, txt, false, false, NULL, NULL));
|
||||
}
|
||||
|
||||
// Create a menu node with an associated value (which might be changed
|
||||
// through the gui).
|
||||
void SVMenuNode::AddChild(const char* txt, int command_event,
|
||||
const char* val) {
|
||||
this->AddChild(new SVMenuNode(command_event, txt, false, false, val, NULL));
|
||||
}
|
||||
|
||||
// Create a menu node with an associated value and description_.
|
||||
void SVMenuNode::AddChild(const char* txt, int command_event, const char* val,
|
||||
const char* desc) {
|
||||
this->AddChild(new SVMenuNode(command_event, txt, false, false, val, desc));
|
||||
}
|
||||
|
||||
// Create a flag menu node.
|
||||
void SVMenuNode::AddChild(const char* txt, int command_event, int tv) {
|
||||
this->AddChild(new SVMenuNode(command_event, txt, tv, true, NULL, NULL));
|
||||
}
|
||||
|
||||
// Convenience function called from the different constructors to initialize
|
||||
// the different values of the menu node.
|
||||
SVMenuNode::SVMenuNode(int command_event, const char* txt,
|
||||
int tv, bool check_box_entry, const char* val,
|
||||
const char* desc) {
|
||||
cmd_event_ = command_event;
|
||||
|
||||
text_ = new char[strlen(txt) + 1];
|
||||
strncpy(text_, txt, strlen(txt));
|
||||
text_[strlen(txt)] = '\0';
|
||||
|
||||
value_ = val;
|
||||
description_ = desc;
|
||||
|
||||
child_ = NULL;
|
||||
next_ = NULL;
|
||||
parent_ = NULL;
|
||||
toggle_value_ = tv;
|
||||
is_check_box_entry_ = check_box_entry;
|
||||
}
|
||||
|
||||
// Add a child node to this menu node.
|
||||
void SVMenuNode::AddChild(SVMenuNode* svmn) {
|
||||
svmn->parent_ = this;
|
||||
// No children yet.
|
||||
if (child_ == NULL) {
|
||||
child_ = svmn;
|
||||
} else {
|
||||
SVMenuNode* cur = child_;
|
||||
while (cur->next_ != NULL) { cur = cur->next_; }
|
||||
cur->next_ = svmn;
|
||||
}
|
||||
}
|
||||
|
||||
// Build a menu structure for the server and send the necessary messages.
|
||||
// Should be called on the root node. If menu_bar is true, a menu_bar menu
|
||||
// is built (e.g. on top of the window), if it is false a popup menu is
|
||||
// built which gets shown by right clicking on the window.
|
||||
// Deletes itself afterwards.
|
||||
void SVMenuNode::BuildMenu(ScrollView* sv, bool menu_bar) {
|
||||
if ((parent_ != NULL) && (menu_bar)) {
|
||||
if (is_check_box_entry_) {
|
||||
sv->MenuItem(parent_->text_, text_, cmd_event_, toggle_value_);
|
||||
} else { sv->MenuItem(parent_->text_, text_, cmd_event_); }
|
||||
} else if ((parent_ != NULL) && (!menu_bar)) {
|
||||
if (description_ != NULL) { sv->PopupItem(parent_->text_, text_,
|
||||
cmd_event_, value_, description_);
|
||||
} else { sv->PopupItem(parent_->text_, text_); }
|
||||
}
|
||||
if (child_ != NULL) { child_->BuildMenu(sv, menu_bar); delete child_; }
|
||||
if (next_ != NULL) { next_->BuildMenu(sv, menu_bar); delete next_; }
|
||||
}
|
94
viewer/svmnode.h
Normal file
94
viewer/svmnode.h
Normal file
@ -0,0 +1,94 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: svmnode.h
|
||||
// description_: ScrollView Menu Node
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A SVMenuNode is an entity which contains the mapping from a menu entry on
|
||||
// the server side to the corresponding associated commands on the client.
|
||||
// It is designed to be a tree structure with a root node, which can then be
|
||||
// used to generate the appropriate messages to the server to display the
|
||||
// menu structure there.
|
||||
// A SVMenuNode can both be used in the context_ of popup menus as well as
|
||||
// menu bars.
|
||||
|
||||
#ifndef THIRD_PARTY_TESSERACT_VIEWER_SVMNODE_H__
|
||||
#define THIRD_PARTY_TESSERACT_VIEWER_SVMNODE_H__
|
||||
|
||||
class ScrollView;
|
||||
|
||||
class SVMenuNode {
|
||||
public:
|
||||
// Creating the (empty) root menu node.
|
||||
SVMenuNode();
|
||||
|
||||
// Destructor for every node.
|
||||
~SVMenuNode();
|
||||
|
||||
// Create a new sub menu node with just a caption. This is used to create
|
||||
// nodes which act as parent nodes to other nodes (e.g. submenus).
|
||||
SVMenuNode* AddChild(const char* txt);
|
||||
|
||||
// Create a "normal" menu node which is associated with a command event.
|
||||
void AddChild(const char* txt, int command_event);
|
||||
|
||||
// Create a flag menu node.
|
||||
void AddChild(const char* txt, int command_event, int tv);
|
||||
|
||||
// Create a menu node with an associated value (which might be changed
|
||||
// through the gui).
|
||||
void AddChild(const char* txt, int command_event, const char* val);
|
||||
|
||||
// Create a menu node with an associated value and description_.
|
||||
void AddChild(const char* txt, int command_event,
|
||||
const char* val, const char* desc);
|
||||
|
||||
// Build a menu structure for the server and send the necessary messages.
|
||||
// Should be called on the root node. If menu_bar is true, a menu_bar menu
|
||||
// is built (e.g. on top of the window), if it is false a popup menu is
|
||||
// built which gets shown by right clicking on the window.
|
||||
void BuildMenu(ScrollView *sv, bool menu_bar = true);
|
||||
|
||||
private:
|
||||
// Constructor holding the actual node data.
|
||||
SVMenuNode(int command_event, const char* txt, int tv,
|
||||
bool check_box_entry, const char* val, const char* desc);
|
||||
|
||||
// Adds a new menu node to the current node.
|
||||
void AddChild(SVMenuNode* svmn);
|
||||
|
||||
// The parent node of this node.
|
||||
SVMenuNode* parent_;
|
||||
// The first child of this node.
|
||||
SVMenuNode* child_;
|
||||
// The next "sibling" of this node (e.g. same parent).
|
||||
SVMenuNode* next_;
|
||||
// Whether this menu node actually is a flag.
|
||||
bool is_check_box_entry_;
|
||||
|
||||
// The command event associated with a specific menu node. Should be unique.
|
||||
int cmd_event_;
|
||||
// The caption associated with a specific menu node.
|
||||
char* text_;
|
||||
// The value of the flag (if this menu node is a flag).
|
||||
bool toggle_value_;
|
||||
// The value of the menu node. (optional)
|
||||
const char* value_;
|
||||
// A description_ of the value. (optional)
|
||||
const char* description_;
|
||||
};
|
||||
|
||||
#endif // THIRD_PARTY_TESSERACT_VIEWER_SVMNODE_H__
|
220
viewer/svpaint.cpp
Normal file
220
viewer/svpaint.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Author: Joern Wanke
|
||||
//
|
||||
// Simple drawing program to illustrate ScrollView capabilities.
|
||||
//
|
||||
// Functionality:
|
||||
// - The menubar is used to select from different sample styles of input.
|
||||
// - With the RMB it is possible to change the RGB values in different
|
||||
// popup menus.
|
||||
// - A LMB click either draws point-to-point, point or text.
|
||||
// - A LMB dragging either draws a line, a rectangle or ellipse.
|
||||
|
||||
|
||||
#include "scrollview.h"
|
||||
#include "svmnode.h"
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
// The current color values we use, initially white (== ScrollView::WHITE).
|
||||
int rgb[3] = { 255, 255, 255 };
|
||||
|
||||
class SVPaint : public SVEventHandler {
|
||||
public:
|
||||
SVPaint(const char* server_name);
|
||||
// This is the main event handling function that we need to overwrite, defined
|
||||
// in SVEventHandler.
|
||||
void Notify(const SVEvent* sv_event);
|
||||
private:
|
||||
// The Handler take care of the SVET_POPUP, SVET_MENU, SVET_CLICK and
|
||||
// SVET_SELECTION events.
|
||||
void PopupHandler(const SVEvent* sv_event);
|
||||
void MenuBarHandler(const SVEvent* sv_event);
|
||||
void ClickHandler(const SVEvent* sv_event);
|
||||
void SelectionHandler(const SVEvent* sv_event);
|
||||
|
||||
// Convenience functions to build little menus.
|
||||
SVMenuNode* BuildPopupMenu();
|
||||
SVMenuNode* BuildMenuBar();
|
||||
|
||||
// Our window.
|
||||
ScrollView* window_;
|
||||
|
||||
// The mode we are in when an SVET_CLICK or an SVET_SELECTION event occurs.
|
||||
int click_mode_;
|
||||
int drag_mode_;
|
||||
|
||||
// In the point-to-point drawing mode, we need to set a start-point the first
|
||||
// time we call it (e.g. call SetCursor).
|
||||
bool has_start_point_;
|
||||
};
|
||||
|
||||
// Build a sample popup menu.
|
||||
SVMenuNode* SVPaint::BuildPopupMenu() {
|
||||
SVMenuNode* root = new SVMenuNode(); // Empty root node
|
||||
// Initial color is white, so we all values to 255.
|
||||
root->AddChild("R", // Shown caption.
|
||||
1, // assoc. command_id.
|
||||
"255", // initial value.
|
||||
"Red Color Value?"); // Shown description.
|
||||
root->AddChild("G", 2, "255", "Green Color Value?");
|
||||
root->AddChild("B", 3, "255", "Blue Color Value?");
|
||||
return root;
|
||||
}
|
||||
|
||||
// Build a sample menu bar.
|
||||
SVMenuNode* SVPaint::BuildMenuBar() {
|
||||
SVMenuNode* root = new SVMenuNode(); // Empty root node
|
||||
|
||||
// Create some submenus and add them to the root.
|
||||
SVMenuNode* click = root->AddChild("Clicking");
|
||||
SVMenuNode* drag = root->AddChild("Dragging");
|
||||
|
||||
// Put some nodes into the submenus.
|
||||
click->AddChild("Point to Point Drawing", // Caption.
|
||||
1); // command_id.
|
||||
click->AddChild("Point Drawing", 2);
|
||||
click->AddChild("Text Drawing", 3);
|
||||
drag->AddChild("Line Drawing", 4);
|
||||
drag->AddChild("Rectangle Drawing", 5);
|
||||
drag->AddChild("Ellipse Drawing", 6);
|
||||
return root;
|
||||
}
|
||||
|
||||
// Takes care of the SVET_POPUP events.
|
||||
// In our case, SVET_POPUP is used to set RGB values.
|
||||
void SVPaint::PopupHandler(const SVEvent* sv_event) {
|
||||
// Since we only have the RGB values as popup items,
|
||||
// we take a shortcut to not bloat up code:
|
||||
rgb[sv_event->command_id - 1] = atoi(sv_event->parameter);
|
||||
window_->Pen(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
|
||||
// Takes care of the SVET_MENU events.
|
||||
// In our case, we change either the click_mode_ (commands 1-3)
|
||||
// or the drag_mode_ (commands 4-6).
|
||||
void SVPaint::MenuBarHandler(const SVEvent* sv_event) {
|
||||
if ((sv_event->command_id > 0) && (sv_event->command_id < 4)) {
|
||||
click_mode_ = sv_event->command_id;
|
||||
has_start_point_ = false;
|
||||
} else { drag_mode_ = sv_event->command_id; }
|
||||
}
|
||||
|
||||
// Takes care of the SVET_CLICK events.
|
||||
// Depending on the click_mode_ we are in, either do Point-to-Point drawing,
|
||||
// point drawing, or draw text.
|
||||
void SVPaint::ClickHandler(const SVEvent* sv_event) {
|
||||
switch (click_mode_) {
|
||||
case 1: //Point to Point
|
||||
if (has_start_point_) { window_->DrawTo(sv_event->x, sv_event->y);
|
||||
} else {
|
||||
has_start_point_ = true;
|
||||
window_->SetCursor(sv_event->x, sv_event->y);
|
||||
}
|
||||
break;
|
||||
case 2: //Point Drawing..simulated by drawing a 1 pixel line.
|
||||
window_->Line(sv_event->x, sv_event->y, sv_event->x, sv_event->y);
|
||||
break;
|
||||
case 3: //Text
|
||||
// We show a modal input dialog on our window, then draw the input and
|
||||
// finally delete the input pointer.
|
||||
char* p = window_->ShowInputDialog("Text:");
|
||||
window_->Text(sv_event->x, sv_event->y, p);
|
||||
delete p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes care of the SVET_SELECTION events.
|
||||
// Depending on the drag_mode_ we are in, either draw a line, a rectangle or
|
||||
// an ellipse.
|
||||
void SVPaint::SelectionHandler(const SVEvent* sv_event) {
|
||||
switch (drag_mode_) {
|
||||
//FIXME inversed x_size, y_size
|
||||
case 4: //Line
|
||||
window_->Line(sv_event->x, sv_event->y,
|
||||
sv_event->x - sv_event->x_size,
|
||||
sv_event->y - sv_event->y_size);
|
||||
break;
|
||||
case 5: //Rectangle
|
||||
window_->Rectangle(sv_event->x, sv_event->y,
|
||||
sv_event->x - sv_event->x_size,
|
||||
sv_event->y - sv_event->y_size);
|
||||
break;
|
||||
case 6: //Ellipse
|
||||
window_->Ellipse(sv_event->x - sv_event->x_size,
|
||||
sv_event->y - sv_event->y_size,
|
||||
sv_event->x_size, sv_event->y_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The event handling function from ScrollView which we have to overwrite.
|
||||
// We handle CLICK, SELECTION, MENU and POPUP and throw away all other events.
|
||||
void SVPaint::Notify(const SVEvent* sv_event) {
|
||||
if (sv_event->type == SVET_CLICK) { ClickHandler(sv_event); }
|
||||
else if (sv_event->type == SVET_SELECTION) { SelectionHandler(sv_event); }
|
||||
else if (sv_event->type == SVET_MENU) { MenuBarHandler(sv_event); }
|
||||
else if (sv_event->type == SVET_POPUP) { PopupHandler(sv_event); }
|
||||
else {} //throw other events away
|
||||
}
|
||||
|
||||
// Builds a new window, initializes the variables and event handler and builds
|
||||
// the menu.
|
||||
SVPaint::SVPaint(const char *server_name) {
|
||||
window_ = new ScrollView("ScrollView Paint Example", // window caption
|
||||
0, 0, // x,y window position
|
||||
500, 500, // window size
|
||||
500, 500, // canvas size
|
||||
false, // whether the Y axis is inversed.
|
||||
// this is included due to legacy
|
||||
// reasons for tesseract and enables
|
||||
// us to have (0,0) as the LOWER left
|
||||
// of the coordinate system.
|
||||
server_name); // the server address.
|
||||
|
||||
// Set the start modes to point-to-point and line drawing.
|
||||
click_mode_ = 1;
|
||||
drag_mode_ = 4;
|
||||
has_start_point_ = false;
|
||||
|
||||
// Bild our menus and add them to the window. The flag illustrates whether
|
||||
// this is a menu bar.
|
||||
SVMenuNode* popup_menu = BuildPopupMenu();
|
||||
popup_menu->BuildMenu(window_,false);
|
||||
|
||||
SVMenuNode* bar_menu = BuildMenuBar();
|
||||
bar_menu->BuildMenu(window_,true);
|
||||
|
||||
// Set the initial color values to White (could also be done by
|
||||
// passing (rgb[0], rgb[1], rgb[2]).
|
||||
window_->Pen(ScrollView::WHITE);
|
||||
window_->Brush(ScrollView::WHITE);
|
||||
|
||||
// Adds the event handler to the window. This actually ensures that Notify
|
||||
// gets called when events occur.
|
||||
window_->AddEventHandler(this);
|
||||
|
||||
// Set the window visible (calling this is important to actually render
|
||||
// everything. Without this call, the window would also be drawn, but the
|
||||
// menu bars would be missing.
|
||||
window_->SetVisible(true);
|
||||
|
||||
// Rest this thread until its window is destroyed.
|
||||
// Note that a special eventhandling thread was created when constructing
|
||||
// the window. Due to this, the application will not deadlock here.
|
||||
window_->AwaitEvent(SVET_DESTROY);
|
||||
// We now have 3 Threads running:
|
||||
// (1) The MessageReceiver thread which fetches messages and distributes them
|
||||
// (2) The EventHandler thread which handles all events for window_
|
||||
// (3) The main thread which waits on window_ for a DESTROY event (blocked)
|
||||
}
|
||||
|
||||
// If a parameter is given, we try to connect to the given server.
|
||||
// This enables us to test the remote capabilites of ScrollView.
|
||||
int main(int argc, char** argv) {
|
||||
const char* server_name;
|
||||
if (argc > 1) { server_name = argv[1]; } else { server_name = "localhost"; }
|
||||
SVPaint svp(server_name);
|
||||
}
|
323
viewer/svutil.cpp
Normal file
323
viewer/svutil.cpp
Normal file
@ -0,0 +1,323 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: svutil.cpp
|
||||
// Description: ScrollView Utilities
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SVUtil contains the SVSync and SVNetwork classes, which are used for
|
||||
// thread/process creation & synchronization and network connection.
|
||||
|
||||
#include "svutil.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
const int kBufferSize = 65536;
|
||||
const int kMaxMsgSize = 4096;
|
||||
|
||||
// Signals a thread to exit.
|
||||
void SVSync::ExitThread() {
|
||||
#ifdef WIN32
|
||||
//ExitThread(0);
|
||||
#else
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Starts a new process.
|
||||
void SVSync::StartProcess(const char* executable, const char* args) {
|
||||
#ifdef WIN32
|
||||
std::string proc;
|
||||
proc.append(executable);
|
||||
proc.append(" ");
|
||||
proc.append(args);
|
||||
std::cout << "Starting " << proc << std::endl;
|
||||
CreateProcess(NULL, (LPWSTR) proc.c_str(), NULL,
|
||||
NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
#else
|
||||
int pid = fork();
|
||||
if (pid != 0) { // The father process returns
|
||||
} else {
|
||||
char* mutable_args = strdup(args);
|
||||
int argc = 1;
|
||||
for (int i = 0; mutable_args[i]; ++i) {
|
||||
if (mutable_args[i] == ' ') {
|
||||
++argc;
|
||||
}
|
||||
}
|
||||
char** argv = new char*[argc + 2];
|
||||
argv[0] = strdup(executable);
|
||||
argv[1] = mutable_args;
|
||||
argc = 2;
|
||||
bool inquote = false;
|
||||
for (int i = 0; mutable_args[i]; ++i) {
|
||||
if (!inquote && mutable_args[i] == ' ') {
|
||||
mutable_args[i] = '\0';
|
||||
argv[argc++] = mutable_args + i + 1;
|
||||
} else if (mutable_args[i] == '"') {
|
||||
inquote = !inquote;
|
||||
mutable_args[i] = ' ';
|
||||
}
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
execvp(executable, argv);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SVSemaphore::SVSemaphore() {
|
||||
#ifdef WIN32
|
||||
semaphore_ = CreateSemaphore(0, 0, 10, 0);
|
||||
#else
|
||||
sem_init(&semaphore_, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SVSemaphore::Signal() {
|
||||
#ifdef WIN32
|
||||
ReleaseSemaphore(semaphore_, 1, NULL);
|
||||
#else
|
||||
sem_post(&semaphore_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SVSemaphore::Wait() {
|
||||
#ifdef WIN32
|
||||
WaitForSingleObject(semaphore_, INFINITE);
|
||||
#else
|
||||
sem_wait(&semaphore_);
|
||||
#endif
|
||||
}
|
||||
|
||||
SVMutex::SVMutex() {
|
||||
#ifdef WIN32
|
||||
mutex_ = CreateMutex(0, FALSE, 0);
|
||||
#else
|
||||
pthread_mutex_init(&mutex_, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SVMutex::Lock() {
|
||||
#ifdef WIN32
|
||||
WaitForSingleObject(mutex_, INFINITE);
|
||||
#else
|
||||
pthread_mutex_lock(&mutex_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SVMutex::Unlock() {
|
||||
#ifdef WIN32
|
||||
ReleaseMutex(mutex_);
|
||||
#else
|
||||
pthread_mutex_unlock(&mutex_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create new thread.
|
||||
|
||||
int SVSync::StartThread(void *(*func)(void*), void* arg) {
|
||||
#ifdef WIN32
|
||||
LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE) func;
|
||||
DWORD threadid;
|
||||
HANDLE newthread = CreateThread(
|
||||
NULL, // default security attributes
|
||||
0, // use default stack size
|
||||
f, // thread function
|
||||
arg, // argument to thread function
|
||||
0, // use default creation flags
|
||||
&threadid); // returns the thread identifier
|
||||
return threadid;
|
||||
#else
|
||||
pthread_t helper;
|
||||
pthread_create(&helper, NULL, func, arg);
|
||||
return helper;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Place a message in the message buffer (and flush it).
|
||||
void SVNetwork::Send(const char* msg) {
|
||||
mutex_send_->Lock();
|
||||
msg_buffer_out_.append(msg);
|
||||
mutex_send_->Unlock();
|
||||
}
|
||||
|
||||
// Send the whole buffer.
|
||||
void SVNetwork::Flush() {
|
||||
mutex_send_->Lock();
|
||||
while (msg_buffer_out_.size() > 0) {
|
||||
int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
|
||||
msg_buffer_out_.erase(0, i);
|
||||
}
|
||||
mutex_send_->Unlock();
|
||||
}
|
||||
|
||||
// Receive a message from the server.
|
||||
// This will always return one line of char* (denoted by \n).
|
||||
char* SVNetwork::Receive() {
|
||||
char* result = NULL;
|
||||
#ifdef WIN32
|
||||
if (has_content) { result = strtok (NULL, "\n"); }
|
||||
#else
|
||||
if (buffer_ptr_ != NULL) { result = strtok_r(NULL, "\n", &buffer_ptr_); }
|
||||
#endif
|
||||
|
||||
// This means there is something left in the buffer and we return it.
|
||||
if (result != NULL) { return result;
|
||||
// Otherwise, we read from the stream_.
|
||||
} else {
|
||||
buffer_ptr_ = NULL;
|
||||
has_content = false;
|
||||
|
||||
// The timeout length is not really important since we are looping anyway
|
||||
// until a new message is delivered.
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// Set the flags to return when the stream_ is ready to be read.
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(stream_, &readfds);
|
||||
|
||||
int i = select(stream_+1, &readfds, NULL, NULL, &tv);
|
||||
|
||||
// The stream_ died.
|
||||
if (i == 0) { return NULL; }
|
||||
|
||||
// Read the message buffer.
|
||||
i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);
|
||||
|
||||
// Server quit (0) or error (-1).
|
||||
if (i <= 0) { return NULL; }
|
||||
msg_buffer_in_[i] = '\0';
|
||||
has_content = true;
|
||||
#ifdef WIN32
|
||||
return strtok(msg_buffer_in_,"\n");
|
||||
#else
|
||||
// Setup a new string tokenizer.
|
||||
return strtok_r(msg_buffer_in_, "\n", &buffer_ptr_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Close the connection to the server.
|
||||
void SVNetwork::Close() {
|
||||
#ifdef WIN32
|
||||
closesocket(stream_);
|
||||
#else
|
||||
close(stream_);
|
||||
#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];
|
||||
msg_buffer_in_[0] = '\0';
|
||||
|
||||
has_content = false;
|
||||
|
||||
buffer_ptr_ = NULL;
|
||||
|
||||
// Get the host data depending on the OS.
|
||||
#ifdef WIN32
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(1, 1), &wsaData);
|
||||
name = gethostbyname(hostname);
|
||||
#else
|
||||
struct hostent hp;
|
||||
int herr;
|
||||
char buffer[kBufferSize];
|
||||
gethostbyname_r(hostname, &hp, buffer, kBufferSize, &name, &herr);
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
|
||||
stream_ = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// If server is not there, we will start a new server as local child process.
|
||||
if (connect(stream_, (struct sockaddr *) &address, sizeof(address)) < 0) {
|
||||
const char* scrollview_path = getenv("SCROLLVIEW_PATH");
|
||||
if (scrollview_path == NULL) {
|
||||
#ifdef SCROLLVIEW_PATH
|
||||
#define _STR(a) #a
|
||||
#define _XSTR(a) _STR(a)
|
||||
scrollview_path = _XSTR(SCROLLVIEW_PATH);
|
||||
#undef _XSTR
|
||||
#undef _STR
|
||||
#else
|
||||
scrollview_path = ".";
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
const char* prog = "java";
|
||||
const char* cmd_template =
|
||||
#else
|
||||
const char* prog = "sh";
|
||||
const char* cmd_template = "-c \"java "
|
||||
#endif
|
||||
"-Djava.library.path=%s -cp %s/luajava-1.1.jar:%s/ScrollView.jar:"
|
||||
"%s/piccolo-1.2.jar:%s/piccolox-1.2.jar"
|
||||
" com.google.scrollview.ScrollView"
|
||||
#ifdef WIN32
|
||||
;
|
||||
#else
|
||||
" >/dev/null 2>&1\"";
|
||||
#endif
|
||||
int cmdlen = strlen(cmd_template) + 5*strlen(scrollview_path) + 1;
|
||||
char* cmd = new char[cmdlen];
|
||||
snprintf(cmd, cmdlen, cmd_template, scrollview_path, scrollview_path,
|
||||
scrollview_path, scrollview_path, scrollview_path);
|
||||
|
||||
SVSync::StartProcess(prog, cmd);
|
||||
delete [] cmd;
|
||||
|
||||
// Wait for server to show up.
|
||||
// Note: There is no exception handling in case the server never turns up.
|
||||
while (connect(stream_, (struct sockaddr *) &address,
|
||||
sizeof(address)) < 0) {
|
||||
std::cout << "ScrollView: Waiting for server...\n";
|
||||
#ifdef WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
sleep(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SVNetwork::~SVNetwork() {
|
||||
delete[] msg_buffer_in_;
|
||||
delete mutex_send_;
|
||||
}
|
124
viewer/svutil.h
Normal file
124
viewer/svutil.h
Normal file
@ -0,0 +1,124 @@
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// File: svutil.h
|
||||
// Description: ScrollView Utilities
|
||||
// Author: Joern Wanke
|
||||
// Created: Thu Nov 29 2007
|
||||
//
|
||||
// (C) Copyright 2007, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SVUtil contains the SVSync, SVSemaphore, SVMutex and SVNetwork
|
||||
// classes, which are used for thread/process creation & synchronization
|
||||
// and network connection.
|
||||
|
||||
#ifndef THIRD_PARTY_TESSERACT_VIEWER_SVUTIL_H__
|
||||
#define THIRD_PARTY_TESSERACT_VIEWER_SVUTIL_H__
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
// The SVSync class provides functionality for Thread & Process Creation
|
||||
class SVSync {
|
||||
public:
|
||||
// Create new thread.
|
||||
static int StartThread(void *(*func)(void*), void* arg);
|
||||
// Signals a thread to exit.
|
||||
static void ExitThread();
|
||||
// Starts a new process.
|
||||
static void StartProcess(const char* executable, const char* args);
|
||||
};
|
||||
|
||||
// A semaphore class which encapsulates the main signalling
|
||||
// and wait abilities of semaphores for windows and unix.
|
||||
class SVSemaphore {
|
||||
public:
|
||||
// Sets up a semaphore.
|
||||
SVSemaphore();
|
||||
// Signal a semaphore.
|
||||
void Signal();
|
||||
// Wait on a semaphore.
|
||||
void Wait();
|
||||
private:
|
||||
#ifdef WIN32
|
||||
HANDLE semaphore_;
|
||||
#else
|
||||
sem_t semaphore_;
|
||||
#endif
|
||||
};
|
||||
|
||||
// A mutex which encapsulates the main locking and unlocking
|
||||
// abilites of mutexes for windows and unix.
|
||||
class SVMutex {
|
||||
public:
|
||||
// Sets up a new mutex.
|
||||
SVMutex();
|
||||
// Locks on a mutex.
|
||||
void Lock();
|
||||
// Unlocks on a mutex.
|
||||
void Unlock();
|
||||
private:
|
||||
#ifdef WIN32
|
||||
HANDLE mutex_;
|
||||
#else
|
||||
pthread_mutex_t mutex_;
|
||||
#endif
|
||||
};
|
||||
|
||||
// The SVNetwork class takes care of the remote connection for ScrollView
|
||||
// This means setting up and maintaining a remote connection, sending and
|
||||
// receiving messages and closing the connection.
|
||||
// It is designed to work on both Linux and Windows.
|
||||
class SVNetwork {
|
||||
public:
|
||||
// Set up a connection to hostname on port.
|
||||
SVNetwork(const char* hostname, int port);
|
||||
|
||||
// Destructor.
|
||||
~SVNetwork();
|
||||
|
||||
// Put a message in the messagebuffer to the server and try to send it.
|
||||
void Send(const char* msg);
|
||||
|
||||
// Receive a message from the server.
|
||||
// This will always return one line of char* (denoted by \n).
|
||||
char* Receive();
|
||||
|
||||
// Close the connection to the server.
|
||||
void Close();
|
||||
|
||||
// Flush the buffer.
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
// The mutex for access to Send() and Flush().
|
||||
SVMutex* mutex_send_;
|
||||
// The actual stream_ to the server.
|
||||
int stream_;
|
||||
// Stores the last received message-chunk from the server.
|
||||
char* msg_buffer_in_;
|
||||
|
||||
// Stores the messages which are supposed to go out.
|
||||
std::string msg_buffer_out_;
|
||||
|
||||
bool has_content; // Win32 (strtok)
|
||||
// Where we are at in our msg_buffer_in_
|
||||
char* buffer_ptr_; // Unix (strtok_r)
|
||||
};
|
||||
|
||||
#endif // THIRD_PARTY_TESSERACT_VIEWER_SVUTIL_H__
|
Loading…
Reference in New Issue
Block a user