Sono anni che non codifico su Amiga e non mi ricordo molto dei nomi dei campi delle strutture e delle API di base...
Il sorgente l'ho scritto di getto senza controllarlo approfonditamente.
showExposé()
{
unsigned int openedWindows, windowIndex;
unsigned int squareSide, squareWidth, squareHeight, targetX,targetY;
unsigned int loop;
unsigned long event;
struct Screen *ActiveScreen,*ExposéScreen;
struct NewScreen newExposéScreen;
struct Window *win,*ExposéWindow;
struct NewWindow newExposéWindow;
ActiveScreen = IntuitionBase->ActiveScreen;
newExposéScreen.Title = "Exposé Screen";
newExposéScreen.width = ActiveScreen->width
newExposéScreen.height= ActiveScreen->height;
newExposéScreen.depth = ActiveScreen->depth;
newExposéWindow.Title = "Exposé Window";
newExposéWindow.width = ActiveScreen->width
newExposéWindow.height= ActiveScreen->height;
newExposéWindow.depth = ActiveScreen->depth;
newExposéWindow.flags = BORDERLESS | BACKDROP;
//Count opened windows
openedWindows=0;
for (win = ActiveScreen->FirstWindow; win!=NULL; win=win->NextWindow)
openedWindows++;
//Compute square side
if (openedWindows>0)
{
squareSide = round(Log( openedWindows ) / Log(2));
squareWidth = round(newExposéScreen.width / squareSide);
squareHeight= round(newExposéScreen.height/ squareSide);
}
else
Exit( OK ); // no windows to show
//Open Exposé main screen
ExposéScreen = OpenScreen( &newExposéScreen );
if (ExposéScreen==NULL) Exit( ERROR_NO_SCREEN );
//Open Exposé main window
newExposéWindow.screen = ExposéScreen;
ExposéWindow = OpenWindow( &newExposéWindow );
if (ExposéWindow==NULL) { CloseScreen(ExposéScreen); Exit( ERROR_NO_WINDOW ); }
//Copy & Resize windows bitmap to Exposé screen
for (win = ActiveScreen->FirstWindow; win!=NULL; win=win->NextWindow)
{
//Compute offsets
targetX = (windowIndex / squareSide)*((ExposéWindow->width)/squareSide);
targetY = (windowIndex % squareSide)*((ExposéWindow->height)/squareSide);
//Copy Gfx Data
BitBlt(win->Bitmap,0,0,win->width, win->height, //Source
ExposéWindow->Bitmap, targetX, targetY, //Destination
targetX+(win->width)/squareSide, targetY+(win->height)/squareSide, COPY_AND_RESIZE);
windowIndex++;
}
//Highlight top left square first
prevX = (0 / squareSide)*((ExposéWindow->width)/squareSide);
prevY = (0 % squareSide)*((ExposéWindow->height)/squareSide);
//Wait user selection
loop = 1;
while (loop)
{
wait(ExposéWindow->MessagePort->mp_SignalBit);
event = ExposéWindow->MessagePort->mp_SignalBit & EVENT_MASK;
switch (event)
{
case MOUSEMOVE:
windowIndex = (ExposéScreen->mouseX / ExposéScreen->width) * squareSide;
windowIndex += (ExposéScreen->mouseY / ExposéScreen->height) * squareSide; // *2 ???
DrawFrame(ExposéWindow->RastPort,prevX,prevY,
prevX+(ExposéWindow->width)/squareSide,prevY+(ExposéWindow->height)/squareSide,COMPLEMENT_PEN);
targetX = (windowIndex / squareSide)*((ExposéWindow->width)/squareSide);
targetY = (windowIndex % squareSide)*((ExposéWindow->height)/squareSide);
prevX = targetX;
prevY = targetY;
DrawFrame(ExposéWindow->RastPort,prevX,prevY,
prevX+(ExposéWindow->width)/squareSide,prevY+(ExposéWindow->height)/squareSide,COMPLEMENT_PEN);
break;
case MOUSECLICK:
loop=0;
}
}
//Bring to front selected window
openedWindows=0;
for (win = ActiveScreen->FirstWindow; win!=NULL; win=win->NextWindow)
{
if (windowIndex==openedWindows) {
ScreenToFront(win->screen);
WindowToFront(win);
break;
}
openedWindows++;
}
//Close Exposé window and custom screen
CloseWindow(ExposéWindow);
CloseScreen(ExposéScreen);
Exit( OK );
}