Exemple #1
0
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;
}
Exemple #2
0
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
	}
}
Exemple #3
0
/**
	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);
    	}
	}
    
    
}
Exemple #4
0
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);
	}
}
Exemple #5
0
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);
}
Exemple #6
0
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;
	}
}
Exemple #8
0
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);
}
Exemple #9
0
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);
   
}
Exemple #10
0
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);
	}
}
Exemple #11
0
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);
	}
}
Exemple #12
0
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);
}
Exemple #13
0
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);
  }
}
Exemple #14
0
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(&region);
				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(&region);
				fOffscreen->UnlockLooper();
				Invalidate(&region);
				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(&region, pattern);
				else {
					BGradient *gradient;
					if (message.ReadGradient(&gradient) != B_OK)
						continue;

					offscreen->FillRegion(&region, *gradient);
					delete gradient;
				}

				invalidRegion.Include(&region);
				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);
	}
}
Exemple #20
0
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);
}