diff --git a/src/land.c b/src/land.c
index 03794aa..0a6b630 100644
--- a/src/land.c
+++ b/src/land.c
@@ -161,11 +161,11 @@ static void commodity_buy(char* str) {
   com = commodity_get(comname);
 
   if(player->credits <= q * com->medium) {
-    toolkit_alert("Not enough Scred!");
+    dialogue_alert("Not enough Scred!");
     return;
   }
   else if(player->cargo_free <= 0) {
-    toolkit_alert("not enough free space!");
+    dialogue_alert("not enough free space!");
     return;
   }
 
@@ -305,23 +305,23 @@ static void outfits_buy(char* str) {
 
   // Can player actually fit the outfit?
   if((pilot_freeSpace(player) - outfit->mass) < 0) {
-    toolkit_alert("No enough free space (you need %d more slots).",
+    dialogue_alert("No enough free space (you need %d more slots).",
                   outfit->mass - pilot_freeSpace(player));
     return;
   }
   else if(player_outfitOwned(outfitname) >= outfit->max) {
     // Already has too many.
-    toolkit_alert("You can only carry %d of this outfit.", outfit->max);
+    dialogue_alert("You can only carry %d of this outfit.", outfit->max);
     return;
   }
   else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
-    toolkit_alert("You can only have one afterburner.");
+    dialogue_alert("You can only have one afterburner.");
     return;
   }
   // Not enough $$.
   else if(q*(int)outfit->price >= player->credits) {
     credits2str(buf, q*outfit->price - player->credits, 2);
-    toolkit_alert("You need %s more SCred.", buf);
+    dialogue_alert("You need %s more SCred.", buf);
     return;
   }
 
@@ -343,7 +343,7 @@ static void outfits_sell(char* str) {
 
   if(player_outfitOwned(outfitname) <= 0) {
     // No outfits to sell.
-    toolkit_alert("You can't sell something you don't have!");
+    dialogue_alert("You can't sell something you don't have!");
     return;
   }
 
@@ -490,7 +490,7 @@ static void shipyard_buy(char* str) {
   ship = ship_get(shipname);
 
   credits2str(buf, ship->price, 2);
-  if(toolkit_YesNo("Are you sure?",
+  if(dialogue_YesNo("Are you sure?",
                    "Do you really want to spend %s on a new ship?", buf)==0);
   return;
 
@@ -613,14 +613,14 @@ static void shipyard_yoursChange(char* str) {
   shipname = toolkit_getList(terciary_wid, "lstYourShips");
   if(strcmp(shipname, "None")==0) {
     // No ships.
-    toolkit_alert("You need another ship to change to!");
+    dialogue_alert("You need another ship to change to!");
     return;
   }
 
   loc = player_getLoc(shipname);
 
   if(strcmp(loc, land_planet->name)) {
-    toolkit_alert("You must transport the ship to %s to be able to get in.",
+    dialogue_alert("You must transport the ship to %s to be able to get in.",
                   land_planet->name);
     return;
   }
@@ -639,20 +639,20 @@ static void shipyard_yoursTransport(char* str) {
 
   shipname = toolkit_getList(terciary_wid, "lstYourShips");
   if(strcmp(shipname, "None")==0) { // No ships.
-    toolkit_alert("You can't transport nothing here!");
+    dialogue_alert("You can't transport nothing here!");
     return;
   }
 
   price = shipyard_yoursTransportPrice(shipname);
   if(price == 0) {
     // Already here.
-    toolkit_alert("Your ship '%s' is already here.", shipname);
+    dialogue_alert("Your ship '%s' is already here.", shipname);
     return;
   }
   else if(player->credits < price) {
     // You are broke.
     credits2str(buf, price-player->credits, 2);
-    toolkit_alert("You need %d more credits to transport '%s' here.",
+    dialogue_alert("You need %d more credits to transport '%s' here.",
                   buf, shipname);
     return;
   }
diff --git a/src/player.c b/src/player.c
index 204725c..10d54bb 100644
--- a/src/player.c
+++ b/src/player.c
@@ -125,9 +125,7 @@ extern void weapon_minimap(const double res,
 extern void planets_minimap(const double res,
                             const double w, const double h, const RadarShape shape); // space.c
 // Internal.
-static void player_nameClose(char* str);
 static void player_newMake(void);
-static void player_nameShipClose(char* str);
 static void player_newShipMake(char* name);
 static void rect_parse(const xmlNodePtr parent,
                        double* x, double* y, double* w, double* h);
@@ -140,8 +138,6 @@ void player_destroyed(void);
 
 // Prompt player name.
 void player_new(void) {
-  unsigned int wid;
-  
   // Let's not seg fault due to a lack of environment.
   player_setFlag(PLAYER_DESTROYED);
   vectnull(&player_cam);
@@ -150,32 +146,8 @@ void player_new(void) {
   // Cleanup player stuff if we'll be re-creating.
   player_cleanup();
 
-  wid = window_create("Player Name", -1, -1, 240, 140);
-
-  window_addText(wid, 30, -30, 180, 20, 0, "txtInfo",
-                 &gl_smallFont, &cDConsole, "Please tell me your name:");
-  window_addInput(wid, 20, -50, 200, 20, "inpName", 20, 1);
-  window_addButton(wid, -20, 20, 80, 30, "btnClose", "Done", player_nameClose);
-
-  window_setFptr(wid, player_nameClose);
-}
-
-static void player_nameClose(char* str) {
-  (void)str;
-  unsigned int wid;
-  char* name;
-
-  wid = window_get("Player Name");
-  name = window_getInput(wid, "inpName");
-
-  if(strlen(name) < 3) {
-    toolkit_alert("Your name must be at least three characters long.");
-    return;
-  }
-
-  player_name = strdup(name);
-  window_destroy(wid);
-
+  player_name = dialogue_input("Player Name", 3, 20,
+                               "Please tell me your name:");
   player_newMake();
 }
 
@@ -252,7 +224,7 @@ static void player_newMake(void) {
 void player_newShip(Ship* ship, double px, double py,
                     double vx, double vy, double dir) {
 
-  unsigned int wid;
+  char* ship_name;
 
   // Temp values while player doesn't exist.
   player_ship = ship;
@@ -262,47 +234,11 @@ void player_newShip(Ship* ship, double px, double py,
   player_vy   = vy;
   player_dir  = dir;
 
-  wid = window_create("Ship Name", -1, 1, 240, 140);
-
-  window_addText(wid, 30, -30, 180, 20, 0, "txtInfo",
-                 &gl_smallFont, &cDConsole, "Name your ship:");
-  window_addInput(wid, 20, -50, 200, 20, "inpName", 20, 1);
-  window_addButton(wid, -20, 20, 80, 30, "btnClose", "Done",
-                   player_nameShipClose);
-
-  window_setFptr(wid, player_nameShipClose);
-}
-
-static void player_nameShipClose(char* str) {
-  (void)str;
-  int i;
-  char* ship_name;
-  unsigned int wid;
-
-  wid = window_get("Ship Name");
-  ship_name = window_getInput(wid, "inpName");
- 
-  if(strlen(ship_name) < 3) {
-    toolkit_alert("Your ship's name must be at least three characters long.");
-    return;
-  }
-
-  // Do not repeat the same ship name.
-  if(player && (strcmp(ship_name, player->name)==0)) {
-    toolkit_alert("You cannot name two ships the same!");
-    return;
-  }
-
-  for(i = 0; i < player_nstack; i++) {
-    if(strcmp(player_stack[i]->name, ship_name)==0) {
-      toolkit_alert("You cannot name two ships the same");
-      return;
-    }
-  }
-  
+  ship_name = dialogue_input("Player Name", 3, 20,
+                             "Please name your shiny new %s", ship->name);
   player_newShipMake(ship_name);
 
-  window_destroy(wid);
+  free(ship->name);
 }
 
 // Change the players ship.
diff --git a/src/toolkit.c b/src/toolkit.c
index b0a8144..c19bb0d 100644
--- a/src/toolkit.c
+++ b/src/toolkit.c
@@ -144,12 +144,13 @@ static void toolkit_drawOutline(double x, double y, double w,
                                 double h, double b, glColour* c, glColour* lc);
 static void toolkit_drawRect(double x, double y, double w, double h,
                              glColour* c, glColour* lc);
-// Misc.
-static void toolkit_alertClose(char* str);
-static void toolkit_YesNoClose(char* str);
+// Dialogues..
+static void dialogue_alertClose(char* str);
+static void dialogue_YesNoClose(char* str);
+static void dialogue_inputClose(char* str);
 // Secondary loop hack.
 static int loop_done;
-static void toolkit_loop(void);
+static int toolkit_loop(void);
 
 // Add a button that when pressed will trigger call, passing it's name as the
 // only parameter.
@@ -1321,7 +1322,7 @@ static Widget* toolkit_getFocus(void) {
   return &wdw->widgets[wdw->focus];
 }
 
-void toolkit_alert(const char* fmt, ...) {
+void dialogue_alert(const char* fmt, ...) {
   char msg[256];
   va_list ap;
   unsigned int wdw;
@@ -1342,10 +1343,10 @@ void toolkit_alert(const char* fmt, ...) {
                  &gl_smallFont, &cBlack, msg);
 
   window_addButton(wdw, 135, 20, 50, 30, "btnOK", "OK",
-                   toolkit_alertClose);
+                   dialogue_alertClose);
 }
 
-static void toolkit_alertClose(char* str) {
+static void dialogue_alertClose(char* str) {
   (void)str;
   if(window_exists("Warning"))
     window_destroy(window_get("Warning"));
@@ -1354,7 +1355,7 @@ static void toolkit_alertClose(char* str) {
 // Runs a dialogue with a Yes No button, return 1 if yes.
 static int yesno_result;
 static unsigned int yesno_wid = 0;
-int toolkit_YesNo(char* caption, const char* fmt, ...) {
+int dialogue_YesNo(char* caption, const char* fmt, ...) {
   char msg[256];
   va_list ap;
 
@@ -1371,14 +1372,14 @@ int toolkit_YesNo(char* caption, const char* fmt, ...) {
   // Create window.
   yesno_wid = window_create(caption, -1, -1, 300, 140);
   // Text.
-  window_addText(yesno_wid, 20, -30, 260, 70, 0, "txtAlert",
+  window_addText(yesno_wid, 20, -30, 260, 70, 0, "txtYesNo",
                  &gl_smallFont, &cBlack, msg);
   // Buttons.
   window_addButton(yesno_wid, 300/2-50-10, 20, 50, 30, "btnYes", "Yes",
-                   toolkit_YesNoClose);
+                   dialogue_YesNoClose);
 
   window_addButton(yesno_wid, 300/2+50+10, 20, 50, 30, "btnNo", "No",
-                   toolkit_YesNoClose);
+                   dialogue_YesNoClose);
 
   // Tricky secondary loop.
   toolkit_loop();
@@ -1387,7 +1388,7 @@ int toolkit_YesNo(char* caption, const char* fmt, ...) {
   return yesno_result;
 }
 
-static void toolkit_YesNoClose(char* str) {
+static void dialogue_YesNoClose(char* str) {
   // Store the result.
   if(strcmp(str, "btnYes")==0) yesno_result = 1;
   else if(strcmp(str, "btnNo")==0) yesno_result = 0;
@@ -1399,6 +1400,67 @@ static void toolkit_YesNoClose(char* str) {
   loop_done = 1;
 }
 
+// Toolkit input boxes, return input.
+static unsigned int input_wid = 0;
+char* dialogue_input(char* title, int min, int max, const char* fmt, ...) {
+  char msg[256], *input;
+  va_list ap;
+
+  if(input_wid) return NULL;
+
+  if(fmt == NULL) return NULL;
+  else {
+    // Get the message.
+    va_start(ap, fmt);
+    vsprintf(msg, fmt, ap);
+    va_end(ap);
+  }
+
+  // Create the window.
+  input_wid = window_create(title, -1, -1, 240, 160);
+  window_setFptr(input_wid, dialogue_inputClose);
+  // Text.
+  window_addText(input_wid, 30, -30, 200, 40, 0, "txtInput",
+                 &gl_smallFont, &cDConsole, msg);
+
+  // Input.
+  window_addInput(input_wid, 20, -70, 200, 20, "inpInput", max, 1);
+
+  //Button.
+  window_addButton(input_wid, -20, 20, 80, 30,
+                   "btnClose", "Done", dialogue_inputClose);
+
+  // Tricky secondary loop.
+  input = NULL;
+  while(!input || ((int)strlen(input) < min)) {
+    // Must be longer than min.
+    if(input) {
+      dialogue_alert("Input must be at least %d characters long!", min);
+      free(input);
+      input = NULL;
+    }
+
+    if(toolkit_loop()) // Error in loop -> quit.
+      return NULL;
+
+    // Save the input.
+    input = strdup(window_getInput(input_wid, "inpInput"));
+  }
+
+  // Cleanup.
+  window_destroy(input_wid);
+  input_wid = 0;
+
+  return input;
+}
+
+static void dialogue_inputClose(char* str) {
+  (void)str;
+
+  // Break the loop.
+  loop_done = 1;
+}
+
 // Init.
 int toolkit_init(void) {
   windows = malloc(sizeof(Window)*MIN_WINDOWS);
@@ -1419,8 +1481,8 @@ void toolkit_exit(void) {
 
 // Spawns a secondary loop that only works until the toolkit dies.
 // A lot like the main while loop in lephisto.c.
-static void toolkit_loop(void) {
-  SDL_Event event;
+static int toolkit_loop(void) {
+  SDL_Event event, quit = { .type = SDL_QUIT };
 
   loop_done = 0;
   while(!loop_done && toolkit) {
@@ -1428,13 +1490,15 @@ static void toolkit_loop(void) {
       // Event loopz.
       if(event.type == SDL_QUIT) {
         // Pass quit event to main engine.
-        SDL_PushEvent(&event);
-        return;
+        loop_done = 1;
+        SDL_PushEvent(&quit);
+        return 1;
       }
       // Handles all the events and player keybinds.
       input_handle(&event);
     }
     main_loop();
   }
+  return 0;
 }
 
diff --git a/src/toolkit.h b/src/toolkit.h
index e1ba54f..302d658 100644
--- a/src/toolkit.h
+++ b/src/toolkit.h
@@ -44,8 +44,9 @@ void window_addInput(const unsigned int wid,
                      char* name, const int max, const int oneline);
 
 // Popups and alerts.
-void toolkit_alert(const char* fmt, ...);
-int toolkit_YesNo(char* caption, const char* fmt, ...);
+void  dialogue_alert(const char* fmt, ...);
+int   dialogue_YesNo(char* caption, const char* fmt, ...);
+char* dialogue_input(char* title, int min, int max, const char* fmt, ...);
 
 // Modification.
 void window_setFptr(const unsigned int wid, void(*fptr)(char*));