1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 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 THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: PortLink.cpp 23 // Author: Pahtz <pahtz@yahoo.com.au> 24 // Description: Class for low-overhead port-based messaging 25 // 26 //------------------------------------------------------------------------------ 27 #include <stdlib.h> 28 #include <string.h> 29 #include <new> 30 31 #include <ServerProtocol.h> 32 #include "PortLink.h" 33 34 #define DEBUG_BPORTLINK 35 #ifdef DEBUG_BPORTLINK 36 # include <stdio.h> 37 # define STRACE(x) printf x 38 const char *strcode(int32 code); 39 const char *bstrcode(int32 code); 40 #else 41 # define STRACE(x) ; 42 #endif 43 44 //set Initial==Max for a fixed buffer size 45 static const int32 kInitialSendBufferSize = 2048; 46 static const int32 kMaxSendBufferSize = 2048; 47 static const int32 kInitialReceiveBufferSize = 2048; 48 static const int32 kMaxReceiveBufferSize = 2048; 49 //make the max receive buffer at least as large as max send 50 51 static const int32 kHeaderSize = sizeof(int32) * 3; //size + code + flags 52 53 BPortLink::BPortLink(port_id send, port_id receive) : 54 fSendPort(send), fReceivePort(receive), fSendBuffer(NULL), fRecvBuffer(NULL), 55 fSendPosition(0), fRecvPosition(0), fSendStart(0), fRecvStart(0), 56 fSendBufferSize(0), fRecvBufferSize(0), fSendCount(0), fDataSize(0), 57 fReplySize(0), fWriteError(B_OK), fReadError(B_OK) 58 { 59 /* */ 60 } 61 62 BPortLink::~BPortLink() 63 { 64 if (fSendBuffer) 65 free(fSendBuffer); 66 if (fRecvBuffer) 67 free(fRecvBuffer); 68 } 69 70 status_t BPortLink::StartMessage(int32 code) 71 { 72 if (EndMessage() < B_OK) //end previous message 73 CancelMessage(); //abandon previous message 74 75 if (fSendBufferSize == 0) 76 { 77 fSendBuffer = (char *)malloc(kInitialSendBufferSize); 78 if (fSendBuffer == NULL) 79 { 80 fWriteError = B_NO_MEMORY; 81 return B_NO_MEMORY; 82 } 83 fSendBufferSize = kInitialSendBufferSize; 84 } 85 86 status_t err; 87 //must have space for at least size + code + flags 88 if (fSendBufferSize - fSendPosition < kHeaderSize) 89 { 90 err = Flush(); //will set fSendPosition and fSendStart to 0 91 if (err < B_OK) 92 return err; 93 } 94 95 int32 *p = (int32 *)(fSendBuffer + fSendStart); //start of current message 96 *p = 0; //size 97 *(++p) = code; //code 98 *(++p) = 0; //flags 99 fSendPosition += kHeaderSize; //size + code + flags 100 101 STRACE(("info: BPortLink buffered header %s [%ld %ld %ld].\n", strcode(code), (int32)0, *(p-1), *p)); 102 103 return B_OK; 104 } 105 106 status_t BPortLink::EndMessage() 107 { 108 if (fSendPosition == fSendStart || fWriteError < B_OK) 109 return fWriteError; 110 111 int32 *p = (int32 *)(fSendBuffer + fSendStart); //start of the message 112 *p = fSendPosition - fSendStart; //record the size of the message 113 fSendCount++; //increase the number of completed messages 114 115 fSendStart = fSendPosition; //start of next new message 116 117 return B_OK; 118 STRACE(("info: BPortLink EndMessage() of size %ld.\n", *p)); 119 } 120 121 void BPortLink::CancelMessage() 122 { 123 fSendPosition = fSendStart; 124 fWriteError = B_OK; 125 } 126 127 status_t BPortLink::Attach(const void *data, ssize_t size) 128 { 129 if (fWriteError < B_OK) 130 return fWriteError; 131 132 if (size <= 0) 133 { 134 fWriteError = B_BAD_VALUE; 135 return B_BAD_VALUE; 136 } 137 138 if (fSendPosition == fSendStart) 139 return B_NO_INIT; //need to call StartMessage() first 140 141 int32 remaining = fSendBufferSize - fSendPosition; 142 if (remaining < size) //we have to make space for the data 143 { 144 int32 total = size + (fSendPosition - fSendStart); 145 //resulting size of current message 146 147 int32 newbuffersize; 148 if (total <= fSendBufferSize) 149 newbuffersize = fSendBufferSize; //no change 150 else if (total > kMaxSendBufferSize) 151 { 152 fWriteError = B_BAD_VALUE; 153 return B_BAD_VALUE; 154 } 155 else if (total <= kInitialSendBufferSize) 156 newbuffersize = kInitialSendBufferSize; 157 else 158 newbuffersize = (total + B_PAGE_SIZE) - (total % B_PAGE_SIZE); 159 160 //FlushCompleted() to make space 161 status_t err; 162 err = FlushCompleted(newbuffersize); 163 if (err < B_OK) 164 { 165 fWriteError = err; 166 return err; 167 } 168 } 169 170 memcpy(fSendBuffer + fSendPosition, data, size); 171 fSendPosition += size; 172 return fWriteError; 173 } 174 175 status_t BPortLink::FlushCompleted(ssize_t newbuffersize) 176 { 177 char *buffer = NULL; 178 if (newbuffersize == fSendBufferSize) 179 buffer = fSendBuffer; //keep existing buffer 180 else 181 { 182 //create new larger buffer 183 buffer = (char *)malloc(newbuffersize); 184 if (buffer == NULL) 185 return B_NO_MEMORY; 186 } 187 188 int32 position = fSendPosition; 189 int32 start = fSendStart; 190 fSendPosition = fSendStart; //trick to hide the incomplete message 191 192 status_t err; 193 err = Flush(); 194 if (err < B_OK) 195 { 196 fSendPosition = position; 197 if (buffer != fSendBuffer) 198 free(buffer); 199 return err; 200 } 201 202 //move the incomplete message to the start of the buffer 203 fSendPosition = min_c(position - start, newbuffersize); 204 memcpy(buffer, fSendBuffer + start, fSendPosition); 205 206 if (fSendBuffer != buffer) 207 { 208 free(fSendBuffer); 209 fSendBuffer = buffer; 210 fSendBufferSize = newbuffersize; 211 } 212 213 return B_OK; 214 } 215 216 217 void BPortLink::SetSendPort( port_id port ) 218 { 219 fSendPort=port; 220 } 221 222 port_id BPortLink::GetSendPort() 223 { 224 return fSendPort; 225 } 226 227 void BPortLink::SetReplyPort( port_id port ) 228 { 229 fReceivePort=port; 230 } 231 232 port_id BPortLink::GetReplyPort() 233 { 234 return fReceivePort; 235 } 236 237 status_t BPortLink::Flush(bigtime_t timeout) 238 { 239 if (fWriteError < B_OK) 240 return fWriteError; 241 242 EndMessage(); 243 if (fSendCount == 0) 244 return B_OK; 245 246 STRACE(("info: BPortLink Flush() waiting to send %ld messages of %ld bytes on port %ld.\n", fSendCount, fSendPosition, fSendPort)); 247 248 //TODO: we only need AS_SERVER_PORTLINK when all OBOS uses BPortLink 249 int32 protocol = (fSendCount > 1 ? AS_SERVER_SESSION : AS_SERVER_PORTLINK); 250 251 status_t err; 252 if(timeout != B_INFINITE_TIMEOUT) 253 { 254 do { 255 err = write_port_etc(fSendPort, protocol, fSendBuffer, 256 fSendPosition, B_RELATIVE_TIMEOUT, timeout); 257 } while(err == B_INTERRUPTED); 258 } 259 else 260 { 261 do { 262 err = write_port(fSendPort, protocol, fSendBuffer, fSendPosition); 263 } while(err == B_INTERRUPTED); 264 } 265 266 if (err == B_OK) 267 { 268 STRACE(("info: BPortLink Flush() %ld messages total of %ld bytes on port %ld.\n", fSendCount, fSendPosition, fSendPort)); 269 fSendPosition = 0; 270 fSendStart = 0; 271 fSendCount = 0; 272 return B_OK; 273 } 274 275 STRACE(("error info: BPortLink Flush() failed for %ld bytes (%s) on port %ld.\n", fSendPosition, strerror(err), fSendPort)); 276 return err; 277 } 278 279 status_t BPortLink::GetNextReply(int32 *code, bigtime_t timeout) 280 { 281 int32 remaining; 282 283 fReadError = B_OK; 284 285 remaining = fDataSize - (fRecvStart + fReplySize); 286 STRACE(("info: BPortLink GetNextReply() reports %ld bytes remaining in buffer.\n", remaining)); 287 288 //find the position of the next message header in the buffer 289 int32 *header; 290 if (remaining <= 0) 291 { 292 status_t err = ReadFromPort(timeout); 293 if (err < B_OK) 294 return err; 295 remaining = fDataSize; 296 header = (int32 *)fRecvBuffer; 297 } 298 else 299 { 300 fRecvStart += fReplySize; //start of the next message 301 fRecvPosition = fRecvStart; 302 header = (int32 *)(fRecvBuffer + fRecvStart); 303 } 304 305 //check we have a well-formed message 306 if (remaining < kHeaderSize) 307 //we don't have enough data for a complete header 308 { 309 STRACE(("error info: BPortLink remaining %ld bytes is less than header size.\n", remaining)); 310 ResetReplyBuffer(); 311 return B_ERROR; 312 } 313 314 fReplySize = *header; //size of the first message 315 if (fReplySize > remaining || fReplySize < kHeaderSize) 316 //the header info declares more data than we have OR 317 //the header info declares less data than kHeaderSize 318 { 319 STRACE(("error info: BPortLink message size of %ld bytes smaller than header size.\n", fReplySize)); 320 ResetReplyBuffer(); 321 return B_ERROR; 322 } 323 324 *code = *(++header); 325 fRecvPosition += kHeaderSize; //size + code + flags 326 327 STRACE(("info: BPortLink got header %s [%ld %ld %ld] from port %ld.\n", strcode(*code), fReplySize, *code, *(header + 1), fReceivePort)); 328 329 return B_OK; 330 } 331 332 void BPortLink::ResetReplyBuffer() 333 { 334 fRecvPosition = 0; 335 fRecvStart = 0; 336 fDataSize = 0; 337 fReplySize = 0; 338 } 339 340 status_t BPortLink::AdjustReplyBuffer(bigtime_t timeout) 341 { 342 //Here we take advantage of the compiler's dead-code elimination 343 if (kInitialReceiveBufferSize == kMaxReceiveBufferSize) //fixed buffer size 344 { 345 if (fRecvBuffer != NULL) 346 return B_OK; 347 348 fRecvBuffer = (char *)malloc(kInitialReceiveBufferSize); 349 if (fRecvBuffer == NULL) 350 return B_NO_MEMORY; 351 fRecvBufferSize = kInitialReceiveBufferSize; 352 } 353 else //if (kInitialReceiveBufferSize < kMaxReceiveBufferSize) 354 { 355 STRACE(("info: BPortLink getting port_buffer_size().\n")); 356 ssize_t buffersize; 357 if (timeout == B_INFINITE_TIMEOUT) 358 buffersize = port_buffer_size(fReceivePort); 359 else 360 buffersize = port_buffer_size_etc(fReceivePort, B_TIMEOUT, timeout); 361 STRACE(("info: BPortLink got port_buffer_size() = %ld.\n", buffersize)); 362 363 if (buffersize < 0) 364 return (status_t)buffersize; 365 366 //make sure our receive buffer is large enough 367 if (buffersize > fRecvBufferSize) 368 { 369 if (buffersize <= kInitialReceiveBufferSize) 370 buffersize = kInitialReceiveBufferSize; 371 else 372 buffersize = (buffersize + B_PAGE_SIZE) - (buffersize % B_PAGE_SIZE); 373 if (buffersize > kMaxReceiveBufferSize) 374 return B_ERROR; //we can't continue 375 376 STRACE(("info: BPortLink setting receive buffersize to %ld.\n", buffersize)); 377 char *buffer = (char *)malloc(buffersize); 378 if (buffer == NULL) 379 return B_NO_MEMORY; 380 if (fRecvBuffer) 381 free(fRecvBuffer); 382 fRecvBuffer = buffer; 383 fRecvBufferSize = buffersize; 384 } 385 } 386 387 return B_OK; 388 } 389 390 status_t BPortLink::ReadFromPort(bigtime_t timeout) 391 { 392 //we are here so it means we finished reading the buffer contents 393 ResetReplyBuffer(); 394 395 status_t err = AdjustReplyBuffer(timeout); 396 if (err < B_OK) 397 return err; 398 399 int32 protocol; 400 ssize_t bytesread; 401 STRACE(("info: BPortLink reading port %ld.\n", fReceivePort)); 402 if (timeout != B_INFINITE_TIMEOUT) 403 { 404 do { 405 bytesread = read_port_etc(fReceivePort, &protocol, fRecvBuffer, 406 fRecvBufferSize, B_TIMEOUT, timeout); 407 } while(bytesread == B_INTERRUPTED); 408 } 409 else 410 { 411 do { 412 bytesread = read_port(fReceivePort, &protocol, fRecvBuffer, 413 fRecvBufferSize); 414 } while(bytesread == B_INTERRUPTED); 415 } 416 417 STRACE(("info: BPortLink read %ld bytes.\n", bytesread)); 418 if (bytesread < B_OK) 419 return bytesread; 420 421 //TODO: we only need AS_SERVER_PORTLINK when all OBOS uses BPortLink 422 if (protocol != AS_SERVER_PORTLINK && protocol != AS_SERVER_SESSION) 423 return B_ERROR; 424 if (protocol == AS_SERVER_PORTLINK && bytesread != *((int32 *)fRecvBuffer)) 425 //should only be one message for PORTLINK so the size declared in the header 426 //(the first int32 in the header) should be the same as bytesread 427 return B_ERROR; 428 429 fDataSize = bytesread; 430 return B_OK; 431 } 432 433 status_t BPortLink::Read(void *data, ssize_t size) 434 { 435 // STRACE(("info: BPortLink Read()ing %ld bytes...\n", size)); 436 if (fReadError < B_OK) 437 return fReadError; 438 439 if (size < 1) 440 { 441 fReadError = B_BAD_VALUE; 442 return B_BAD_VALUE; 443 } 444 445 if (fDataSize == 0 || fReplySize == 0) 446 return B_NO_INIT; //need to call GetNextReply() first 447 448 if (fRecvPosition + size > fRecvStart + fReplySize) 449 { 450 //reading past the end of current message 451 fReadError = B_BAD_VALUE; 452 return B_BAD_VALUE; 453 } 454 455 memcpy(data, fRecvBuffer + fRecvPosition, size); 456 fRecvPosition += size; 457 return fReadError; 458 } 459 460 status_t BPortLink::ReadString(char **string) 461 { 462 status_t err; 463 int32 len = 0; 464 465 err = Read<int32>(&len); 466 if (err < B_OK) 467 return err; 468 469 if (len) 470 { 471 *string = (char *)malloc(len); 472 if (*string == NULL) 473 { 474 fRecvPosition -= sizeof(int32); //rewind the transaction 475 return B_NO_MEMORY; 476 } 477 478 err = Read(*string, len); 479 if (err < B_OK) 480 { 481 free(*string); 482 *string = NULL; 483 fRecvPosition -= sizeof(int32); //rewind the transaction 484 return err; 485 } 486 (*string)[len-1] = '\0'; 487 return B_OK; 488 } 489 else 490 { 491 fRecvPosition -= sizeof(int32); //rewind the transaction 492 return B_ERROR; 493 } 494 } 495 496 status_t BPortLink::AttachString(const char *string) 497 { 498 status_t err; 499 if (string == NULL) 500 return B_BAD_VALUE; 501 502 int32 len = strlen(string)+1; 503 err = Attach<int32>(len); 504 if (err < B_OK) 505 return err; 506 507 err = Attach(string, len); 508 if (err < B_OK) 509 fSendPosition -= sizeof(int32); //rewind the transaction 510 511 return err; 512 } 513 514 #ifdef DEBUG_BPORTLINK 515 #include <ServerProtocol.h> 516 #include <AppDefs.h> 517 518 static const char *kASCodeNames[] = 519 { 520 "SERVER_TRUE", 521 "SERVER_FALSE", 522 "AS_SERVER_BMESSAGE", 523 "AS_SERVER_AREALINK", 524 "AS_SERVER_SESSION", 525 "AS_SERVER_PORTLINK", 526 "AS_CLIENT_DEAD", 527 "AS_CREATE_APP", 528 "AS_DELETE_APP", 529 "AS_QUIT_APP", 530 "AS_SET_SERVER_PORT", 531 "AS_CREATE_WINDOW", 532 "AS_DELETE_WINDOW", 533 "AS_CREATE_BITMAP", 534 "AS_DELETE_BITMAP", 535 "AS_SET_CURSOR_DATA", 536 "AS_SET_CURSOR_BCURSOR", 537 "AS_SET_CURSOR_BBITMAP", 538 "AS_SET_CURSOR_SYSTEM", 539 "AS_SET_SYSCURSOR_DATA", 540 "AS_SET_SYSCURSOR_BCURSOR", 541 "AS_SET_SYSCURSOR_BBITMAP", 542 "AS_SET_SYSCURSOR_DEFAULTS", 543 "AS_GET_SYSCURSOR", 544 "AS_SHOW_CURSOR", 545 "AS_HIDE_CURSOR", 546 "AS_OBSCURE_CURSOR", 547 "AS_QUERY_CURSOR_HIDDEN", 548 "AS_CREATE_BCURSOR", 549 "AS_DELETE_BCURSOR", 550 "AS_BEGIN_RECT_TRACKING", 551 "AS_END_RECT_TRACKING", 552 "AS_SHOW_WINDOW", 553 "AS_HIDE_WINDOW", 554 "AS_QUIT_WINDOW", 555 "AS_SEND_BEHIND", 556 "AS_SET_LOOK", 557 "AS_SET_FEEL", 558 "AS_SET_FLAGS", 559 "AS_DISABLE_UPDATES", 560 "AS_ENABLE_UPDATES", 561 "AS_BEGIN_UPDATE", 562 "AS_END_UPDATE", 563 "AS_NEEDS_UPDATE", 564 "AS_WINDOW_TITLE", 565 "AS_ADD_TO_SUBSET", 566 "AS_REM_FROM_SUBSET", 567 "AS_SET_ALIGNMENT", 568 "AS_GET_ALIGNMENT", 569 "AS_GET_WORKSPACES", 570 "AS_SET_WORKSPACES", 571 "AS_WINDOW_RESIZE", 572 "AS_WINDOW_MOVE", 573 "AS_SET_SIZE_LIMITS", 574 "AS_ACTIVATE_WINDOW", 575 "AS_WINDOW_MINIMIZE", 576 "AS_UPDATE_IF_NEEDED", 577 "_ALL_UPDATED_", 578 "AS_CREATE_PICTURE", 579 "AS_DELETE_PICTURE", 580 "AS_CLONE_PICTURE", 581 "AS_DOWNLOAD_PICTURE", 582 "AS_QUERY_FONTS_CHANGED", 583 "AS_UPDATED_CLIENT_FONTLIST", 584 "AS_GET_FAMILY_ID", 585 "AS_GET_STYLE_ID", 586 "AS_GET_STYLE_FOR_FACE", 587 "AS_GET_SCREEN_MODE", 588 "AS_SET_UI_COLORS", 589 "AS_GET_UI_COLORS", 590 "AS_GET_UI_COLOR", 591 "AS_SET_DECORATOR", 592 "AS_GET_DECORATOR", 593 "AS_R5_SET_DECORATOR", 594 "AS_COUNT_WORKSPACES", 595 "AS_SET_WORKSPACE_COUNT", 596 "AS_CURRENT_WORKSPACE", 597 "AS_ACTIVATE_WORKSPACE", 598 "AS_SET_SCREEN_MODE", 599 "AS_GET_SCROLLBAR_INFO", 600 "AS_SET_SCROLLBAR_INFO", 601 "AS_IDLE_TIME", 602 "AS_SELECT_PRINTER_PANEL", 603 "AS_ADD_PRINTER_PANEL", 604 "AS_RUN_BE_ABOUT", 605 "AS_SET_FOCUS_FOLLOWS_MOUSE", 606 "AS_FOCUS_FOLLOWS_MOUSE", 607 "AS_SET_MOUSE_MODE", 608 "AS_GET_MOUSE_MODE", 609 "AS_WORKSPACE_ACTIVATED", 610 "AS_WORKSPACES_CHANGED", 611 "AS_WINDOW_ACTIVATED", 612 "AS_SCREENMODE_CHANGED", 613 "AS_BEGIN_TRANSACTION", 614 "AS_END_TRANSACTION", 615 "AS_SET_HIGH_COLOR", 616 "AS_SET_LOW_COLOR", 617 "AS_SET_VIEW_COLOR", 618 "AS_STROKE_ARC", 619 "AS_STROKE_BEZIER", 620 "AS_STROKE_ELLIPSE", 621 "AS_STROKE_LINE", 622 "AS_STROKE_LINEARRAY", 623 "AS_STROKE_POLYGON", 624 "AS_STROKE_RECT", 625 "AS_STROKE_ROUNDRECT", 626 "AS_STROKE_SHAPE", 627 "AS_STROKE_TRIANGLE", 628 "AS_FILL_ARC", 629 "AS_FILL_BEZIER", 630 "AS_FILL_ELLIPSE", 631 "AS_FILL_POLYGON", 632 "AS_FILL_RECT", 633 "AS_FILL_REGION", 634 "AS_FILL_ROUNDRECT", 635 "AS_FILL_SHAPE", 636 "AS_FILL_TRIANGLE", 637 "AS_MOVEPENBY", 638 "AS_MOVEPENTO", 639 "AS_SETPENSIZE", 640 "AS_DRAW_STRING", 641 "AS_SET_FONT", 642 "AS_SET_FONT_SIZE", 643 "AS_FLUSH", 644 "AS_SYNC", 645 "AS_LAYER_CREATE", 646 "AS_LAYER_DELETE", 647 "AS_LAYER_CREATE_ROOT", 648 "AS_LAYER_DELETE_ROOT", 649 "AS_LAYER_ADD_CHILD", 650 "AS_LAYER_REMOVE_CHILD", 651 "AS_LAYER_REMOVE_SELF", 652 "AS_LAYER_SHOW", 653 "AS_LAYER_HIDE", 654 "AS_LAYER_MOVE", 655 "AS_LAYER_RESIZE", 656 "AS_LAYER_INVALIDATE", 657 "AS_LAYER_DRAW", 658 "AS_LAYER_GET_TOKEN", 659 "AS_LAYER_ADD", 660 "AS_LAYER_REMOVE", 661 "AS_LAYER_GET_COORD", 662 "AS_LAYER_SET_FLAGS", 663 "AS_LAYER_SET_ORIGIN", 664 "AS_LAYER_GET_ORIGIN", 665 "AS_LAYER_RESIZE_MODE", 666 "AS_LAYER_CURSOR", 667 "AS_LAYER_BEGIN_RECT_TRACK", 668 "AS_LAYER_END_RECT_TRACK", 669 "AS_LAYER_DRAG_RECT", 670 "AS_LAYER_DRAG_IMAGE", 671 "AS_LAYER_GET_MOUSE_COORDS", 672 "AS_LAYER_SCROLL", 673 "AS_LAYER_SET_LINE_MODE", 674 "AS_LAYER_GET_LINE_MODE", 675 "AS_LAYER_PUSH_STATE", 676 "AS_LAYER_POP_STATE", 677 "AS_LAYER_SET_SCALE", 678 "AS_LAYER_GET_SCALE", 679 "AS_LAYER_SET_DRAW_MODE", 680 "AS_LAYER_GET_DRAW_MODE", 681 "AS_LAYER_SET_BLEND_MODE", 682 "AS_LAYER_GET_BLEND_MODE", 683 "AS_LAYER_SET_PEN_LOC", 684 "AS_LAYER_GET_PEN_LOC", 685 "AS_LAYER_SET_PEN_SIZE", 686 "AS_LAYER_GET_PEN_SIZE", 687 "AS_LAYER_SET_HIGH_COLOR", 688 "AS_LAYER_SET_LOW_COLOR", 689 "AS_LAYER_SET_VIEW_COLOR", 690 "AS_LAYER_GET_COLORS", 691 "AS_LAYER_PRINT_ALIASING", 692 "AS_LAYER_CLIP_TO_PICTURE", 693 "AS_LAYER_CLIP_TO_INVERSE_PICTURE", 694 "AS_LAYER_GET_CLIP_REGION", 695 "AS_LAYER_DRAW_BITMAP_ASYNC_IN_RECT", 696 "AS_LAYER_DRAW_BITMAP_ASYNC_AT_POINT", 697 "AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT", 698 "AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT", 699 "AS_LAYER_DRAW_STRING", 700 "AS_LAYER_SET_CLIP_REGION", 701 "AS_LAYER_LINE_ARRAY", 702 "AS_LAYER_BEGIN_PICTURE", 703 "AS_LAYER_APPEND_TO_PICTURE", 704 "AS_LAYER_END_PICTURE", 705 "AS_LAYER_COPY_BITS", 706 "AS_LAYER_DRAW_PICTURE", 707 "AS_LAYER_INVAL_RECT", 708 "AS_LAYER_INVAL_REGION", 709 "AS_LAYER_INVERT_RECT", 710 "AS_LAYER_MOVETO", 711 "AS_LAYER_RESIZETO", 712 "AS_LAYER_SET_STATE", 713 "AS_LAYER_SET_FONT_STATE", 714 "AS_LAYER_GET_STATE", 715 "AS_LAYER_SET_VIEW_IMAGE", 716 "AS_LAYER_SET_PATTERN", 717 "AS_SET_CURRENT_LAYER", 718 }; 719 720 const char *strcode(int32 code) 721 { 722 code = code - SERVER_TRUE; 723 if (code >= 0 && code <= AS_SET_CURRENT_LAYER - SERVER_TRUE) 724 return kASCodeNames[code]; 725 else 726 return bstrcode(code); 727 } 728 729 const char *bstrcode(int32 code) 730 { 731 switch(code) 732 { 733 case B_ABOUT_REQUESTED: 734 { 735 return "B_ABOUT_REQUESTED"; 736 } 737 case B_APP_ACTIVATED: 738 { 739 return "B_APP_ACTIVATED/B_WINDOW_ACTIVATED"; 740 } 741 case B_ARGV_RECEIVED: 742 { 743 return "B_ARGV_RECEIVED"; 744 } 745 case B_QUIT_REQUESTED: 746 { 747 return "B_QUIT_REQUESTED"; 748 } 749 case B_CANCEL: 750 { 751 return "B_CANCEL"; 752 } 753 case B_KEY_DOWN: 754 { 755 return "B_KEY_DOWN"; 756 } 757 case B_KEY_UP: 758 { 759 return "B_KEY_UP"; 760 } 761 case B_UNMAPPED_KEY_DOWN: 762 { 763 return "B_UNMAPPED_KEY_DOWN"; 764 } 765 case B_UNMAPPED_KEY_UP: 766 { 767 return "B_UNMAPPED_KEY_UP"; 768 } 769 case B_MODIFIERS_CHANGED: 770 { 771 return "B_MODIFIERS_CHANGED"; 772 } 773 case B_MINIMIZE: 774 { 775 return "B_MINIMIZE"; 776 } 777 case B_MOUSE_DOWN: 778 { 779 return "B_MOUSE_DOWN"; 780 } 781 case B_MOUSE_MOVED: 782 { 783 return "B_MOUSE_MOVED"; 784 } 785 case B_MOUSE_ENTER_EXIT: 786 { 787 return "B_MOUSE_ENTER_EXIT"; 788 } 789 case B_MOUSE_UP: 790 { 791 return "B_MOUSE_UP"; 792 } 793 case B_MOUSE_WHEEL_CHANGED: 794 { 795 return "B_MOUSE_WHEEL_CHANGED"; 796 } 797 case B_OPEN_IN_WORKSPACE: 798 { 799 return "B_OPEN_IN_WORKSPACE"; 800 } 801 case B_PRINTER_CHANGED: 802 { 803 return "B_PRINTER_CHANGED"; 804 } 805 case B_PULSE: 806 { 807 return "B_PULSE"; 808 } 809 case B_READY_TO_RUN: 810 { 811 return "B_READY_TO_RUN"; 812 } 813 case B_REFS_RECEIVED: 814 { 815 return "B_REFS_RECEIVED"; 816 } 817 case B_RELEASE_OVERLAY_LOCK: 818 { 819 return "B_RELEASE_OVERLAY_LOCK"; 820 } 821 case B_ACQUIRE_OVERLAY_LOCK: 822 { 823 return "B_ACQUIRE_OVERLAY_LOCK"; 824 } 825 case B_SCREEN_CHANGED: 826 { 827 return "B_SCREEN_CHANGED"; 828 } 829 case B_VALUE_CHANGED: 830 { 831 return "B_VALUE_CHANGED"; 832 } 833 case B_VIEW_MOVED: 834 { 835 return "B_VIEW_MOVED"; 836 } 837 case B_VIEW_RESIZED: 838 { 839 return "B_VIEW_RESIZED"; 840 } 841 case B_WINDOW_MOVED: 842 { 843 return "B_WINDOW_MOVED"; 844 } 845 case B_WINDOW_RESIZED: 846 { 847 return "B_WINDOW_RESIZED"; 848 } 849 case B_WORKSPACES_CHANGED: 850 { 851 return "B_WORKSPACES_CHANGED"; 852 } 853 case B_WORKSPACE_ACTIVATED: 854 { 855 return "B_WORKSPACE_ACTIVATED"; 856 } 857 case B_ZOOM: 858 { 859 return "B_ZOOM"; 860 } 861 case _APP_MENU_: 862 { 863 return "_APP_MENU"; 864 } 865 case _BROWSER_MENUS_: 866 { 867 return "_BROWSER_MENUS_"; 868 } 869 case _MENU_EVENT_: 870 { 871 return "_MENU_EVENT"; 872 } 873 case _PING_: 874 { 875 return "_PING_"; 876 } 877 case _QUIT_: 878 { 879 return "_QUIT_"; 880 } 881 case _VOLUME_MOUNTED_: 882 { 883 return "_VOLUME_MOUNTED"; 884 } 885 case _VOLUME_UNMOUNTED_: 886 { 887 return "_VOLUME_UNMOUNTED"; 888 } 889 case _MESSAGE_DROPPED_: 890 { 891 return "_MESSAGE_DROPPED"; 892 } 893 case _DISPOSE_DRAG_: 894 { 895 return "_DISPOSE_DRAG"; 896 } 897 case _MENUS_DONE_: 898 { 899 return "_MENUS_DONE_"; 900 } 901 case _SHOW_DRAG_HANDLES_: 902 { 903 return "_SHOW_DRAG_HANDLES_"; 904 } 905 case _EVENTS_PENDING_: 906 { 907 return "_EVENTS_PENDING_"; 908 } 909 case _UPDATE_: 910 { 911 return "_UPDATE_"; 912 } 913 case _UPDATE_IF_NEEDED_: 914 { 915 return "_UPDATE_IF_NEEDED_"; 916 } 917 case _PRINTER_INFO_: 918 { 919 return "_PRINTER_INFO_"; 920 } 921 case _SETUP_PRINTER_: 922 { 923 return "_SETUP_PRINTER_"; 924 } 925 case _SELECT_PRINTER_: 926 { 927 return "_SELECT_PRINTER_"; 928 } 929 case B_SET_PROPERTY: 930 { 931 return "B_SET_PROPERTY"; 932 } 933 case B_GET_PROPERTY: 934 { 935 return "B_GET_PROERTY"; 936 } 937 case B_CREATE_PROPERTY: 938 { 939 return "B_CREATE_PROPERTY"; 940 } 941 case B_DELETE_PROPERTY: 942 { 943 return "B_DELETE_PROPERTY"; 944 } 945 case B_COUNT_PROPERTIES: 946 { 947 return "B_COUNT_PROPERTIES"; 948 } 949 case B_EXECUTE_PROPERTY: 950 { 951 return "B_EXECUTE_PROPERTY"; 952 } 953 case B_GET_SUPPORTED_SUITES: 954 { 955 return "B_GET_SUPPORTED_SUITES"; 956 } 957 case B_UNDO: 958 { 959 return "B_UNDO"; 960 } 961 case B_CUT: 962 { 963 return "B_CUT"; 964 } 965 case B_COPY: 966 { 967 return "B_COPY"; 968 } 969 case B_PASTE: 970 { 971 return "B_PASTE"; 972 } 973 case B_SELECT_ALL: 974 { 975 return "B_SELECT_ALL"; 976 } 977 case B_SAVE_REQUESTED: 978 { 979 return "B_SAVE_REQUESTED"; 980 } 981 case B_MESSAGE_NOT_UNDERSTOOD: 982 { 983 return "B_MESSAGE_NOT_UNDERSTOOD"; 984 } 985 case B_NO_REPLY: 986 { 987 return "B_NO_REPLY"; 988 } 989 case B_REPLY: 990 { 991 return "B_REPLY"; 992 } 993 case B_SIMPLE_DATA: 994 { 995 return "B_SIMPLE_DATA"; 996 } 997 case B_MIME_DATA: 998 { 999 return "B_MIME_DATA"; 1000 } 1001 case B_ARCHIVED_OBJECT: 1002 { 1003 return "B_ARCHIVED_OBJECT"; 1004 } 1005 case B_UPDATE_STATUS_BAR: 1006 { 1007 return "B_UPDATE_STATUS_BAR"; 1008 } 1009 case B_RESET_STATUS_BAR: 1010 { 1011 return "B_RESET_STATUS_BAR"; 1012 } 1013 case B_NODE_MONITOR: 1014 { 1015 return "B_NODE_MONITOR"; 1016 } 1017 case B_QUERY_UPDATE: 1018 { 1019 return "B_QUERY_UPDATE"; 1020 } 1021 case B_ENDORSABLE: 1022 { 1023 return "B_ENDORSABLE"; 1024 } 1025 case B_COPY_TARGET: 1026 { 1027 return "B_COPY_TARGET"; 1028 } 1029 case B_MOVE_TARGET: 1030 { 1031 return "B_MOVE_TARGET"; 1032 } 1033 case B_TRASH_TARGET: 1034 { 1035 return "B_TRASH_TARGET"; 1036 } 1037 case B_LINK_TARGET: 1038 { 1039 return "B_LINK_TARGET"; 1040 } 1041 case B_INPUT_DEVICES_CHANGED: 1042 { 1043 return "B_INPUT_DEVICES_CHANGED"; 1044 } 1045 case B_INPUT_METHOD_EVENT: 1046 { 1047 return "B_INPUT_METHOD_EVENT"; 1048 } 1049 case B_WINDOW_MOVE_TO: 1050 { 1051 return "B_WINDOW_MOVE_TO"; 1052 } 1053 case B_WINDOW_MOVE_BY: 1054 { 1055 return "B_WINDOW_MOVE_BY"; 1056 } 1057 case B_SILENT_RELAUNCH: 1058 { 1059 return "B_SILENT_RELAUNCH"; 1060 } 1061 case B_OBSERVER_NOTICE_CHANGE: 1062 { 1063 return "B_OBSERVER_NOTICE_CHANGE"; 1064 } 1065 case B_CONTROL_INVOKED: 1066 { 1067 return "B_CONTROL_INVOKED"; 1068 } 1069 case B_CONTROL_MODIFIED: 1070 { 1071 return "B_CONTROL_MODIFIED"; 1072 } 1073 default: 1074 { 1075 return "Unknown"; 1076 } 1077 } 1078 } 1079 #endif //DEBUG_BPORTLINK 1080 1081 1082