x11.c revision 5dfecf96
1/* 2 * Copyright (c) 2001 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the XFree86 Project shall 23 * not be used in advertising or otherwise to promote the sale, use or other 24 * dealings in this Software without prior written authorization from the 25 * XFree86 Project. 26 * 27 * Author: Paulo César Pereira de Andrade 28 */ 29 30/* $XFree86: xc/programs/xedit/lisp/modules/x11.c,v 1.11tsi Exp $ */ 31 32#include <stdlib.h> 33#include <string.h> 34#include "lisp/internal.h" 35#include "lisp/private.h" 36#include <X11/Xlib.h> 37 38/* 39 * Prototypes 40 */ 41int x11LoadModule(void); 42 43LispObj *Lisp_XOpenDisplay(LispBuiltin *builtin); 44LispObj *Lisp_XCloseDisplay(LispBuiltin *builtin); 45LispObj *Lisp_XDefaultRootWindow(LispBuiltin *builtin); 46LispObj *Lisp_XDefaultScreen(LispBuiltin *builtin); 47LispObj *Lisp_XDefaultScreenOfDisplay(LispBuiltin *builtin); 48LispObj *Lisp_XBlackPixel(LispBuiltin *builtin); 49LispObj *Lisp_XBlackPixelOfScreen(LispBuiltin *builtin); 50LispObj *Lisp_XWidthOfScreen(LispBuiltin *builtin); 51LispObj *Lisp_XHeightOfScreen(LispBuiltin *builtin); 52LispObj *Lisp_XWhitePixel(LispBuiltin *builtin); 53LispObj *Lisp_XWhitePixelOfScreen(LispBuiltin *builtin); 54LispObj *Lisp_XDefaultGC(LispBuiltin *builtin); 55LispObj *Lisp_XDefaultGCOfScreen(LispBuiltin *builtin); 56LispObj *Lisp_XCreateSimpleWindow(LispBuiltin *builtin); 57LispObj *Lisp_XMapWindow(LispBuiltin *builtin); 58LispObj *Lisp_XDestroyWindow(LispBuiltin *builtin); 59LispObj *Lisp_XFlush(LispBuiltin *builtin); 60LispObj *Lisp_XRaiseWindow(LispBuiltin *builtin); 61LispObj *Lisp_XBell(LispBuiltin *builtin); 62 63LispObj *Lisp_XDrawLine(LispBuiltin *builtin); 64 65/* 66 * Initialization 67 */ 68static LispBuiltin lispbuiltins[] = { 69 {LispFunction, Lisp_XOpenDisplay, "x-open-display &optional display-name"}, 70 {LispFunction, Lisp_XCloseDisplay, "x-close-display display"}, 71 {LispFunction, Lisp_XDefaultRootWindow, "x-default-root-window display"}, 72 {LispFunction, Lisp_XDefaultScreen, "x-default-screen display"}, 73 {LispFunction, Lisp_XDefaultScreenOfDisplay, "x-default-screen-of-display display"}, 74 {LispFunction, Lisp_XBlackPixel, "x-black-pixel display &optional screen"}, 75 {LispFunction, Lisp_XBlackPixelOfScreen, "x-black-pixel-of-screen screen"}, 76 {LispFunction, Lisp_XWhitePixel, "x-white-pixel display &optional screen"}, 77 {LispFunction, Lisp_XWhitePixelOfScreen, "x-white-pixel-of-screen screen"}, 78 {LispFunction, Lisp_XDefaultGC, "x-default-gc display &optional screen"}, 79 {LispFunction, Lisp_XDefaultGCOfScreen, "x-default-gc-of-screen screen"}, 80 {LispFunction, Lisp_XCreateSimpleWindow, "x-create-simple-window display parent x y width height &optional border-width border background"}, 81 {LispFunction, Lisp_XMapWindow, "x-map-window display window"}, 82 {LispFunction, Lisp_XDestroyWindow, "X-DESTROY-WINDOW"}, 83 {LispFunction, Lisp_XFlush, "x-flush display"}, 84 {LispFunction, Lisp_XDrawLine, "x-draw-line display drawable gc x1 y1 x2 y2"}, 85 {LispFunction, Lisp_XBell, "x-bell display &optional percent"}, 86 {LispFunction, Lisp_XRaiseWindow, "x-raise-window display window"}, 87 {LispFunction, Lisp_XWidthOfScreen, "x-width-of-screen screen"}, 88 {LispFunction, Lisp_XHeightOfScreen, "x-height-of-screen screen"}, 89}; 90 91LispModuleData x11LispModuleData = { 92 LISP_MODULE_VERSION, 93 x11LoadModule 94}; 95 96static int x11Display_t, x11Screen_t, x11Window_t, x11GC_t; 97 98/* 99 * Implementation 100 */ 101int 102x11LoadModule(void) 103{ 104 int i; 105 106 x11Display_t = LispRegisterOpaqueType("Display*"); 107 x11Screen_t = LispRegisterOpaqueType("Screen*"); 108 x11Window_t = LispRegisterOpaqueType("Window"); 109 x11GC_t = LispRegisterOpaqueType("GC"); 110 111 for (i = 0; i < sizeof(lispbuiltins) / sizeof(lispbuiltins[0]); i++) 112 LispAddBuiltinFunction(&lispbuiltins[i]); 113 114 return (1); 115} 116 117LispObj * 118Lisp_XOpenDisplay(LispBuiltin *builtin) 119/* 120x-open-display &optional display-name 121 */ 122{ 123 LispObj *display_name; 124 char *dname; 125 126 display_name = ARGUMENT(0); 127 128 if (display_name == UNSPEC) 129 dname = NULL; 130 else { 131 CHECK_STRING(display_name); 132 dname = THESTR(display_name); 133 } 134 135 return (OPAQUE(XOpenDisplay(dname), x11Display_t)); 136} 137 138LispObj * 139Lisp_XCloseDisplay(LispBuiltin *builtin) 140/* 141 x-close-display display 142 */ 143{ 144 LispObj *display; 145 146 display = ARGUMENT(0); 147 148 if (!CHECKO(display, x11Display_t)) 149 LispDestroy("%s: cannot convert %s to Display*", 150 STRFUN(builtin), STROBJ(display)); 151 152 XCloseDisplay((Display*)(display->data.opaque.data)); 153 154 return (NIL); 155} 156 157LispObj * 158Lisp_XDefaultRootWindow(LispBuiltin *builtin) 159/* 160 x-default-root-window display 161 */ 162{ 163 LispObj *display; 164 165 display = ARGUMENT(0); 166 167 if (!CHECKO(display, x11Display_t)) 168 LispDestroy("%s: cannot convert %s to Display*", 169 STRFUN(builtin), STROBJ(display)); 170 171 return (OPAQUE(DefaultRootWindow((Display*)(display->data.opaque.data)), 172 x11Window_t)); 173} 174 175LispObj * 176Lisp_XDefaultScreen(LispBuiltin *builtin) 177/* 178 x-default-screen display 179 */ 180{ 181 LispObj *display; 182 183 display = ARGUMENT(0); 184 185 if (!CHECKO(display, x11Display_t)) 186 LispDestroy("%s: cannot convert %s to Display*", 187 STRFUN(builtin), STROBJ(display)); 188 189 return (INTEGER(DefaultScreen((Display*)(display->data.opaque.data)))); 190} 191 192LispObj * 193Lisp_XDefaultScreenOfDisplay(LispBuiltin *builtin) 194/* 195 x-default-screen-of-display display 196 */ 197{ 198 LispObj *display; 199 200 display = ARGUMENT(0); 201 202 if (!CHECKO(display, x11Display_t)) 203 LispDestroy("%s: cannot convert %s to Display*", 204 STRFUN(builtin), STROBJ(display)); 205 206 return (OPAQUE(DefaultScreenOfDisplay((Display*)(display->data.opaque.data)), 207 x11Screen_t)); 208} 209 210LispObj * 211Lisp_XBlackPixel(LispBuiltin *builtin) 212/* 213 x-black-pixel display &optional screen 214 */ 215{ 216 Display *display; 217 int screen; 218 219 LispObj *odisplay, *oscreen; 220 221 oscreen = ARGUMENT(1); 222 odisplay = ARGUMENT(0); 223 224 if (!CHECKO(odisplay, x11Display_t)) 225 LispDestroy("%s: cannot convert %s to Display*", 226 STRFUN(builtin), STROBJ(odisplay)); 227 display = (Display*)(odisplay->data.opaque.data); 228 229 if (oscreen == UNSPEC) 230 screen = DefaultScreen(display); 231 else { 232 CHECK_INDEX(oscreen); 233 screen = FIXNUM_VALUE(oscreen); 234 } 235 236 if (screen >= ScreenCount(display)) 237 LispDestroy("%s: screen index %d too large, %d screens available", 238 STRFUN(builtin), screen, ScreenCount(display)); 239 240 return (INTEGER(BlackPixel(display, screen))); 241} 242 243LispObj * 244Lisp_XBlackPixelOfScreen(LispBuiltin *builtin) 245/* 246 x-black-pixel-of-screen screen 247 */ 248{ 249 LispObj *screen; 250 251 screen = ARGUMENT(0); 252 253 if (!CHECKO(screen, x11Screen_t)) 254 LispDestroy("%s: cannot convert %s to Screen*", 255 STRFUN(builtin), STROBJ(screen)); 256 257 return (INTEGER(XBlackPixelOfScreen((Screen*)(screen->data.opaque.data)))); 258} 259 260LispObj * 261Lisp_XWhitePixel(LispBuiltin *builtin) 262/* 263 x-white-pixel display &optional screen 264 */ 265{ 266 Display *display; 267 int screen; 268 269 LispObj *odisplay, *oscreen; 270 271 oscreen = ARGUMENT(1); 272 odisplay = ARGUMENT(0); 273 274 if (!CHECKO(odisplay, x11Display_t)) 275 LispDestroy("%s: cannot convert %s to Display*", 276 STRFUN(builtin), STROBJ(odisplay)); 277 display = (Display*)(odisplay->data.opaque.data); 278 279 if (oscreen == UNSPEC) 280 screen = DefaultScreen(display); 281 else { 282 CHECK_FIXNUM(oscreen); 283 screen = FIXNUM_VALUE(oscreen); 284 } 285 286 if (screen >= ScreenCount(display)) 287 LispDestroy("%s: screen index %d too large, %d screens available", 288 STRFUN(builtin), screen, ScreenCount(display)); 289 290 return (INTEGER(WhitePixel(display, screen))); 291} 292 293LispObj * 294Lisp_XWhitePixelOfScreen(LispBuiltin *builtin) 295/* 296 x-white-pixel-of-screen screen 297 */ 298{ 299 LispObj *screen; 300 301 screen = ARGUMENT(0); 302 303 if (!CHECKO(screen, x11Screen_t)) 304 LispDestroy("%s: cannot convert %s to Screen*", 305 STRFUN(builtin), STROBJ(screen)); 306 307 return (INTEGER(WhitePixelOfScreen((Screen*)(screen->data.opaque.data)))); 308} 309 310LispObj * 311Lisp_XDefaultGC(LispBuiltin *builtin) 312/* 313 x-default-gc display &optional screen 314 */ 315{ 316 Display *display; 317 int screen; 318 319 LispObj *odisplay, *oscreen; 320 321 oscreen = ARGUMENT(1); 322 odisplay = ARGUMENT(0); 323 324 if (!CHECKO(odisplay, x11Display_t)) 325 LispDestroy("%s: cannot convert %s to Display*", 326 STRFUN(builtin), STROBJ(odisplay)); 327 display = (Display*)(odisplay->data.opaque.data); 328 329 if (oscreen == UNSPEC) 330 screen = DefaultScreen(display); 331 else { 332 CHECK_FIXNUM(oscreen); 333 screen = FIXNUM_VALUE(oscreen); 334 } 335 336 if (screen >= ScreenCount(display)) 337 LispDestroy("%s: screen index %d too large, %d screens available", 338 STRFUN(builtin), screen, ScreenCount(display)); 339 340 return (OPAQUE(DefaultGC(display, screen), x11GC_t)); 341} 342 343LispObj * 344Lisp_XDefaultGCOfScreen(LispBuiltin *builtin) 345/* 346 x-default-gc-of-screen screen 347 */ 348{ 349 LispObj *screen; 350 351 screen = ARGUMENT(0); 352 353 if (!CHECKO(screen, x11Screen_t)) 354 LispDestroy("%s: cannot convert %s to Screen*", 355 STRFUN(builtin), STROBJ(screen)); 356 357 return (OPAQUE(DefaultGCOfScreen((Screen*)(screen->data.opaque.data)), 358 x11GC_t)); 359} 360 361LispObj * 362Lisp_XCreateSimpleWindow(LispBuiltin *builtin) 363/* 364 x-create-simple-window display parent x y width height &optional border-width border background 365 */ 366{ 367 Display *display; 368 Window parent; 369 int x, y; 370 unsigned int width, height, border_width; 371 unsigned long border, background; 372 373 LispObj *odisplay, *oparent, *ox, *oy, *owidth, *oheight, 374 *oborder_width, *oborder, *obackground; 375 376 obackground = ARGUMENT(8); 377 oborder = ARGUMENT(7); 378 oborder_width = ARGUMENT(6); 379 oheight = ARGUMENT(5); 380 owidth = ARGUMENT(4); 381 oy = ARGUMENT(3); 382 ox = ARGUMENT(2); 383 oparent = ARGUMENT(1); 384 odisplay = ARGUMENT(0); 385 386 if (!CHECKO(odisplay, x11Display_t)) 387 LispDestroy("%s: cannot convert %s to Display*", 388 STRFUN(builtin), STROBJ(odisplay)); 389 display = (Display*)(odisplay->data.opaque.data); 390 391 if (!CHECKO(oparent, x11Window_t)) 392 LispDestroy("%s: cannot convert %s to Window", 393 STRFUN(builtin), STROBJ(oparent)); 394 parent = (Window)(oparent->data.opaque.data); 395 396 CHECK_FIXNUM(ox); 397 x = FIXNUM_VALUE(ox); 398 399 CHECK_FIXNUM(oy); 400 y = FIXNUM_VALUE(oy); 401 402 CHECK_INDEX(owidth); 403 width = FIXNUM_VALUE(owidth); 404 405 CHECK_INDEX(oheight); 406 height = FIXNUM_VALUE(oheight); 407 408 /* check &OPTIONAL parameters */ 409 if (oborder_width == UNSPEC) 410 border_width = 1; 411 else { 412 CHECK_INDEX(oborder_width); 413 border_width = FIXNUM_VALUE(oborder_width); 414 } 415 416 if (oborder == UNSPEC) 417 border = BlackPixel(display, DefaultScreen(display)); 418 else { 419 CHECK_LONGINT(oborder); 420 border = LONGINT_VALUE(oborder); 421 } 422 423 if (obackground == UNSPEC) 424 background = WhitePixel(display, DefaultScreen(display)); 425 else { 426 CHECK_LONGINT(obackground); 427 background = LONGINT_VALUE(obackground); 428 } 429 430 return (OPAQUE( 431 XCreateSimpleWindow(display, parent, x, y, width, height, 432 border_width, border, background), 433 x11Window_t)); 434} 435 436LispObj * 437Lisp_XMapWindow(LispBuiltin *builtin) 438/* 439 x-map-window display window 440 */ 441{ 442 Display *display; 443 Window window; 444 445 LispObj *odisplay, *owindow; 446 447 owindow = ARGUMENT(1); 448 odisplay = ARGUMENT(0); 449 450 if (!CHECKO(odisplay, x11Display_t)) 451 LispDestroy("%s: cannot convert %s to Display*", 452 STRFUN(builtin), STROBJ(odisplay)); 453 display = (Display*)(odisplay->data.opaque.data); 454 455 if (!CHECKO(owindow, x11Window_t)) 456 LispDestroy("%s: cannot convert %s to Window", 457 STRFUN(builtin), STROBJ(owindow)); 458 window = (Window)(owindow->data.opaque.data); 459 460 XMapWindow(display, window); 461 462 return (owindow); 463} 464 465LispObj * 466Lisp_XDestroyWindow(LispBuiltin *builtin) 467/* 468 x-destroy-window display window 469 */ 470{ 471 Display *display; 472 Window window; 473 474 LispObj *odisplay, *owindow; 475 476 owindow = ARGUMENT(1); 477 odisplay = ARGUMENT(0); 478 479 if (!CHECKO(odisplay, x11Display_t)) 480 LispDestroy("%s: cannot convert %s to Display*", 481 STRFUN(builtin), STROBJ(odisplay)); 482 display = (Display*)(odisplay->data.opaque.data); 483 484 if (!CHECKO(owindow, x11Window_t)) 485 LispDestroy("%s: cannot convert %s to Window", 486 STRFUN(builtin), STROBJ(owindow)); 487 window = (Window)(owindow->data.opaque.data); 488 489 XDestroyWindow(display, window); 490 491 return (NIL); 492} 493 494LispObj * 495Lisp_XFlush(LispBuiltin *builtin) 496/* 497 x-flush display 498 */ 499{ 500 Display *display; 501 502 LispObj *odisplay; 503 504 odisplay = ARGUMENT(0); 505 506 if (!CHECKO(odisplay, x11Display_t)) 507 LispDestroy("%s: cannot convert %s to Display*", 508 STRFUN(builtin), STROBJ(odisplay)); 509 display = (Display*)(odisplay->data.opaque.data); 510 511 XFlush(display); 512 513 return (odisplay); 514} 515 516LispObj * 517Lisp_XDrawLine(LispBuiltin *builtin) 518/* 519 x-draw-line display drawable gc x1 y1 x2 y2 520 */ 521{ 522 Display *display; 523 Drawable drawable; 524 GC gc; 525 int x1, y1, x2, y2; 526 527 LispObj *odisplay, *odrawable, *ogc, *ox1, *oy1, *ox2, *oy2; 528 529 oy2 = ARGUMENT(6); 530 ox2 = ARGUMENT(5); 531 oy1 = ARGUMENT(4); 532 ox1 = ARGUMENT(3); 533 ogc = ARGUMENT(2); 534 odrawable = ARGUMENT(1); 535 odisplay = ARGUMENT(0); 536 537 if (!CHECKO(odisplay, x11Display_t)) 538 LispDestroy("%s: cannot convert %s to Display*", 539 STRFUN(builtin), STROBJ(odisplay)); 540 display = (Display*)(odisplay->data.opaque.data); 541 542 /* XXX correct check when drawing to pixmaps implemented */ 543 if (!CHECKO(odrawable, x11Window_t)) 544 LispDestroy("%s: cannot convert %s to Drawable", 545 STRFUN(builtin), STROBJ(odrawable)); 546 drawable = (Drawable)(odrawable->data.opaque.data); 547 548 if (!CHECKO(ogc, x11GC_t)) 549 LispDestroy("%s: cannot convert %s to Display*", 550 STRFUN(builtin), STROBJ(ogc)); 551 gc = (GC)(ogc->data.opaque.data); 552 553 CHECK_FIXNUM(ox1); 554 x1 = FIXNUM_VALUE(ox1); 555 556 CHECK_FIXNUM(oy1); 557 y1 = FIXNUM_VALUE(oy1); 558 559 CHECK_FIXNUM(ox2); 560 x2 = FIXNUM_VALUE(ox2); 561 562 CHECK_FIXNUM(oy2); 563 y2 = FIXNUM_VALUE(oy2); 564 565 XDrawLine(display, drawable, gc, x1, y1, x2, y2); 566 567 return (odrawable); 568} 569 570LispObj * 571Lisp_XBell(LispBuiltin *builtin) 572/* 573 x-bell &optional percent 574 */ 575{ 576 Display *display; 577 int percent; 578 579 LispObj *odisplay, *opercent; 580 581 opercent = ARGUMENT(1); 582 odisplay = ARGUMENT(0); 583 584 if (!CHECKO(odisplay, x11Display_t)) 585 LispDestroy("%s: cannot convert %s to Display*", 586 STRFUN(builtin), STROBJ(odisplay)); 587 display = (Display*)(odisplay->data.opaque.data); 588 589 if (opercent == UNSPEC) 590 percent = 0; 591 else { 592 CHECK_FIXNUM(opercent); 593 percent = FIXNUM_VALUE(opercent); 594 } 595 596 if (percent < -100 || percent > 100) 597 LispDestroy("%s: percent value %d out of range -100 to 100", 598 STRFUN(builtin), percent); 599 600 XBell(display, percent); 601 602 return (odisplay); 603} 604 605LispObj * 606Lisp_XRaiseWindow(LispBuiltin *builtin) 607/* 608 x-raise-window display window 609 */ 610{ 611 Display *display; 612 Window window; 613 614 LispObj *odisplay, *owindow; 615 616 owindow = ARGUMENT(1); 617 odisplay = ARGUMENT(0); 618 619 if (!CHECKO(odisplay, x11Display_t)) 620 LispDestroy("%s: cannot convert %s to Display*", 621 STRFUN(builtin), STROBJ(odisplay)); 622 display = (Display*)(odisplay->data.opaque.data); 623 624 if (!CHECKO(owindow, x11Window_t)) 625 LispDestroy("%s: cannot convert %s to Window", 626 STRFUN(builtin), STROBJ(owindow)); 627 window = (Window)(owindow->data.opaque.data); 628 629 XRaiseWindow(display, window); 630 631 return (owindow); 632} 633 634LispObj * 635Lisp_XWidthOfScreen(LispBuiltin *builtin) 636/* 637 x-width-of-screen screen 638 */ 639{ 640 LispObj *screen; 641 642 screen = ARGUMENT(0); 643 644 if (!CHECKO(screen, x11Screen_t)) 645 LispDestroy("%s: cannot convert %s to Screen*", 646 STRFUN(builtin), STROBJ(screen)); 647 648 return (FIXNUM(WidthOfScreen((Screen*)(screen->data.opaque.data)))); 649} 650 651LispObj * 652Lisp_XHeightOfScreen(LispBuiltin *builtin) 653/* 654 x-height-of-screen screen 655 */ 656{ 657 LispObj *screen; 658 659 screen = ARGUMENT(0); 660 661 if (!CHECKO(screen, x11Screen_t)) 662 LispDestroy("%s: cannot convert %s to Screen*", 663 STRFUN(builtin), STROBJ(screen)); 664 665 return (FIXNUM(HeightOfScreen((Screen*)(screen->data.opaque.data)))); 666} 667