int main(int argc, char *argv[]) { Display *display = NULL; char *host = "localhost"; int port = 9090; display = OpenDisplay("localhost", 9090); if (display == NULL) { fprintf(stderr, "Unable to connect to display %s:%d\n", host, port); exit(1); } /* Register Callbacks */ RegisterCallback(display, ExposeEventType, expose_event, NULL); RegisterCallback(display, SetupEventType, setup, NULL); RegisterCallback(display, MouseMoveEventType, mouse_move, NULL); MainLoop(display); CloseDisplay(display); free(eyes); free(pupils); return 0; }
/** Create a new task bar tray component. */ TrayComponentType *CreateTaskBar() { TrayComponentType *cp; TaskBarType *tp; tp = Allocate(sizeof(TaskBarType)); tp->next = bars; bars = tp; tp->itemHeight = 0; tp->itemWidth = 0; tp->userHeight = 0; tp->maxItemWidth = 0; tp->layout = LAYOUT_HORIZONTAL; tp->mousex = -settings.doubleClickDelta; tp->mousey = -settings.doubleClickDelta; tp->mouseTime.seconds = 0; tp->mouseTime.ms = 0; cp = CreateTrayComponent(); cp->object = tp; tp->cp = cp; cp->SetSize = SetSize; cp->Create = Create; cp->Resize = Resize; cp->ProcessButtonPress = ProcessTaskButtonEvent; cp->ProcessMotionEvent = ProcessTaskMotionEvent; RegisterCallback(settings.popupDelay / 2, SignalTaskbar, tp); return cp; }
/** Create a button tray component. */ TrayComponentType *CreateTrayButton(const char *iconName, const char *label, const char *popup, unsigned int width, unsigned int height) { TrayButtonType *bp; TrayComponentType *cp; if(JUNLIKELY((label == NULL || strlen(label) == 0) && (iconName == NULL || strlen(iconName) == 0))) { Warning(_("no icon or label for TrayButton")); return NULL; } bp = Allocate(sizeof(TrayButtonType)); bp->next = buttons; buttons = bp; bp->icon = NULL; bp->iconName = CopyString(iconName); bp->label = CopyString(label); bp->actions = NULL; bp->popup = CopyString(popup); cp = CreateTrayComponent(); cp->object = bp; bp->cp = cp; cp->requestedWidth = width; cp->requestedHeight = height; bp->mousex = -settings.doubleClickDelta; bp->mousey = -settings.doubleClickDelta; cp->Create = Create; cp->Destroy = Destroy; cp->SetSize = SetSize; cp->Resize = Resize; cp->Redraw = Draw; cp->ProcessButtonPress = ProcessButtonPress; cp->ProcessButtonRelease = ProcessButtonRelease; if(popup || label) { cp->ProcessMotionEvent = ProcessMotionEvent; } RegisterCallback(settings.popupDelay / 2, SignalTrayButton, bp); return cp; }
bool CallbackManager::RegisterCallback(const std::string &name, PyObject *pycb, PyObject *pycb_data) { bool retval = false; StringSubjectMap::iterator it = nameToSubject.find(name); if(it != nameToSubject.end()) { retval = RegisterCallback(it->second, pycb, pycb_data); } else cerr << "Could not register callback " << name.c_str() << endl; return retval; }
/** Update window state information. */ void UpdateState(ClientNode *np) { const char alreadyMapped = (np->state.status & STAT_MAPPED) ? 1 : 0; const char active = (np->state.status & STAT_ACTIVE) ? 1 : 0; /* Remove from the layer list. */ if(np->prev != NULL) { np->prev->next = np->next; } else { Assert(nodes[np->state.layer] == np); nodes[np->state.layer] = np->next; } if(np->next != NULL) { np->next->prev = np->prev; } else { Assert(nodeTail[np->state.layer] == np); nodeTail[np->state.layer] = np->prev; } /* Read the state (and new layer). */ if(np->state.status & STAT_URGENT) { UnregisterCallback(SignalUrgent, np); } np->state = ReadWindowState(np->window, alreadyMapped); if(np->state.status & STAT_URGENT) { RegisterCallback(URGENCY_DELAY, SignalUrgent, np); } /* We don't handle mapping the window, so restore its mapped state. */ if(!alreadyMapped) { np->state.status &= ~STAT_MAPPED; } /* Add to the layer list. */ np->prev = NULL; np->next = nodes[np->state.layer]; if(np->next == NULL) { nodeTail[np->state.layer] = np; } else { np->next->prev = np; } nodes[np->state.layer] = np; if(active) { FocusClient(np); } }
/** Create a clock tray component. */ TrayComponentType *CreateClock(const char *format, const char *zone, int width, int height) { TrayComponentType *cp; ClockType *clk; clk = Allocate(sizeof(ClockType)); clk->next = clocks; clocks = clk; clk->mousex = -settings.doubleClickDelta; clk->mousey = -settings.doubleClickDelta; clk->mouseTime.seconds = 0; clk->mouseTime.ms = 0; clk->userWidth = 0; if(!format) { format = DEFAULT_FORMAT; } clk->format = CopyString(format); clk->zone = CopyString(zone); clk->actions = NULL; memset(&clk->lastTime, 0, sizeof(clk->lastTime)); cp = CreateTrayComponent(); cp->object = clk; clk->cp = cp; if(width > 0) { cp->requestedWidth = width; clk->userWidth = 1; } else { cp->requestedWidth = 0; clk->userWidth = 0; } cp->requestedHeight = height; cp->Create = Create; cp->Resize = Resize; cp->Destroy = Destroy; cp->ProcessButtonPress = ProcessClockButtonPress; cp->ProcessButtonRelease = ProcessClockButtonRelease; cp->ProcessMotionEvent = ProcessClockMotionEvent; RegisterCallback(Min(900, settings.popupDelay / 2), SignalClock, clk); return cp; }
/** Create an empty tray. */ TrayType *CreateTray(void) { TrayType *tp; tp = Allocate(sizeof(TrayType)); tp->requestedX = 0; tp->requestedY = -1; tp->x = 0; tp->y = -1; tp->requestedWidth = 0; tp->requestedHeight = 0; tp->width = 0; tp->height = 0; tp->layer = DEFAULT_TRAY_LAYER; tp->layout = LAYOUT_HORIZONTAL; tp->valign = TALIGN_FIXED; tp->halign = TALIGN_FIXED; tp->autoHide = THIDE_OFF; tp->hidden = 0; tp->window = None; tp->components = NULL; tp->componentsTail = NULL; tp->next = trays; trays = tp; RegisterCallback(100, SignalTray, tp); return tp; }
/** Move a client window. */ char MoveClient(ClientNode *np, int startx, int starty, int snap) { XEvent event; int oldx, oldy; int doMove; int north, south, east, west; int height; int hmax, vmax; Assert(np); if(!(np->state.border & BORDER_MOVE)) { return 0; } if(np->state.status & STAT_FULLSCREEN) { return 0; } GrabMouseForMove(); RegisterCallback(0, SignalMove, NULL); np->controller = MoveController; shouldStopMove = 0; oldx = np->x; oldy = np->y; vmax = 0; hmax = 0; if(!(GetMouseMask() & (Button1Mask | Button2Mask))) { StopMove(np, 0, oldx, oldy, 0, 0); return 0; } GetBorderSize(&np->state, &north, &south, &east, &west); startx -= west; starty -= north; currentClient = np; atTop = 0; atBottom = 0; atLeft = 0; atRight = 0; doMove = 0; for(;;) { WaitForEvent(&event); if(shouldStopMove) { np->controller = NULL; SetDefaultCursor(np->parent); UnregisterCallback(SignalMove, NULL); return doMove; } switch(event.type) { case ButtonRelease: if(event.xbutton.button == Button1 || event.xbutton.button == Button2) { StopMove(np, doMove, oldx, oldy, hmax, vmax); return doMove; } break; case MotionNotify: DiscardMotionEvents(&event, np->window); np->x = event.xmotion.x_root - startx; np->y = event.xmotion.y_root - starty; GetCurrentTime(&moveTime); atLeft = 0; atTop = 0; atRight = 0; atBottom = 0; if(event.xmotion.x_root == 0) { atLeft = 1; } else if(event.xmotion.x_root == rootWidth - 1) { atRight = 1; } if(event.xmotion.y_root == 0) { atTop = 1; } else if(event.xmotion.y_root == rootHeight - 1) { atBottom = 1; } if(snap) { DoSnap(np); } if(!doMove && (abs(np->x - oldx) > MOVE_DELTA || abs(np->y - oldy) > MOVE_DELTA)) { if(np->state.status & (STAT_HMAX | STAT_VMAX)) { if(np->state.status & STAT_HMAX) { hmax = 1; } if(np->state.status & STAT_VMAX) { vmax = 1; } MaximizeClient(np, 0, 0); startx = np->width / 2; starty = -north / 2; MoveMouse(np->parent, startx, starty); } CreateMoveWindow(np); doMove = 1; } if(doMove) { if(settings.moveMode == MOVE_OUTLINE) { ClearOutline(); height = north + south; if(!(np->state.status & STAT_SHADED)) { height += np->height; } DrawOutline(np->x - west, np->y - north, np->width + west + east, height); } else { JXMoveWindow(display, np->parent, np->x - west, np->y - north); SendConfigureEvent(np); } UpdateMoveWindow(np); UpdatePager(); } break; default: break; } } }
/// \brief /// Operator to register a callback. Same as RegisterCallback(pHandler). inline VCallback* operator += (IVisCallbackHandler_cl *pHandler) { RegisterCallback(pHandler); return this; }
/// \brief /// Operator to register a callback. Same as RegisterCallback(pHandler). inline VCallback& operator += (IVisCallbackHandler_cl &pHandler) { RegisterCallback(&pHandler); return *this; }
static int Start(dtaudio_output_t *aout) { SLresult result; aout_sys_t *sys = (aout_sys_t *) aout->ao_priv; dtaudio_para_t *para = &aout->para; // configure audio source - this defines the number of samples you can enqueue. SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, OPENSLES_BUFFERS }; int mask; if (para->dst_channels > 1) mask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else mask = SL_SPEAKER_FRONT_CENTER; SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = para->dst_channels; //format_pcm.samplesPerSec = ((SLuint32) para->dst_samplerate * 1000) ; format_pcm.samplesPerSec = ((SLuint32) convertSampleRate(para->dst_samplerate)); format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; format_pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; format_pcm.channelMask = mask; format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; SLDataSource audioSrc = {&loc_bufq, &format_pcm}; // configure audio sink SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, sys->outputMixObject }; SLDataSink audioSnk = {&loc_outmix, NULL}; //create audio player const SLInterfaceID ids2[] = {sys->SL_IID_ANDROIDSIMPLEBUFFERQUEUE, sys->SL_IID_VOLUME}; static const SLboolean req2[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc, &audioSnk, sizeof(ids2) / sizeof(*ids2), ids2, req2); if (unlikely(result != SL_RESULT_SUCCESS)) { // error return -1; /* Try again with a more sensible samplerate */ #if 0 fmt->i_rate = 44100; format_pcm.samplesPerSec = ((SLuint32) 44100 * 1000) ; result = CreateAudioPlayer(sys->engineEngine, &sys->playerObject, &audioSrc, &audioSnk, sizeof(ids2) / sizeof(*ids2), ids2, req2); #endif } CHECK_OPENSL_ERROR("Failed to create audio player"); result = Realize(sys->playerObject, SL_BOOLEAN_FALSE); CHECK_OPENSL_ERROR("Failed to realize player object."); result = GetInterface(sys->playerObject, sys->SL_IID_PLAY, &sys->playerPlay); CHECK_OPENSL_ERROR("Failed to get player interface."); result = GetInterface(sys->playerObject, sys->SL_IID_VOLUME, &sys->volumeItf); CHECK_OPENSL_ERROR("failed to get volume interface."); result = GetInterface(sys->playerObject, sys->SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &sys->playerBufferQueue); CHECK_OPENSL_ERROR("Failed to get buff queue interface"); result = RegisterCallback(sys->playerBufferQueue, PlayedCallback, (void *) aout); CHECK_OPENSL_ERROR("Failed to register buff queue callback."); // set the player's state to playing result = SetPlayState(sys->playerPlay, SL_PLAYSTATE_PLAYING); CHECK_OPENSL_ERROR("Failed to switch to playing state"); /* XXX: rounding shouldn't affect us at normal sampling rate */ sys->rate = para->dst_samplerate; sys->samples_per_buf = OPENSLES_BUFLEN * para->dst_samplerate / 1000; sys->buf = malloc(OPENSLES_BUFFERS * sys->samples_per_buf * bytesPerSample(aout)); if (!sys->buf) goto error; sys->started = 0; sys->next_buf = 0; sys->samples = 0; SetPositionUpdatePeriod(sys->playerPlay, AOUT_MIN_PREPARE_TIME * 1000 / CLOCK_FREQ); return 0; error: if (sys->playerObject) { Destroy(sys->playerObject); sys->playerObject = NULL; } return -1; }
/** Startup popups. */ void StartupPopup(void) { popup.text = NULL; popup.window = None; RegisterCallback(100, SignalPopup, NULL); }
/** Move a client window (keyboard or menu initiated). */ char MoveClientKeyboard(ClientNode *np) { XEvent event; int oldx, oldy; int moved; int height; int north, south, east, west; MaxFlags maxFlags; Assert(np); if(!(np->state.border & BORDER_MOVE)) { return 0; } if(np->state.status & STAT_FULLSCREEN) { return 0; } maxFlags = np->state.maxFlags; if(np->state.maxFlags != MAX_NONE) { MaximizeClient(np, MAX_NONE); } if(JUNLIKELY(JXGrabKeyboard(display, np->parent, True, GrabModeAsync, GrabModeAsync, CurrentTime))) { Debug("MoveClient: could not grab keyboard"); return 0; } GrabMouseForMove(); GetBorderSize(&np->state, &north, &south, &east, &west); oldx = np->x; oldy = np->y; RegisterCallback(0, SignalMove, NULL); np->controller = MoveController; shouldStopMove = 0; CreateMoveWindow(np); UpdateMoveWindow(np); MoveMouse(rootWindow, np->x, np->y); DiscardMotionEvents(&event, np->window); if(np->state.status & STAT_SHADED) { height = 0; } else { height = np->height; } for(;;) { WaitForEvent(&event); if(shouldStopMove) { np->controller = NULL; SetDefaultCursor(np->parent); UnregisterCallback(SignalMove, NULL); return 1; } moved = 0; if(event.type == KeyPress) { DiscardKeyEvents(&event, np->window); switch(GetKey(&event.xkey) & 0xFF) { case KEY_UP: if(np->y + height > 0) { np->y -= 10; } break; case KEY_DOWN: if(np->y < rootHeight) { np->y += 10; } break; case KEY_RIGHT: if(np->x < rootWidth) { np->x += 10; } break; case KEY_LEFT: if(np->x + np->width > 0) { np->x -= 10; } break; default: StopMove(np, 1, oldx, oldy, maxFlags); return 1; } MoveMouse(rootWindow, np->x, np->y); DiscardMotionEvents(&event, np->window); moved = 1; } else if(event.type == MotionNotify) { DiscardMotionEvents(&event, np->window); np->x = event.xmotion.x; np->y = event.xmotion.y; moved = 1; } else if(event.type == ButtonRelease) { StopMove(np, 1, oldx, oldy, maxFlags); return 1; } if(moved) { if(settings.moveMode == MOVE_OUTLINE) { ClearOutline(); DrawOutline(np->x - west, np->y - west, np->width + west + east, height + north + west); } else { JXMoveWindow(display, np->parent, np->x - west, np->y - north); SendConfigureEvent(np); } UpdateMoveWindow(np); RequirePagerUpdate(); } } }
HRESULT InitializeTAPI() { LogMessage("InitializeTAPI: started"); HRESULT hr = E_FAIL; // // cocreate the TAPI object // hr = CoCreateInstance( CLSID_TAPI, NULL, CLSCTX_INPROC_SERVER, IID_ITTAPI, (LPVOID *)&g_pTapi ); if (FAILED(hr)) { LogError("InitializeTAPI: failed to CoCreateInstance TAPI"); return hr; } // // cannot use tapi until it's initialized // hr = g_pTapi->Initialize(); if (FAILED(hr)) { LogError("InitializeTAPI: TAPI failed to initialize"); g_pTapi->Release(); g_pTapi = NULL; return hr; } // // register the callback object that will receive tapi notifications // hr = RegisterCallback(); if (FAILED(hr)) { LogError("InitializeTAPI: failed to register callback"); g_pTapi->Shutdown(); g_pTapi->Release(); g_pTapi = NULL; return hr; } // // we want to be notified of these events: // hr = g_pTapi->put_EventFilter(TE_CALLNOTIFICATION | TE_CALLSTATE | TE_CALLMEDIA); if (FAILED(hr)) { LogError("InitializeTAPI: Failed to put_EventFilter"); // // unregister callback // UnRegisterCallBack(); // // shutdown and release TAPI // g_pTapi->Shutdown(); g_pTapi->Release(); g_pTapi = NULL; return hr; } // // start listening on the addresses that support audio // hr = StartListening(); if (S_OK != hr) { LogError("InitializeTAPI: Failed to start listening"); // // unregister callback // UnRegisterCallBack(); // // shutdown and release TAPI // g_pTapi->Shutdown(); g_pTapi->Release(); g_pTapi = NULL; return hr; } LogMessage("InitializeTAPI: succeeded"); return S_OK; }
/** Add a window to management. */ ClientNode *AddClientWindow(Window w, char alreadyMapped, char notOwner) { XWindowAttributes attr; ClientNode *np; Assert(w != None); /* Get window attributes. */ if(JXGetWindowAttributes(display, w, &attr) == 0) { return NULL; } /* Determine if we should care about this window. */ if(attr.override_redirect == True) { return NULL; } if(attr.class == InputOnly) { return NULL; } /* Prepare a client node for this window. */ np = Allocate(sizeof(ClientNode)); memset(np, 0, sizeof(ClientNode)); np->window = w; np->owner = None; np->state.desktop = currentDesktop; np->x = attr.x; np->y = attr.y; np->width = attr.width; np->height = attr.height; np->cmap = attr.colormap; np->state.status = STAT_NONE; np->state.maxFlags = MAX_NONE; np->state.layer = LAYER_NORMAL; np->state.defaultLayer = LAYER_NORMAL; np->state.border = BORDER_DEFAULT; np->borderAction = BA_NONE; ReadClientInfo(np, alreadyMapped); if(!notOwner) { np->state.border = BORDER_OUTLINE | BORDER_TITLE | BORDER_MOVE; np->state.status |= STAT_WMDIALOG | STAT_STICKY; np->state.layer = LAYER_ABOVE; np->state.defaultLayer = LAYER_ABOVE; } ApplyGroups(np); if(np->icon == NULL) { LoadIcon(np); } /* We now know the layer, so insert */ np->prev = NULL; np->next = nodes[np->state.layer]; if(np->next) { np->next->prev = np; } else { nodeTail[np->state.layer] = np; } nodes[np->state.layer] = np; SetDefaultCursor(np->window); ReparentClient(np, notOwner); PlaceClient(np, alreadyMapped); if(!((np->state.status & STAT_FULLSCREEN) || np->state.maxFlags)) { int north, south, east, west; GetBorderSize(&np->state, &north, &south, &east, &west); if(np->parent != None) { JXMoveResizeWindow(display, np->parent, np->x - west, np->y - north, np->width + east + west, np->height + north + south); JXMoveResizeWindow(display, np->window, west, north, np->width, np->height); } else { JXMoveResizeWindow(display, np->window, np->x, np->y, np->width, np->height); } } /* If one of these fails we are SOL, so who cares. */ XSaveContext(display, np->window, clientContext, (void*)np); if(np->parent != None) { XSaveContext(display, np->parent, frameContext, (void*)np); } if(np->state.status & STAT_MAPPED) { JXMapWindow(display, np->window); if(np->parent != None) { JXMapWindow(display, np->parent); } } clientCount += 1; if(!alreadyMapped) { RaiseClient(np); } if(np->state.status & STAT_OPACITY) { SetOpacity(np, np->state.opacity, 1); } else { SetOpacity(np, settings.inactiveClientOpacity, 1); } if(np->state.status & STAT_STICKY) { SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, ~0UL); } else { SetCardinalAtom(np->window, ATOM_NET_WM_DESKTOP, np->state.desktop); } /* Shade the client if requested. */ if(np->state.status & STAT_SHADED) { np->state.status &= ~STAT_SHADED; ShadeClient(np); } /* Minimize the client if requested. */ if(np->state.status & STAT_MINIMIZED) { np->state.status &= ~STAT_MINIMIZED; MinimizeClient(np, 0); } /* Maximize the client if requested. */ if(np->state.maxFlags) { const MaxFlags flags = np->state.maxFlags; np->state.maxFlags = MAX_NONE; MaximizeClient(np, flags); } if(np->state.status & STAT_URGENT) { RegisterCallback(URGENCY_DELAY, SignalUrgent, np); } /* Update task bars. */ AddClientToTaskBar(np); /* Make sure we're still in sync */ WriteState(np); SendConfigureEvent(np); /* Hide the client if we're not on the right desktop. */ if(np->state.desktop != currentDesktop && !(np->state.status & STAT_STICKY)) { HideClient(np); } ReadClientStrut(np); /* Focus transients if their parent has focus. */ if(np->owner != None) { if(activeClient && np->owner == activeClient->window) { FocusClient(np); } } /* Make the client fullscreen if requested. */ if(np->state.status & STAT_FULLSCREEN) { np->state.status &= ~STAT_FULLSCREEN; SetClientFullScreen(np, 1); } ResetBorder(np); return np; }
NTSTATUS DeviceControl ( _In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp ) /*++ Routine Description: Dispatches ioctl requests. Arguments: DeviceObject - The device object receiving the request. Irp - The request packet. Return Value: Status returned from the method called. --*/ { PIO_STACK_LOCATION IrpStack; ULONG Ioctl; NTSTATUS Status; UNREFERENCED_PARAMETER(DeviceObject); Status = STATUS_SUCCESS; IrpStack = IoGetCurrentIrpStackLocation(Irp); Ioctl = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (Ioctl) { case IOCTL_DO_KERNELMODE_SAMPLES: Status = DoCallbackSamples(DeviceObject, Irp); break; case IOCTL_REGISTER_CALLBACK: Status = RegisterCallback(DeviceObject, Irp); break; case IOCTL_UNREGISTER_CALLBACK: Status = UnRegisterCallback(DeviceObject, Irp); break; case IOCTL_GET_CALLBACK_VERSION: Status = GetCallbackVersion(DeviceObject, Irp); break; default: ErrorPrint("Unrecognized ioctl code 0x%x", Ioctl); } // // Complete the irp and return. // Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
void CallbacksRequestProducts::RegisterCallbacks(s3eCallback onSuccess, s3eCallback onFailure, s3eCallback onCancel) { RegisterCallback(onSuccess, &m_onSuccess, S3E_ODK_CALLBACKS_REQUEST_PRODUCTS_ON_SUCCESS); RegisterCallback(onFailure, &m_onFailure, S3E_ODK_CALLBACKS_REQUEST_PRODUCTS_ON_FAILURE); RegisterCallback(onCancel, &m_onCancel, S3E_ODK_CALLBACKS_REQUEST_PRODUCTS_ON_CANCEL); }
PD2MMF::PD2MMF() { RegisterCallback(NEWSTATE_CALLBACK, (CallbackFunction)&PD2MMF::LuaNewState, this); RegisterCallback(REQUIRE_CALLBACK, (CallbackFunction)&PD2MMF::LuaPostRequire, this); }
/** Move a client window. */ char MoveClient(ClientNode *np, int startx, int starty) { XEvent event; int oldx, oldy; int doMove; int north, south, east, west; int height; MaxFlags maxFlags; Assert(np); if(!(np->state.border & BORDER_MOVE)) { return 0; } if(np->state.status & STAT_FULLSCREEN) { return 0; } GrabMouseForMove(); RegisterCallback(0, SignalMove, NULL); np->controller = MoveController; shouldStopMove = 0; oldx = np->x; oldy = np->y; maxFlags = np->state.maxFlags; if(!(GetMouseMask() & (Button1Mask | Button2Mask))) { StopMove(np, 0, oldx, oldy, maxFlags); return 0; } GetBorderSize(&np->state, &north, &south, &east, &west); startx -= west; starty -= north; currentClient = np; atTop = atBottom = atLeft = atRight = 0; doMove = 0; for(;;) { WaitForEvent(&event); if(shouldStopMove) { np->controller = NULL; SetDefaultCursor(np->parent); UnregisterCallback(SignalMove, NULL); return doMove; } switch(event.type) { case ButtonRelease: if(event.xbutton.button == Button1 || event.xbutton.button == Button2) { StopMove(np, doMove, oldx, oldy, maxFlags); return doMove; } break; case MotionNotify: DiscardMotionEvents(&event, np->window); np->x = event.xmotion.x_root - startx; np->y = event.xmotion.y_root - starty; /* Get the move time used for desktop switching. */ if(!(atLeft | atTop | atRight | atBottom)) { if(event.xmotion.state & Mod1Mask) { moveTime.seconds = 0; moveTime.ms = 0; } else { GetCurrentTime(&moveTime); } } /* Determine if we are at a border for desktop switching. */ atLeft = atTop = atRight = atBottom = 0; if(event.xmotion.x_root == 0) { atLeft = 1; } else if(event.xmotion.x_root == rootWidth - 1) { atRight = 1; } if(event.xmotion.y_root == 0) { atTop = 1; } else if(event.xmotion.y_root == rootHeight - 1) { atBottom = 1; } if(event.xmotion.state & Mod1Mask) { /* Switch desktops immediately if alt is pressed. */ if(atLeft | atRight | atTop | atBottom) { TimeType now; GetCurrentTime(&now); UpdateDesktop(&now); } } else { /* If alt is not pressed, snap to borders. */ DoSnap(np); } if(!doMove && (abs(np->x - oldx) > MOVE_DELTA || abs(np->y - oldy) > MOVE_DELTA)) { if(np->state.maxFlags) { MaximizeClient(np, MAX_NONE); startx = np->width / 2; starty = -north / 2; MoveMouse(np->parent, startx, starty); } CreateMoveWindow(np); doMove = 1; } if(doMove) { if(settings.moveMode == MOVE_OUTLINE) { ClearOutline(); height = north + south; if(!(np->state.status & STAT_SHADED)) { height += np->height; } DrawOutline(np->x - west, np->y - north, np->width + west + east, height); } else { JXMoveWindow(display, np->parent, np->x - west, np->y - north); SendConfigureEvent(np); } UpdateMoveWindow(np); RequirePagerUpdate(); } break; default: break; } } }
/** Handle a property notify event. */ char HandlePropertyNotify(const XPropertyEvent *event) { ClientNode *np = FindClientByWindow(event->window); if(np) { char changed = 0; switch(event->atom) { case XA_WM_NAME: ReadWMName(np); changed = 1; break; case XA_WM_NORMAL_HINTS: ReadWMNormalHints(np); if(ConstrainSize(np)) { ResetBorder(np); } changed = 1; break; case XA_WM_HINTS: if(np->state.status & STAT_URGENT) { UnregisterCallback(SignalUrgent, np); } ReadWMHints(np->window, &np->state, 1); if(np->state.status & STAT_URGENT) { RegisterCallback(URGENCY_DELAY, SignalUrgent, np); } WriteState(np); break; case XA_WM_TRANSIENT_FOR: JXGetTransientForHint(display, np->window, &np->owner); break; case XA_WM_ICON_NAME: case XA_WM_CLIENT_MACHINE: break; default: if(event->atom == atoms[ATOM_WM_COLORMAP_WINDOWS]) { ReadWMColormaps(np); UpdateClientColormap(np); } else if(event->atom == atoms[ATOM_WM_PROTOCOLS]) { ReadWMProtocols(np->window, &np->state); } else if(event->atom == atoms[ATOM_NET_WM_ICON]) { LoadIcon(np); changed = 1; } else if(event->atom == atoms[ATOM_NET_WM_NAME]) { ReadWMName(np); changed = 1; } else if(event->atom == atoms[ATOM_NET_WM_STRUT_PARTIAL]) { ReadClientStrut(np); } else if(event->atom == atoms[ATOM_NET_WM_STRUT]) { ReadClientStrut(np); } else if(event->atom == atoms[ATOM_MOTIF_WM_HINTS]) { UpdateState(np); WriteState(np); ResetBorder(np); changed = 1; } else if(event->atom == atoms[ATOM_NET_WM_WINDOW_OPACITY]) { ReadWMOpacity(np->window, &np->state.opacity); if(np->parent != None) { SetOpacity(np, np->state.opacity, 1); } } break; } if(changed) { DrawBorder(np); RequireTaskUpdate(); RequirePagerUpdate(); } if(np->state.status & STAT_WMDIALOG) { return 0; } else { return 1; } } return 1; }