Ejemplo n.º 1
0
/**
  Reorder boot options

  Ask for the boot option to move and then move it when up or down arrows
  are pressed. This function is called when the user selects the "Reorder Boot
  Device Entries" entry in the boot manager menu.
  The order of the boot options in BootOptionList and in the UEFI BootOrder
  global variable are kept coherent until the user confirm his reordering (ie:
  he does not exit by pressing escape).

  @param[in]  BootOptionsList  List of the boot devices constructed in
                               BootMenuMain()

  @retval  EFI_SUCCESS   No error encountered.
  @retval  !EFI_SUCCESS  An error has occured either in the selection of the
                         boot option to move or while interacting with the user.

**/
STATIC
EFI_STATUS
BootMenuReorderBootOptions (
  IN LIST_ENTRY *BootOptionsList
  )
{
  EFI_STATUS              Status;
  BDS_LOAD_OPTION_ENTRY  *BootOptionEntry;
  LIST_ENTRY             *SelectedEntry;
  LIST_ENTRY             *PrevEntry;
  BOOLEAN                 Move;
  BOOLEAN                 Save;
  BOOLEAN                 Cancel;
  UINTN                   WaitIndex;
  EFI_INPUT_KEY           Key;
  LIST_ENTRY             *SecondEntry;
  UINTN                   BootOrderSize;
  UINT16                 *BootOrder;
  LIST_ENTRY             *Entry;
  UINTN                   Index;

  DisplayBootOptions (BootOptionsList);

  // Ask to select the boot option to move
  while (TRUE) {
    Status = SelectBootOption (BootOptionsList, MOVE_BOOT_ENTRY, &BootOptionEntry);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    SelectedEntry = &BootOptionEntry->Link;
    SecondEntry = NULL;
    // Note down the previous entry in the list to be able to cancel changes
    PrevEntry = GetPreviousNode (BootOptionsList, SelectedEntry);

    //  Start of interaction
    while (TRUE) {
      Print (
        L"* Use up/down arrows to move the entry '%s'",
        BootOptionEntry->BdsLoadOption->Description
        );

      // Wait for a move, save or cancel request
      Move   = FALSE;
      Save   = FALSE;
      Cancel = FALSE;
      do {
        Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
        if (!EFI_ERROR (Status)) {
          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
        }
        if (EFI_ERROR (Status)) {
          Print (L"\n");
          goto ErrorExit;
        }

        switch (Key.ScanCode) {
        case SCAN_NULL:
          Save = (Key.UnicodeChar == CHAR_LINEFEED)        ||
                 (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) ||
                 (Key.UnicodeChar == 0x7f);
          break;

        case SCAN_UP:
          SecondEntry = GetPreviousNode (BootOptionsList, SelectedEntry);
          Move = SecondEntry != BootOptionsList;
          break;

        case SCAN_DOWN:
          SecondEntry = GetNextNode (BootOptionsList, SelectedEntry);
          Move = SecondEntry != BootOptionsList;
          break;

        case SCAN_ESC:
          Cancel = TRUE;
          break;
        }
      } while ((!Move) && (!Save) && (!Cancel));

      if (Move) {
        if ((SelectedEntry != NULL) && (SecondEntry != NULL)) {
          SwapListEntries (SelectedEntry, SecondEntry);
        }
      } else {
        if (Save) {
          Status = GetGlobalEnvironmentVariable (
                    L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder
                    );
          BootOrderSize /= sizeof (UINT16);

          if (!EFI_ERROR (Status)) {
            // The order of the boot options in the 'BootOptionsList' is the
            // new order that has been just defined by the user. Save this new
            // order in "BootOrder" UEFI global variable.
            Entry = GetFirstNode (BootOptionsList);
            for (Index = 0; Index < BootOrderSize; Index++) {
              BootOrder[Index] = (LOAD_OPTION_FROM_LINK (Entry))->LoadOptionIndex;
              Entry = GetNextNode (BootOptionsList, Entry);
            }
            Status = gRT->SetVariable (
                           (CHAR16*)L"BootOrder",
                           &gEfiGlobalVariableGuid,
                           EFI_VARIABLE_NON_VOLATILE       |
                           EFI_VARIABLE_BOOTSERVICE_ACCESS |
                           EFI_VARIABLE_RUNTIME_ACCESS,
                           BootOrderSize * sizeof (UINT16),
                           BootOrder
                           );
            FreePool (BootOrder);
          }

          if (EFI_ERROR (Status)) {
            Print (L"\nAn error occurred, move not completed!\n");
            Cancel = TRUE;
          }
        }

        if (Cancel) {
          //
          // Restore initial position of the selected boot option
          //
          RemoveEntryList (SelectedEntry);
          InsertHeadList (PrevEntry, SelectedEntry);
        }
      }

      Print (L"\n");
      DisplayBootOptions (BootOptionsList);
      // Saved or cancelled, back to the choice of boot option to move
      if (!Move) {
        break;
      }
    }
  }

ErrorExit:
  return Status ;
}
Ejemplo n.º 2
0
Archivo: main.c Proyecto: Jasu/HashTWM
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  node *current = NULL;
  node *nodes;
  unsigned short tag;

  switch (msg)
  {
    case WM_CREATE:
      if (experimental_mouse) {
        SetTimer(hwnd, TIMER_UPDATE_MOUSE, 500, NULL); // Poll for mouse position
      }
      break;

    case WM_CLOSE:
      {
        ClipCursor(0); // Release Cursor Lock
        DeregisterShellHookWindow(hwnd);
        UnregisterHotkeys(hwnd);
        if (experimental_mouse) {
          KillTimer(hwnd, TIMER_UPDATE_MOUSE); // Mouse Poll Timer
        }
        for (tag=0; tag<TAGS; tag++) {
          nodes = tags[tag].nodes;
          for (current = nodes; current;) {
            node *next = current->next;
            RestoreWindow(current->hwnd);
            RemoveNode(current->hwnd, tag);
            current = next;
          }
          DestroyWindow(hwnd);
        }
      }
      break;

    case WM_DESTROY:
      PostQuitMessage(WM_QUIT);
      break;

    case WM_HOTKEY:
      if (wParam >= KEY_TOGGLE_T1 && wParam < (KEY_TOGGLE_T1 + TAGS)) {
        ToggleTag(wParam - KEY_TOGGLE_T1);
        break;
      } else if (wParam >= KEY_SWITCH_T1 && wParam < (KEY_SWITCH_T1 + TAGS)) {
        MinimizeTag(current_tag);
        current_tag = wParam - KEY_SWITCH_T1;
        ArrangeWindows();
        break;
      }

      current = tags[current_tag].current_window;

      switch (wParam)
      {
        case KEY_SELECT_UP:
          if (current) {
            tags[current_tag].current_window = GetNextNode();
            FocusCurrent();
          }
          break;

        case KEY_SELECT_DOWN:
          if (current) {
            tags[current_tag].current_window = GetPreviousNode();
            FocusCurrent();
          }
          break;

        case KEY_MOVE_MAIN:
          SwapWindowWithNode(tags[current_tag].nodes);
          ArrangeWindows();
          break;

        case KEY_EXIT:
          PostMessage(hwnd, WM_CLOSE, 0, 0);
          break;

        case KEY_MARGIN_LEFT:
          margin -= 20;
          ArrangeWindows();
          break;

        case KEY_MARGIN_RIGHT:
          margin += 20;
          ArrangeWindows();
          break;

        case KEY_IGNORE:
          if (!disableNext) {
            disableNext = 1;
          } else {
            disableNext = 0;
          }
          break;

        case KEY_MOUSE_LOCK:
          if (lockMouse) {
            lockMouse = 0;
            ClipCursor(0);
          } else {
            lockMouse = 1;
            FocusCurrent();
          }
          break;

        case KEY_TILING_MODE:
          tags[current_tag].tilingMode = (tags[current_tag].tilingMode + 1) % 3;
          ArrangeWindows();
          break;

        case KEY_MOVE_UP:
          if (current) {
            SwapWindowWithNode(GetNextNode());
            ArrangeWindows();
          }
          break;

        case KEY_MOVE_DOWN:
          if (current) {
            SwapWindowWithNode(GetPreviousNode());
            ArrangeWindows();
          }
          break;

        case KEY_DISP_CLASS:
          {
            LPSTR temp = (LPSTR)malloc(sizeof(TCHAR) * 128);
            GetClassName(GetForegroundWindow(), temp, 128);
            MessageBox(NULL, temp, "Window Class", MB_OK);
            free(temp);
          }
          break;

        case KEY_TILE:
          if (IsGoodWindow(GetForegroundWindow())) {
            AddNode(GetForegroundWindow(), current_tag);
            ArrangeWindows();
          }
          break;

        case KEY_UNTILE:
          FullRemoveNode(GetForegroundWindow());
          ArrangeWindows();
          break;

        case KEY_INC_AREA:
          tags[current_tag].masterarea_count++;
          ArrangeWindows();
          break;

        case KEY_DEC_AREA:
          tags[current_tag].masterarea_count--;
          ArrangeWindows();
          break;

        case KEY_CLOSE_WIN:
          PostMessage(GetForegroundWindow(), WM_CLOSE, 0, 0);
          break;
      }
      break;

    case WM_TIMER:
      switch (wParam)
      {
        case TIMER_UPDATE_MOUSE:
          UpdateMousePos(hwnd);
          break;
      }
      break;

    default:
      if (msg == shellhookid) { // Handle the Shell Hook message
        switch (wParam)
        {
          case HSHELL_WINDOWCREATED:
            if (IsGoodWindow((HWND)lParam)) {
              AddNode((HWND)lParam, current_tag);
              ArrangeWindows();
              FocusCurrent();
            }
            break;

          case HSHELL_WINDOWDESTROYED:
            FullRemoveNode((HWND)lParam);
            ArrangeWindows();
            FocusCurrent();
            break;

          case HSHELL_WINDOWACTIVATED:
            {
              node *found = FindNode((HWND)lParam, current_tag);
              if (found) {
                tags[current_tag].current_window = current = found;
                FocusCurrent();
              }
            }
            break;
        }
      } else {
        return DefWindowProc(hwnd, msg, wParam, lParam);
      }
  }
  return 0;
}