void Settings::UpdateFrom(BMessage* message) { BPoint point; if (message->FindPoint("window_location", &point) == B_OK) { fMessage.RemoveName("window_location"); fMessage.AddPoint("window_location", point); } BString langName; // We make sure there is at least one string before erasing the previous // settings, then we add the remaining ones, if any if (message->FindString("language", &langName) == B_OK) { // Remove any old data as we know we have newer one to replace it fMessage.RemoveName("language"); for (int i = 0;; i++) { if (message->FindString("language", i, &langName) != B_OK) break; fMessage.AddString("language", langName); } } if (message->FindString("country",&langName) == B_OK) fMessage.ReplaceString("country", langName); fUpdated = true; }
void CannaMethod::WriteSettings() { BMessage pref; BFile preffile( CANNAIM_SETTINGS_FILE, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE ); if ( preffile.InitCheck() == B_NO_ERROR ) { pref.AddBool( "arrowkey", gSettings.convert_arrowkey ); pref.AddPoint( "palette", gSettings.palette_loc ); pref.AddPoint( "standalone", gSettings.standalone_loc ); pref.Flatten( &preffile ); #ifdef DEBUG SERIAL_PRINT(( "CannaMethod: WriteSettings() success. arrowkey=%d, palette_loc=%d,%d standalone_loc=%d, %d\n", gSettings.convert_arrowkey, gSettings.palette_loc.x, gSettings.palette_loc.y, gSettings.standalone_loc.x, gSettings.standalone_loc.y )); #endif } }
/** Mouse click scenarios. */ void AlbumView::MouseDown(BPoint where) { // This is an event hook so there must be a Looper. BMessage *message = Window()->CurrentMessage(); int32 mods = 0, clicks = 0, buttons=0; message->FindInt32("modifiers", &mods); message->FindInt32("clicks", &clicks); message->FindInt32("buttons", &buttons); // Scale back. where.x /= fZoom; where.y /= fZoom; int32 i = IndexOf(&where); int32 changes = 0; if (i >= 0) { AlbumItem *item = ItemAt(i); // double-clicks are handled later in MouseUp() fDoubleClick = (fLastSelected == i && clicks == 2 && (buttons & B_PRIMARY_MOUSE_BUTTON)); fMayDrag = !fDoubleClick && (buttons & B_PRIMARY_MOUSE_BUTTON); if (mods & B_SHIFT_KEY) // Block selection changes += SelectBlock(fLastSelected, i, !item->IsSelected()); else if (mods & B_COMMAND_KEY) // Modify selection changes += Select(i, 1, !item->IsSelected()); else { // Normal selection if (!item->IsSelected()) changes += DeselectAll(); changes += Select(i); } fLastWhere = where; fLastSelected = i; } else changes += DeselectAll(); if (changes > 0) { //PRINT(("selection changed\n")); SelectionChanged(); if (!fDoubleClick && Message()) { BMessage msg = *Message(); msg.AddInt32("buttons", buttons); msg.AddPoint("where", where); msg.AddInt32("index", fLastSelected); Invoke(&msg); } } }
int32 MouseWatcher(void* data) { BMessenger* TheMessenger = (BMessenger*)data; BPoint PreviousPos; uint32 PreviousButtons; bool FirstCheck = true; BMessage MessageToSend; MessageToSend.AddPoint("where",BPoint(0,0)); MessageToSend.AddInt32("buttons",0); MessageToSend.AddInt32("modifiers",0); while(true) { if (!TheMessenger->LockTarget()) { delete TheMessenger; return 0; // window is dead so exit } BLooper *TheLooper; BView* TheView = (BView*)TheMessenger->Target(&TheLooper); BPoint Where; uint32 Buttons; TheView->GetMouse(&Where,&Buttons,false); if(FirstCheck) { PreviousPos = Where; PreviousButtons = Buttons; FirstCheck = false; } bool Send = false; if(Buttons != PreviousButtons || Buttons == 0 || Where != PreviousPos) { if(Buttons == 0) MessageToSend.what = MW_MOUSE_UP; else if(Buttons != PreviousButtons) MessageToSend.what = MW_MOUSE_DOWN; else MessageToSend.what = MW_MOUSE_MOVED; MessageToSend.ReplacePoint("where",Where); MessageToSend.ReplaceInt32("buttons",Buttons); MessageToSend.ReplaceInt32("modifiers",modifiers()); Send = true; } TheLooper->Unlock(); if(Send) TheMessenger->SendMessage(&MessageToSend); if(Buttons == 0) { //Button was released delete TheMessenger; return 0; } snooze(50000); } }
void NSBrowserFrameView::MouseDown(BPoint where) { BMessage *message = Window()->DetachCurrentMessage(); BPoint screenWhere; if (message->FindPoint("screen_where", &screenWhere) < B_OK) { screenWhere = ConvertToScreen(where); message->AddPoint("screen_where", screenWhere); } nsbeos_pipe_message(message, this, fGuiWindow); }
void DeskbarView::MouseUp(BPoint point) { uint32 buttons = lastButtons; BMessage *mes = new BMessage('TRAY'); mes->AddInt32("event",TRAY_MOUSEUP); mes->AddPoint("point",ConvertToScreen(point)); mes->AddInt32("buttons",buttons); mes->AddInt32("clicks",1); mes->AddData("qtrayobject",B_ANY_TYPE,&traysysobject,sizeof(void*)); ReplyMessenger.SendMessage(mes); }
void TCueSheetWindow::SetPanelOpen(bool theVal) { fPanelOpen = theVal; if (fPanelOpen == false) { BPoint where; where.x = 0; BMessage* message = new BMessage(UPDATE_TIMELINE_MSG); message->AddPoint("Where", where); message->AddInt32("TheTime", GetCurrentTime()); fTimeline->MessageReceived(message); delete message; } }
void BViewState::ArchiveToMessage(BMessage &message) const { message.AddInt32(kViewStateVersionName, kViewStateArchiveVersion); message.AddInt32(kViewStateViewModeName, static_cast<int32>(fViewMode)); message.AddInt32(kViewStateLastIconModeName, static_cast<int32>(fLastIconMode)); message.AddPoint(kViewStateListOriginName, fListOrigin); message.AddPoint(kViewStateIconOriginName, fIconOrigin); message.AddInt32(kViewStatePrimarySortAttrName, static_cast<int32>(fPrimarySortAttr)); message.AddInt32(kViewStatePrimarySortTypeName, static_cast<int32>(fPrimarySortType)); message.AddInt32(kViewStateSecondarySortAttrName, static_cast<int32>(fSecondarySortAttr)); message.AddInt32(kViewStateSecondarySortTypeName, static_cast<int32>(fSecondarySortType)); message.AddBool(kViewStateReverseSortName, fReverseSort); }
void DeskbarView::MouseDown(BPoint point) { uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons"); int32 clicks = Window()->CurrentMessage()->FindInt32("clicks"); lastButtons = buttons; BMessage *mes = new BMessage('TRAY'); mes->AddInt32("event",TRAY_MOUSEDOWN); mes->AddPoint("point",ConvertToScreen(point)); mes->AddInt32("buttons",buttons); mes->AddInt32("clicks",clicks); mes->AddData("qtrayobject",B_ANY_TYPE,&traysysobject,sizeof(void*)); ReplyMessenger.SendMessage(mes); }
FontsSettings::~FontsSettings() { BPath path; BMessage msg; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK) return; path.Append(kSettingsFile); BFile file(path.Path(), B_WRITE_ONLY|B_CREATE_FILE); if (file.InitCheck() == B_OK) { msg.AddPoint("windowlocation", fCorner); msg.Flatten(&file); } }
void TBarApp::SaveSettings() { if (fSettingsFile->InitCheck() == B_OK) { fSettingsFile->Seek(0, SEEK_SET); BMessage prefs; prefs.AddBool("vertical", fSettings.vertical); prefs.AddBool("left", fSettings.left); prefs.AddBool("top", fSettings.top); prefs.AddInt32("state", fSettings.state); prefs.AddFloat("width", fSettings.width); prefs.AddPoint("switcherLoc", fSettings.switcherLoc); prefs.AddBool("showClock", fSettings.showClock); // applications prefs.AddBool("trackerAlwaysFirst", fSettings.trackerAlwaysFirst); prefs.AddBool("sortRunningApps", fSettings.sortRunningApps); prefs.AddBool("superExpando", fSettings.superExpando); prefs.AddBool("expandNewTeams", fSettings.expandNewTeams); prefs.AddBool("hideLabels", fSettings.hideLabels); prefs.AddInt32("iconSize", fSettings.iconSize); // recent items prefs.AddBool("recentDocsEnabled", fSettings.recentDocsEnabled); prefs.AddBool("recentFoldersEnabled", fSettings.recentFoldersEnabled); prefs.AddBool("recentAppsEnabled", fSettings.recentAppsEnabled); prefs.AddInt32("recentDocsCount", fSettings.recentDocsCount); prefs.AddInt32("recentFoldersCount", fSettings.recentFoldersCount); prefs.AddInt32("recentAppsCount", fSettings.recentAppsCount); // window prefs.AddBool("alwaysOnTop", fSettings.alwaysOnTop); prefs.AddBool("autoRaise", fSettings.autoRaise); prefs.AddBool("autoHide", fSettings.autoHide); prefs.Flatten(fSettingsFile); } if (fClockSettingsFile->InitCheck() == B_OK) { fClockSettingsFile->Seek(0, SEEK_SET); BMessage prefs; prefs.AddBool("showSeconds", fClockSettings.showSeconds); prefs.AddBool("showDayOfWeek", fClockSettings.showDayOfWeek); prefs.AddBool("showTimeZone", fClockSettings.showTimeZone); prefs.Flatten(fClockSettingsFile); } }
void TCueSheetWindow::WindowActivated( bool activate) { // Move indicator tick offscreen to hide it if ( activate == false ) { BPoint where; where.x = 0; BMessage* message = new BMessage(UPDATE_TIMELINE_MSG); message->AddPoint("Where", where); message->AddInt32("TheTime", GetCurrentTime()); fTimeline->MessageReceived(message); delete message; } else { // Tell stage to end edit mode BMessage* theMessage = new BMessage(END_STAGE_EDIT_MSG); fStageWindow->PostMessage(theMessage, fStageWindow->GetStageView()); delete theMessage; } /* if (activate) { // Show stage fStageWindow->Lock(); if (fStageWindow->IsHidden()) fStageWindow->Show(); fStageWindow->Unlock(); // We are now the main Cue Sheet if ( static_cast<MuseumApp *>(be_app)->GetCueSheet() != this ) static_cast<MuseumApp *>(be_app)->SetCueSheet(this); } else { fStageWindow->Lock(); if (fStageWindow->IsHidden() == false) { if ( IsHidden() ) fStageWindow->Hide(); } fStageWindow->Unlock(); } */ BWindow::WindowActivated(activate); }
void ResizeView::MouseMoved (BPoint, uint32, const BMessage *) { SetViewCursor (&cursor); if (mousePressed) { BWindow *window (Window ()); BMessage *windowmsg (window->CurrentMessage()); BPoint windowCoord; windowmsg->FindPoint ("where", &windowCoord); BMessage msg (kResizeMessage); if (windowCoord.x <= 0.0 || windowCoord.x >= window->Bounds().right) return; msg.AddPoint ("loc", windowCoord); msg.AddPointer ("view", attachedView); BMessenger(window).SendMessage (&msg); } }
void TBarApp::SaveSettings() { if (fSettingsFile->InitCheck() == B_OK) { fSettingsFile->Seek(0, SEEK_SET); BMessage storedSettings; storedSettings.AddBool("vertical", fSettings.vertical); storedSettings.AddBool("left", fSettings.left); storedSettings.AddBool("top", fSettings.top); storedSettings.AddBool("ampmMode", fSettings.ampmMode); storedSettings.AddInt32("state", fSettings.state); storedSettings.AddFloat("width", fSettings.width); storedSettings.AddBool("showTime", fSettings.showTime); storedSettings.AddPoint("switcherLoc", fSettings.switcherLoc); storedSettings.AddInt32("recentAppsCount", fSettings.recentAppsCount); storedSettings.AddInt32("recentDocsCount", fSettings.recentDocsCount); storedSettings.AddBool("timeShowSeconds", fSettings.timeShowSeconds); storedSettings.AddInt32("recentFoldersCount", fSettings.recentFoldersCount); storedSettings.AddBool("alwaysOnTop", fSettings.alwaysOnTop); storedSettings.AddBool("timeFullDate", fSettings.timeFullDate); storedSettings.AddBool("trackerAlwaysFirst", fSettings.trackerAlwaysFirst); storedSettings.AddBool("sortRunningApps", fSettings.sortRunningApps); storedSettings.AddBool("superExpando", fSettings.superExpando); storedSettings.AddBool("expandNewTeams", fSettings.expandNewTeams); storedSettings.AddBool("autoRaise", fSettings.autoRaise); storedSettings.AddBool("autoHide", fSettings.autoHide); storedSettings.AddBool("recentAppsEnabled", fSettings.recentAppsEnabled); storedSettings.AddBool("recentDocsEnabled", fSettings.recentDocsEnabled); storedSettings.AddBool("recentFoldersEnabled", fSettings.recentFoldersEnabled); storedSettings.Flatten(fSettingsFile); } }
void EventDispatcher::_EventLoop() { BMessage* event; while (fStream->GetNextEvent(&event)) { BAutolock _(this); fLastUpdate = system_time(); EventTarget* current = NULL; EventTarget* previous = NULL; bool pointerEvent = false; bool keyboardEvent = false; bool addedTokens = false; switch (event->what) { case kFakeMouseMoved: _SendFakeMouseMoved(event); break; case B_MOUSE_MOVED: { BPoint where; if (event->FindPoint("where", &where) == B_OK) fLastCursorPosition = where; if (fDraggingMessage) event->AddMessage("be:drag_message", &fDragMessage); if (!HasCursorThread()) { // There is no cursor thread, we need to move the cursor // ourselves BAutolock _(fCursorLock); if (fHWInterface != NULL) { fHWInterface->MoveCursorTo(fLastCursorPosition.x, fLastCursorPosition.y); } } // This is for B_NO_POINTER_HISTORY - we always want the // latest mouse moved event in the queue only if (fNextLatestMouseMoved == NULL) fNextLatestMouseMoved = fStream->PeekLatestMouseMoved(); else if (fNextLatestMouseMoved != event) { // Drop older mouse moved messages if the server is lagging // too much (if the message is older than 100 msecs) bigtime_t eventTime; if (event->FindInt64("when", &eventTime) == B_OK) { if (system_time() - eventTime > 100000) break; } } // supposed to fall through } case B_MOUSE_DOWN: case B_MOUSE_UP: { #ifdef TRACE_EVENTS if (event->what != B_MOUSE_MOVED) printf("mouse up/down event, previous target = %p\n", fPreviousMouseTarget); #endif pointerEvent = true; if (fMouseFilter == NULL) break; EventTarget* mouseTarget = fPreviousMouseTarget; int32 viewToken = B_NULL_TOKEN; if (fMouseFilter->Filter(event, &mouseTarget, &viewToken, fNextLatestMouseMoved) == B_SKIP_MESSAGE) { // this is a work-around if the wrong B_MOUSE_UP // event is filtered out if (event->what == B_MOUSE_UP && event->FindInt32("buttons") == 0) { fSuspendFocus = false; _RemoveTemporaryListeners(); } break; } int32 buttons; if (event->FindInt32("buttons", &buttons) == B_OK) fLastButtons = buttons; else fLastButtons = 0; // The "where" field will be filled in by the receiver // (it's supposed to be expressed in local window coordinates) event->RemoveName("where"); event->AddPoint("screen_where", fLastCursorPosition); if (event->what == B_MOUSE_MOVED && fPreviousMouseTarget != NULL && mouseTarget != fPreviousMouseTarget) { // Target has changed, we need to notify the previous target // that the mouse has exited its views addedTokens = _AddTokens(event, fPreviousMouseTarget, B_POINTER_EVENTS); if (addedTokens) _SetFeedFocus(event); _SendMessage(fPreviousMouseTarget->Messenger(), event, kMouseTransitImportance); previous = fPreviousMouseTarget; } current = fPreviousMouseTarget = mouseTarget; if (current != NULL) { int32 focusView = viewToken; addedTokens |= _AddTokens(event, current, B_POINTER_EVENTS, fNextLatestMouseMoved, &focusView); bool noPointerHistoryFocus = focusView != viewToken; if (viewToken != B_NULL_TOKEN) event->AddInt32("_view_token", viewToken); if (addedTokens && !noPointerHistoryFocus) _SetFeedFocus(event); else if (noPointerHistoryFocus) { // No tokens were added or the focus shouldn't get a // mouse moved break; } _SendMessage(current->Messenger(), event, event->what == B_MOUSE_MOVED ? kMouseMovedImportance : kStandardImportance); } break; } case B_KEY_DOWN: case B_KEY_UP: case B_UNMAPPED_KEY_DOWN: case B_UNMAPPED_KEY_UP: case B_MODIFIERS_CHANGED: case B_INPUT_METHOD_EVENT: ETRACE(("key event, focus = %p\n", fFocus)); if (fKeyboardFilter != NULL && fKeyboardFilter->Filter(event, &fFocus) == B_SKIP_MESSAGE) break; keyboardEvent = true; if (fFocus != NULL && _AddTokens(event, fFocus, B_KEYBOARD_EVENTS)) { // if tokens were added, we need to explicetly suspend // focus in the event - if not, the event is simply not // forwarded to the target addedTokens = true; if (!fSuspendFocus) _SetFeedFocus(event); } // supposed to fall through default: // TODO: the keyboard filter sets the focus - ie. no other // focus messages that go through the event dispatcher can // go through. if (event->what == B_MOUSE_WHEEL_CHANGED) current = fPreviousMouseTarget; else current = fFocus; if (current != NULL && (!fSuspendFocus || addedTokens)) { _SendMessage(current->Messenger(), event, kStandardImportance); } break; } if (keyboardEvent || pointerEvent) { // send the event to the additional listeners if (addedTokens) { _RemoveTokens(event); _UnsetFeedFocus(event); } if (pointerEvent) { // this is added in the Desktop mouse processing // but it's only intended for the focus view event->RemoveName("_view_token"); } for (int32 i = fTargets.CountItems(); i-- > 0;) { EventTarget* target = fTargets.ItemAt(i); // We already sent the event to the all focus and last focus // tokens if (current == target || previous == target) continue; // Don't send the message if there are no tokens for this event if (!_AddTokens(event, target, keyboardEvent ? B_KEYBOARD_EVENTS : B_POINTER_EVENTS, event->what == B_MOUSE_MOVED ? fNextLatestMouseMoved : NULL)) continue; if (!_SendMessage(target->Messenger(), event, event->what == B_MOUSE_MOVED ? kMouseMovedImportance : kListenerImportance)) { // the target doesn't seem to exist anymore, let's remove it fTargets.RemoveItemAt(i); } } if (event->what == B_MOUSE_UP && fLastButtons == 0) { // no buttons are pressed anymore fSuspendFocus = false; _RemoveTemporaryListeners(); if (fDraggingMessage) _DeliverDragMessage(); } } if (fNextLatestMouseMoved == event) fNextLatestMouseMoved = NULL; delete event; } // The loop quit, therefore no more events are coming from the input // server, it must have died. Unset ourselves and notify the desktop. fThread = -1; // Needed to avoid problems with wait_for_thread in _Unset() _Unset(); if (fDesktop) fDesktop->PostMessage(AS_EVENT_STREAM_CLOSED); }
int setNPprefs_byscript(int enableproxies) { BMessage reply; const char *s; status_t r; // open the prefs window { BMessage message; // set the command constant message.what = B_EXECUTE_PROPERTY; // construct the specifier stack message.AddSpecifier("MenuItem","Preferences…"); message.AddSpecifier("Menu","Edit"); message.AddSpecifier("MenuBar"); message.AddSpecifier("Window", _0); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; } snooze(10000); // select the "Proxies" tab { BMessage message; // set the command constant message.what = B_MOUSE_DOWN; message.AddInt32("modifiers",0); message.AddInt32("buttons",B_PRIMARY_MOUSE_BUTTON); message.AddInt32("clicks",1); message.AddPoint("be:view_where",BPoint(150,16)); // construct the specifier stack message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window","Preferences"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='NONE') return reply.what; } // check that "Enable Proxies" is where we expect it { BMessage message; // set the command constant message.what = B_GET_PROPERTY; // construct the specifier stack message.AddSpecifier("Label"); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; // check the result if(reply.FindString("result",&s) || strcmp(s,"Enable Proxies")) return -1; } // set "Enable Proxies" { BMessage message; // set the command constant message.what = B_SET_PROPERTY; // construct the specifier stack message.AddSpecifier("Value"); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // specify the data message.AddInt32("data", enableproxies); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; } // check that "HTTP" is where we expect it { BMessage message; // set the command constant message.what = B_GET_PROPERTY; // construct the specifier stack message.AddSpecifier("Label"); message.AddSpecifier("View",1); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; // check the result if(reply.FindString("result",&s) || strcmp(s,"HTTP:")) return -1; } // set "HTTP" { BMessage message; // set the command constant message.what = B_SET_PROPERTY; // construct the specifier stack message.AddSpecifier("Value"); message.AddSpecifier("View",1); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // specify the data message.AddString("data", "127.0.0.1"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; } // check that "Port" is where we expect it { BMessage message; // set the command constant message.what = B_GET_PROPERTY; // construct the specifier stack message.AddSpecifier("Label"); message.AddSpecifier("View",2); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; // check the result if(reply.FindString("result",&s) || strcmp(s,"Port:")) return -1; } // set "Port" { BMessage message; // set the command constant message.what = B_SET_PROPERTY; // construct the specifier stack message.AddSpecifier("Value"); message.AddSpecifier("View",2); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // specify the data message.AddString("data", "8080"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; } // check that "OK" is where we expect it { BMessage message; // set the command constant message.what = B_GET_PROPERTY; // construct the specifier stack message.AddSpecifier("Label"); message.AddSpecifier("View",2); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; // check the result if(reply.FindString("result",&s) || strcmp(s,"OK")) return -1; } // click "OK" { BMessage message; // set the command constant message.what = B_SET_PROPERTY; // construct the specifier stack message.AddSpecifier("Value"); message.AddSpecifier("View",2); message.AddSpecifier("View",_0); message.AddSpecifier("Window", "Preferences"); // specify the data message.AddInt32("data", 1); // send the message and fetch the result r=BMessenger(appsig).SendMessage(&message, &reply); if(r) return r; if(reply.what!='RPLY') return reply.what; } return 0; }
bool CanvasEventStream::EventReceived(CanvasMessage& message) { uint16 code = message.Code(); uint32 what = 0; switch (code) { case RP_MOUSE_MOVED: what = B_MOUSE_MOVED; break; case RP_MOUSE_DOWN: what = B_MOUSE_DOWN; break; case RP_MOUSE_UP: what = B_MOUSE_UP; break; case RP_MOUSE_WHEEL_CHANGED: what = B_MOUSE_WHEEL_CHANGED; break; case RP_KEY_DOWN: what = B_KEY_DOWN; break; case RP_KEY_UP: what = B_KEY_UP; break; case RP_MODIFIERS_CHANGED: what = B_MODIFIERS_CHANGED; break; } if (what == 0) return false; BMessage* event = new BMessage(what); if (event == NULL) return false; event->AddInt64("when", system_time()); switch (code) { case RP_MOUSE_MOVED: case RP_MOUSE_DOWN: case RP_MOUSE_UP: { message.Read(fMousePosition); if (code != RP_MOUSE_MOVED) message.Read(fMouseButtons); event->AddPoint("where", fMousePosition); event->AddInt32("buttons", fMouseButtons); event->AddInt32("modifiers", fModifiers); if (code == RP_MOUSE_DOWN) { int32 clicks; if (message.Read(clicks) == B_OK) event->AddInt32("clicks", clicks); } if (code == RP_MOUSE_MOVED) fLatestMouseMovedEvent = event; break; } case RP_MOUSE_WHEEL_CHANGED: { float xDelta, yDelta; message.Read(xDelta); message.Read(yDelta); event->AddFloat("be:wheel_delta_x", xDelta); event->AddFloat("be:wheel_delta_y", yDelta); break; } case RP_KEY_DOWN: case RP_KEY_UP: { int32 numBytes; if (message.Read(numBytes) != B_OK) break; char* bytes = (char*)malloc(numBytes + 1); if (bytes == NULL) break; if (message.ReadList(bytes, numBytes) != B_OK) { free(bytes); break; } for (int32 i = 0; i < numBytes; i++) event->AddInt8("byte", (int8)bytes[i]); bytes[numBytes] = 0; event->AddData("bytes", B_STRING_TYPE, bytes, numBytes + 1, false); event->AddInt32("modifiers", fModifiers); int32 rawChar; if (message.Read(rawChar) == B_OK) event->AddInt32("raw_char", rawChar); int32 key; if (message.Read(key) == B_OK) event->AddInt32("key", key); free(bytes); break; } case RP_MODIFIERS_CHANGED: { event->AddInt32("be:old_modifiers", fModifiers); message.Read(fModifiers); event->AddInt32("modifiers", fModifiers); break; } } BAutolock lock(fEventListLocker); fEventList.AddItem(event); if (fWaitingOnEvent) { fWaitingOnEvent = false; lock.Unlock(); release_sem(fEventNotification); } return true; }
void RemoteView::_DrawThread() { RemoteMessage reply(NULL, fSendBuffer); RemoteMessage message(fReceiveBuffer, NULL); // cursor BPoint cursorHotSpot(0, 0); while (!fStopThread) { uint16 code; status_t status = message.NextMessage(code); if (status != B_OK) { TRACE_ERROR("failed to read message from receiver\n"); break; } TRACE("code %u with %ld bytes data\n", code, message.DataLeft()); BAutolock locker(this->Looper()); if (!locker.IsLocked()) break; // handle stuff that doesn't go to a specicifc engine switch (code) { case RP_INIT_CONNECTION: { uint16 port; status_t result = message.Read(port); if (result != B_OK) { TRACE_ERROR("failed to read remote port\n"); continue; } BNetEndpoint *endpoint = fReceiver->Endpoint(); if (endpoint == NULL) { TRACE_ERROR("receiver not connected anymore\n"); continue; } in_addr remoteHost; char hostName[MAXHOSTNAMELEN + 1]; BNetAddress address(endpoint->RemoteAddr()); address.GetAddr(remoteHost); address.GetAddr(hostName, NULL); address.SetTo(remoteHost, port); TRACE("connecting to host \"%s\" port %u\n", hostName, port); result = fSendEndpoint->Connect(address); if (result != B_OK) { TRACE_ERROR("failed to connect to host \"%s\" port %u\n", hostName, port); continue; } BRect bounds = fOffscreenBitmap->Bounds(); reply.Start(RP_UPDATE_DISPLAY_MODE); reply.Add(bounds.IntegerWidth() + 1); reply.Add(bounds.IntegerHeight() + 1); if (reply.Flush() == B_OK) fIsConnected = true; continue; } case RP_CLOSE_CONNECTION: { be_app->PostMessage(B_QUIT_REQUESTED); continue; } case RP_CREATE_STATE: case RP_DELETE_STATE: { uint32 token; message.Read(token); if (code == RP_CREATE_STATE) _CreateState(token); else _DeleteState(token); continue; } case RP_SET_CURSOR: { BBitmap *bitmap; BPoint oldHotSpot = cursorHotSpot; message.Read(cursorHotSpot); if (message.ReadBitmap(&bitmap) != B_OK) continue; delete fCursorBitmap; fCursorBitmap = bitmap; Invalidate(fCursorFrame); BRect bounds = fCursorBitmap->Bounds(); fCursorFrame.right = fCursorFrame.left + bounds.IntegerWidth() + 1; fCursorFrame.bottom = fCursorFrame.bottom + bounds.IntegerHeight() + 1; fCursorFrame.OffsetBy(oldHotSpot - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_SET_CURSOR_VISIBLE: { bool wasVisible = fCursorVisible; message.Read(fCursorVisible); if (wasVisible != fCursorVisible) Invalidate(fCursorFrame); continue; } case RP_MOVE_CURSOR_TO: { BPoint position; message.Read(position); if (fCursorVisible) Invalidate(fCursorFrame); fCursorFrame.OffsetTo(position - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_INVALIDATE_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; Invalidate(rect); continue; } case RP_INVALIDATE_REGION: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; Invalidate(®ion); continue; } case RP_FILL_REGION_COLOR_NO_CLIPPING: { BRegion region; rgb_color color; message.ReadRegion(region); if (message.Read(color) != B_OK) continue; fOffscreen->LockLooper(); fOffscreen->SetHighColor(color); fOffscreen->FillRegion(®ion); fOffscreen->UnlockLooper(); Invalidate(®ion); continue; } case RP_COPY_RECT_NO_CLIPPING: { int32 xOffset, yOffset; BRect rect; message.Read(xOffset); message.Read(yOffset); if (message.Read(rect) != B_OK) continue; BRect dest = rect.OffsetByCopy(xOffset, yOffset); fOffscreen->LockLooper(); fOffscreen->CopyBits(rect, dest); fOffscreen->UnlockLooper(); continue; } } uint32 token; message.Read(token); engine_state *state = _FindState(token); if (state == NULL) { TRACE_ERROR("didn't find state for token %lu\n", token); continue; } BView *offscreen = state->view; ::pattern &pattern = state->pattern; BRegion &clippingRegion = state->clipping_region; float &penSize = state->pen_size; bool &syncDrawing = state->sync_drawing; BRegion invalidRegion; BAutolock offscreenLocker(offscreen->Looper()); if (!offscreenLocker.IsLocked()) break; switch (code) { case RP_ENABLE_SYNC_DRAWING: syncDrawing = true; continue; case RP_DISABLE_SYNC_DRAWING: syncDrawing = false; continue; case RP_SET_OFFSETS: { int32 xOffset, yOffset; message.Read(xOffset); if (message.Read(yOffset) != B_OK) continue; offscreen->MovePenTo(xOffset, yOffset); break; } case RP_SET_HIGH_COLOR: case RP_SET_LOW_COLOR: { rgb_color color; if (message.Read(color) != B_OK) continue; if (code == RP_SET_HIGH_COLOR) offscreen->SetHighColor(color); else offscreen->SetLowColor(color); break; } case RP_SET_PEN_SIZE: { float newPenSize; if (message.Read(newPenSize) != B_OK) continue; offscreen->SetPenSize(newPenSize); penSize = newPenSize / 2; break; } case RP_SET_STROKE_MODE: { cap_mode capMode; join_mode joinMode; float miterLimit; message.Read(capMode); message.Read(joinMode); if (message.Read(miterLimit) != B_OK) continue; offscreen->SetLineMode(capMode, joinMode, miterLimit); break; } case RP_SET_BLENDING_MODE: { source_alpha sourceAlpha; alpha_function alphaFunction; message.Read(sourceAlpha); if (message.Read(alphaFunction) != B_OK) continue; offscreen->SetBlendingMode(sourceAlpha, alphaFunction); break; } case RP_SET_PATTERN: { if (message.Read(pattern) != B_OK) continue; break; } case RP_SET_DRAWING_MODE: { drawing_mode drawingMode; if (message.Read(drawingMode) != B_OK) continue; offscreen->SetDrawingMode(drawingMode); break; } case RP_SET_FONT: { BFont font; if (message.ReadFontState(font) != B_OK) continue; offscreen->SetFont(&font); break; } case RP_CONSTRAIN_CLIPPING_REGION: { if (message.ReadRegion(clippingRegion) != B_OK) continue; offscreen->ConstrainClippingRegion(&clippingRegion); break; } case RP_INVERT_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; offscreen->InvertRect(rect); invalidRegion.Include(rect); break; } case RP_DRAW_BITMAP: { BBitmap *bitmap; BRect bitmapRect, viewRect; uint32 options; message.Read(bitmapRect); message.Read(viewRect); message.Read(options); if (message.ReadBitmap(&bitmap) != B_OK || bitmap == NULL) continue; offscreen->DrawBitmap(bitmap, bitmapRect, viewRect, options); invalidRegion.Include(viewRect); delete bitmap; break; } case RP_DRAW_BITMAP_RECTS: { color_space colorSpace; int32 rectCount; uint32 flags, options; message.Read(options); message.Read(colorSpace); message.Read(flags); message.Read(rectCount); for (int32 i = 0; i < rectCount; i++) { BBitmap *bitmap; BRect viewRect; message.Read(viewRect); if (message.ReadBitmap(&bitmap, true, colorSpace, flags) != B_OK || bitmap == NULL) { continue; } offscreen->DrawBitmap(bitmap, bitmap->Bounds(), viewRect, options); invalidRegion.Include(viewRect); delete bitmap; } break; } case RP_STROKE_ARC: case RP_FILL_ARC: case RP_FILL_ARC_GRADIENT: { BRect rect; float angle, span; message.Read(rect); message.Read(angle); if (message.Read(span) != B_OK) continue; if (code == RP_STROKE_ARC) { offscreen->StrokeArc(rect, angle, span, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ARC) offscreen->FillArc(rect, angle, span, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillArc(rect, angle, span, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_BEZIER: case RP_FILL_BEZIER: case RP_FILL_BEZIER_GRADIENT: { BPoint points[4]; if (message.ReadList(points, 4) != B_OK) continue; BRect bounds = _BuildInvalidateRect(points, 4); if (code == RP_STROKE_BEZIER) { offscreen->StrokeBezier(points, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_BEZIER) offscreen->FillBezier(points, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillBezier(points, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_ELLIPSE: case RP_FILL_ELLIPSE: case RP_FILL_ELLIPSE_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_ELLIPSE) { offscreen->StrokeEllipse(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ELLIPSE) offscreen->FillEllipse(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillEllipse(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_POLYGON: case RP_FILL_POLYGON: case RP_FILL_POLYGON_GRADIENT: { BRect bounds; bool closed; int32 numPoints; message.Read(bounds); message.Read(closed); if (message.Read(numPoints) != B_OK) continue; BPoint points[numPoints]; for (int32 i = 0; i < numPoints; i++) message.Read(points[i]); if (code == RP_STROKE_POLYGON) { offscreen->StrokePolygon(points, numPoints, bounds, closed, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_POLYGON) offscreen->FillPolygon(points, numPoints, bounds, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillPolygon(points, numPoints, bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_RECT: case RP_FILL_RECT: case RP_FILL_RECT_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_RECT) { offscreen->StrokeRect(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_RECT) offscreen->FillRect(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRect(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_ROUND_RECT: case RP_FILL_ROUND_RECT: case RP_FILL_ROUND_RECT_GRADIENT: { BRect rect; float xRadius, yRadius; message.Read(rect); message.Read(xRadius); if (message.Read(yRadius) != B_OK) continue; if (code == RP_STROKE_ROUND_RECT) { offscreen->StrokeRoundRect(rect, xRadius, yRadius, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ROUND_RECT) offscreen->FillRoundRect(rect, xRadius, yRadius, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRoundRect(rect, xRadius, yRadius, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_SHAPE: case RP_FILL_SHAPE: case RP_FILL_SHAPE_GRADIENT: { BRect bounds; int32 opCount, pointCount; message.Read(bounds); if (message.Read(opCount) != B_OK) continue; BMessage archive; for (int32 i = 0; i < opCount; i++) { int32 op; message.Read(op); archive.AddInt32("ops", op); } if (message.Read(pointCount) != B_OK) continue; for (int32 i = 0; i < pointCount; i++) { BPoint point; message.Read(point); archive.AddPoint("pts", point); } BPoint offset; message.Read(offset); float scale; if (message.Read(scale) != B_OK) continue; offscreen->PushState(); offscreen->MovePenTo(offset); offscreen->SetScale(scale); BShape shape(&archive); if (code == RP_STROKE_SHAPE) { offscreen->StrokeShape(&shape, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_SHAPE) offscreen->FillShape(&shape, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) { offscreen->PopState(); continue; } offscreen->FillShape(&shape, *gradient); delete gradient; } offscreen->PopState(); invalidRegion.Include(bounds); break; } case RP_STROKE_TRIANGLE: case RP_FILL_TRIANGLE: case RP_FILL_TRIANGLE_GRADIENT: { BRect bounds; BPoint points[3]; message.ReadList(points, 3); if (message.Read(bounds) != B_OK) continue; if (code == RP_STROKE_TRIANGLE) { offscreen->StrokeTriangle(points[0], points[1], points[2], bounds, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_TRIANGLE) { offscreen->FillTriangle(points[0], points[1], points[2], bounds, pattern); } else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillTriangle(points[0], points[1], points[2], bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_LINE: { BPoint points[2]; if (message.ReadList(points, 2) != B_OK) continue; offscreen->StrokeLine(points[0], points[1], pattern); BRect bounds = _BuildInvalidateRect(points, 2); invalidRegion.Include(bounds.InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_ARRAY: { int32 numLines; if (message.Read(numLines) != B_OK) continue; BRect bounds; offscreen->BeginLineArray(numLines); for (int32 i = 0; i < numLines; i++) { rgb_color color; BPoint start, end; message.ReadArrayLine(start, end, color); offscreen->AddLine(start, end, color); bounds.left = min_c(bounds.left, min_c(start.x, end.x)); bounds.top = min_c(bounds.top, min_c(start.y, end.y)); bounds.right = max_c(bounds.right, max_c(start.x, end.x)); bounds.bottom = max_c(bounds.bottom, max_c(start.y, end.y)); } offscreen->EndLineArray(); invalidRegion.Include(bounds); break; } case RP_FILL_REGION: case RP_FILL_REGION_GRADIENT: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; if (code == RP_FILL_REGION) offscreen->FillRegion(®ion, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRegion(®ion, *gradient); delete gradient; } invalidRegion.Include(®ion); break; } case RP_STROKE_POINT_COLOR: { BPoint point; rgb_color color; message.Read(point); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); offscreen->StrokeLine(point, point); offscreen->SetHighColor(oldColor); invalidRegion.Include( BRect(point, point).InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_1PX_COLOR: { BPoint points[2]; rgb_color color; message.ReadList(points, 2); if (message.Read(color) != B_OK) continue; float oldSize = offscreen->PenSize(); rgb_color oldColor = offscreen->HighColor(); drawing_mode oldMode = offscreen->DrawingMode(); offscreen->SetPenSize(1); offscreen->SetHighColor(color); offscreen->SetDrawingMode(B_OP_OVER); offscreen->StrokeLine(points[0], points[1]); offscreen->SetDrawingMode(oldMode); offscreen->SetHighColor(oldColor); offscreen->SetPenSize(oldSize); invalidRegion.Include(_BuildInvalidateRect(points, 2)); break; } case RP_STROKE_RECT_1PX_COLOR: case RP_FILL_RECT_COLOR: { BRect rect; rgb_color color; message.Read(rect); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); if (code == RP_STROKE_RECT_1PX_COLOR) { float oldSize = PenSize(); offscreen->SetPenSize(1); offscreen->StrokeRect(rect); offscreen->SetPenSize(oldSize); } else offscreen->FillRect(rect); offscreen->SetHighColor(oldColor); invalidRegion.Include(rect); break; } case RP_DRAW_STRING: { BPoint point; size_t length; char *string; bool hasDelta; message.Read(point); message.ReadString(&string, length); if (message.Read(hasDelta) != B_OK) { free(string); continue; } if (hasDelta) { escapement_delta delta[length]; message.ReadList(delta, length); offscreen->DrawString(string, point, delta); } else offscreen->DrawString(string, point); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); font_height height; offscreen->GetFontHeight(&height); BRect bounds(point, offscreen->PenLocation()); bounds.top -= height.ascent; bounds.bottom += height.descent; invalidRegion.Include(bounds); break; } case RP_DRAW_STRING_WITH_OFFSETS: { size_t length; char *string; message.ReadString(&string, length); int32 count = UTF8CountChars(string, length); BPoint offsets[count]; if (message.ReadList(offsets, count) != B_OK) { free(string); continue; } offscreen->DrawString(string, offsets, count); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); BFont font; offscreen->GetFont(&font); BRect boxes[count]; font.GetBoundingBoxesAsGlyphs(string, count, B_SCREEN_METRIC, boxes); font_height height; offscreen->GetFontHeight(&height); for (int32 i = 0; i < count; i++) { // TODO: validate boxes[i].OffsetBy(offsets[i] + BPoint(0, -height.ascent)); invalidRegion.Include(boxes[i]); } break; } case RP_READ_BITMAP: { BRect bounds; bool drawCursor; message.Read(bounds); if (message.Read(drawCursor) != B_OK) continue; // TODO: support the drawCursor flag BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_RGB32); bitmap.ImportBits(fOffscreenBitmap, bounds.LeftTop(), BPoint(0, 0), bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); reply.Start(RP_READ_BITMAP_RESULT); reply.Add(token); reply.AddBitmap(&bitmap); reply.Flush(); break; } default: TRACE_ERROR("unknown protocol code: %u\n", code); break; } if (syncDrawing) { offscreen->Sync(); Invalidate(&invalidRegion); } } }
int32 MouseDragOrPopupWatcher(void* data) { BMessenger* TheMessenger = (BMessenger*)data; BPoint StartPos; uint32 StartButtons = 0; bigtime_t StartTime = 0; bool FirstCheck = true; BMessage MessageToSend; MessageToSend.AddPoint("where",BPoint(0,0)); MessageToSend.AddInt32("buttons",0); MessageToSend.AddInt32("modifiers",0); bigtime_t PopupTime; if(get_click_speed(&PopupTime) != B_OK) return 0; PopupTime *= 2; while(true) { if (!TheMessenger->LockTarget()) { delete TheMessenger; return 0; // window is dead so exit } BLooper *TheLooper; BView* TheView = (BView*)TheMessenger->Target(&TheLooper); BPoint Where; uint32 Buttons; bigtime_t Time = system_time(); TheView->GetMouse(&Where,&Buttons,false); if(FirstCheck) { StartPos = Where; StartButtons = Buttons; StartTime = Time; FirstCheck = false; } bool Send = false; if(Buttons == 0 || Buttons != StartButtons) { //Changed or released MessageToSend.what = MW_MOUSE_CLICK; Send = true; } else if(Where.x < StartPos.x-1.0 || Where.x > StartPos.x+1.0 || Where.y < StartPos.y-1.0 || Where.y > StartPos.y+1.0) { MessageToSend.what = MW_MOUSE_DRAG; Send = true; } else if(Time >= StartTime + PopupTime) { MessageToSend.what = MW_MOUSE_POPUP; Send = true; } TheLooper->Unlock(); if(Send) { MessageToSend.ReplacePoint("where",StartPos); MessageToSend.ReplaceInt32("buttons",Buttons); MessageToSend.ReplaceInt32("modifiers",modifiers()); TheMessenger->SendMessage(&MessageToSend); delete TheMessenger; return 0; } snooze(50000); } }
void BComboBox::ChoiceListView::MouseDown(BPoint where) { BRect rect(Window()->Frame()); ConvertFromScreen(&rect); if (!rect.Contains(where)) { // hide the popup window when the user clicks outside of it if (fParent->Window()->Lock()) { fParent->HidePopupWindow(); fParent->Window()->Unlock(); } // HACK: the window is locked and unlocked so that it will get // activated before we potentially send the mouse down event in the // code below. Is there a way to wait until the window is activated // before sending the mouse down? Should we call // fParent->Window()->MakeActive(true) here? if (fParent->Window()->Lock()) { // resend the mouse event to the textinput, if necessary BTextView *text = fParent->TextView(); BPoint screenWhere(ConvertToScreen(where)); rect = text->Window()->ConvertToScreen(text->Frame()); if (rect.Contains(screenWhere)) { //printf(" resending mouse down to textinput\n"); BMessage *msg = new BMessage(*Window()->CurrentMessage()); msg->RemoveName("be:view_where"); text->ConvertFromScreen(&screenWhere); msg->AddPoint("be:view_where", screenWhere); text->Window()->PostMessage(msg, text); delete msg; } fParent->Window()->Unlock(); } return; } rect = Bounds(); if (!rect.Contains(where)) return; fTrackingMouseDown = true; // check for double click bigtime_t now = system_time(); bigtime_t clickSpeed; get_click_speed(&clickSpeed); if ((now - fClickTime < clickSpeed) && ((abs((int)(fClickLoc.x - where.x)) < 3) && (abs((int)(fClickLoc.y - where.y)) < 3))) { // this is a double click // XXX: what to do here? printf("BComboBox::ChoiceListView::MouseDown() -- unhandled double click\n"); } fClickTime = now; fClickLoc = where; float h = LineHeight(); int32 oldIndex = fSelIndex; fSelIndex = (int32)floor(where.y / h); int32 choices = fParent->fChoiceList->CountChoices(); if (fSelIndex < 0 || fSelIndex >= choices) fSelIndex = -1; if (oldIndex != fSelIndex) { InvalidateItem(oldIndex); InvalidateItem(fSelIndex); } // XXX: this probably isn't necessary since we are doing a SetEventMask // whenever the popup window becomes visible which routes all mouse events // to this view // SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); }