mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-06-20 19:40:40 +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 =
|
SUBDIRS =
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/image -I$(top_srcdir)/ccutil
|
AM_CPPFLAGS =
|
||||||
|
|
||||||
include_HEADERS = \
|
include_HEADERS = \
|
||||||
evntlst.h evnts.h grphics.h grphshm.h sbgconst.h sbgdefs.h \
|
scrollview.h svmnode.h svutil.h svpaint.cpp
|
||||||
sbgtypes.h showim.h
|
|
||||||
|
|
||||||
lib_LIBRARIES = libtesseract_viewer.a
|
lib_LIBRARIES = libtesseract_viewer.a
|
||||||
libtesseract_viewer_a_SOURCES = \
|
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@
|
VERSION = @VERSION@
|
||||||
|
|
||||||
SUBDIRS =
|
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
|
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
|
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||||
CONFIG_HEADER = ../config_auto.h
|
CONFIG_HEADER = ../config_auto.h
|
||||||
@ -94,8 +94,7 @@ CPPFLAGS = @CPPFLAGS@
|
|||||||
LDFLAGS = @LDFLAGS@
|
LDFLAGS = @LDFLAGS@
|
||||||
LIBS = @LIBS@
|
LIBS = @LIBS@
|
||||||
libtesseract_viewer_a_LIBADD =
|
libtesseract_viewer_a_LIBADD =
|
||||||
libtesseract_viewer_a_OBJECTS = evntlst.o grphics.o evnts.o showim.o \
|
libtesseract_viewer_a_OBJECTS = scrollview.o svmnode.o svutil.o
|
||||||
grphshm.o
|
|
||||||
AR = ar
|
AR = ar
|
||||||
CXXFLAGS = @CXXFLAGS@
|
CXXFLAGS = @CXXFLAGS@
|
||||||
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_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
|
TAR = tar
|
||||||
GZIP_ENV = --best
|
GZIP_ENV = --best
|
||||||
DEP_FILES = .deps/evntlst.P .deps/evnts.P .deps/grphics.P \
|
DEP_FILES = .deps/scrollview.P .deps/svmnode.P .deps/svutil.P
|
||||||
.deps/grphshm.P .deps/showim.P
|
|
||||||
SOURCES = $(libtesseract_viewer_a_SOURCES)
|
SOURCES = $(libtesseract_viewer_a_SOURCES)
|
||||||
OBJECTS = $(libtesseract_viewer_a_OBJECTS)
|
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