[4] | 1 | /************************************************************************** |
---|
| 2 | sagepdf - a PDF viewer for SAGE tiled displays. |
---|
| 3 | Copyright (C) 2011 Christoph Willing |
---|
| 4 | |
---|
| 5 | This program is free software; you can redistribute it and/or modify |
---|
| 6 | it under the terms of the GNU General Public License as published by |
---|
| 7 | the Free Software Foundation; either version 2 of the License, or |
---|
| 8 | (at your option) any later version. |
---|
| 9 | |
---|
| 10 | This program is distributed in the hope that it will be useful, |
---|
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 13 | GNU General Public License for more details. |
---|
| 14 | |
---|
| 15 | You should have received a copy of the GNU General Public License along |
---|
| 16 | with this program; if not, write to the Free Software Foundation, Inc., |
---|
| 17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
---|
| 18 | **************************************************************************/ |
---|
| 19 | |
---|
| 20 | |
---|
| 21 | #include <unistd.h> |
---|
| 22 | #include <stdio.h> |
---|
| 23 | #include <stdlib.h> |
---|
| 24 | #include <cairo.h> |
---|
| 25 | #include <libgen.h> |
---|
| 26 | #include <string.h> |
---|
| 27 | #include <gtk/gtk.h> |
---|
| 28 | #include <gdk/gdkkeysyms.h> |
---|
| 29 | #include <glib/poppler.h> |
---|
| 30 | #include <math.h> |
---|
| 31 | |
---|
| 32 | #define SAGEPDF_DEF_SCALEFACTOR (4) |
---|
| 33 | |
---|
| 34 | int npages; |
---|
| 35 | int firstPage = 0; |
---|
| 36 | PopplerDocument *document; |
---|
| 37 | PopplerPage *page; |
---|
| 38 | double width, height; |
---|
| 39 | cairo_t *cr, *sage_cr; |
---|
| 40 | cairo_surface_t *surface, *sage_surface; |
---|
| 41 | int scaleFactor; |
---|
| 42 | |
---|
| 43 | #ifndef NOSAGE |
---|
| 44 | // headers for SAGE |
---|
| 45 | #include "sail.h" |
---|
| 46 | #include "misc.h" |
---|
| 47 | sail sageInf; // sail object |
---|
| 48 | |
---|
| 49 | // for dxt compression |
---|
| 50 | #include "libdxt.h" |
---|
| 51 | |
---|
| 52 | using namespace std; |
---|
| 53 | bool useDXT = true; |
---|
| 54 | |
---|
| 55 | byte *sageBuffer = NULL; // buffers for sage and dxt data |
---|
| 56 | byte *dxt = NULL; |
---|
| 57 | byte *rgba = NULL; |
---|
| 58 | |
---|
| 59 | float lastX = 0; |
---|
| 60 | float lastY = 0; |
---|
| 61 | float dist = 0; |
---|
| 62 | |
---|
| 63 | GdkWindow *local_window = NULL; |
---|
| 64 | #endif |
---|
| 65 | |
---|
| 66 | float local_startX = 0; |
---|
| 67 | float local_startY = 0; |
---|
| 68 | float local_dist = 0; |
---|
| 69 | bool button1_is_pressed = false; |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | void |
---|
| 73 | show_page() |
---|
| 74 | { |
---|
| 75 | /* Clear window */ |
---|
| 76 | cairo_rectangle(cr, 0, 0, width, height); |
---|
| 77 | cairo_stroke_preserve(cr); |
---|
| 78 | cairo_set_source_rgb(cr, 1, 1, 1); |
---|
| 79 | cairo_fill(cr); |
---|
| 80 | |
---|
| 81 | |
---|
| 82 | cairo_set_source_surface(cr, surface, 0, 0); |
---|
| 83 | cairo_translate(cr, 0, 0); |
---|
| 84 | cairo_scale(cr, 1, 1); |
---|
| 85 | poppler_page_render(page, cr); |
---|
| 86 | |
---|
| 87 | cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER); |
---|
| 88 | cairo_set_source_rgb(cr, 1, 1, 1); |
---|
| 89 | cairo_paint(cr); |
---|
| 90 | |
---|
| 91 | |
---|
| 92 | #ifndef NOSAGE |
---|
| 93 | if( useDXT ) |
---|
| 94 | { |
---|
| 95 | int cairo_height, cairo_width, cairo_rowstride; |
---|
| 96 | unsigned int numBytes, *src; |
---|
| 97 | unsigned char *cairo_data, *dst; |
---|
| 98 | |
---|
| 99 | sage_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width*scaleFactor, height*scaleFactor); |
---|
| 100 | sage_cr = cairo_create(sage_surface); |
---|
| 101 | cairo_save (sage_cr); |
---|
| 102 | /* Flip */ |
---|
| 103 | cairo_translate(sage_cr, 0, height*scaleFactor); |
---|
| 104 | cairo_scale(sage_cr, scaleFactor, -scaleFactor); |
---|
| 105 | poppler_page_render (page, sage_cr); |
---|
| 106 | cairo_restore (sage_cr); |
---|
| 107 | |
---|
| 108 | cairo_set_operator(sage_cr, CAIRO_OPERATOR_DEST_OVER); |
---|
| 109 | cairo_set_source_rgba(sage_cr, 1, 1, 1, 1); |
---|
| 110 | cairo_paint(sage_cr); |
---|
| 111 | |
---|
| 112 | /* We'd like to apply the sage_surface data directly to the |
---|
| 113 | * DXT compression engine but it is in the wrong colour space. |
---|
| 114 | * Therefore we extract it manually to the rgba buffer. |
---|
| 115 | */ |
---|
| 116 | cairo_height = cairo_image_surface_get_height (sage_surface); |
---|
| 117 | cairo_width = cairo_image_surface_get_width (sage_surface); |
---|
| 118 | cairo_rowstride = cairo_image_surface_get_stride (sage_surface); |
---|
| 119 | cairo_data = cairo_image_surface_get_data (sage_surface); |
---|
| 120 | for (int y = 0; y < cairo_height; y++) |
---|
| 121 | { |
---|
| 122 | src = (unsigned int *) (cairo_data + y * cairo_rowstride); |
---|
| 123 | dst = rgba + y * cairo_rowstride; |
---|
| 124 | for (int x = 0; x < cairo_width; x++) |
---|
| 125 | { |
---|
| 126 | dst[0] = (*src >> 16) & 0xff; |
---|
| 127 | dst[1] = (*src >> 8) & 0xff; |
---|
| 128 | dst[2] = (*src >> 0) & 0xff; |
---|
| 129 | dst[3] = (*src >> 24) & 0xff; |
---|
| 130 | dst += 4; |
---|
| 131 | src++; |
---|
| 132 | } |
---|
| 133 | } |
---|
| 134 | |
---|
| 135 | numBytes = CompressDXT(rgba, dxt, scaleFactor * width, scaleFactor * height, FORMAT_DXT1, 1); |
---|
| 136 | sageBuffer = (byte*)sageInf.getBuffer(); |
---|
| 137 | memcpy(sageBuffer, dxt, scaleFactor * scaleFactor * width*height*4/8); |
---|
| 138 | sageInf.swapBuffer(); |
---|
| 139 | |
---|
| 140 | cairo_destroy(sage_cr); |
---|
| 141 | } |
---|
| 142 | else |
---|
| 143 | { |
---|
| 144 | sage_surface = cairo_image_surface_create_for_data ((unsigned char*)sageInf.getBuffer(), |
---|
| 145 | CAIRO_FORMAT_ARGB32, width * scaleFactor, height * scaleFactor, |
---|
| 146 | cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width * scaleFactor)); |
---|
| 147 | sage_cr = cairo_create(sage_surface); |
---|
| 148 | |
---|
| 149 | /* Clear SAGE window */ |
---|
| 150 | cairo_rectangle(sage_cr, 0, 0, width * scaleFactor, height * scaleFactor); |
---|
| 151 | cairo_stroke_preserve(sage_cr); |
---|
| 152 | cairo_set_source_rgb(sage_cr, 1, 1, 1); |
---|
| 153 | cairo_fill(sage_cr); |
---|
| 154 | |
---|
| 155 | cairo_set_source_surface(sage_cr, sage_surface, 0, 0); |
---|
| 156 | cairo_scale(sage_cr, scaleFactor, scaleFactor); |
---|
| 157 | poppler_page_render(page, sage_cr); |
---|
| 158 | cairo_set_operator(sage_cr, CAIRO_OPERATOR_DEST_OVER); |
---|
| 159 | cairo_set_source_rgb(sage_cr, 1, 1, 1); |
---|
| 160 | cairo_paint(sage_cr); |
---|
| 161 | |
---|
| 162 | sageInf.swapBuffer(); |
---|
| 163 | cairo_destroy(sage_cr); |
---|
| 164 | } |
---|
| 165 | #endif |
---|
| 166 | |
---|
| 167 | } |
---|
| 168 | |
---|
| 169 | void |
---|
| 170 | show_absolute_page(int requested_page) |
---|
| 171 | { |
---|
| 172 | if( requested_page < 0 ) |
---|
| 173 | requested_page = 0; |
---|
| 174 | if( requested_page >= npages ) |
---|
| 175 | requested_page = npages - 1; |
---|
| 176 | |
---|
| 177 | /* Don't render again if we're already at that page */ |
---|
| 178 | if( poppler_page_get_index(page) == requested_page ) |
---|
| 179 | return; |
---|
| 180 | |
---|
| 181 | page = poppler_document_get_page(document, requested_page); |
---|
| 182 | show_page(); |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | void |
---|
| 186 | show_next_page(int next) |
---|
| 187 | { |
---|
| 188 | show_absolute_page(poppler_page_get_index(page) + next); |
---|
| 189 | /* |
---|
| 190 | int ncurrent = poppler_page_get_index(page) + next; |
---|
| 191 | if( (ncurrent > -1) && (ncurrent < npages) ) |
---|
| 192 | page = poppler_document_get_page(document, ncurrent); |
---|
| 193 | show_page(); |
---|
| 194 | */ |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | gint |
---|
| 198 | check_sage_messages(gpointer data) |
---|
| 199 | { |
---|
| 200 | #ifndef NOSAGE |
---|
| 201 | sageMessage msg; |
---|
| 202 | if (sageInf.checkMsg(msg, false) > 0) { |
---|
| 203 | char *data = (char*) msg.getData(); |
---|
| 204 | |
---|
| 205 | switch (msg.getCode()) { |
---|
| 206 | case APP_QUIT : { |
---|
| 207 | sageInf.shutdown(); |
---|
| 208 | gtk_main_quit(); |
---|
| 209 | break; |
---|
| 210 | |
---|
| 211 | case EVT_CLICK: |
---|
| 212 | // Click event x and y location normalized to size of window |
---|
| 213 | float clickX, clickY; |
---|
| 214 | |
---|
| 215 | // Click device Id, button Id, and is down flag |
---|
| 216 | int clickDeviceId, clickButtonId, clickIsDown, clickEvent; |
---|
| 217 | |
---|
| 218 | // Parse message |
---|
| 219 | sscanf(data, |
---|
| 220 | "%d %f %f %d %d %d", |
---|
| 221 | &clickDeviceId, &clickX, &clickY, |
---|
| 222 | &clickButtonId, &clickIsDown, &clickEvent); |
---|
| 223 | //printf("Pointer click at %f,%f\n", clickX, clickY); |
---|
| 224 | |
---|
| 225 | // record the click position so we know how far we moved |
---|
| 226 | if (clickIsDown && clickEvent == EVT_PAN) { |
---|
| 227 | lastX = clickX; |
---|
| 228 | lastY = clickY; |
---|
| 229 | } |
---|
| 230 | |
---|
| 231 | if( clickIsDown ) |
---|
| 232 | { |
---|
| 233 | //printf("Pointer click by button %d\n", clickButtonId); |
---|
| 234 | |
---|
| 235 | cr = gdk_cairo_create(local_window); |
---|
| 236 | if( clickButtonId == 1 ) |
---|
| 237 | show_next_page(1); |
---|
| 238 | else |
---|
| 239 | show_next_page(-1); |
---|
| 240 | } |
---|
| 241 | |
---|
| 242 | break; |
---|
| 243 | |
---|
| 244 | case EVT_PAN: |
---|
| 245 | // Pan event properties |
---|
| 246 | int panDeviceId; |
---|
| 247 | |
---|
| 248 | // Pan event x and y location and change in x, y and z direction |
---|
| 249 | // normalized to size of window |
---|
| 250 | float startX, startY, panDX, panDY, panDZ; |
---|
| 251 | sscanf(data, |
---|
| 252 | "%d %f %f %f %f %f", |
---|
| 253 | &panDeviceId, &startX, &startY, &panDX, &panDY, &panDZ); |
---|
| 254 | |
---|
| 255 | // keep track of distance |
---|
| 256 | dist += panDX; |
---|
| 257 | |
---|
| 258 | // we started a new drag |
---|
| 259 | if (lastX != startX) { |
---|
| 260 | lastX = startX; |
---|
| 261 | dist = 0; |
---|
| 262 | } |
---|
| 263 | else if( fabs(dist) > 0.07 ) { // if we dragged more than a certain distance, change a page |
---|
| 264 | cr = gdk_cairo_create(local_window); |
---|
| 265 | if (dist > 0) |
---|
| 266 | show_next_page(1); |
---|
| 267 | else |
---|
| 268 | show_next_page(-1); |
---|
| 269 | |
---|
| 270 | // reset the counter |
---|
| 271 | lastX = startX; |
---|
| 272 | dist = 0; |
---|
| 273 | } |
---|
| 274 | break; |
---|
| 275 | |
---|
| 276 | } |
---|
| 277 | } |
---|
| 278 | } |
---|
| 279 | #endif |
---|
| 280 | return TRUE; |
---|
| 281 | } |
---|
| 282 | |
---|
| 283 | static gboolean |
---|
| 284 | on_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) |
---|
| 285 | { |
---|
| 286 | float local_lastX = event->x; |
---|
| 287 | local_dist = local_lastX - local_startX; |
---|
| 288 | |
---|
| 289 | if( button1_is_pressed ) |
---|
| 290 | if( fabs(local_dist / width) > 0.07 ) |
---|
| 291 | { |
---|
| 292 | cr = gdk_cairo_create(widget->window); |
---|
| 293 | local_startX = local_lastX; |
---|
| 294 | if( local_dist > 0 ) |
---|
| 295 | show_next_page(1); |
---|
| 296 | else |
---|
| 297 | show_next_page(-1); |
---|
| 298 | } |
---|
| 299 | |
---|
| 300 | return true; |
---|
| 301 | } |
---|
| 302 | |
---|
| 303 | static gboolean |
---|
| 304 | on_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) |
---|
| 305 | { |
---|
| 306 | cr = gdk_cairo_create(widget->window); |
---|
| 307 | button1_is_pressed = false; |
---|
| 308 | switch(event->button) |
---|
| 309 | { |
---|
| 310 | case 1: |
---|
| 311 | button1_is_pressed = true; |
---|
| 312 | local_startX = event->x; |
---|
| 313 | show_next_page(1); |
---|
| 314 | break; |
---|
| 315 | case 3: |
---|
| 316 | show_next_page(-1); |
---|
| 317 | break; |
---|
| 318 | default: |
---|
| 319 | // printf("Unhandled button press: %d\n", event->button); |
---|
| 320 | return false; |
---|
| 321 | break; |
---|
| 322 | } |
---|
| 323 | return true; |
---|
| 324 | } |
---|
| 325 | |
---|
| 326 | static gboolean |
---|
| 327 | on_key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer data) |
---|
| 328 | { |
---|
| 329 | cr = gdk_cairo_create(widget->window); |
---|
| 330 | switch(event->keyval) |
---|
| 331 | { |
---|
| 332 | case GDK_Home: |
---|
| 333 | show_absolute_page(0); |
---|
| 334 | break; |
---|
| 335 | case GDK_End: |
---|
| 336 | show_absolute_page(npages); |
---|
| 337 | break; |
---|
| 338 | case GDK_Page_Up: |
---|
| 339 | case GDK_Left: |
---|
| 340 | show_next_page(-1); |
---|
| 341 | break; |
---|
| 342 | case GDK_Page_Down: |
---|
| 343 | case GDK_Right: |
---|
| 344 | show_next_page(1); |
---|
| 345 | break; |
---|
| 346 | case GDK_Escape: |
---|
| 347 | printf("Quit\n"); |
---|
| 348 | gtk_main_quit(); |
---|
| 349 | break; |
---|
| 350 | default: |
---|
| 351 | // printf("XXXXXXXXXX Unhandled key: %d\n", event->keyval); |
---|
| 352 | return false; |
---|
| 353 | break; |
---|
| 354 | } |
---|
| 355 | return true; |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | static gboolean |
---|
| 359 | on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) |
---|
| 360 | { |
---|
| 361 | cr = gdk_cairo_create(widget->window); |
---|
| 362 | show_page(); |
---|
| 363 | |
---|
| 364 | return FALSE; |
---|
| 365 | } |
---|
| 366 | |
---|
| 367 | |
---|
| 368 | int main(int argc, char *argv[]) |
---|
| 369 | { |
---|
| 370 | unsigned int window_width=-1, window_height=-1; // sage window size |
---|
| 371 | GtkWidget *window; |
---|
| 372 | |
---|
| 373 | char *filename; |
---|
| 374 | char pathbuf[PATH_MAX]; |
---|
| 375 | char uri[256]; |
---|
| 376 | char *dirc, *basec, *dname, *bname; |
---|
| 377 | int i=0; |
---|
| 378 | |
---|
| 379 | gtk_init(&argc, &argv); |
---|
| 380 | scaleFactor = SAGEPDF_DEF_SCALEFACTOR; |
---|
| 381 | #ifndef NOSAGE |
---|
| 382 | sage::initUtil(); |
---|
| 383 | #endif |
---|
| 384 | |
---|
| 385 | // parse command line arguments |
---|
| 386 | if( argc < 2 ) |
---|
| 387 | { |
---|
| 388 | #ifndef NOSAGE |
---|
| 389 | sage::printLog("PDF> sagepdf filename [width] [height] [-show_original] [-page num] [-scale num]"); |
---|
| 390 | #else |
---|
| 391 | fprintf(stderr, "PDF> sagepdf filename [width] [height] [-show_original] [-page num] [-scale num]\n"); |
---|
| 392 | #endif |
---|
| 393 | exit(1); |
---|
| 394 | } |
---|
| 395 | for (int argNum=2; argNum<argc; argNum++) |
---|
| 396 | { |
---|
| 397 | if( strcmp(argv[argNum], "-page") == 0 ) |
---|
| 398 | { |
---|
| 399 | int p = atoi(argv[argNum+1]); |
---|
| 400 | if( p > 0 ) |
---|
| 401 | firstPage = p - 1; |
---|
| 402 | if( p < 0 ) |
---|
| 403 | firstPage = 0; |
---|
| 404 | argNum++; |
---|
| 405 | } |
---|
| 406 | #ifndef NOSAGE |
---|
| 407 | else if (strcmp(argv[argNum], "-show_original") == 0) |
---|
| 408 | { |
---|
| 409 | useDXT = false; |
---|
| 410 | } |
---|
| 411 | #endif |
---|
| 412 | else if( strcmp(argv[argNum], "-scale") == 0 ) |
---|
| 413 | { |
---|
| 414 | scaleFactor = atoi(argv[argNum+1]); |
---|
| 415 | if( scaleFactor < 1 ) |
---|
| 416 | scaleFactor = 1; |
---|
| 417 | argNum++; |
---|
| 418 | } |
---|
| 419 | else if(atoi(argv[argNum]) != 0 && atoi(argv[argNum+1]) != 0) |
---|
| 420 | { |
---|
| 421 | window_width = atoi( argv[argNum] ); |
---|
| 422 | window_height = atoi( argv[argNum+1] ); |
---|
| 423 | argNum++; |
---|
| 424 | } |
---|
| 425 | } |
---|
| 426 | |
---|
| 427 | /* Check that the filename is an absolute pathname */ |
---|
| 428 | filename = argv[1]; |
---|
| 429 | dirc = strdup(filename); |
---|
| 430 | basec = strdup(filename); |
---|
| 431 | dname = dirname(dirc); |
---|
| 432 | bname = basename(basec); |
---|
| 433 | |
---|
| 434 | if( dname[0] != '/' ) |
---|
| 435 | { |
---|
| 436 | fprintf(stderr, "Need absolute path for PDF file\n"); |
---|
| 437 | |
---|
| 438 | /* We could try to construct a path - |
---|
| 439 | * assume the path givern is relative to here |
---|
| 440 | */ |
---|
| 441 | if( ! getcwd(pathbuf, PATH_MAX) ) |
---|
| 442 | exit(1); |
---|
| 443 | sprintf(pathbuf + strlen(pathbuf), "/\0"); |
---|
| 444 | strcat(pathbuf, filename); |
---|
| 445 | fprintf(stderr, "Lets try %s\n", pathbuf); |
---|
| 446 | } |
---|
| 447 | else |
---|
| 448 | { |
---|
| 449 | sprintf(pathbuf, "%s\0", filename); |
---|
| 450 | } |
---|
| 451 | /* Can we read it ? */ |
---|
| 452 | if( access(pathbuf, R_OK ) ) |
---|
| 453 | { |
---|
| 454 | fprintf(stderr, "Can't access %s - exiting now ...\n", filename); |
---|
| 455 | exit(2); |
---|
| 456 | } |
---|
| 457 | |
---|
| 458 | sprintf(uri, "file://%s\0", pathbuf); |
---|
| 459 | document = poppler_document_new_from_file(uri, NULL, NULL); |
---|
| 460 | npages = poppler_document_get_n_pages(document); |
---|
| 461 | |
---|
| 462 | if( npages <= firstPage ) |
---|
| 463 | firstPage = npages - 1; |
---|
| 464 | page = poppler_document_get_page(document, firstPage); |
---|
| 465 | poppler_page_get_size(page, &width, &height); |
---|
| 466 | printf("Page %d has size %fx%f\n", firstPage, width, height); |
---|
| 467 | |
---|
| 468 | |
---|
| 469 | #ifndef NOSAGE |
---|
| 470 | if (useDXT) |
---|
| 471 | { |
---|
| 472 | if ((int)width % 4 != 0 || (int)height % 4 != 0) |
---|
| 473 | { |
---|
| 474 | fprintf(stderr, "\n**** Image cropped a few pixels to be a multiple of 4 for dxt"); |
---|
| 475 | width -= (int)width % 4; width = (int)width * 1.0; |
---|
| 476 | height -= (int)height % 4; height = (int)height * 1.0; |
---|
| 477 | } |
---|
| 478 | |
---|
| 479 | // allocate buffers |
---|
| 480 | rgba = (byte*) memalign(16, scaleFactor * scaleFactor * width*height*4); |
---|
| 481 | dxt = (byte*) memalign(16, scaleFactor * scaleFactor * width*height*4/8); |
---|
| 482 | } |
---|
| 483 | |
---|
| 484 | // SAGE setup |
---|
| 485 | sailConfig cfg; |
---|
| 486 | cfg.init("sagepdf.conf"); // every app has a config file named "appName.conf" |
---|
| 487 | std::cout << "SAIL configuration was initialized by sagepdf.conf" << std::endl; |
---|
| 488 | |
---|
| 489 | cfg.setAppName("sagepdf"); |
---|
| 490 | cfg.rank = 0; |
---|
| 491 | cfg.resX = width * scaleFactor; |
---|
| 492 | cfg.resY = height * scaleFactor; |
---|
| 493 | cfg.winWidth = width * scaleFactor; |
---|
| 494 | cfg.winHeight = height * scaleFactor; |
---|
| 495 | |
---|
| 496 | sageRect renderImageMap; |
---|
| 497 | renderImageMap.left = 0.0; |
---|
| 498 | renderImageMap.right = 1.0; |
---|
| 499 | renderImageMap.bottom = 0.0; |
---|
| 500 | renderImageMap.top = 1.0; |
---|
| 501 | |
---|
| 502 | cfg.imageMap = renderImageMap; |
---|
| 503 | if( useDXT ) |
---|
| 504 | { |
---|
| 505 | cfg.pixFmt = PIXFMT_DXT; |
---|
| 506 | cfg.rowOrd = BOTTOM_TO_TOP; |
---|
| 507 | } |
---|
| 508 | else |
---|
| 509 | { |
---|
| 510 | cfg.pixFmt = PIXFMT_8888_INV; |
---|
| 511 | cfg.rowOrd = TOP_TO_BOTTOM; |
---|
| 512 | } |
---|
| 513 | cfg.master = TRUE; |
---|
| 514 | |
---|
| 515 | sageInf.init(cfg); |
---|
| 516 | std::cout << "sail initialized " << std::endl; |
---|
| 517 | #endif |
---|
| 518 | |
---|
| 519 | //printf("Using page size %fx%f\n", width, height); |
---|
| 520 | surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); |
---|
| 521 | |
---|
| 522 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
---|
| 523 | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); |
---|
| 524 | gtk_window_set_default_size(GTK_WINDOW(window), width, height); |
---|
| 525 | gtk_widget_set_app_paintable(window, TRUE); |
---|
| 526 | |
---|
| 527 | |
---|
| 528 | g_signal_connect(window, "expose-event", G_CALLBACK (on_expose_event), NULL); |
---|
| 529 | g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL); |
---|
| 530 | g_signal_connect(window, "key_release_event", G_CALLBACK (on_key_release_event), NULL); |
---|
| 531 | g_signal_connect(window, "button_press_event", G_CALLBACK (on_button_press_event), NULL); |
---|
| 532 | g_signal_connect(window, "motion_notify_event", G_CALLBACK (on_motion_notify_event), NULL); |
---|
| 533 | gtk_widget_set_events (window, GDK_KEY_RELEASE | |
---|
| 534 | GDK_BUTTON_PRESS_MASK | |
---|
| 535 | GDK_BUTTON_MOTION_MASK | |
---|
| 536 | GDK_POINTER_MOTION_HINT_MASK ); |
---|
| 537 | |
---|
| 538 | gtk_widget_show_all(window); |
---|
| 539 | #ifndef NOSAGE |
---|
| 540 | local_window = window->window; |
---|
| 541 | #endif |
---|
| 542 | |
---|
| 543 | g_timeout_add (200, check_sage_messages, NULL); |
---|
| 544 | |
---|
| 545 | gtk_main(); |
---|
| 546 | sageInf.shutdown(); |
---|
| 547 | cairo_surface_destroy(surface); |
---|
| 548 | |
---|
| 549 | return 0; |
---|
| 550 | } |
---|
| 551 | |
---|